Skip to content

Commit b4c9275

Browse files
[AP][GP] Added Post-Global Placement Wirelength Estimation
After a recent change where we are ignoring high-fanout nets in the global placer, this caused the high-fanout nets to also be ignored during wirlength estimation in the global placement. This wirelength is used in the global placer to decide when to stop and to print logs to the user. I would like to continue to ignore these nets when computing the objective of the global placer since it is the wirelength of the nets which are not ignored; however, for the user, I would like them to see a more accurate estimation of the wirelength. Created a function which tries to estimate the wirelength of the global placement solution assuming all blocks can be placed exactly where there flat placement wants them to be placed.
1 parent 724ced2 commit b4c9275

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

vpr/src/analytical_place/global_placer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ static void print_placement_stats(const PartialPlacement& p_placement,
127127
FlatPlacementDensityManager& density_manager,
128128
const PreClusterTimingManager& pre_cluster_timing_manager) {
129129
// Print the placement HPWL
130-
VTR_LOG("\tPlacement HPWL: %f\n", p_placement.get_hpwl(ap_netlist));
130+
VTR_LOG("\tPlacement objective HPWL: %f\n", p_placement.get_hpwl(ap_netlist));
131+
VTR_LOG("\tPlacement estimated wirelength: %u\n", p_placement.estimate_post_placement_wirelength(ap_netlist));
131132

132133
// Print the timing information.
133134
if (pre_cluster_timing_manager.is_valid()) {

vpr/src/analytical_place/partial_placement.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,48 @@ double PartialPlacement::get_hpwl(const APNetlist& netlist) const {
3333
return hpwl;
3434
}
3535

36+
double PartialPlacement::estimate_post_placement_wirelength(const APNetlist& netlist) const {
37+
// Go through each net and calculate the half-perimeter wirelength. Since
38+
// we want to estimate the post-placement wirelength, we do not want the
39+
// flat placement positions of the blocks. Instead we compute the HPWL over
40+
// the tiles that the flat placement is placing the blocks over.
41+
unsigned total_hpwl = 0;
42+
for (APNetId net_id : netlist.nets()) {
43+
// Note: Other wirelength estimates in VTR ignore global nets; however
44+
// it is not known if a net is global or not until packing is
45+
// complete. For now, we just approximate post-placement wirelength
46+
// using the HPWL (in tile space).
47+
// TODO: The reason we do not know what nets are ignored / global is
48+
// because the pin on the tile that the net connects to is what
49+
// decides if a net is global / ignored for place and route. Since
50+
// we have not packed anything yet, we do not know what pin each
51+
// net will go to; however, we can probably get a good idea based
52+
// on some properties of the net and the tile its going to / from.
53+
// Should investigate this to get a better estimate of wirelength.
54+
double min_x = std::numeric_limits<unsigned>::max();
55+
double max_x = std::numeric_limits<unsigned>::lowest();
56+
double min_y = std::numeric_limits<unsigned>::max();
57+
double max_y = std::numeric_limits<unsigned>::lowest();
58+
for (APPinId pin_id : netlist.net_pins(net_id)) {
59+
APBlockId blk_id = netlist.pin_block(pin_id);
60+
min_x = std::min(min_x, block_x_locs[blk_id]);
61+
max_x = std::max(max_x, block_x_locs[blk_id]);
62+
min_y = std::min(min_y, block_y_locs[blk_id]);
63+
max_y = std::max(max_y, block_y_locs[blk_id]);
64+
}
65+
VTR_ASSERT_SAFE(max_x >= min_x && max_y >= min_y);
66+
67+
// Floor the positions to get the x and y coordinates of the tiles each
68+
// block belongs to.
69+
unsigned tile_dx = std::floor(max_x) - std::floor(min_x);
70+
unsigned tile_dy = std::floor(max_y) - std::floor(min_y);
71+
72+
total_hpwl += tile_dx + tile_dy;
73+
}
74+
75+
return total_hpwl;
76+
}
77+
3678
bool PartialPlacement::verify_locs(const APNetlist& netlist,
3779
size_t grid_width,
3880
size_t grid_height) const {

vpr/src/analytical_place/partial_placement.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,15 @@ struct PartialPlacement {
145145
*/
146146
double get_hpwl(const APNetlist& netlist) const;
147147

148+
/**
149+
* @brief Estimate the wirelength of the current placement assuming that all
150+
* blocks will be placed exactly where they are in the partial placement.
151+
*
152+
* NOTE: This is an underestimate of the actual wirelength mainly due to
153+
* the placement not being legalized yet.
154+
*/
155+
double estimate_post_placement_wirelength(const APNetlist& netlist) const;
156+
148157
/**
149158
* @brief Verify the block_x_locs and block_y_locs vectors
150159
*

vtr_flow/parse/qor_config/qor_ap_fixed_chan_width.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# channel width.
33

44
vpr_status;output.txt;vpr_status=(.*)
5-
post_gp_hpwl;vpr.out;\s*Placement HPWL: (.*)
5+
post_gp_hpwl;vpr.out;\s*Placement estimated wirelength: (.*)
66
post_fl_hpwl;vpr.out;Initial placement BB estimate of wirelength: (.*)
77
post_dp_hpwl;vpr.out;BB estimate of min-dist \(placement\) wire length: (.*)
88
total_wirelength;vpr.out;\s*Total wirelength: (\d+)

0 commit comments

Comments
 (0)