@@ -52,12 +52,14 @@ void verify_segments(pugi::xml_node parent, const pugiutil::loc_data& loc_data,
52
52
void verify_blocks (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
53
53
void process_blocks (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
54
54
void verify_grid (pugi::xml_node parent, const pugiutil::loc_data& loc_data, const DeviceGrid& grid);
55
+ void process_nodes_and_switches_bin (FILE* fp, int * wire_to_rr_ipin_switch, bool is_global_graph, const std::vector<t_segment_inf>& segment_inf, int numSwitches);
55
56
void process_nodes (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
56
57
void process_edges (pugi::xml_node parent, const pugiutil::loc_data& loc_data, int * wire_to_rr_ipin_switch, const int num_rr_switches);
57
58
void process_channels (t_chan_width& chan_width, const DeviceGrid& grid, pugi::xml_node parent, const pugiutil::loc_data& loc_data);
58
59
void process_rr_node_indices (const DeviceGrid& grid);
59
60
void process_seg_id (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
60
61
void set_cost_indices (pugi::xml_node parent, const pugiutil::loc_data& loc_data, const bool is_global_graph, const int num_seg_types);
62
+ void set_cost_index_bin (int inode, t_rr_type node_type, const bool is_global_graph, const int num_seg_types, short seg_id);
61
63
62
64
/* *********************** Subroutine definitions ****************************/
63
65
@@ -137,41 +139,60 @@ void load_rr_file(const t_graph_type graph_type,
137
139
int max_chan_width = (is_global_graph ? 1 : nodes_per_chan.max );
138
140
VTR_ASSERT (max_chan_width > 0 );
139
141
140
- /* Alloc rr nodes and count count nodes */
141
- next_component = get_single_child (rr_graph, " rr_nodes" , loc_data);
142
-
143
- int num_rr_nodes = count_children (next_component, " node" , loc_data);
144
-
145
- device_ctx.rr_nodes .resize (num_rr_nodes);
146
- process_nodes (next_component, loc_data);
147
-
148
142
/* Loads edges, switches, and node look up tables*/
149
143
next_component = get_single_child (rr_graph, " switches" , loc_data);
150
144
151
145
int numSwitches = count_children (next_component, " switch" , loc_data);
152
146
device_ctx.rr_switch_inf .resize (numSwitches);
153
147
154
148
process_switches (next_component, loc_data);
149
+ /* Branches to binary format */
150
+ next_component = get_single_child (rr_graph, " binary_nodes_and_edges" , loc_data, OPTIONAL);
151
+ if (next_component) {
152
+ auto filename = get_attribute (next_component, " file" , loc_data).as_string (" " );
153
+ VTR_LOG (" Using Binary File: %s\n " , filename);
154
+ FILE* fp = fopen (filename, " rb" );
155
+ if (fp == NULL ) {
156
+ VPR_THROW (VPR_ERROR_OTHER, " Binary File %s Does Not Exist\n " , filename);
157
+ }
158
+
159
+ process_nodes_and_switches_bin (fp, wire_to_rr_ipin_switch, is_global_graph, segment_inf, numSwitches);
160
+
161
+ partition_rr_graph_edges (device_ctx);
162
+ process_rr_node_indices (grid);
163
+ init_fan_in (device_ctx.rr_nodes , device_ctx.rr_nodes .size ());
164
+ alloc_and_load_rr_indexed_data (segment_inf, device_ctx.rr_node_indices ,
165
+ max_chan_width, *wire_to_rr_ipin_switch, base_cost_type);
155
166
156
- next_component = get_single_child (rr_graph, " rr_edges" , loc_data);
157
- process_edges (next_component, loc_data, wire_to_rr_ipin_switch, numSwitches);
167
+ } else {
168
+ /* Alloc rr nodes and count count nodes */
169
+ next_component = get_single_child (rr_graph, " rr_nodes" , loc_data);
170
+
171
+ int num_rr_nodes = count_children (next_component, " node" , loc_data);
172
+
173
+ device_ctx.rr_nodes .resize (num_rr_nodes);
174
+ process_nodes (next_component, loc_data);
158
175
159
- // Partition the rr graph edges for efficient access to configurable/non-configurable
160
- // edge subsets. Must be done after RR switches have been allocated
161
- partition_rr_graph_edges (device_ctx);
176
+ next_component = get_single_child (rr_graph, " rr_edges" , loc_data);
177
+ process_edges (next_component, loc_data, wire_to_rr_ipin_switch, numSwitches);
162
178
163
- process_rr_node_indices (grid);
179
+ // Partition the rr graph edges for efficient access to configurable/non-configurable
180
+ // edge subsets. Must be done after RR switches have been allocated
181
+ partition_rr_graph_edges (device_ctx);
164
182
165
- init_fan_in (device_ctx. rr_nodes , device_ctx. rr_nodes . size () );
183
+ process_rr_node_indices (grid );
166
184
167
- // sets the cost index and seg id information
168
- next_component = get_single_child (rr_graph, " rr_nodes" , loc_data);
169
- set_cost_indices (next_component, loc_data, is_global_graph, segment_inf.size ());
185
+ init_fan_in (device_ctx.rr_nodes , device_ctx.rr_nodes .size ());
170
186
171
- alloc_and_load_rr_indexed_data (segment_inf, device_ctx.rr_node_indices ,
172
- max_chan_width, *wire_to_rr_ipin_switch, base_cost_type);
187
+ // sets the cost index and seg id information
188
+ next_component = get_single_child (rr_graph, " rr_nodes" , loc_data);
189
+ set_cost_indices (next_component, loc_data, is_global_graph, segment_inf.size ());
173
190
174
- process_seg_id (next_component, loc_data);
191
+ alloc_and_load_rr_indexed_data (segment_inf, device_ctx.rr_node_indices ,
192
+ max_chan_width, *wire_to_rr_ipin_switch, base_cost_type);
193
+
194
+ process_seg_id (next_component, loc_data);
195
+ }
175
196
176
197
device_ctx.chan_width = nodes_per_chan;
177
198
device_ctx.read_rr_graph_filename = std::string (read_rr_graph_name);
@@ -183,6 +204,103 @@ void load_rr_file(const t_graph_type graph_type,
183
204
}
184
205
}
185
206
207
+ void process_nodes_and_switches_bin (FILE* fp,
208
+ int * wire_to_rr_ipin_switch,
209
+ bool is_global_graph,
210
+ const std::vector<t_segment_inf>& segment_inf,
211
+ int numSwitches) {
212
+ auto & device_ctx = g_vpr_ctx.mutable_device ();
213
+ uint32_t magic_num;
214
+ uint16_t format_version;
215
+ uint16_t header_length;
216
+ uint64_t num_rr_nodes;
217
+ fread_secure (&magic_num, sizeof (magic_num), 1 , fp);
218
+ fread_secure (&format_version, sizeof (format_version), 1 , fp);
219
+ fread_secure (&header_length, sizeof (header_length), 1 , fp);
220
+ char * header = new char [header_length + 1 ];
221
+ header[header_length] = ' \0 ' ;
222
+ fread_secure (header, sizeof (char ), header_length, fp);
223
+ fread_secure (&num_rr_nodes, sizeof (num_rr_nodes), 1 , fp);
224
+ device_ctx.rr_nodes .resize (num_rr_nodes);
225
+
226
+ if (magic_num != BINARY_MAGIC_NUM) {
227
+ VTR_LOG_WARN (" Not a VPR Binary rr_graph file\n " );
228
+ }
229
+
230
+ if (format_version != BINARY_FILE_VERSION) {
231
+ VTR_LOG_WARN (" Binary file format versions do not match\n " );
232
+ }
233
+
234
+ int inode;
235
+ t_rr_type node_type;
236
+ uint16_t num_edges;
237
+ e_direction direction;
238
+ e_side side;
239
+ int edge_sink_node;
240
+ uint16_t edge_switch;
241
+ uint16_t capacity;
242
+ float R;
243
+ float C;
244
+ uint16_t pos[5 ];
245
+
246
+ for (uint64_t i = 0 ; i < num_rr_nodes; i++) {
247
+ fread_secure (&inode, sizeof (inode), 1 , fp);
248
+ fread_secure (&node_type, sizeof (node_type), 1 , fp);
249
+ auto & node = device_ctx.rr_nodes [inode];
250
+ node.set_type (node_type);
251
+ if (node.type () == CHANX || node.type () == CHANY) {
252
+ fread_secure (&direction, sizeof (direction), 1 , fp);
253
+ node.set_direction (direction);
254
+ }
255
+
256
+ fread_secure (&capacity, sizeof (capacity), 1 , fp);
257
+ if (capacity > 0 )
258
+ node.set_capacity (capacity);
259
+ fread_secure (pos, sizeof (*pos), 5 , fp);
260
+ node.set_coordinates (pos[0 ], pos[1 ], pos[2 ], pos[3 ]);
261
+ node.set_ptc_num (pos[4 ]);
262
+ if (node.type () == IPIN || node.type () == OPIN) {
263
+ fread_secure (&side, sizeof (side), 1 , fp);
264
+ node.set_side (side);
265
+ }
266
+
267
+ fread_secure (&R, sizeof (R), 1 , fp);
268
+ fread_secure (&C, sizeof (C), 1 , fp);
269
+ node.set_rc_index (find_create_rr_rc_data (R, C));
270
+
271
+ fread_secure (&num_edges, sizeof (num_edges), 1 , fp);
272
+
273
+ node.set_num_edges (num_edges);
274
+ for (int j = 0 ; j < num_edges; j++) {
275
+ fread_secure (&edge_sink_node, sizeof (edge_sink_node), 1 , fp);
276
+ fread_secure (&edge_switch, sizeof (edge_switch), 1 , fp);
277
+ node.set_edge_sink_node (j, edge_sink_node);
278
+ node.set_edge_switch (j, edge_switch);
279
+ }
280
+ set_cost_index_bin (inode, node_type, is_global_graph, segment_inf.size (), 0 );
281
+ }
282
+ std::vector<int > count_for_wire_to_ipin_switches;
283
+ count_for_wire_to_ipin_switches.resize (numSwitches, 0 );
284
+ for (uint64_t i = 0 ; i < num_rr_nodes; i++) {
285
+ auto & node = device_ctx.rr_nodes [i];
286
+ if (node.type () == CHANX || node.type () == CHANY) {
287
+ num_edges = node.num_edges ();
288
+ for (int j = 0 ; j < num_edges; j++) {
289
+ if (device_ctx.rr_nodes [node.edge_sink_node (j)].type () == IPIN) {
290
+ count_for_wire_to_ipin_switches[j]++;
291
+ }
292
+ }
293
+ }
294
+ }
295
+ int max = -1 ;
296
+ for (int j = 0 ; j < numSwitches; j++) {
297
+ if (count_for_wire_to_ipin_switches[j] > max) {
298
+ *wire_to_rr_ipin_switch = j;
299
+ max = count_for_wire_to_ipin_switches[j];
300
+ }
301
+ }
302
+ }
303
+
186
304
/* Reads in the switch information and adds it to device_ctx.rr_switch_inf as specified*/
187
305
void process_switches (pugi::xml_node parent, const pugiutil::loc_data& loc_data) {
188
306
auto & device_ctx = g_vpr_ctx.mutable_device ();
@@ -884,3 +1002,30 @@ void set_cost_indices(pugi::xml_node parent, const pugiutil::loc_data& loc_data,
884
1002
rr_node = rr_node.next_sibling (rr_node.name ());
885
1003
}
886
1004
}
1005
+
1006
+ /* This function sets the Source pins, sink pins, ipin, and opin
1007
+ * to their unique cost index identifier. CHANX and CHANY cost indicies are set after the
1008
+ * seg_id is read in from the rr graph */
1009
+ void set_cost_index_bin (int inode, t_rr_type node_type, const bool is_global_graph, const int num_seg_types, short seg_id) {
1010
+ auto & device_ctx = g_vpr_ctx.mutable_device ();
1011
+ auto & node = device_ctx.rr_nodes [inode];
1012
+ // set the cost index in order to load the segment information, rr nodes should be set already
1013
+ if (node_type == SOURCE) {
1014
+ node.set_cost_index (SOURCE_COST_INDEX);
1015
+ } else if (node_type == SINK) {
1016
+ node.set_cost_index (SINK_COST_INDEX);
1017
+ } else if (node_type == IPIN) {
1018
+ node.set_cost_index (IPIN_COST_INDEX);
1019
+ } else if (node_type == OPIN) {
1020
+ node.set_cost_index (OPIN_COST_INDEX);
1021
+ } else if (node_type == CHANX || node_type == CHANY) {
1022
+ /* CHANX and CHANY cost index is dependent on the segment id*/
1023
+ if (is_global_graph) {
1024
+ node.set_cost_index (0 );
1025
+ } else if (device_ctx.rr_nodes [inode].type () == CHANX) {
1026
+ node.set_cost_index (CHANX_COST_INDEX_START + seg_id);
1027
+ } else if (device_ctx.rr_nodes [inode].type () == CHANY) {
1028
+ node.set_cost_index (CHANX_COST_INDEX_START + num_seg_types + seg_id);
1029
+ }
1030
+ }
1031
+ }
0 commit comments