Skip to content

[Logging] Overly Verbose Log Messages When Building RRGraph #2689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
AlexandreSinger opened this issue Aug 15, 2024 · 3 comments · Fixed by #2723
Closed

[Logging] Overly Verbose Log Messages When Building RRGraph #2689

AlexandreSinger opened this issue Aug 15, 2024 · 3 comments · Fixed by #2723
Labels
Good First Issue Good issues for new or first-time contributors

Comments

@AlexandreSinger
Copy link
Contributor

The logs produced by VPR when building the RRGraph include information on the different types of edge counts. This is a bit verbose, and most users would not need this information:
image

The number of nodes and edges in the RRGraph itself should remain, since this information is general enough.

These log messages are printed here:

static std::function<void(t_chan_width*)> alloc_and_load_rr_graph(RRGraphBuilder& rr_graph_builder,
t_rr_graph_storage& L_rr_node,
const RRGraphView& rr_graph,
const int num_seg_types,
const int num_seg_types_x,
const t_unified_to_parallel_seg_index& seg_index_map,
const t_chan_details& chan_details_x,
const t_chan_details& chan_details_y,
const t_track_to_pin_lookup& track_to_pin_lookup_x,
const t_track_to_pin_lookup& track_to_pin_lookup_y,
const t_pin_to_track_lookup& opin_to_track_map,
const vtr::NdMatrix<std::vector<int>, 3>& switch_block_conn,
t_sb_connection_map* sb_conn_map,
const DeviceGrid& grid,
const int Fs,
t_sblock_pattern& sblock_pattern,
const std::vector<vtr::Matrix<int>>& Fc_out,
vtr::NdMatrix<int, 3>& Fc_xofs,
vtr::NdMatrix<int, 3>& Fc_yofs,
const t_chan_width& chan_width,
const int wire_to_ipin_switch,
const int wire_to_pin_between_dice_switch,
const int delayless_switch,
const enum e_directionality directionality,
bool* Fc_clipped,
const t_direct_inf* directs,
const int num_directs,
const t_clb_to_clb_directs* clb_to_clb_directs,
bool is_global_graph,
const enum e_clock_modeling clock_modeling,
bool /*is_flat*/) {
//We take special care when creating RR graph edges (there are typically many more
//edges than nodes in an RR graph).
//
//In particular, all the following build_*() functions do not create the edges, but
//instead record the edges they wish to create in rr_edges_to_create.
//
//We uniquify the edges to be created (avoiding any duplicates), and create
//the edges in alloc_and_load_edges().
//
//By doing things in this manner we ensure we know exactly how many edges leave each RR
//node, which avoids resizing the RR edge arrays (which can cause significant memory
//fragmentation, and significantly increasing peak memory usage). This is important since
//RR graph creation is the high-watermark of VPR's memory use.
t_rr_edge_info_set rr_edges_to_create;
/* If Fc gets clipped, this will be flagged to true */
*Fc_clipped = false;
int num_edges = 0;
/* Connection SINKS and SOURCES to their pins - Initializing IPINs/OPINs. */
for (int layer = 0; layer < grid.get_num_layers(); ++layer) {
for (int i = 0; i < (int)grid.width(); ++i) {
for (int j = 0; j < (int)grid.height(); ++j) {
if (grid.get_width_offset({i, j, layer}) == 0 && grid.get_height_offset({i, j, layer}) == 0) {
t_physical_tile_type_ptr physical_tile = grid.get_physical_type({i, j, layer});
std::vector<int> class_num_vec;
std::vector<int> pin_num_vec;
class_num_vec = get_tile_root_classes(physical_tile);
pin_num_vec = get_tile_root_pins(physical_tile);
add_classes_rr_graph(rr_graph_builder,
class_num_vec,
layer,
i,
j,
physical_tile);
add_pins_rr_graph(rr_graph_builder,
pin_num_vec,
layer,
i,
j,
physical_tile);
connect_src_sink_to_pins(rr_graph_builder,
class_num_vec,
layer,
i,
j,
rr_edges_to_create,
delayless_switch,
physical_tile);
//Create the actual SOURCE->OPIN, IPIN->SINK edges
uniquify_edges(rr_edges_to_create);
alloc_and_load_edges(rr_graph_builder, rr_edges_to_create);
num_edges += rr_edges_to_create.size();
rr_edges_to_create.clear();
}
}
}
}
VTR_LOG("SOURCE->OPIN and IPIN->SINK edge count:%d\n", num_edges);
num_edges = 0;
/* Build opins */
int rr_edges_before_directs = 0;
for (int layer = 0; layer < grid.get_num_layers(); layer++) {
for (size_t i = 0; i < grid.width(); ++i) {
for (size_t j = 0; j < grid.height(); ++j) {
for (e_side side : SIDES) {
if (BI_DIRECTIONAL == directionality) {
build_bidir_rr_opins(rr_graph_builder, rr_graph, layer, i, j, side,
opin_to_track_map, Fc_out, rr_edges_to_create, chan_details_x,
chan_details_y,
grid,
directs, num_directs, clb_to_clb_directs, num_seg_types);
} else {
VTR_ASSERT(UNI_DIRECTIONAL == directionality);
bool clipped;
build_unidir_rr_opins(rr_graph_builder, rr_graph, layer, i, j, side, grid, Fc_out, chan_width,
chan_details_x, chan_details_y, Fc_xofs, Fc_yofs,
rr_edges_to_create, &clipped, seg_index_map,
directs, num_directs, clb_to_clb_directs, num_seg_types,
rr_edges_before_directs);
if (clipped) {
*Fc_clipped = true;
}
}
//Create the actual OPIN->CHANX/CHANY edges
uniquify_edges(rr_edges_to_create);
alloc_and_load_edges(rr_graph_builder, rr_edges_to_create);
num_edges += rr_edges_to_create.size();
rr_edges_to_create.clear();
}
}
}
}
VTR_LOG("OPIN->CHANX/CHANY edge count before creating direct connections: %d\n", rr_edges_before_directs);
VTR_LOG("OPIN->CHANX/CHANY edge count after creating direct connections: %d\n", num_edges);
num_edges = 0;
/* Build channels */
VTR_ASSERT(Fs % 3 == 0);
for (int layer = 0; layer < grid.get_num_layers(); ++layer) {
auto& device_ctx = g_vpr_ctx.device();
/* Skip the current die if architecture file specifies that it doesn't require inter-cluster programmable resource routing */
if (!device_ctx.inter_cluster_prog_routing_resources.at(layer)) {
continue;
}
for (size_t i = 0; i < grid.width() - 1; ++i) {
for (size_t j = 0; j < grid.height() - 1; ++j) {
if (i > 0) {
int tracks_per_chan = ((is_global_graph) ? 1 : chan_width.x_list[j]);
build_rr_chan(rr_graph_builder, layer, i, j, CHANX, track_to_pin_lookup_x, sb_conn_map, switch_block_conn,
CHANX_COST_INDEX_START,
chan_width, grid, tracks_per_chan,
sblock_pattern, Fs / 3, chan_details_x, chan_details_y,
rr_edges_to_create,
wire_to_ipin_switch,
wire_to_pin_between_dice_switch,
directionality);
//Create the actual CHAN->CHAN edges
uniquify_edges(rr_edges_to_create);
alloc_and_load_edges(rr_graph_builder, rr_edges_to_create);
num_edges += rr_edges_to_create.size();
rr_edges_to_create.clear();
}
if (j > 0) {
int tracks_per_chan = ((is_global_graph) ? 1 : chan_width.y_list[i]);
build_rr_chan(rr_graph_builder, layer, i, j, CHANY, track_to_pin_lookup_y, sb_conn_map, switch_block_conn,
CHANX_COST_INDEX_START + num_seg_types_x,
chan_width, grid, tracks_per_chan,
sblock_pattern, Fs / 3, chan_details_x, chan_details_y,
rr_edges_to_create,
wire_to_ipin_switch,
wire_to_pin_between_dice_switch,
directionality);
//Create the actual CHAN->CHAN edges
uniquify_edges(rr_edges_to_create);
alloc_and_load_edges(rr_graph_builder, rr_edges_to_create);
num_edges += rr_edges_to_create.size();
rr_edges_to_create.clear();
}
}
}
}
VTR_LOG("CHAN->CHAN type edge count:%d\n", num_edges);
num_edges = 0;
std::function<void(t_chan_width*)> update_chan_width = [](t_chan_width*) noexcept {};
if (clock_modeling == DEDICATED_NETWORK) {
ClockRRGraphBuilder builder(chan_width, grid, &L_rr_node, &rr_graph_builder);
builder.create_and_append_clock_rr_graph(num_seg_types_x, &rr_edges_to_create);
uniquify_edges(rr_edges_to_create);
alloc_and_load_edges(rr_graph_builder, rr_edges_to_create);
num_edges += rr_edges_to_create.size();
rr_edges_to_create.clear();
update_chan_width = [builder](t_chan_width* c) {
builder.update_chan_width(c);
};
VTR_LOG("\n Dedicated clock network edge count: %d \n", num_edges);
}
rr_graph_builder.init_fan_in();
return update_chan_width;
}

Instead of VTR_LOG, they should use VTR_LOGV; however, this may require some work since a "verbosity" variable will need to be passed into this method somehow.

@AlexandreSinger AlexandreSinger added the Good First Issue Good issues for new or first-time contributors label Aug 21, 2024
@ZohairZaidi
Copy link
Contributor

Hi @AlexandreSinger , I wanted to clarify whether the specific log messages you mentioned are those that detail edge counts for types like SOURCE->OPIN, OPIN->CHANX/CHANY, CHAN->CHAN, and Dedicated clock network edges? Additionally, are these the only logs that should be controlled by verbosity in the alloc_and_load_rr_graph function, or are there others we should consider?

@AlexandreSinger
Copy link
Contributor Author

Hi @ZohairZaidi , that is correct! As of right now these are the only logs that should be controlled by verbosity in this function.

As a starting point, I recommend checking out how the clusterer solves this issue:
https://github.com/verilog-to-routing/vtr-verilog-to-routing/blob/master/vpr/src/pack/cluster.cpp

You will notice that it gets the verbosity from the user using the --pack-verbosity command-line option: https://docs.verilogtorouting.org/en/latest/vpr/command_line_usage/#cmdoption-vpr-pack_verbosity

We may want to create a --route-verbosity option!

@ZohairZaidi
Copy link
Contributor

I will have a look, thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good First Issue Good issues for new or first-time contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants