@@ -55,13 +55,15 @@ void verify_segments(pugi::xml_node parent, const pugiutil::loc_data& loc_data,
5555void verify_blocks (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
5656void process_blocks (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
5757void verify_grid (pugi::xml_node parent, const pugiutil::loc_data& loc_data, const DeviceGrid& grid);
58+ 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);
5859void process_nodes (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
5960void process_connection_boxes (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
6061void process_edges (pugi::xml_node parent, const pugiutil::loc_data& loc_data, int * wire_to_rr_ipin_switch, const int num_rr_switches);
6162void process_channels (t_chan_width& chan_width, pugi::xml_node parent, const pugiutil::loc_data& loc_data);
6263void process_rr_node_indices (const DeviceGrid& grid);
6364void process_seg_id (pugi::xml_node parent, const pugiutil::loc_data& loc_data);
6465void set_cost_indices (pugi::xml_node parent, const pugiutil::loc_data& loc_data, const bool is_global_graph, const int num_seg_types);
66+ 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);
6567
6668/* *********************** Subroutine definitions ****************************/
6769
@@ -148,42 +150,61 @@ void load_rr_file(const t_graph_type graph_type,
148150 int max_chan_width = (is_global_graph ? 1 : nodes_per_chan.max );
149151 VTR_ASSERT (max_chan_width > 0 );
150152
151- /* Alloc rr nodes and count count nodes */
152- next_component = get_single_child (rr_graph, " rr_nodes" , loc_data);
153-
154- int num_rr_nodes = count_children (next_component, " node" , loc_data);
155-
156- device_ctx.rr_nodes .resize (num_rr_nodes);
157- device_ctx.connection_boxes .resize_nodes (num_rr_nodes);
158- process_nodes (next_component, loc_data);
159-
160153 /* Loads edges, switches, and node look up tables*/
161154 next_component = get_single_child (rr_graph, " switches" , loc_data);
162155
163156 int numSwitches = count_children (next_component, " switch" , loc_data);
164157 device_ctx.rr_switch_inf .resize (numSwitches);
165158
166159 process_switches (next_component, loc_data);
160+ /* Branches to binary format */
161+ next_component = get_single_child (rr_graph, " binary_nodes_and_edges" , loc_data, OPTIONAL);
162+ if (next_component) {
163+ auto filename = get_attribute (next_component, " file" , loc_data).as_string (" " );
164+ VTR_LOG (" Using Binary File: %s\n " , filename);
165+ FILE* fp = fopen (filename, " rb" );
166+ if (fp == NULL ) {
167+ VPR_THROW (VPR_ERROR_OTHER, " Binary File %s Does Not Exist\n " , filename);
168+ }
169+
170+ process_nodes_and_switches_bin (fp, wire_to_rr_ipin_switch, is_global_graph, segment_inf, numSwitches);
171+
172+ partition_rr_graph_edges (device_ctx);
173+ process_rr_node_indices (grid);
174+ init_fan_in (device_ctx.rr_nodes , device_ctx.rr_nodes .size ());
175+ alloc_and_load_rr_indexed_data (segment_inf, device_ctx.rr_node_indices ,
176+ max_chan_width, *wire_to_rr_ipin_switch, base_cost_type);
167177
168- next_component = get_single_child (rr_graph, " rr_edges" , loc_data);
169- process_edges (next_component, loc_data, wire_to_rr_ipin_switch, numSwitches);
178+ } else {
179+ /* Alloc rr nodes and count count nodes */
180+ next_component = get_single_child (rr_graph, " rr_nodes" , loc_data);
181+
182+ int num_rr_nodes = count_children (next_component, " node" , loc_data);
183+
184+ device_ctx.rr_nodes .resize (num_rr_nodes);
185+ device_ctx.connection_boxes .resize_nodes (num_rr_nodes);
186+ process_nodes (next_component, loc_data);
170187
171- // Partition the rr graph edges for efficient access to configurable/non-configurable
172- // edge subsets. Must be done after RR switches have been allocated
173- partition_rr_graph_edges (device_ctx);
188+ next_component = get_single_child (rr_graph, " rr_edges" , loc_data);
189+ process_edges (next_component, loc_data, wire_to_rr_ipin_switch, numSwitches);
174190
175- process_rr_node_indices (grid);
191+ // Partition the rr graph edges for efficient access to configurable/non-configurable
192+ // edge subsets. Must be done after RR switches have been allocated
193+ partition_rr_graph_edges (device_ctx);
176194
177- init_fan_in (device_ctx. rr_nodes , device_ctx. rr_nodes . size () );
195+ process_rr_node_indices (grid );
178196
179- // sets the cost index and seg id information
180- next_component = get_single_child (rr_graph, " rr_nodes" , loc_data);
181- set_cost_indices (next_component, loc_data, is_global_graph, segment_inf.size ());
197+ init_fan_in (device_ctx.rr_nodes , device_ctx.rr_nodes .size ());
182198
183- alloc_and_load_rr_indexed_data (segment_inf, device_ctx.rr_node_indices ,
184- max_chan_width, *wire_to_rr_ipin_switch, base_cost_type);
199+ // sets the cost index and seg id information
200+ next_component = get_single_child (rr_graph, " rr_nodes" , loc_data);
201+ set_cost_indices (next_component, loc_data, is_global_graph, segment_inf.size ());
185202
186- process_seg_id (next_component, loc_data);
203+ alloc_and_load_rr_indexed_data (segment_inf, device_ctx.rr_node_indices ,
204+ max_chan_width, *wire_to_rr_ipin_switch, base_cost_type);
205+
206+ process_seg_id (next_component, loc_data);
207+ }
187208
188209 device_ctx.chan_width = nodes_per_chan;
189210
@@ -195,6 +216,103 @@ void load_rr_file(const t_graph_type graph_type,
195216 }
196217}
197218
219+ void process_nodes_and_switches_bin (FILE* fp,
220+ int * wire_to_rr_ipin_switch,
221+ bool is_global_graph,
222+ const std::vector<t_segment_inf>& segment_inf,
223+ int numSwitches) {
224+ auto & device_ctx = g_vpr_ctx.mutable_device ();
225+ uint32_t magic_num;
226+ uint16_t format_version;
227+ uint16_t header_length;
228+ uint64_t num_rr_nodes;
229+ fread_secure (&magic_num, sizeof (magic_num), 1 , fp);
230+ fread_secure (&format_version, sizeof (format_version), 1 , fp);
231+ fread_secure (&header_length, sizeof (header_length), 1 , fp);
232+ char * header = new char [header_length + 1 ];
233+ header[header_length] = ' \0 ' ;
234+ fread_secure (header, sizeof (char ), header_length, fp);
235+ fread_secure (&num_rr_nodes, sizeof (num_rr_nodes), 1 , fp);
236+ device_ctx.rr_nodes .resize (num_rr_nodes);
237+
238+ if (magic_num != BINARY_MAGIC_NUM) {
239+ VTR_LOG_WARN (" Not a VPR Binary rr_graph file\n " );
240+ }
241+
242+ if (format_version != BINARY_FILE_VERSION) {
243+ VTR_LOG_WARN (" Binary file format versions do not match\n " );
244+ }
245+
246+ int inode;
247+ t_rr_type node_type;
248+ uint16_t num_edges;
249+ e_direction direction;
250+ e_side side;
251+ int edge_sink_node;
252+ uint16_t edge_switch;
253+ uint16_t capacity;
254+ float R;
255+ float C;
256+ uint16_t pos[5 ];
257+
258+ for (uint64_t i = 0 ; i < num_rr_nodes; i++) {
259+ fread_secure (&inode, sizeof (inode), 1 , fp);
260+ fread_secure (&node_type, sizeof (node_type), 1 , fp);
261+ auto & node = device_ctx.rr_nodes [inode];
262+ node.set_type (node_type);
263+ if (node.type () == CHANX || node.type () == CHANY) {
264+ fread_secure (&direction, sizeof (direction), 1 , fp);
265+ node.set_direction (direction);
266+ }
267+
268+ fread_secure (&capacity, sizeof (capacity), 1 , fp);
269+ if (capacity > 0 )
270+ node.set_capacity (capacity);
271+ fread_secure (pos, sizeof (*pos), 5 , fp);
272+ node.set_coordinates (pos[0 ], pos[1 ], pos[2 ], pos[3 ]);
273+ node.set_ptc_num (pos[4 ]);
274+ if (node.type () == IPIN || node.type () == OPIN) {
275+ fread_secure (&side, sizeof (side), 1 , fp);
276+ node.set_side (side);
277+ }
278+
279+ fread_secure (&R, sizeof (R), 1 , fp);
280+ fread_secure (&C, sizeof (C), 1 , fp);
281+ node.set_rc_index (find_create_rr_rc_data (R, C));
282+
283+ fread_secure (&num_edges, sizeof (num_edges), 1 , fp);
284+
285+ node.set_num_edges (num_edges);
286+ for (int j = 0 ; j < num_edges; j++) {
287+ fread_secure (&edge_sink_node, sizeof (edge_sink_node), 1 , fp);
288+ fread_secure (&edge_switch, sizeof (edge_switch), 1 , fp);
289+ node.set_edge_sink_node (j, edge_sink_node);
290+ node.set_edge_switch (j, edge_switch);
291+ }
292+ set_cost_index_bin (inode, node_type, is_global_graph, segment_inf.size (), 0 );
293+ }
294+ std::vector<int > count_for_wire_to_ipin_switches;
295+ count_for_wire_to_ipin_switches.resize (numSwitches, 0 );
296+ for (uint64_t i = 0 ; i < num_rr_nodes; i++) {
297+ auto & node = device_ctx.rr_nodes [i];
298+ if (node.type () == CHANX || node.type () == CHANY) {
299+ num_edges = node.num_edges ();
300+ for (int j = 0 ; j < num_edges; j++) {
301+ if (device_ctx.rr_nodes [node.edge_sink_node (j)].type () == IPIN) {
302+ count_for_wire_to_ipin_switches[j]++;
303+ }
304+ }
305+ }
306+ }
307+ int max = -1 ;
308+ for (int j = 0 ; j < numSwitches; j++) {
309+ if (count_for_wire_to_ipin_switches[j] > max) {
310+ *wire_to_rr_ipin_switch = j;
311+ max = count_for_wire_to_ipin_switches[j];
312+ }
313+ }
314+ }
315+
198316/* Reads in the switch information and adds it to device_ctx.rr_switch_inf as specified*/
199317void process_switches (pugi::xml_node parent, const pugiutil::loc_data& loc_data) {
200318 auto & device_ctx = g_vpr_ctx.mutable_device ();
@@ -932,3 +1050,29 @@ void process_connection_boxes(pugi::xml_node parent, const pugiutil::loc_data& l
9321050
9331051 device_ctx.connection_boxes .reset_boxes (std::make_pair (x_dim, y_dim), boxes);
9341052}
1053+ /* This function sets the Source pins, sink pins, ipin, and opin
1054+ * to their unique cost index identifier. CHANX and CHANY cost indicies are set after the
1055+ * seg_id is read in from the rr graph */
1056+ 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) {
1057+ auto & device_ctx = g_vpr_ctx.mutable_device ();
1058+ auto & node = device_ctx.rr_nodes [inode];
1059+ // set the cost index in order to load the segment information, rr nodes should be set already
1060+ if (node_type == SOURCE) {
1061+ node.set_cost_index (SOURCE_COST_INDEX);
1062+ } else if (node_type == SINK) {
1063+ node.set_cost_index (SINK_COST_INDEX);
1064+ } else if (node_type == IPIN) {
1065+ node.set_cost_index (IPIN_COST_INDEX);
1066+ } else if (node_type == OPIN) {
1067+ node.set_cost_index (OPIN_COST_INDEX);
1068+ } else if (node_type == CHANX || node_type == CHANY) {
1069+ /* CHANX and CHANY cost index is dependent on the segment id*/
1070+ if (is_global_graph) {
1071+ node.set_cost_index (0 );
1072+ } else if (device_ctx.rr_nodes [inode].type () == CHANX) {
1073+ node.set_cost_index (CHANX_COST_INDEX_START + seg_id);
1074+ } else if (device_ctx.rr_nodes [inode].type () == CHANY) {
1075+ node.set_cost_index (CHANX_COST_INDEX_START + num_seg_types + seg_id);
1076+ }
1077+ }
1078+ }
0 commit comments