Skip to content

Commit

Permalink
Merge pull request verilog-to-routing#2756 from AlexandreSinger/featu…
Browse files Browse the repository at this point in the history
…re-ap-solver-upstreaming

[AP] Analytical Solver
  • Loading branch information
AlexandreSinger authored Oct 7, 2024
2 parents 999961a + eabb6e3 commit 3b74db5
Show file tree
Hide file tree
Showing 23 changed files with 672 additions and 38 deletions.
42 changes: 30 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,57 +139,68 @@ jobs:
{
name: 'Basic',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on',
suite: 'vtr_reg_basic'
suite: 'vtr_reg_basic',
extra_pkgs: ""
},
{
name: 'Basic with highest assertion level',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=4 -DWITH_BLIFEXPLORER=on',
suite: 'vtr_reg_basic'
suite: 'vtr_reg_basic',
extra_pkgs: ""
},
{
name: 'Basic_odin',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DWITH_PARMYS=OFF -DWITH_ODIN=on',
suite: 'vtr_reg_basic_odin'
suite: 'vtr_reg_basic_odin',
extra_pkgs: ""
},
{
name: 'Basic with NO_GRAPHICS',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVPR_USE_EZGL=off',
suite: 'vtr_reg_basic'
suite: 'vtr_reg_basic',
extra_pkgs: ""
},
{
name: 'Basic with NO_SERVER',
params: '-DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVPR_USE_EZGL=on -DVPR_USE_SERVER=off',
suite: 'vtr_reg_basic'
suite: 'vtr_reg_basic',
extra_pkgs: ""
},
{
name: 'Basic with CAPNPROTO disabled',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVTR_ENABLE_CAPNPROTO=off',
suite: 'vtr_reg_basic'
suite: 'vtr_reg_basic',
extra_pkgs: ""
},
{
name: 'Basic with VTR_ENABLE_DEBUG_LOGGING',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVTR_ENABLE_DEBUG_LOGGING=on',
suite: 'vtr_reg_basic'
suite: 'vtr_reg_basic',
extra_pkgs: ""
},
{
name: 'Basic_odin with VTR_ENABLE_DEBUG_LOGGING',
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',
suite: 'vtr_reg_basic_odin'
suite: 'vtr_reg_basic_odin',
extra_pkgs: ""
},
{
name: 'Strong',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on',
suite: 'vtr_reg_strong'
suite: 'vtr_reg_strong',
extra_pkgs: "libeigen3-dev"
},
{
name: 'Strong_odin',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DWITH_PARMYS=OFF -DWITH_ODIN=on',
suite: 'vtr_reg_strong_odin'
suite: 'vtr_reg_strong_odin',
extra_pkgs: ""
},
{
name: 'Valgrind Memory',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DWITH_ODIN=on',
suite: 'vtr_reg_valgrind_small'
suite: 'vtr_reg_valgrind_small',
extra_pkgs: ""
}
]
name: 'R: ${{ matrix.name }}'
Expand All @@ -198,10 +209,17 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: 3.10.10

- uses: actions/checkout@v4
with:
submodules: 'true'
- run: ./.github/scripts/install_dependencies.sh

- name: Install dependencies
run: ./.github/scripts/install_dependencies.sh

- name: Install external libraries
run: sudo apt install -y ${{ matrix.extra_pkgs }}
if: ${{ matrix.extra_pkgs }}

- uses: hendrikmuhs/ccache-action@v1.2

Expand Down
18 changes: 15 additions & 3 deletions vpr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,27 @@ add_library(libvpr STATIC

target_include_directories(libvpr PUBLIC ${LIB_INCLUDE_DIRS})


# Find if Eigen is installed. Eigen is used within the Analytical Solver of the
# Analytical Placement flow. If Eigen is not installed, certain solvers cannot
# be used.
find_package(Eigen3 3.3 NO_MODULE)
if (TARGET Eigen3::Eigen)
target_link_libraries (libvpr Eigen3::Eigen)
target_compile_definitions(libvpr PUBLIC -DEIGEN_INSTALLED)
message(STATUS "Eigen3: Found")
else ()
message(STATUS "Eigen3: Not Found. Some features may be disabled.")
endif (TARGET Eigen3::Eigen)

#VPR_ANALYTIC_PLACE is initialized in the root CMakeLists
#Check Eigen dependency
# NOTE: This is the cluster-level Analytical Placement which existed before the
# flat Analytical Placement flow.
if(${VPR_ANALYTIC_PLACE})
message(STATUS "VPR Analytic Placement: Requested")
find_package(Eigen3 3.3 NO_MODULE)
if (TARGET Eigen3::Eigen)
message(STATUS "VPR Analytic Placement dependency (Eigen3): Found")
message(STATUS "VPR Analytic Placement: Enabled")
target_link_libraries (libvpr Eigen3::Eigen)
target_compile_definitions(libvpr PUBLIC -DENABLE_ANALYTIC_PLACE)
else ()
message(STATUS "VPR Analytic Placement dependency (Eigen3): Not Found (Download manually with sudo apt install libeigen3-dev, and rebuild)")
Expand Down
55 changes: 44 additions & 11 deletions vpr/src/analytical_place/analytical_placement_flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/

#include "analytical_placement_flow.h"
#include <memory>
#include "analytical_solver.h"
#include "ap_netlist.h"
#include "atom_netlist.h"
#include "full_legalizer.h"
Expand All @@ -19,6 +21,40 @@
#include "vtr_assert.h"
#include "vtr_time.h"

/**
* @brief A helper method to log statistics on the APNetlist.
*/
static void print_ap_netlist_stats(const APNetlist& netlist) {
// Get the number of moveable and fixed blocks
size_t num_moveable_blocks = 0;
size_t num_fixed_blocks = 0;
for (APBlockId blk_id : netlist.blocks()) {
if (netlist.block_mobility(blk_id) == APBlockMobility::MOVEABLE)
num_moveable_blocks++;
else
num_fixed_blocks++;
}
// Get the fanout information of nets
size_t highest_fanout = 0;
float average_fanout = 0.f;
for (APNetId net_id : netlist.nets()) {
size_t net_fanout = netlist.net_pins(net_id).size();
if (net_fanout > highest_fanout)
highest_fanout = net_fanout;
average_fanout += static_cast<float>(net_fanout);
}
average_fanout /= static_cast<float>(netlist.nets().size());
// Print the statistics
VTR_LOG("Analytical Placement Netlist Statistics:\n");
VTR_LOG("\tBlocks: %zu\n", netlist.blocks().size());
VTR_LOG("\t\tMoveable Blocks: %zu\n", num_moveable_blocks);
VTR_LOG("\t\tFixed Blocks: %zu\n", num_fixed_blocks);
VTR_LOG("\tNets: %zu\n", netlist.nets().size());
VTR_LOG("\t\tAverage Fanout: %.2f\n", average_fanout);
VTR_LOG("\t\tHighest Fanout: %zu\n", highest_fanout);
VTR_LOG("\tPins: %zu\n", netlist.pins().size());
}

void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
(void)vpr_setup;
// Start an overall timer for the Analytical Placement flow.
Expand All @@ -38,22 +74,19 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
APNetlist ap_netlist = gen_ap_netlist_from_atoms(atom_nlist,
prepacker,
constraints);
print_ap_netlist_stats(ap_netlist);

// Run the Global Placer
// For now, just put all the moveable blocks at the center of the device
// grid. This will be replaced later. This is just for testing.
// For now, just runs the solver.
PartialPlacement p_placement(ap_netlist);
std::unique_ptr<AnalyticalSolver> solver = make_analytical_solver(e_analytical_solver::QP_HYBRID,
ap_netlist);
solver->solve(0, p_placement);

// Verify that the partial placement is valid before running the full
// legalizer.
const size_t device_width = device_ctx.grid.width();
const size_t device_height = device_ctx.grid.height();
double device_center_x = static_cast<double>(device_width) / 2.0;
double device_center_y = static_cast<double>(device_height) / 2.0;
for (APBlockId ap_blk_id : ap_netlist.blocks()) {
if (ap_netlist.block_mobility(ap_blk_id) != APBlockMobility::MOVEABLE)
continue;
// If the APBlock is moveable, put it on the center for the device.
p_placement.block_x_locs[ap_blk_id] = device_center_x;
p_placement.block_y_locs[ap_blk_id] = device_center_y;
}
VTR_ASSERT(p_placement.verify(ap_netlist,
device_width,
device_height,
Expand Down
Loading

0 comments on commit 3b74db5

Please sign in to comment.