11
22#include " stats.h"
33
4- #include < set>
54#include < fstream>
5+ #include < sstream>
6+ #include < vector>
7+ #include < algorithm>
8+ #include < filesystem>
69#include < string>
710#include < iomanip>
811
2528
2629#include " crr_common.h"
2730
31+ namespace fs = std::filesystem;
32+
2833/* ********************* Subroutines local to this module *********************/
2934
3035// Helper struct to parse the sb_id keys
@@ -66,14 +71,14 @@ static std::vector<std::vector<std::string>> read_and_trim_csv(const std::string
6671 std::string cell;
6772 int col_count = 0 ;
6873
69- if (row_count < NUM_EMPTY_ROWS) {
74+ if (row_count < crrgenerator:: NUM_EMPTY_ROWS) {
7075 // Keep entire row for first NUM_EMPTY_ROWS rows
7176 while (std::getline (ss, cell, ' ,' )) {
7277 row.push_back (cell);
7378 }
7479 } else {
7580 // Keep only first NUM_EMPTY_COLS columns for other rows
76- while (std::getline (ss, cell, ' ,' ) && col_count < NUM_EMPTY_COLS) {
81+ while (std::getline (ss, cell, ' ,' ) && col_count < crrgenerator:: NUM_EMPTY_COLS) {
7782 row.push_back (cell);
7883 col_count++;
7984 }
@@ -87,6 +92,23 @@ static std::vector<std::vector<std::string>> read_and_trim_csv(const std::string
8792 return data;
8893}
8994
95+ // Write 2D vector to CSV file
96+ void write_csv (const std::string& filepath, const std::vector<std::vector<std::string>>& data) {
97+ std::ofstream file (filepath);
98+
99+ for (size_t i = 0 ; i < data.size (); ++i) {
100+ for (size_t j = 0 ; j < data[i].size (); ++j) {
101+ file << data[i][j];
102+ if (j < data[i].size () - 1 ) {
103+ file << " ," ;
104+ }
105+ }
106+ file << " \n " ;
107+ }
108+
109+ file.close ();
110+ }
111+
90112/* *
91113 * @brief Loads the two arrays passed in with the total occupancy at each of the
92114 * channel segments in the FPGA.
@@ -188,7 +210,9 @@ void routing_stats(const Netlist<>& net_list,
188210 }
189211}
190212
191- void write_sb_count_stats (const Netlist<>& net_list, const std::string& /* out_dir*/ ) {
213+ void write_sb_count_stats (const Netlist<>& net_list,
214+ const std::string& sb_map_dir,
215+ const std::string& sb_count_dir) {
192216 const auto & rr_graph = g_vpr_ctx.device ().rr_graph ;
193217 const auto & route_ctx = g_vpr_ctx.routing ();
194218 std::unordered_map<std::string, int > sb_count;
@@ -226,6 +250,68 @@ void write_sb_count_stats(const Netlist<>& net_list, const std::string& /*out_di
226250 }
227251
228252 // Write the sb_count to a file
253+ // First, read all CSV files from directory and trim them
254+ std::unordered_map<std::string, std::vector<std::vector<std::string>>> csv_data;
255+
256+ for (const auto & entry : fs::directory_iterator (sb_map_dir)) {
257+ if (entry.is_regular_file () && entry.path ().extension () == " .csv" ) {
258+ std::string filename = entry.path ().filename ().string ();
259+ csv_data[filename] = read_and_trim_csv (entry.path ().string ());
260+ }
261+ }
262+
263+ // Group sb_count entries by filename
264+ std::unordered_map<std::string, std::vector<std::pair<int , std::pair<int , int >>>> file_groups;
265+
266+ for (const auto & [sb_id, count] : sb_count) {
267+ SBKeyParts parts = parse_sb_key (sb_id);
268+ file_groups[parts.filename ].push_back ({parts.row , {parts.col , count}});
269+ }
270+
271+ // Process each file
272+ for (auto & [filename, data] : csv_data) {
273+ // Check if this file has updates from sb_count
274+ if (file_groups.find (filename) == file_groups.end ()) {
275+ // No updates for this file, just write trimmed version
276+ std::string output_path = sb_count_dir + " /" + filename;
277+ write_csv (output_path, data);
278+ VTR_LOG (" Written trimmed CSV: %s\n " , filename.c_str ());
279+ continue ;
280+ }
281+
282+ const auto & entries = file_groups[filename];
283+
284+ // Find maximum row and column needed
285+ int max_row = 0 , max_col = 0 ;
286+ for (const auto & entry : entries) {
287+ max_row = std::max (max_row, entry.first );
288+ max_col = std::max (max_col, entry.second .first );
289+ }
290+
291+ // Expand data structure if needed
292+ while (data.size () <= static_cast <size_t >(max_row)) {
293+ data.push_back (std::vector<std::string>());
294+ }
295+
296+ for (auto & row : data) {
297+ while (row.size () <= static_cast <size_t >(max_col)) {
298+ row.push_back (" " );
299+ }
300+ }
301+
302+ // Update values from sb_count
303+ for (const auto & entry : entries) {
304+ int row = entry.first ;
305+ int col = entry.second .first ;
306+ int count = entry.second .second ;
307+ data[row][col] = std::to_string (count);
308+ }
309+
310+ // Write updated file
311+ std::string output_path = sb_count_dir + " /" + filename;
312+ write_csv (output_path, data);
313+ VTR_LOG (" Written switchbox counts to: %s\n " , filename.c_str ());
314+ }
229315}
230316
231317void length_and_bends_stats (const Netlist<>& net_list, bool is_flat) {
0 commit comments