11#pragma once
22
3+ #include < charconv>
34#include < mt-kahypar/io/hypergraph_factory.h>
45#include < filesystem>
56#include < fstream>
@@ -49,15 +50,31 @@ namespace mt_kahypar::dyn {
4950 std::cout.flush ();
5051 }
5152
52- inline std::vector<HypernodeID> parseIDs (const std::string& line) {
53- std::vector<HypernodeID> ids;
54- std::stringstream ss (line);
55- int id;
56- while (ss >> id) {
57- ids.push_back (id);
58- }
59- return ids;
53+ inline std::vector<HypernodeID> parseIDs (const std::string& line) {
54+ std::vector<HypernodeID> ids;
55+ ids.reserve (2 );
56+
57+ const char * p = line.data ();
58+ const char * end = p + line.size ();
59+
60+ while (p < end) {
61+ // skip whitespace
62+ while (p < end && *p <= ' ' ) ++p;
63+ if (p >= end) break ;
64+
65+ HypernodeID id;
66+ auto [np, ec] = std::from_chars (p, end, id);
67+ if (ec == std::errc ()) {
68+ ids.push_back (id);
69+ p = np;
70+ } else {
71+ // skip malformed token
72+ while (p < end && *p > ' ' ) ++p;
6073 }
74+ }
75+
76+ return ids;
77+ }
6178
6279 inline std::vector<PinChange> parsePins (const std::string& line) {
6380 std::vector<PinChange> pins;
@@ -78,6 +95,47 @@ namespace mt_kahypar::dyn {
7895 return pins;
7996 }
8097
98+ inline std::vector<PinChange> parsePins_fast (const std::string& line) {
99+ std::vector<PinChange> pins;
100+ pins.reserve (16 );
101+
102+ const char * p = line.data ();
103+ const char * end = p + line.size ();
104+
105+ while (p < end) {
106+ // Skip whitespace
107+ while (p < end && *p <= ' ' ) ++p;
108+ if (p >= end) break ;
109+
110+ if (*p != ' (' ) {
111+ // Malformed token, skip
112+ while (p < end && *p > ' ' ) ++p;
113+ continue ;
114+ }
115+ ++p; // skip '('
116+
117+ HypernodeID node;
118+ auto [p1, ec1] = std::from_chars (p, end, node);
119+ if (ec1 != std::errc ()) break ;
120+ p = p1;
121+
122+ if (p >= end || *p != ' ,' ) break ;
123+ ++p; // skip ','
124+
125+ HyperedgeID edge;
126+ auto [p2, ec2] = std::from_chars (p, end, edge);
127+ if (ec2 != std::errc ()) break ;
128+ p = p2;
129+
130+ if (p >= end || *p != ' )' ) break ;
131+ ++p; // skip ')'
132+
133+ pins.push_back ({node, edge});
134+ }
135+
136+ return pins;
137+ }
138+
81139 inline std::string getNextNonCommentLine (std::ifstream& file) {
82140 std::string line;
83141 while (std::getline (file, line)) {
@@ -98,7 +156,6 @@ namespace mt_kahypar::dyn {
98156 // removed_edges_id1 removed_edges_id2, ...
99157 // (removed_pins1.hypernode,removed_pins1.hyperedge) (removed_pins2.hypernode,removed_pins2.hyperedge), ...
100158 inline std::vector<Change> parseChanges (const std::string& filename) {
101- std::vector<Change> changes;
102159 std::ifstream file (filename);
103160 if (!file.is_open ()) {
104161 throw std::runtime_error (" Could not open file: " + filename);
@@ -110,35 +167,46 @@ namespace mt_kahypar::dyn {
110167 size_t num_changes = std::stoi (line);
111168 // file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Move to the next line
112169
113- for (size_t i = 0 ; i < num_changes; ++i) {
114- Change change;
115-
116- // Parse added nodes
117- line = getNextNonCommentLine (file);
118- change.added_nodes = parseIDs (line);
119-
120- // Parse added edges
121- line = getNextNonCommentLine (file);
122- change.added_edges = parseIDs (line);
123-
124- // Parse added pins
125- line = getNextNonCommentLine (file);
126- change.added_pins = parsePins (line);
170+ std::vector<Change> changes;
171+ changes.reserve (num_changes);
172+ for (size_t i = 0 ; i < num_changes; ++i) { // Parse added nodes
127173
128- // Parse removed nodes
129- line = getNextNonCommentLine (file);
130- change.removed_nodes = parseIDs (line);
174+ // line = getNextNonCommentLine(file);
175+ // change.added_nodes = parseIDs(line);
176+ //
177+ // // Parse added edges
178+ // line = getNextNonCommentLine(file);
179+ // change.added_edges = parseIDs(line);
180+ //
181+ // // Parse added pins
182+ // line = getNextNonCommentLine(file);
183+ // change.added_pins = parsePins_fast(line);
184+ //
185+ // // Parse removed nodes
186+ // line = getNextNonCommentLine(file);
187+ // change.removed_nodes = parseIDs(line);
188+ //
189+ // // Parse removed edges
190+ // line = getNextNonCommentLine(file);
191+ // change.removed_edges = parseIDs(line);
192+ //
193+ // // Parse removed pins
194+ // line = getNextNonCommentLine(file);
195+ // change.removed_pins = parsePins_fast(line);
131196
132- // Parse removed edges
133- line = getNextNonCommentLine (file);
134- change.removed_edges = parseIDs (line);
197+ changes.emplace_back (Change{
198+ parseIDs (getNextNonCommentLine (file)), // added nodes
199+ parseIDs (getNextNonCommentLine (file)), // added edges
200+ parsePins_fast (getNextNonCommentLine (file)), // added pins
201+ parseIDs (getNextNonCommentLine (file)), // removed nodes
202+ parseIDs (getNextNonCommentLine (file)), // removed edges
203+ parsePins_fast (getNextNonCommentLine (file)) // removed pins
204+ });
135205
136- // Parse removed pins
137- line = getNextNonCommentLine (file) ;
138- change. removed_pins = parsePins (line);
206+ if (i % 1000000 == 0 ) {
207+ std::cout << " Parsed " << i << " / " << num_changes << " changes \r " << std::flush ;
208+ }
139209
140- // Add the parsed change to the list
141- changes.push_back (change);
142210 }
143211
144212 file.close ();
0 commit comments