Skip to content

Commit 3b74db5

Browse files
Merge pull request verilog-to-routing#2756 from AlexandreSinger/feature-ap-solver-upstreaming
[AP] Analytical Solver
2 parents 999961a + eabb6e3 commit 3b74db5

File tree

23 files changed

+672
-38
lines changed

23 files changed

+672
-38
lines changed

.github/workflows/test.yml

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,57 +139,68 @@ jobs:
139139
{
140140
name: 'Basic',
141141
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on',
142-
suite: 'vtr_reg_basic'
142+
suite: 'vtr_reg_basic',
143+
extra_pkgs: ""
143144
},
144145
{
145146
name: 'Basic with highest assertion level',
146147
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=4 -DWITH_BLIFEXPLORER=on',
147-
suite: 'vtr_reg_basic'
148+
suite: 'vtr_reg_basic',
149+
extra_pkgs: ""
148150
},
149151
{
150152
name: 'Basic_odin',
151153
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DWITH_PARMYS=OFF -DWITH_ODIN=on',
152-
suite: 'vtr_reg_basic_odin'
154+
suite: 'vtr_reg_basic_odin',
155+
extra_pkgs: ""
153156
},
154157
{
155158
name: 'Basic with NO_GRAPHICS',
156159
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVPR_USE_EZGL=off',
157-
suite: 'vtr_reg_basic'
160+
suite: 'vtr_reg_basic',
161+
extra_pkgs: ""
158162
},
159163
{
160164
name: 'Basic with NO_SERVER',
161165
params: '-DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVPR_USE_EZGL=on -DVPR_USE_SERVER=off',
162-
suite: 'vtr_reg_basic'
166+
suite: 'vtr_reg_basic',
167+
extra_pkgs: ""
163168
},
164169
{
165170
name: 'Basic with CAPNPROTO disabled',
166171
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVTR_ENABLE_CAPNPROTO=off',
167-
suite: 'vtr_reg_basic'
172+
suite: 'vtr_reg_basic',
173+
extra_pkgs: ""
168174
},
169175
{
170176
name: 'Basic with VTR_ENABLE_DEBUG_LOGGING',
171177
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVTR_ENABLE_DEBUG_LOGGING=on',
172-
suite: 'vtr_reg_basic'
178+
suite: 'vtr_reg_basic',
179+
extra_pkgs: ""
173180
},
174181
{
175182
name: 'Basic_odin with VTR_ENABLE_DEBUG_LOGGING',
176183
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVTR_ENABLE_DEBUG_LOGGING=on -DWITH_PARMYS=OFF -DWITH_ODIN=on',
177-
suite: 'vtr_reg_basic_odin'
184+
suite: 'vtr_reg_basic_odin',
185+
extra_pkgs: ""
178186
},
179187
{
180188
name: 'Strong',
181189
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on',
182-
suite: 'vtr_reg_strong'
190+
suite: 'vtr_reg_strong',
191+
extra_pkgs: "libeigen3-dev"
183192
},
184193
{
185194
name: 'Strong_odin',
186195
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DWITH_PARMYS=OFF -DWITH_ODIN=on',
187-
suite: 'vtr_reg_strong_odin'
196+
suite: 'vtr_reg_strong_odin',
197+
extra_pkgs: ""
188198
},
189199
{
190200
name: 'Valgrind Memory',
191201
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DWITH_ODIN=on',
192-
suite: 'vtr_reg_valgrind_small'
202+
suite: 'vtr_reg_valgrind_small',
203+
extra_pkgs: ""
193204
}
194205
]
195206
name: 'R: ${{ matrix.name }}'
@@ -198,10 +209,17 @@ jobs:
198209
- uses: actions/setup-python@v5
199210
with:
200211
python-version: 3.10.10
212+
201213
- uses: actions/checkout@v4
202214
with:
203215
submodules: 'true'
204-
- run: ./.github/scripts/install_dependencies.sh
216+
217+
- name: Install dependencies
218+
run: ./.github/scripts/install_dependencies.sh
219+
220+
- name: Install external libraries
221+
run: sudo apt install -y ${{ matrix.extra_pkgs }}
222+
if: ${{ matrix.extra_pkgs }}
205223

206224
- uses: hendrikmuhs/[email protected]
207225

vpr/CMakeLists.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,27 @@ add_library(libvpr STATIC
7676

7777
target_include_directories(libvpr PUBLIC ${LIB_INCLUDE_DIRS})
7878

79+
80+
# Find if Eigen is installed. Eigen is used within the Analytical Solver of the
81+
# Analytical Placement flow. If Eigen is not installed, certain solvers cannot
82+
# be used.
83+
find_package(Eigen3 3.3 NO_MODULE)
84+
if (TARGET Eigen3::Eigen)
85+
target_link_libraries (libvpr Eigen3::Eigen)
86+
target_compile_definitions(libvpr PUBLIC -DEIGEN_INSTALLED)
87+
message(STATUS "Eigen3: Found")
88+
else ()
89+
message(STATUS "Eigen3: Not Found. Some features may be disabled.")
90+
endif (TARGET Eigen3::Eigen)
91+
7992
#VPR_ANALYTIC_PLACE is initialized in the root CMakeLists
80-
#Check Eigen dependency
93+
# NOTE: This is the cluster-level Analytical Placement which existed before the
94+
# flat Analytical Placement flow.
8195
if(${VPR_ANALYTIC_PLACE})
8296
message(STATUS "VPR Analytic Placement: Requested")
83-
find_package(Eigen3 3.3 NO_MODULE)
8497
if (TARGET Eigen3::Eigen)
8598
message(STATUS "VPR Analytic Placement dependency (Eigen3): Found")
8699
message(STATUS "VPR Analytic Placement: Enabled")
87-
target_link_libraries (libvpr Eigen3::Eigen)
88100
target_compile_definitions(libvpr PUBLIC -DENABLE_ANALYTIC_PLACE)
89101
else ()
90102
message(STATUS "VPR Analytic Placement dependency (Eigen3): Not Found (Download manually with sudo apt install libeigen3-dev, and rebuild)")

vpr/src/analytical_place/analytical_placement_flow.cpp

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77

88
#include "analytical_placement_flow.h"
9+
#include <memory>
10+
#include "analytical_solver.h"
911
#include "ap_netlist.h"
1012
#include "atom_netlist.h"
1113
#include "full_legalizer.h"
@@ -19,6 +21,40 @@
1921
#include "vtr_assert.h"
2022
#include "vtr_time.h"
2123

24+
/**
25+
* @brief A helper method to log statistics on the APNetlist.
26+
*/
27+
static void print_ap_netlist_stats(const APNetlist& netlist) {
28+
// Get the number of moveable and fixed blocks
29+
size_t num_moveable_blocks = 0;
30+
size_t num_fixed_blocks = 0;
31+
for (APBlockId blk_id : netlist.blocks()) {
32+
if (netlist.block_mobility(blk_id) == APBlockMobility::MOVEABLE)
33+
num_moveable_blocks++;
34+
else
35+
num_fixed_blocks++;
36+
}
37+
// Get the fanout information of nets
38+
size_t highest_fanout = 0;
39+
float average_fanout = 0.f;
40+
for (APNetId net_id : netlist.nets()) {
41+
size_t net_fanout = netlist.net_pins(net_id).size();
42+
if (net_fanout > highest_fanout)
43+
highest_fanout = net_fanout;
44+
average_fanout += static_cast<float>(net_fanout);
45+
}
46+
average_fanout /= static_cast<float>(netlist.nets().size());
47+
// Print the statistics
48+
VTR_LOG("Analytical Placement Netlist Statistics:\n");
49+
VTR_LOG("\tBlocks: %zu\n", netlist.blocks().size());
50+
VTR_LOG("\t\tMoveable Blocks: %zu\n", num_moveable_blocks);
51+
VTR_LOG("\t\tFixed Blocks: %zu\n", num_fixed_blocks);
52+
VTR_LOG("\tNets: %zu\n", netlist.nets().size());
53+
VTR_LOG("\t\tAverage Fanout: %.2f\n", average_fanout);
54+
VTR_LOG("\t\tHighest Fanout: %zu\n", highest_fanout);
55+
VTR_LOG("\tPins: %zu\n", netlist.pins().size());
56+
}
57+
2258
void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
2359
(void)vpr_setup;
2460
// Start an overall timer for the Analytical Placement flow.
@@ -38,22 +74,19 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
3874
APNetlist ap_netlist = gen_ap_netlist_from_atoms(atom_nlist,
3975
prepacker,
4076
constraints);
77+
print_ap_netlist_stats(ap_netlist);
4178

4279
// Run the Global Placer
43-
// For now, just put all the moveable blocks at the center of the device
44-
// grid. This will be replaced later. This is just for testing.
80+
// For now, just runs the solver.
4581
PartialPlacement p_placement(ap_netlist);
82+
std::unique_ptr<AnalyticalSolver> solver = make_analytical_solver(e_analytical_solver::QP_HYBRID,
83+
ap_netlist);
84+
solver->solve(0, p_placement);
85+
86+
// Verify that the partial placement is valid before running the full
87+
// legalizer.
4688
const size_t device_width = device_ctx.grid.width();
4789
const size_t device_height = device_ctx.grid.height();
48-
double device_center_x = static_cast<double>(device_width) / 2.0;
49-
double device_center_y = static_cast<double>(device_height) / 2.0;
50-
for (APBlockId ap_blk_id : ap_netlist.blocks()) {
51-
if (ap_netlist.block_mobility(ap_blk_id) != APBlockMobility::MOVEABLE)
52-
continue;
53-
// If the APBlock is moveable, put it on the center for the device.
54-
p_placement.block_x_locs[ap_blk_id] = device_center_x;
55-
p_placement.block_y_locs[ap_blk_id] = device_center_y;
56-
}
5790
VTR_ASSERT(p_placement.verify(ap_netlist,
5891
device_width,
5992
device_height,

0 commit comments

Comments
 (0)