Skip to content

Fix Segment Usage Message #2408

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

Merged
merged 12 commits into from
Oct 6, 2023
Merged
85 changes: 57 additions & 28 deletions vpr/src/route/segment_stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,55 +20,67 @@ void get_segment_usage_stats(std::vector<t_segment_inf>& segment_inf) {
* are counted as full-length segments (e.g. length 4 even if the last 2 *
* units of wire were chopped off by the chip edge). */

int max_segment_length;
RRIndexedDataId cost_index;
float utilization;

auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;
auto& route_ctx = g_vpr_ctx.routing();

max_segment_length = 0;
int max_segment_name_length = 0;
for (size_t seg_type = 0; seg_type < segment_inf.size(); seg_type++) {
if (segment_inf[seg_type].longline == false) {
max_segment_length = std::max(max_segment_length,
segment_inf[seg_type].length);
std::map<e_parallel_axis, std::map<int, int>> directed_occ_by_length = {
{X_AXIS, std::map<int, int>()},
{Y_AXIS, std::map<int, int>()}};

std::map<e_parallel_axis, std::map<int, int>> directed_cap_by_length = {
{X_AXIS, std::map<int, int>()},
{Y_AXIS, std::map<int, int>()}};

std::set<int, std::less<int>> segment_lengths;
for (const auto& seg_inf : segment_inf) {
int seg_length = seg_inf.longline ? LONGLINE : seg_inf.length;

for (auto ax : {X_AXIS, Y_AXIS}) {
directed_cap_by_length[ax].insert({seg_length, 0});
directed_occ_by_length[ax].insert({seg_length, 0});
}

max_segment_name_length = std::max(max_segment_name_length, static_cast<int>(segment_inf[seg_type].name.size()));
segment_lengths.insert(seg_length);

max_segment_name_length = std::max(max_segment_name_length, static_cast<int>(seg_inf.name.size()));
}

std::map<e_parallel_axis, std::vector<int>> directed_occ_by_length = {
{X_AXIS, std::vector<int>(max_segment_length + 1, 0)},
{Y_AXIS, std::vector<int>(max_segment_length + 1, 0)}};
std::map<e_parallel_axis, std::vector<int>> directed_occ_by_type = {
{X_AXIS, std::vector<int>(segment_inf.size(), 0)},
{Y_AXIS, std::vector<int>(segment_inf.size(), 0)}};

std::map<e_parallel_axis, std::vector<int>> directed_cap_by_length = {
{X_AXIS, std::vector<int>(max_segment_length + 1, 0)},
{Y_AXIS, std::vector<int>(max_segment_length + 1, 0)}};
std::map<e_parallel_axis, std::vector<int>> directed_cap_by_type = {
{X_AXIS, std::vector<int>(segment_inf.size(), 0)},
{Y_AXIS, std::vector<int>(segment_inf.size(), 0)}};

for (RRNodeId inode : device_ctx.rr_graph.nodes()) {
auto node_type = rr_graph.node_type(inode);
if (node_type == CHANX || node_type == CHANY) {
cost_index = rr_graph.node_cost_index(inode);
size_t seg_type = device_ctx.rr_indexed_data[cost_index].seg_index;
int length = -1;
if (!segment_inf[seg_type].longline)
length = segment_inf[seg_type].length;
else
length = LONGLINE;
int length = segment_inf[seg_type].longline ? LONGLINE : segment_inf[seg_type].length;

const short& inode_capacity = rr_graph.node_capacity(inode);
int occ = route_ctx.rr_node_route_inf[inode].occ();
auto ax = (node_type == CHANX) ? X_AXIS : Y_AXIS;

directed_occ_by_length[ax][length] += occ;
directed_cap_by_length[ax][length] += inode_capacity;

directed_occ_by_type[ax][seg_type] += occ;
directed_cap_by_type[ax][seg_type] += inode_capacity;
}
}

VTR_LOG("\n");
VTR_LOG("Total Number of Wiring Segments by Direction: direction length number\n");
VTR_LOG(" --------- ------ -------\n");
for (int length = 0; length <= max_segment_length; length++) {
for (auto length : segment_lengths) {
for (auto ax : {X_AXIS, Y_AXIS}) {
std::string ax_name = (ax == X_AXIS) ? "X" : "Y";
if (directed_cap_by_length[ax][length] != 0) {
Expand All @@ -88,35 +100,52 @@ void get_segment_usage_stats(std::vector<t_segment_inf>& segment_inf) {
VTR_LOG("\n");
VTR_LOG("%s - Directed Wiring Segment usage by length: length utilization\n", ax_name.c_str());
VTR_LOG(" ------ -----------\n");
for (int length = 0; length <= max_segment_length; length++) {
for (auto length : segment_lengths) {
if (directed_cap_by_length[ax][length] != 0) {
std::string length_str = (length == LONGLINE) ? "longline" : std::to_string(length);
utilization = (float)directed_occ_by_length[ax][length] / (float)directed_cap_by_length[ax][length];
VTR_LOG(" %s%s %11.3g\n",
std::string(std::max(6 - (int)length_str.length(), 0), ' ').c_str(),
std::string(std::max(7 - (int)length_str.length(), 0), ' ').c_str(),
length_str.c_str(),
utilization);
}
}
}

VTR_LOG("\n");
VTR_LOG("Segment usage by type (index): %sname type utilization\n", std::string(std::max(max_segment_name_length - 4, 0), ' ').c_str());
VTR_LOG(" %s ---- -----------\n", std::string(std::max(4, max_segment_name_length), '-').c_str());
VTR_LOG("Segment occupancy by length: Length utilization\n");
VTR_LOG(" ------ -----------\n");
for (const auto& seg_length : segment_lengths) {
if (directed_cap_by_length[X_AXIS][seg_length] != 0 || directed_cap_by_length[Y_AXIS][seg_length] != 0) {
std::string seg_name = "L" + std::to_string(seg_length);

int occ = 0;
int cap = 0;
for (auto ax : {X_AXIS, Y_AXIS}) {
occ += directed_occ_by_length[ax][seg_length];
cap += directed_cap_by_length[ax][seg_length];
}
utilization = (float)occ / (float)cap;
VTR_LOG(" %s %11.3g\n", seg_name.c_str(), utilization);
}
}

VTR_LOG("\n");
VTR_LOG("Segment occupancy by type: %sname type utilization\n", std::string(std::max(max_segment_name_length - 4, 0), ' ').c_str());
VTR_LOG(" %s ---- -----------\n", std::string(std::max(4, max_segment_name_length), '-').c_str());

for (size_t seg_type = 0; seg_type < segment_inf.size(); seg_type++) {
int seg_length = segment_inf[seg_type].length;
if (directed_cap_by_length[X_AXIS][seg_length] != 0 || directed_cap_by_length[Y_AXIS][seg_length] != 0) {
if (directed_cap_by_type[X_AXIS][seg_type] != 0 || directed_cap_by_type[Y_AXIS][seg_type] != 0) {
std::string seg_name = segment_inf[seg_type].name;
int seg_name_size = static_cast<int>(seg_name.size());
int occ = 0;
int cap = 0;
for (auto ax : {X_AXIS, Y_AXIS}) {
occ += directed_occ_by_length[ax][seg_length];
cap += directed_cap_by_length[ax][seg_length];
occ += directed_occ_by_type[ax][seg_type];
cap += directed_cap_by_type[ax][seg_type];
}
utilization = (float)occ / (float)cap;
VTR_LOG(" %s%s %4d %11.3g\n", std::string(std::max(4 - seg_name_size, (max_segment_name_length - seg_name_size)), ' ').c_str(), seg_name.c_str(), seg_type, utilization);
VTR_LOG(" %s%s %4d %11.3g\n", std::string(std::max(4 - seg_name_size, (max_segment_name_length - seg_name_size)), ' ').c_str(), seg_name.c_str(), seg_type, utilization);
}
}
}