Skip to content

Commit 1046c2c

Browse files
[Place] Updated Place Context Init Based on Soheil Comments
1 parent 2876a45 commit 1046c2c

11 files changed

+234
-171
lines changed

vpr/src/analytical_place/full_legalizer.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ class APClusterPlacer {
130130
: place_macros_(place_macros) {
131131
// Initialize the block loc registry.
132132
auto& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
133-
blk_loc_registry.init(g_vpr_ctx.clustering().clb_nlist,
134-
g_vpr_ctx.device().grid);
133+
blk_loc_registry.init();
135134

136135
// Place the fixed blocks and mark them as fixed.
137136
mark_fixed_blocks(blk_loc_registry);
@@ -351,7 +350,6 @@ void NaiveFullLegalizer::create_clusters(const PartialPlacement& p_placement) {
351350
// FIXME: This writing and loading from a file is wasteful. Should generate
352351
// the clusters directly from the cluster legalizer.
353352
vpr_load_packing(vpr_setup_, arch_);
354-
load_cluster_constraints();
355353
const ClusteredNetlist& clb_nlist = g_vpr_ctx.clustering().clb_nlist;
356354

357355
// Verify the packing and print some info
@@ -445,13 +443,14 @@ void NaiveFullLegalizer::legalize(const PartialPlacement& p_placement) {
445443
const ClusteredNetlist& clb_nlist = g_vpr_ctx.clustering().clb_nlist;
446444

447445
// Initialize the placement context.
448-
init_placement_context(g_vpr_ctx.mutable_placement(),
449-
vpr_setup_.PlacerOpts,
450-
vpr_setup_.NocOpts,
451-
arch_.directs);
446+
g_vpr_ctx.mutable_placement().init_placement_context(vpr_setup_.PlacerOpts,
447+
arch_.directs);
452448

453449
const PlaceMacros& place_macros = *g_vpr_ctx.placement().place_macros;
454450

451+
// Update the floorplanning context with the macro information.
452+
g_vpr_ctx.mutable_floorplanning().update_floorplanning_context_pre_place(place_macros);
453+
455454
// Place the clusters based on where the atoms want to be placed.
456455
place_clusters(clb_nlist, place_macros, p_placement);
457456

@@ -467,7 +466,10 @@ void NaiveFullLegalizer::legalize(const PartialPlacement& p_placement) {
467466
}
468467

469468
// Clean the placement context.
470-
clean_placement_context(g_vpr_ctx.mutable_placement());
469+
g_vpr_ctx.mutable_placement().clean_placement_context_post_place();
470+
471+
// Clean the floorplanning context.
472+
g_vpr_ctx.mutable_floorplanning().clean_floorplanning_context_post_place();
471473

472474
// TODO: This was taken from vpr_api. Not sure why it is needed. Should be
473475
// made part of the placement and verify placement should check for
@@ -505,7 +507,6 @@ void APPack::legalize(const PartialPlacement& p_placement) {
505507
// The Packer stores the clusters into a .net file. Load the packing file.
506508
// FIXME: This should be removed. Reading from a file is strange.
507509
vpr_load_packing(vpr_setup_, arch_);
508-
load_cluster_constraints();
509510
const ClusteredNetlist& clb_nlist = g_vpr_ctx.clustering().clb_nlist;
510511

511512
// Verify the packing and print some info

vpr/src/base/blk_loc_registry.cpp

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,12 @@
77
#include "physical_types_util.h"
88
#include "vpr_context.h"
99

10-
/**
11-
* @brief Initialize `grid_blocks`, the inverse structure of `block_locs`.
12-
*
13-
* The container at each grid block location should have a length equal to the
14-
* subtile capacity of that block. Unused subtile would be marked ClusterBlockId::INVALID().
15-
*/
16-
static GridBlock init_grid_blocks(const DeviceGrid& device_grid);
17-
1810
BlkLocRegistry::BlkLocRegistry()
1911
: expected_transaction_(e_expected_transaction::APPLY) {}
2012

21-
void BlkLocRegistry::init(const ClusteredNetlist& clb_nlist, const DeviceGrid& device_grid) {
13+
void BlkLocRegistry::init() {
14+
const ClusteredNetlist& clb_nlist = g_vpr_ctx.clustering().clb_nlist;
15+
const DeviceGrid& device_grid = g_vpr_ctx.device().grid;
2216
auto& block_locs = mutable_block_locs();
2317
auto& grid_blocks = mutable_grid_blocks();
2418

@@ -27,35 +21,14 @@ void BlkLocRegistry::init(const ClusteredNetlist& clb_nlist, const DeviceGrid& d
2721
block_locs.resize(clb_nlist.blocks().size());
2822

2923
/* Initialize the reverse lookup of CLB block positions */
30-
grid_blocks = init_grid_blocks(device_grid);
24+
grid_blocks.init_grid_blocks(device_grid);
3125

3226
/* Initialize the grid blocks to empty.
3327
* Initialize all the blocks to unplaced.
3428
*/
3529
clear_all_grid_locs();
3630
}
3731

38-
static GridBlock init_grid_blocks(const DeviceGrid& device_grid) {
39-
size_t grid_width = device_grid.width();
40-
size_t grid_height = device_grid.height();
41-
int num_layers = device_grid.get_num_layers();
42-
43-
/* Structure should have the same dimensions as the grid. */
44-
auto grid_blocks = GridBlock(grid_width, grid_height, num_layers);
45-
46-
for (int layer_num = 0; layer_num < num_layers; layer_num++) {
47-
for (size_t x = 0; x < grid_width; x++) {
48-
for (size_t y = 0; y < grid_height; y++) {
49-
const t_physical_tile_loc tile_loc({(int)x, (int)y, layer_num});
50-
auto type = device_grid.get_physical_type(tile_loc);
51-
grid_blocks.initialized_grid_block_at_location(tile_loc, type->capacity);
52-
}
53-
}
54-
}
55-
56-
return grid_blocks;
57-
}
58-
5932
const vtr::vector_map<ClusterBlockId, t_block_loc>& BlkLocRegistry::block_locs() const {
6033
return block_locs_;
6134
}

vpr/src/base/blk_loc_registry.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class BlkLocRegistry {
2828

2929
/// @brief Initialize the block loc registry's internal data. Must be called
3030
/// before any other method is called.
31-
void init(const ClusteredNetlist& clb_nlist, const DeviceGrid& device_grid);
31+
void init();
3232

3333
private:
3434
///@brief Clustered block placement locations

vpr/src/base/grid_block.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
11

22
#include "grid_block.h"
33

4+
#include "device_grid.h"
45
#include "globals.h"
6+
#include "physical_types.h"
7+
8+
void GridBlock::init_grid_blocks(const DeviceGrid& device_grid) {
9+
size_t grid_width = device_grid.width();
10+
size_t grid_height = device_grid.height();
11+
size_t num_layers = device_grid.get_num_layers();
12+
13+
/* Structure should have the same dimensions as the grid. */
14+
grid_blocks_.resize({num_layers, grid_width, grid_height});
15+
16+
for (size_t layer_num = 0; layer_num < num_layers; layer_num++) {
17+
for (size_t x = 0; x < grid_width; x++) {
18+
for (size_t y = 0; y < grid_height; y++) {
19+
const t_physical_tile_loc tile_loc({(int)x, (int)y, (int)layer_num});
20+
auto type = device_grid.get_physical_type(tile_loc);
21+
initialized_grid_block_at_location(tile_loc, type->capacity);
22+
}
23+
}
24+
}
25+
}
526

627
void GridBlock::zero_initialize() {
728
auto& device_ctx = g_vpr_ctx.device();

vpr/src/base/grid_block.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ class GridBlock {
3838
grid_blocks_.resize({layers, width, height});
3939
}
4040

41+
/**
42+
* @brief Initialize `grid_blocks`, the inverse structure of `block_locs`.
43+
*
44+
* The container at each grid block location should have a length equal to the
45+
* subtile capacity of that block. Unused subtiles would be marked ClusterBlockId::INVALID().
46+
*/
47+
void init_grid_blocks(const DeviceGrid& device_grid);
48+
4149
inline void initialized_grid_block_at_location(const t_physical_tile_loc& loc, int num_sub_tiles) {
4250
grid_blocks_[loc.layer_num][loc.x][loc.y].blocks.resize(num_sub_tiles, ClusterBlockId::INVALID());
4351
}

vpr/src/base/vpr_api.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
#include "atom_netlist_utils.h"
7070
#include "output_clustering.h"
7171
#include "vpr_constraints_reader.h"
72-
#include "place_constraints.h"
7372
#include "place_util.h"
7473
#include "timing_fail_error.h"
7574
#include "analytical_placement_flow.h"
@@ -683,8 +682,9 @@ void vpr_load_packing(const t_vpr_setup& vpr_setup, const t_arch& arch) {
683682
report_packing_pin_usage(ofs, g_vpr_ctx);
684683
}
685684

686-
// Load cluster_constraints data structure.
687-
load_cluster_constraints();
685+
// Ater the clustered netlist has been loaded, update the floorplanning
686+
// constraints with the new information.
687+
g_vpr_ctx.mutable_floorplanning().update_floorplanning_context_post_pack();
688688

689689
/* Sanity check the resulting netlist */
690690
check_netlist(vpr_setup.PackerOpts.pack_verbosity);
@@ -844,7 +844,7 @@ void vpr_load_placement(t_vpr_setup& vpr_setup,
844844
const auto& filename_opts = vpr_setup.FileNameOpts;
845845

846846
//Initialize the block location registry, which will be filled when loading placement
847-
blk_loc_registry.init(g_vpr_ctx.clustering().clb_nlist, device_ctx.grid);
847+
blk_loc_registry.init();
848848

849849
// Alloc and load the placement macros.
850850
place_ctx.place_macros = std::make_unique<PlaceMacros>(directs,

vpr/src/base/vpr_context.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date February 2025
5+
* @brief Implementation of the more complicated context member functions.
6+
* These are methods used to initialize / clean the contexts.
7+
*/
8+
9+
#include "vpr_context.h"
10+
#include <memory>
11+
#include "compressed_grid.h"
12+
#include "globals.h"
13+
#include "physical_types.h"
14+
#include "place_constraints.h"
15+
#include "place_macro.h"
16+
#include "vpr_types.h"
17+
#include "vtr_memory.h"
18+
19+
/**
20+
* @brief determine the type of the bounding box used by the placer to predict
21+
* the wirelength.
22+
*
23+
* @param place_bb_mode The bounding box mode passed by the CLI
24+
* @param rr_graph The routing resource graph
25+
*/
26+
static bool is_cube_bb(const e_place_bounding_box_mode place_bb_mode,
27+
const RRGraphView& rr_graph);
28+
29+
void FloorplanningContext::update_floorplanning_context_post_pack() {
30+
// Initialize the cluster_constraints using the constraints loaded from the
31+
// user and clustering generated from packing.
32+
load_cluster_constraints();
33+
}
34+
35+
void FloorplanningContext::update_floorplanning_context_pre_place(
36+
const PlaceMacros& place_macros) {
37+
// Go through cluster blocks to calculate the tightest placement
38+
// floorplan constraint for each constrained block.
39+
propagate_place_constraints(place_macros);
40+
41+
// Compute and store compressed floorplanning constraints.
42+
alloc_and_load_compressed_cluster_constraints();
43+
}
44+
45+
void FloorplanningContext::clean_floorplanning_context_post_place() {
46+
// The cluster constraints are loaded in propagate_place_constraints and are
47+
// not used outside of placement.
48+
vtr::release_memory(cluster_constraints);
49+
50+
// The compressed cluster constraints are loaded in alloc_and_laod_compressed
51+
// cluster_constraints and are not used outside of placement.
52+
vtr::release_memory(compressed_cluster_constraints);
53+
}
54+
55+
void PlacementContext::init_placement_context(
56+
const t_placer_opts& placer_opts,
57+
const std::vector<t_direct_inf>& directs) {
58+
const AtomContext& atom_ctx = g_vpr_ctx.atom();
59+
const ClusteringContext& cluster_ctx = g_vpr_ctx.clustering();
60+
const DeviceContext& device_ctx = g_vpr_ctx.device();
61+
62+
cube_bb = is_cube_bb(placer_opts.place_bounding_box_mode, device_ctx.rr_graph);
63+
64+
compressed_block_grids = create_compressed_block_grids();
65+
66+
// Alloc and load the placement macros.
67+
place_macros = std::make_unique<PlaceMacros>(directs,
68+
device_ctx.physical_tile_types,
69+
cluster_ctx.clb_nlist,
70+
atom_ctx.nlist,
71+
atom_ctx.lookup);
72+
}
73+
74+
static bool is_cube_bb(const e_place_bounding_box_mode place_bb_mode,
75+
const RRGraphView& rr_graph) {
76+
bool cube_bb;
77+
const int number_layers = g_vpr_ctx.device().grid.get_num_layers();
78+
79+
if (place_bb_mode == e_place_bounding_box_mode::AUTO_BB) {
80+
// If the auto_bb is used, we analyze the RR graph to see whether is there any inter-layer connection that is not
81+
// originated from OPIN. If there is any, cube BB is chosen, otherwise, per-layer bb is chosen.
82+
if (number_layers > 1 && inter_layer_connections_limited_to_opin(rr_graph)) {
83+
cube_bb = false;
84+
} else {
85+
cube_bb = true;
86+
}
87+
} else if (place_bb_mode == e_place_bounding_box_mode::CUBE_BB) {
88+
// The user has specifically asked for CUBE_BB
89+
cube_bb = true;
90+
} else {
91+
// The user has specifically asked for PER_LAYER_BB
92+
VTR_ASSERT_SAFE(place_bb_mode == e_place_bounding_box_mode::PER_LAYER_BB);
93+
cube_bb = false;
94+
}
95+
96+
return cube_bb;
97+
}
98+
99+
void PlacementContext::clean_placement_context_post_place() {
100+
// The compressed block grids are currently only used during placement.
101+
vtr::release_memory(compressed_block_grids);
102+
}
103+

vpr/src/base/vpr_context.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <mutex>
77

88
#include "FlatPlacementInfo.h"
9+
#include "physical_types.h"
910
#include "place_macro.h"
1011
#include "user_place_constraints.h"
1112
#include "user_route_constraints.h"
@@ -337,6 +338,30 @@ struct PlacementContext : public Context {
337338

338339
public:
339340

341+
/**
342+
* @brief Initialize the variables stored within the placement context. This
343+
* must be called before performing placement, but must be called
344+
* after the clusters are loaded.
345+
*
346+
* @param placer_opts
347+
* The options passed into the placer.
348+
* @param directs
349+
* A list of the direct connections in the architecture.
350+
*/
351+
void init_placement_context(const t_placer_opts& placer_opts,
352+
const std::vector<t_direct_inf>& directs);
353+
354+
/**
355+
* @brief Clean variables from the placement context which are not used
356+
* outside of placement.
357+
*
358+
* There are some variables that are stored in the placement context and are
359+
* only used in placement; while there are some that are used outside of
360+
* placement. This method frees up the memory of the variables used only
361+
* within placement.
362+
*/
363+
void clean_placement_context_post_place();
364+
340365
const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs() const { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.block_locs(); }
341366
vtr::vector_map<ClusterBlockId, t_block_loc>& mutable_block_locs() { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.mutable_block_locs(); }
342367
const GridBlock& grid_blocks() const { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.grid_blocks(); }
@@ -480,6 +505,42 @@ struct RoutingContext : public Context {
480505
* to certain regions on the chip.
481506
*/
482507
struct FloorplanningContext : public Context {
508+
/**
509+
* @brief Update the floorplanning constraints after a clustering has been
510+
* created.
511+
*
512+
* After clustering, the constraints of contained atoms are used to compute
513+
* the constraints of clusters.
514+
*
515+
* This must be called before using the cluster_constraints.
516+
*/
517+
void update_floorplanning_context_post_pack();
518+
519+
/**
520+
* @brief Update the floorplanning constraints before placement.
521+
*
522+
* Placement groups clusters together into macros which must be placed
523+
* together. This imposes more constraints onto the clusters which needs to
524+
* be updated.
525+
*
526+
* This must be called before placement, but after the placement context is
527+
* initialized.
528+
*
529+
* @param place_macros
530+
* Macros of clusters which must be placed together. Initialized in the
531+
* placement context.
532+
*/
533+
void update_floorplanning_context_pre_place(const PlaceMacros& place_macros);
534+
535+
/**
536+
* @brief Clean the floorplanning constraints after placement.
537+
*
538+
* After placement, many of the variables in this class will no longer be
539+
* used (since the placement is no longer changing, the constraints are no
540+
* longer needed). This method will free up the memory used by this class.
541+
*/
542+
void clean_floorplanning_context_post_place();
543+
483544
/**
484545
* @brief Stores groups of constrained atoms, areas where the atoms are constrained to
485546
*

vpr/src/place/initial_placement.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ void initial_placement(const t_placer_opts& placer_opts,
12981298
vtr::ScopedStartFinishTimer timer("Initial Placement");
12991299

13001300
// Initialize the block loc registry.
1301-
blk_loc_registry.init(g_vpr_ctx.clustering().clb_nlist, g_vpr_ctx.device().grid);
1301+
blk_loc_registry.init();
13021302

13031303
/*Mark the blocks that have already been locked to one spot via floorplan constraints
13041304
* as fixed, so they do not get moved during initial placement or later during the simulated annealing stage of placement*/

0 commit comments

Comments
 (0)