Skip to content

Commit 78f3632

Browse files
[AP][PartialLegalizer] Added Bi-Partitioning Spreader
Bi-partitioning spreading is a technique where minimum spanning windows are formed around overfilled regions of the device such that the capacity of the bins within the window is larger than the utilization of the bins within the window. These windows are then successively partitioned, moving the blocks to the different partitions, until the window is small enough. Due to its divide and conquer nature, this algorithm tends to be very fast. Created a basic version of this algorithm which does not take into account the different types of blocks being spread. It worked suprisingly well, giving better QoR and runtime than the original spreader that I decided to merge this in immediately. In the future, will add these features. Kept the old spreader in as a separate Global Placer as it may be interesting to compare since the old multi-commodity flow-based approach should, in theory, do a better job spreading (at the expense of runtime). This old spreader may also be interesting to add into other stages of the flow. Added tests to keep this spreader from regressing.
1 parent 039785b commit 78f3632

File tree

21 files changed

+759
-46
lines changed

21 files changed

+759
-46
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,16 @@ Analytical Placement is generally split into three stages:
11881188

11891189
Analytical Placement is experimental and under active development.
11901190

1191+
.. option:: --ap_global_placer {quadratic-bipartitioning-lookahead | quadratic-flowbased-lookahead}
1192+
1193+
Controls which Global Placer to use in the AP Flow.
1194+
1195+
* ``quadratic-bipartitioning-lookahead`` Use a Global Placer which uses a quadratic solver and a bi-partitioning lookahead legalizer. Anchor points are used to spread the solved solution to the legalized solution.
1196+
1197+
* ``quadratic-flowbased-lookahead`` Use a Global Placer which uses a quadratic solver and a multi-commodity-flow-based lookahead legalizer. Anchor points are used to spread the solved solution to the legalized solution.
1198+
1199+
**Default:** ``quadratic-bipartitioning-lookahead``
1200+
11911201
.. option:: --ap_full_legalizer {naive | appack}
11921202

11931203
Controls which Full Legalizer to use in the AP Flow.
@@ -1208,6 +1218,23 @@ Analytical Placement is generally split into three stages:
12081218

12091219
**Default:** ``annealer``
12101220

1221+
.. option:: --ap_verbosity <int>
1222+
1223+
Controls the verbosity of the AP flow output.
1224+
Larger values produce more detailed output, which may be useful for
1225+
debugging the algorithms in the AP flow.
1226+
1227+
* ``1 <= verbosity < 10`` Print standard, stage-level messages. This will
1228+
print messages at the GP, FL, or DP level.
1229+
1230+
* ``10 <= verbosity < 20`` Print more detailed messages of what is happening
1231+
within stages. For example, show high-level information on the legalization
1232+
iterations within the Global Placer.
1233+
1234+
* ``20 <= verbosity`` Print very detailed messages on intra-stage algorithms.
1235+
1236+
**Default:** ``1``
1237+
12111238

12121239
.. _router_options:
12131240

libs/libvtrutil/src/vtr_geometry.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ class Rect {
180180
///@brief Returns true if other is contained within the rectangle (including all edges)
181181
bool contains(const Rect<T>& other) const;
182182

183+
///@brief Returns true if other strictly overlaps this rectangle (two rectangles that only share an edge do not overlap)
184+
bool strictly_overlaps(const Rect<T>& other) const;
185+
183186
/**
184187
* @brief Checks whether the rectangle is empty
185188
*

libs/libvtrutil/src/vtr_geometry.tpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ bool Rect<T>::contains(const Rect<T>& other) const {
187187
&& other.ymin() >= ymin() && other.ymax() <= ymax();
188188
}
189189

190+
template<class T>
191+
bool Rect<T>::strictly_overlaps(const Rect<T>& other) const {
192+
return xmin() < other.xmax() && xmax() > other.xmin()
193+
&& ymax() > other.ymin() && ymin() < other.ymax();
194+
}
195+
190196
template<class T>
191197
bool Rect<T>::empty() const {
192198
return xmax() <= xmin() || ymax() <= ymin();

vpr/src/analytical_place/analytical_placement_flow.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@ static void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_plac
114114
* @brief If a flat placement is provided, skips the Global Placer and
115115
* converts it to a partial placement. Otherwise, runs the Global Placer.
116116
*/
117-
static PartialPlacement run_global_placer(const AtomNetlist& atom_nlist, const APNetlist& ap_netlist, const Prepacker& prepacker, const DeviceContext& device_ctx) {
117+
static PartialPlacement run_global_placer(const t_ap_opts& ap_opts,
118+
const AtomNetlist& atom_nlist,
119+
const APNetlist& ap_netlist,
120+
const Prepacker& prepacker,
121+
const DeviceContext& device_ctx) {
118122
if (g_vpr_ctx.atom().flat_placement_info().valid) {
119123
VTR_LOG("Flat Placement is provided in the AP flow, skipping the Global Placement.\n");
120124
PartialPlacement p_placement(ap_netlist);
@@ -125,13 +129,14 @@ static PartialPlacement run_global_placer(const AtomNetlist& atom_nlist, const A
125129
return p_placement;
126130
} else {
127131
// Run the Global Placer
128-
std::unique_ptr<GlobalPlacer> global_placer = make_global_placer(e_global_placer::SimPL,
132+
std::unique_ptr<GlobalPlacer> global_placer = make_global_placer(ap_opts.global_placer_type,
129133
ap_netlist,
130134
prepacker,
131135
atom_nlist,
132136
device_ctx.grid,
133137
device_ctx.logical_block_types,
134-
device_ctx.physical_tile_types);
138+
device_ctx.physical_tile_types,
139+
ap_opts.log_verbosity);
135140
return global_placer->place();
136141
}
137142
}
@@ -156,7 +161,9 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
156161
print_ap_netlist_stats(ap_netlist);
157162

158163
// Run the Global Placer.
159-
PartialPlacement p_placement = run_global_placer(atom_nlist,
164+
const t_ap_opts& ap_opts = vpr_setup.APOpts;
165+
PartialPlacement p_placement = run_global_placer(ap_opts,
166+
atom_nlist,
160167
ap_netlist,
161168
prepacker,
162169
device_ctx);
@@ -171,7 +178,6 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
171178
device_ctx.grid.get_num_layers()));
172179

173180
// Run the Full Legalizer.
174-
const t_ap_opts& ap_opts = vpr_setup.APOpts;
175181
std::unique_ptr<FullLegalizer> full_legalizer = make_full_legalizer(ap_opts.full_legalizer_type,
176182
ap_netlist,
177183
atom_nlist,

vpr/src/analytical_place/ap_flow_enums.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@
77

88
#pragma once
99

10+
/**
11+
* @brief The type of a Global Placer.
12+
*
13+
* The Analytical Placement flow may implement different Global Placers. This
14+
* enum can select between these different Global Placers.
15+
*/
16+
enum class e_ap_global_placer {
17+
// Global placers based on the the SimPL paper.
18+
SimPL_BiParitioning, ///< Global Placer based on the SimPL technique to Global Placement. Uses a quadratic solver and a bi-partitioning Partial Legalizer.
19+
SimPL_FlowBased ///< Global Placer based on the SimPL technique to Global Placement. Uses a quadratic solver and a multi-commodity-flow-baed Partial Legalizer.
20+
};
21+
1022
/**
1123
* @brief The type of a Full Legalizer.
1224
*

vpr/src/analytical_place/global_placer.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <memory>
1212
#include <vector>
1313
#include "analytical_solver.h"
14+
#include "ap_flow_enums.h"
1415
#include "ap_netlist.h"
1516
#include "atom_netlist.h"
1617
#include "device_grid.h"
@@ -22,36 +23,50 @@
2223
#include "vtr_log.h"
2324
#include "vtr_time.h"
2425

25-
std::unique_ptr<GlobalPlacer> make_global_placer(e_global_placer placer_type,
26+
std::unique_ptr<GlobalPlacer> make_global_placer(e_ap_global_placer placer_type,
2627
const APNetlist& ap_netlist,
2728
const Prepacker& prepacker,
2829
const AtomNetlist& atom_netlist,
2930
const DeviceGrid& device_grid,
3031
const std::vector<t_logical_block_type>& logical_block_types,
31-
const std::vector<t_physical_tile_type>& physical_tile_types) {
32+
const std::vector<t_physical_tile_type>& physical_tile_types,
33+
int log_verbosity) {
3234
// Based on the placer type passed in, build the global placer.
3335
switch (placer_type) {
34-
case e_global_placer::SimPL:
35-
return std::make_unique<SimPLGlobalPlacer>(ap_netlist,
36+
case e_ap_global_placer::SimPL_BiParitioning:
37+
return std::make_unique<SimPLGlobalPlacer>(e_partial_legalizer::BI_PARTITIONING,
38+
ap_netlist,
3639
prepacker,
3740
atom_netlist,
3841
device_grid,
3942
logical_block_types,
40-
physical_tile_types);
43+
physical_tile_types,
44+
log_verbosity);
45+
case e_ap_global_placer::SimPL_FlowBased:
46+
return std::make_unique<SimPLGlobalPlacer>(e_partial_legalizer::FLOW_BASED,
47+
ap_netlist,
48+
prepacker,
49+
atom_netlist,
50+
device_grid,
51+
logical_block_types,
52+
physical_tile_types,
53+
log_verbosity);
4154
default:
4255
VPR_FATAL_ERROR(VPR_ERROR_AP,
4356
"Unrecognized global placer type");
4457

4558
}
4659
}
4760

48-
SimPLGlobalPlacer::SimPLGlobalPlacer(const APNetlist& ap_netlist,
61+
SimPLGlobalPlacer::SimPLGlobalPlacer(e_partial_legalizer partial_legalizer_type,
62+
const APNetlist& ap_netlist,
4963
const Prepacker& prepacker,
5064
const AtomNetlist& atom_netlist,
5165
const DeviceGrid& device_grid,
5266
const std::vector<t_logical_block_type>& logical_block_types,
53-
const std::vector<t_physical_tile_type>& physical_tile_types)
54-
: GlobalPlacer(ap_netlist) {
67+
const std::vector<t_physical_tile_type>& physical_tile_types,
68+
int log_verbosity)
69+
: GlobalPlacer(ap_netlist, log_verbosity) {
5570
// This can be a long method. Good to time this to see how long it takes to
5671
// construct the global placer.
5772
vtr::ScopedStartFinishTimer global_placer_building_timer("Constructing Global Placer");
@@ -67,9 +82,10 @@ SimPLGlobalPlacer::SimPLGlobalPlacer(const APNetlist& ap_netlist,
6782
physical_tile_types,
6883
log_verbosity_);
6984
// Build the partial legalizer
70-
partial_legalizer_ = make_partial_legalizer(e_partial_legalizer::FLOW_BASED,
85+
partial_legalizer_ = make_partial_legalizer(partial_legalizer_type,
7186
ap_netlist_,
72-
density_manager_);
87+
density_manager_,
88+
log_verbosity_);
7389
}
7490

7591
/**

vpr/src/analytical_place/global_placer.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
#pragma once
1616

1717
#include <memory>
18+
#include "ap_flow_enums.h"
1819
#include "flat_placement_density_manager.h"
20+
#include "partial_legalizer.h"
1921

2022
// Forward declarations
2123
class APNetlist;
@@ -24,13 +26,6 @@ class PartialLegalizer;
2426
class Prepacker;
2527
struct PartialPlacement;
2628

27-
/**
28-
* @brief Enumeration of all of the global placers currently implemented in VPR.
29-
*/
30-
enum class e_global_placer {
31-
SimPL // Global placer based on the SimPL paper.
32-
};
33-
3429
/**
3530
* @brief The Global Placer base class
3631
*
@@ -52,7 +47,7 @@ class GlobalPlacer {
5247
* @param log_verbosity The verbosity of log messages in the Global
5348
* Placer.
5449
*/
55-
GlobalPlacer(const APNetlist& ap_netlist, int log_verbosity = 1)
50+
GlobalPlacer(const APNetlist& ap_netlist, int log_verbosity)
5651
: ap_netlist_(ap_netlist),
5752
log_verbosity_(log_verbosity) {}
5853

@@ -78,13 +73,14 @@ class GlobalPlacer {
7873
/**
7974
* @brief A factory method which creates a Global Placer of the given type.
8075
*/
81-
std::unique_ptr<GlobalPlacer> make_global_placer(e_global_placer placer_type,
76+
std::unique_ptr<GlobalPlacer> make_global_placer(e_ap_global_placer placer_type,
8277
const APNetlist& ap_netlist,
8378
const Prepacker& prepacker,
8479
const AtomNetlist& atom_netlist,
8580
const DeviceGrid& device_grid,
8681
const std::vector<t_logical_block_type>& logical_block_types,
87-
const std::vector<t_physical_tile_type>& physical_tile_types);
82+
const std::vector<t_physical_tile_type>& physical_tile_types,
83+
int log_verbosity);
8884

8985
/**
9086
* @brief A Global Placer based on the SimPL work for analytical ASIC placement.
@@ -140,12 +136,14 @@ class SimPLGlobalPlacer : public GlobalPlacer {
140136
*
141137
* Constructs the solver and partial legalizer.
142138
*/
143-
SimPLGlobalPlacer(const APNetlist& ap_netlist,
139+
SimPLGlobalPlacer(e_partial_legalizer partial_legalizer_type,
140+
const APNetlist& ap_netlist,
144141
const Prepacker& prepacker,
145142
const AtomNetlist& atom_netlist,
146143
const DeviceGrid& device_grid,
147144
const std::vector<t_logical_block_type>& logical_block_types,
148-
const std::vector<t_physical_tile_type>& physical_tile_types);
145+
const std::vector<t_physical_tile_type>& physical_tile_types,
146+
int log_verbosity);
149147

150148
/**
151149
* @brief Run a SimPL-like global placement algorithm

0 commit comments

Comments
 (0)