@@ -27,27 +27,21 @@ using namespace std;
27
27
#include " read_xml_arch_file.h"
28
28
#include " globals.h"
29
29
#include " atom_netlist.h"
30
- #include " hash.h"
31
30
#include " prepack.h"
32
31
#include " vpr_utils.h"
33
32
#include " echo_files.h"
34
33
35
34
/* ****************************************/
36
35
/* Local Function Declaration */
37
36
/* ****************************************/
38
- static int add_pattern_name_to_hash (t_hash **nhash,
39
- const char *pattern_name, int *ncount);
40
-
41
37
static void discover_pattern_names_in_pb_graph_node (
42
- t_pb_graph_node *pb_graph_node, t_hash **nhash,
43
- int *ncount);
38
+ t_pb_graph_node *pb_graph_node, std::unordered_map<std::string, int >& pattern_names);
44
39
45
40
static void forward_infer_pattern (t_pb_graph_pin *pb_graph_pin);
46
41
47
42
static void backward_infer_pattern (t_pb_graph_pin *pb_graph_pin);
48
43
49
- static t_pack_patterns *alloc_and_init_pattern_list_from_hash (const int ncount,
50
- t_hash **nhash);
44
+ static t_pack_patterns *alloc_and_init_pattern_list_from_hash (std::unordered_map<std::string, int > pattern_names);
51
45
52
46
static t_pb_graph_edge * find_expansion_edge_of_pattern (const int pattern_index,
53
47
const t_pb_graph_node *pb_graph_node);
@@ -122,29 +116,26 @@ static AtomBlockId get_driving_block(const AtomBlockId block_id, const t_model_p
122
116
* If this limitation is too constraining, code is designed so that this limitation can be removed.
123
117
*/
124
118
t_pack_patterns *alloc_and_load_pack_patterns (int *num_packing_patterns) {
125
- int i, j, ncount, k;
119
+
126
120
int L_num_blocks;
127
- t_hash **nhash;
128
121
t_pack_patterns *list_of_packing_patterns;
129
122
t_pb_graph_edge *expansion_edge;
130
123
auto & device_ctx = g_vpr_ctx.device ();
131
124
132
125
/* alloc and initialize array of packing patterns based on architecture complex blocks */
133
- nhash = alloc_hash_table ();
134
- ncount = 0 ;
135
- for (i = 0 ; i < device_ctx.num_block_types ; i++) {
136
- discover_pattern_names_in_pb_graph_node (
137
- device_ctx.block_types [i].pb_graph_head , nhash, &ncount);
126
+ std::unordered_map<std::string, int > pattern_names;
127
+ for (int i = 0 ; i < device_ctx.num_block_types ; i++) {
128
+ discover_pattern_names_in_pb_graph_node (device_ctx.block_types [i].pb_graph_head , pattern_names);
138
129
}
139
130
140
- list_of_packing_patterns = alloc_and_init_pattern_list_from_hash (ncount, nhash );
131
+ list_of_packing_patterns = alloc_and_init_pattern_list_from_hash (pattern_names );
141
132
142
133
/* load packing patterns by traversing the edges to find edges belonging to pattern */
143
- for (i = 0 ; i < ncount ; i++) {
144
- for (j = 0 ; j < device_ctx.num_block_types ; j++) {
134
+ for (size_t i = 0 ; i < pattern_names. size () ; i++) {
135
+ for (int j = 0 ; j < device_ctx.num_block_types ; j++) {
145
136
// find an edge that belongs to this pattern
146
137
expansion_edge = find_expansion_edge_of_pattern (i, device_ctx.block_types [j].pb_graph_head );
147
- if (expansion_edge == nullptr ) {
138
+ if (! expansion_edge) {
148
139
continue ;
149
140
}
150
141
@@ -162,7 +153,7 @@ t_pack_patterns *alloc_and_load_pack_patterns(int *num_packing_patterns) {
162
153
* of size, it is optional whether or not an atom in a netlist matches any
163
154
* particular block inside the chain */
164
155
list_of_packing_patterns[i].is_block_optional = (bool *) vtr::malloc (L_num_blocks * sizeof (bool ));
165
- for (k = 0 ; k < L_num_blocks; k++) {
156
+ for (int k = 0 ; k < L_num_blocks; k++) {
166
157
list_of_packing_patterns[i].is_block_optional [k] = false ;
167
158
if (list_of_packing_patterns[i].is_chain && list_of_packing_patterns[i].root_block ->block_id != k) {
168
159
list_of_packing_patterns[i].is_block_optional [k] = true ;
@@ -181,73 +172,55 @@ t_pack_patterns *alloc_and_load_pack_patterns(int *num_packing_patterns) {
181
172
}
182
173
183
174
// Sanity check, every pattern should have a root block
184
- for (i = 0 ; i < ncount ; ++i) {
175
+ for (size_t i = 0 ; i < pattern_names. size () ; ++i) {
185
176
if (list_of_packing_patterns[i].root_block == nullptr ) {
186
177
VPR_THROW (VPR_ERROR_ARCH, " Failed to find root block for pack pattern %s" , list_of_packing_patterns[i].name );
187
178
}
188
179
}
189
180
190
- free_hash_table (nhash);
191
-
192
- *num_packing_patterns = ncount;
181
+ *num_packing_patterns = pattern_names.size ();
193
182
194
183
195
184
return list_of_packing_patterns;
196
185
}
197
186
198
- /* *
199
- * Adds pack pattern name to hashtable of pack pattern names.
200
- */
201
- static int add_pattern_name_to_hash (t_hash **nhash,
202
- const char *pattern_name, int *ncount) {
203
- t_hash *hash_value;
204
-
205
- hash_value = insert_in_hash_table (nhash, pattern_name, *ncount);
206
- if (hash_value->count == 1 ) {
207
- VTR_ASSERT (*ncount == hash_value->index );
208
- (*ncount)++;
209
- }
210
- return hash_value->index ;
211
- }
212
187
213
188
/* *
214
189
* Locate all pattern names
215
190
* Side-effect: set all pb_graph_node temp_scratch_pad field to NULL
216
191
* For cases where a pattern inference is "obvious", mark it as obvious.
217
192
*/
218
193
static void discover_pattern_names_in_pb_graph_node (
219
- t_pb_graph_node *pb_graph_node, t_hash **nhash,
220
- int *ncount) {
221
- int i, j, k, m;
222
- int index;
223
- bool hasPattern;
194
+ t_pb_graph_node *pb_graph_node, std::unordered_map<std::string, int >& pattern_names) {
195
+
224
196
/* Iterate over all edges to discover if an edge in current physical block belongs to a pattern
225
- If edge does, then record the name of the pattern in a hash table
226
- */
197
+ If edge does, then record the name of the pattern in a hash table */
227
198
228
199
if (pb_graph_node == nullptr ) {
229
200
return ;
230
201
}
231
202
232
203
pb_graph_node->temp_scratch_pad = nullptr ;
233
204
234
- for (i = 0 ; i < pb_graph_node->num_input_ports ; i++) {
235
- for (j = 0 ; j < pb_graph_node->num_input_pins [i]; j++) {
236
- hasPattern = false ;
237
- for (k = 0 ; k < pb_graph_node->input_pins [i][j].num_output_edges ; k++) {
238
- for (m = 0 ; m < pb_graph_node->input_pins [i][j].output_edges [k]->num_pack_patterns ; m++) {
205
+ for (int i = 0 ; i < pb_graph_node->num_input_ports ; i++) {
206
+ for (int j = 0 ; j < pb_graph_node->num_input_pins [i]; j++) {
207
+ bool hasPattern = false ;
208
+ for (int k = 0 ; k < pb_graph_node->input_pins [i][j].num_output_edges ; k++) {
209
+ auto output_edge = pb_graph_node->input_pins [i][j].output_edges [k];
210
+ for (int m = 0 ; m < output_edge->num_pack_patterns ; m++) {
239
211
hasPattern = true ;
240
- index = add_pattern_name_to_hash (nhash,
241
- pb_graph_node->input_pins [i][j].output_edges [k]->pack_pattern_names [m], ncount);
242
- if (pb_graph_node->input_pins [i][j].output_edges [k]->pack_pattern_indices == nullptr ) {
243
- pb_graph_node->input_pins [i][j].output_edges [k]->pack_pattern_indices =
244
- (int *) vtr::malloc (pb_graph_node->input_pins [i][j].output_edges [k]->num_pack_patterns
245
- * sizeof (int ));
212
+ // insert the found pattern name to the hash table. If this pattern is inserted
213
+ // for the first time, then its index is the current size of the hash table
214
+ // otherwise the insert function will return an iterator of the previously
215
+ // inserted element with the index given to that pattern
216
+ std::string pattern_name (output_edge->pack_pattern_names [m]);
217
+ int index = (pattern_names.insert ({pattern_name, pattern_names.size ()}).first )->second ;
218
+ if (!output_edge->pack_pattern_indices ) {
219
+ output_edge->pack_pattern_indices = (int *) vtr::malloc (output_edge->num_pack_patterns * sizeof (int ));
246
220
}
247
- pb_graph_node-> input_pins [i][j]. output_edges [k] ->pack_pattern_indices [m] = index;
221
+ output_edge ->pack_pattern_indices [m] = index;
248
222
// if this output edges belongs to a pack pattern. Expand forward starting from
249
223
// all its output pins to check if you need to infer pattern for direct connections
250
- auto & output_edge = pb_graph_node->input_pins [i][j].output_edges [k];
251
224
for (int ipin = 0 ; ipin < output_edge->num_output_pins ; ipin++) {
252
225
forward_infer_pattern (output_edge->output_pins [ipin]);
253
226
}
@@ -256,29 +229,31 @@ static void discover_pattern_names_in_pb_graph_node(
256
229
// if the output edge to this pin is annotated with a pack pattern
257
230
// trace the inputs to this pin and mark them to infer pattern
258
231
// if they are direct connections (num_input_edges == 1)
259
- if (hasPattern == true ) {
232
+ if (hasPattern) {
260
233
backward_infer_pattern (&pb_graph_node->input_pins [i][j]);
261
234
}
262
235
}
263
236
}
264
237
265
- for (i = 0 ; i < pb_graph_node->num_output_ports ; i++) {
266
- for (j = 0 ; j < pb_graph_node->num_output_pins [i]; j++) {
267
- hasPattern = false ;
268
- for (k = 0 ; k < pb_graph_node->output_pins [i][j].num_output_edges ; k++) {
269
- for (m = 0 ; m < pb_graph_node->output_pins [i][j].output_edges [k]->num_pack_patterns ; m++) {
238
+ for (int i = 0 ; i < pb_graph_node->num_output_ports ; i++) {
239
+ for (int j = 0 ; j < pb_graph_node->num_output_pins [i]; j++) {
240
+ bool hasPattern = false ;
241
+ for (int k = 0 ; k < pb_graph_node->output_pins [i][j].num_output_edges ; k++) {
242
+ auto output_edge = pb_graph_node->output_pins [i][j].output_edges [k];
243
+ for (int m = 0 ; m < output_edge->num_pack_patterns ; m++) {
270
244
hasPattern = true ;
271
- index = add_pattern_name_to_hash (nhash,
272
- pb_graph_node->output_pins [i][j].output_edges [k]->pack_pattern_names [m], ncount);
273
- if (pb_graph_node->output_pins [i][j].output_edges [k]->pack_pattern_indices == nullptr ) {
274
- pb_graph_node->output_pins [i][j].output_edges [k]->pack_pattern_indices =
275
- (int *) vtr::malloc (pb_graph_node->output_pins [i][j].output_edges [k]->num_pack_patterns
276
- * sizeof (int ));
245
+ // insert the found pattern name to the hash table. If this pattern is inserted
246
+ // for the first time, then its index is the current size of the hash table
247
+ // otherwise the insert function will return an iterator of the previously
248
+ // inserted element with the index given to that pattern
249
+ std::string pattern_name (output_edge->pack_pattern_names [m]);
250
+ int index = (pattern_names.insert ({pattern_name, pattern_names.size ()}).first )->second ;
251
+ if (!output_edge->pack_pattern_indices ) {
252
+ output_edge->pack_pattern_indices = (int *) vtr::malloc (output_edge->num_pack_patterns * sizeof (int ));
277
253
}
278
- pb_graph_node-> output_pins [i][j]. output_edges [k] ->pack_pattern_indices [m] = index;
254
+ output_edge ->pack_pattern_indices [m] = index;
279
255
// if this output edges belongs to a pack pattern. Expand forward starting from
280
256
// all its output pins to check if you need to infer pattern for direct connections
281
- auto & output_edge = pb_graph_node->output_pins [i][j].output_edges [k];
282
257
for (int ipin = 0 ; ipin < output_edge->num_output_pins ; ipin++) {
283
258
forward_infer_pattern (output_edge->output_pins [ipin]);
284
259
}
@@ -287,29 +262,31 @@ static void discover_pattern_names_in_pb_graph_node(
287
262
// if the output edge to this pin is annotated with a pack pattern
288
263
// trace the inputs to this pin and mark them to infer pattern
289
264
// if they are direct connections (num_input_edges == 1)
290
- if (hasPattern == true ) {
265
+ if (hasPattern) {
291
266
backward_infer_pattern (&pb_graph_node->output_pins [i][j]);
292
267
}
293
268
}
294
269
}
295
270
296
- for (i = 0 ; i < pb_graph_node->num_clock_ports ; i++) {
297
- for (j = 0 ; j < pb_graph_node->num_clock_pins [i]; j++) {
298
- hasPattern = false ;
299
- for (k = 0 ; k < pb_graph_node->clock_pins [i][j].num_output_edges ; k++) {
300
- for (m = 0 ; m < pb_graph_node->clock_pins [i][j].output_edges [k]->num_pack_patterns ; m++) {
271
+ for (int i = 0 ; i < pb_graph_node->num_clock_ports ; i++) {
272
+ for (int j = 0 ; j < pb_graph_node->num_clock_pins [i]; j++) {
273
+ bool hasPattern = false ;
274
+ for (int k = 0 ; k < pb_graph_node->clock_pins [i][j].num_output_edges ; k++) {
275
+ auto & output_edge = pb_graph_node->clock_pins [i][j].output_edges [k];
276
+ for (int m = 0 ; m < output_edge->num_pack_patterns ; m++) {
301
277
hasPattern = true ;
302
- index = add_pattern_name_to_hash (nhash,
303
- pb_graph_node->clock_pins [i][j].output_edges [k]->pack_pattern_names [m], ncount);
304
- if (pb_graph_node->clock_pins [i][j].output_edges [k]->pack_pattern_indices == nullptr ) {
305
- pb_graph_node->clock_pins [i][j].output_edges [k]->pack_pattern_indices =
306
- (int *) vtr::malloc (pb_graph_node->clock_pins [i][j].output_edges [k]->num_pack_patterns
307
- * sizeof (int ));
278
+ // insert the found pattern name to the hash table. If this pattern is inserted
279
+ // for the first time, then its index is the current size of the hash table
280
+ // otherwise the insert function will return an iterator of the previously
281
+ // inserted element with the index given to that pattern
282
+ std::string pattern_name (output_edge->pack_pattern_names [m]);
283
+ int index = (pattern_names.insert ({pattern_name, pattern_names.size ()}).first )->second ;
284
+ if (output_edge->pack_pattern_indices == nullptr ) {
285
+ output_edge->pack_pattern_indices = (int *) vtr::malloc (output_edge->num_pack_patterns * sizeof (int ));
308
286
}
309
- pb_graph_node-> clock_pins [i][j]. output_edges [k] ->pack_pattern_indices [m] = index;
287
+ output_edge ->pack_pattern_indices [m] = index;
310
288
// if this output edges belongs to a pack pattern. Expand forward starting from
311
289
// all its output pins to check if you need to infer pattern for direct connections
312
- auto & output_edge = pb_graph_node->clock_pins [i][j].output_edges [k];
313
290
for (int ipin = 0 ; ipin < output_edge->num_output_pins ; ipin++) {
314
291
forward_infer_pattern (output_edge->output_pins [ipin]);
315
292
}
@@ -318,17 +295,17 @@ static void discover_pattern_names_in_pb_graph_node(
318
295
// if the output edge to this pin is annotated with a pack pattern
319
296
// trace the inputs to this pin and mark them to infer pattern
320
297
// if they are direct connections (num_input_edges == 1)
321
- if (hasPattern == true ) {
298
+ if (hasPattern) {
322
299
backward_infer_pattern (&pb_graph_node->clock_pins [i][j]);
323
300
}
324
301
}
325
302
}
326
303
327
- for (i = 0 ; i < pb_graph_node->pb_type ->num_modes ; i++) {
328
- for (j = 0 ; j < pb_graph_node->pb_type ->modes [i].num_pb_type_children ; j++) {
329
- for (k = 0 ; k < pb_graph_node->pb_type ->modes [i].pb_type_children [j].num_pb ; k++) {
304
+ for (int i = 0 ; i < pb_graph_node->pb_type ->num_modes ; i++) {
305
+ for (int j = 0 ; j < pb_graph_node->pb_type ->modes [i].num_pb_type_children ; j++) {
306
+ for (int k = 0 ; k < pb_graph_node->pb_type ->modes [i].pb_type_children [j].num_pb ; k++) {
330
307
discover_pattern_names_in_pb_graph_node (
331
- &pb_graph_node->child_pb_graph_nodes [i][j][k], nhash, ncount );
308
+ &pb_graph_node->child_pb_graph_nodes [i][j][k], pattern_names );
332
309
}
333
310
}
334
311
}
@@ -358,24 +335,18 @@ static void backward_infer_pattern(t_pb_graph_pin *pb_graph_pin) {
358
335
* Allocates memory for models and loads the name of the packing pattern
359
336
* so that it can be identified and loaded with more complete information later
360
337
*/
361
- static t_pack_patterns *alloc_and_init_pattern_list_from_hash (const int ncount,
362
- t_hash **nhash) {
363
- t_pack_patterns *nlist;
364
- t_hash_iterator hash_iter;
365
- t_hash *curr_pattern;
366
-
367
- nlist = new t_pack_patterns[ncount];
368
-
369
- hash_iter = start_hash_table_iterator ();
370
- curr_pattern = get_next_hash (nhash, &hash_iter);
371
- while (curr_pattern != nullptr ) {
372
- VTR_ASSERT (nlist[curr_pattern->index ].name == nullptr );
373
- nlist[curr_pattern->index ].name = vtr::strdup (curr_pattern->name );
374
- nlist[curr_pattern->index ].root_block = nullptr ;
375
- nlist[curr_pattern->index ].is_chain = false ;
376
- nlist[curr_pattern->index ].index = curr_pattern->index ;
377
- curr_pattern = get_next_hash (nhash, &hash_iter);
338
+ static t_pack_patterns *alloc_and_init_pattern_list_from_hash (std::unordered_map<std::string, int > pattern_names) {
339
+
340
+ t_pack_patterns* nlist = new t_pack_patterns[pattern_names.size ()];
341
+
342
+ for (const auto & curr_pattern : pattern_names) {
343
+ VTR_ASSERT (nlist[curr_pattern.second ].name == nullptr );
344
+ nlist[curr_pattern.second ].name = vtr::strdup (curr_pattern.first .c_str ());
345
+ nlist[curr_pattern.second ].root_block = nullptr ;
346
+ nlist[curr_pattern.second ].is_chain = false ;
347
+ nlist[curr_pattern.second ].index = curr_pattern.second ;
378
348
}
349
+
379
350
return nlist;
380
351
}
381
352
0 commit comments