Skip to content

Commit 4147967

Browse files
[Place] Cleaned Up Placement Context Initialization
Cleaned up how the variables in the placement context were initialized to make it easier to initialize the placement context outside of the placement stage (Analytical Placement). Added an optional argument to the Placer class to allow an initial placement to be passed in. This allows a different initial placement to be used without having to pull the initial placer out of the Placer class. With this change, it should be easier to create the Detailed Placer in Analytical Placement.
1 parent 4c81b1d commit 4147967

File tree

11 files changed

+206
-144
lines changed

11 files changed

+206
-144
lines changed

vpr/src/analytical_place/full_legalizer.cpp

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -131,30 +131,13 @@ class APClusterPlacer {
131131
*/
132132
APClusterPlacer(const PlaceMacros& place_macros)
133133
: place_macros_(place_macros) {
134-
// FIXME: This was stolen from place/place.cpp
135-
// it used a static method, just taking what I think I will need.
134+
// Initialize the block loc registry.
136135
auto& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
136+
blk_loc_registry.init(g_vpr_ctx.clustering().clb_nlist,
137+
g_vpr_ctx.device().grid);
137138

138-
init_placement_context(blk_loc_registry);
139-
140-
// stolen from place/place.cpp:alloc_and_load_try_swap_structs
141-
// FIXME: set cube_bb to false by hand, should be passed in.
142-
g_vpr_ctx.mutable_placement().cube_bb = false;
143-
g_vpr_ctx.mutable_placement().compressed_block_grids = create_compressed_block_grids();
144-
145-
// TODO: The next few steps will be basically a direct copy of the initial
146-
// placement code since it does everything we need! It would be nice
147-
// to share the code.
148-
149-
// Clear the grid locations (stolen from initial_placement)
150-
blk_loc_registry.clear_all_grid_locs();
151-
152-
// Deal with the placement constraints.
153-
propagate_place_constraints(place_macros_);
154-
139+
// Place the fixed blocks and mark them as fixed.
155140
mark_fixed_blocks(blk_loc_registry);
156-
157-
alloc_and_load_compressed_cluster_constraints();
158141
}
159142

160143
/**
@@ -468,13 +451,11 @@ void NaiveFullLegalizer::legalize(const PartialPlacement& p_placement) {
468451
// TODO: Eventually should be returned from the create_clusters method.
469452
const ClusteredNetlist& clb_nlist = g_vpr_ctx.clustering().clb_nlist;
470453

471-
// Alloc and load the placement macros.
472-
VTR_ASSERT(!g_vpr_ctx.placement().place_macros);
473-
g_vpr_ctx.mutable_placement().place_macros = std::make_unique<PlaceMacros>(g_vpr_ctx.device().arch->directs,
474-
g_vpr_ctx.device().physical_tile_types,
475-
g_vpr_ctx.clustering().clb_nlist,
476-
g_vpr_ctx.atom().nlist,
477-
g_vpr_ctx.atom().lookup);
454+
// Initialize the placement context.
455+
init_placement_context(g_vpr_ctx.mutable_placement(),
456+
vpr_setup_.PlacerOpts,
457+
vpr_setup_.NocOpts,
458+
arch_.directs);
478459

479460
const PlaceMacros& place_macros = *g_vpr_ctx.placement().place_macros;
480461

@@ -492,6 +473,9 @@ void NaiveFullLegalizer::legalize(const PartialPlacement& p_placement) {
492473
num_placement_errors);
493474
}
494475

476+
// Clean the placement context.
477+
clean_placement_context(g_vpr_ctx.mutable_placement());
478+
495479
// TODO: This was taken from vpr_api. Not sure why it is needed. Should be
496480
// made part of the placement and verify placement should check for
497481
// it.

vpr/src/base/blk_loc_registry.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,61 @@
11

22
#include "blk_loc_registry.h"
33

4+
#include "device_grid.h"
45
#include "move_transactions.h"
56
#include "globals.h"
67
#include "physical_types_util.h"
8+
#include "vpr_context.h"
9+
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);
717

818
BlkLocRegistry::BlkLocRegistry()
919
: expected_transaction_(e_expected_transaction::APPLY) {}
1020

21+
void BlkLocRegistry::init(const ClusteredNetlist& clb_nlist, const DeviceGrid& device_grid) {
22+
auto& block_locs = mutable_block_locs();
23+
auto& grid_blocks = mutable_grid_blocks();
24+
25+
/* Initialize the lookup of CLB block positions */
26+
block_locs.clear();
27+
block_locs.resize(clb_nlist.blocks().size());
28+
29+
/* Initialize the reverse lookup of CLB block positions */
30+
grid_blocks = init_grid_blocks(device_grid);
31+
32+
/* Initialize the grid blocks to empty.
33+
* Initialize all the blocks to unplaced.
34+
*/
35+
clear_all_grid_locs();
36+
}
37+
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+
1159
const vtr::vector_map<ClusterBlockId, t_block_loc>& BlkLocRegistry::block_locs() const {
1260
return block_locs_;
1361
}

vpr/src/base/blk_loc_registry.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class BlkLocRegistry {
2626
BlkLocRegistry(BlkLocRegistry&&) = delete;
2727
BlkLocRegistry& operator=(BlkLocRegistry&&) = delete;
2828

29+
/// @brief Initialize the block loc registry's internal data. Must be called
30+
/// before any other method is called.
31+
void init(const ClusteredNetlist& clb_nlist, const DeviceGrid& device_grid);
32+
2933
private:
3034
///@brief Clustered block placement locations
3135
vtr::vector_map<ClusterBlockId, t_block_loc> block_locs_;

vpr/src/base/vpr_api.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -845,8 +845,8 @@ void vpr_load_placement(t_vpr_setup& vpr_setup,
845845
auto& blk_loc_registry = place_ctx.mutable_blk_loc_registry();
846846
const auto& filename_opts = vpr_setup.FileNameOpts;
847847

848-
//Initialize placement data structures, which will be filled when loading placement
849-
init_placement_context(blk_loc_registry);
848+
//Initialize the block location registry, which will be filled when loading placement
849+
blk_loc_registry.init(g_vpr_ctx.clustering().clb_nlist, device_ctx.grid);
850850

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

vpr/src/place/initial_placement.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,23 +1251,13 @@ void initial_placement(const t_placer_opts& placer_opts,
12511251
vtr::RngContainer& rng) {
12521252
vtr::ScopedStartFinishTimer timer("Initial Placement");
12531253

1254-
/* Initialize the grid blocks to empty.
1255-
* Initialize all the blocks to unplaced.
1256-
*/
1257-
blk_loc_registry.clear_all_grid_locs();
1258-
1259-
/* Go through cluster blocks to calculate the tightest placement
1260-
* floorplan constraint for each constrained block
1261-
*/
1262-
propagate_place_constraints(place_macros);
1254+
// Initialize the block loc registry.
1255+
blk_loc_registry.init(g_vpr_ctx.clustering().clb_nlist, g_vpr_ctx.device().grid);
12631256

12641257
/*Mark the blocks that have already been locked to one spot via floorplan constraints
12651258
* as fixed, so they do not get moved during initial placement or later during the simulated annealing stage of placement*/
12661259
mark_fixed_blocks(blk_loc_registry);
12671260

1268-
// Compute and store compressed floorplanning constraints
1269-
alloc_and_load_compressed_cluster_constraints();
1270-
12711261
// read the constraint file and place fixed blocks
12721262
if (strlen(constraints_file) != 0) {
12731263
read_constraints(constraints_file, blk_loc_registry);

vpr/src/place/place.cpp

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11

22
#include <memory>
3+
#include <optional>
34

45
#include "FlatPlacementInfo.h"
6+
#include "initial_placement.h"
7+
#include "load_flat_place.h"
8+
#include "noc_place_utils.h"
9+
#include "pack.h"
10+
#include "place_constraints.h"
511
#include "place_macro.h"
12+
#include "vpr_context.h"
613
#include "vtr_assert.h"
714
#include "vtr_log.h"
15+
#include "vtr_memory.h"
816
#include "vtr_time.h"
917
#include "vpr_types.h"
1018
#include "vpr_utils.h"
@@ -53,6 +61,18 @@ void try_place(const Netlist<>& net_list,
5361
const auto& cluster_ctx = g_vpr_ctx.clustering();
5462
const auto& atom_ctx = g_vpr_ctx.atom();
5563

64+
// Initialize the variables in the placement context.
65+
init_placement_context(g_vpr_ctx.mutable_placement(),
66+
placer_opts,
67+
noc_opts,
68+
directs);
69+
70+
const bool cube_bb = g_vpr_ctx.placement().cube_bb;
71+
72+
VTR_LOG("\n");
73+
VTR_LOG("Bounding box mode is %s\n", (cube_bb ? "Cube" : "Per-layer"));
74+
VTR_LOG("\n");
75+
5676
/* Placement delay model is independent of the placement and can be shared across
5777
* multiple placers if we are performing parallel annealing.
5878
* So, it is created and initialized once. */
@@ -74,28 +94,11 @@ void try_place(const Netlist<>& net_list,
7494
}
7595
}
7696

77-
g_vpr_ctx.mutable_placement().cube_bb = is_cube_bb(placer_opts.place_bounding_box_mode, device_ctx.rr_graph);
78-
const bool cube_bb = g_vpr_ctx.placement().cube_bb;
79-
80-
VTR_LOG("\n");
81-
VTR_LOG("Bounding box mode is %s\n", (cube_bb ? "Cube" : "Per-layer"));
82-
VTR_LOG("\n");
83-
84-
auto& place_ctx = g_vpr_ctx.mutable_placement();
85-
8697
/* Make the global instance of BlkLocRegistry inaccessible through the getter methods of the
8798
* placement context. This is done to make sure that the placement stage only accesses its
8899
* own local instances of BlkLocRegistry.
89100
*/
90-
place_ctx.lock_loc_vars();
91-
place_ctx.compressed_block_grids = create_compressed_block_grids();
92-
93-
// Alloc and load the placement macros.
94-
place_ctx.place_macros = std::make_unique<PlaceMacros>(directs,
95-
device_ctx.physical_tile_types,
96-
cluster_ctx.clb_nlist,
97-
atom_ctx.nlist,
98-
atom_ctx.lookup);
101+
g_vpr_ctx.mutable_placement().lock_loc_vars();
99102

100103
/* Start measuring placement time. The measured execution time will be printed
101104
* when this object goes out of scope at the end of this function.
@@ -107,18 +110,74 @@ void try_place(const Netlist<>& net_list,
107110
// Enables fast look-up of atom pins connect to CLB pins
108111
ClusteredPinAtomPinsLookup netlist_pin_lookup(cluster_ctx.clb_nlist, atom_ctx.nlist, pb_gpin_lookup);
109112

110-
Placer placer(net_list, placer_opts, analysis_opts, noc_opts, pb_gpin_lookup, netlist_pin_lookup,
113+
Placer placer(net_list, {}, placer_opts, analysis_opts, noc_opts, pb_gpin_lookup, netlist_pin_lookup,
111114
flat_placement_info, place_delay_model, cube_bb, is_flat, /*quiet=*/false);
112115

113116
placer.place();
114117

115-
vtr::release_memory(place_ctx.compressed_block_grids);
116-
117118
/* The placer object has its own copy of block locations and doesn't update
118119
* the global context directly. We need to copy its internal data structures
119120
* to the global placement context before it goes out of scope.
120121
*/
121-
placer.copy_locs_to_global_state(place_ctx);
122+
placer.copy_locs_to_global_state(g_vpr_ctx.mutable_placement());
123+
124+
// Clean the variables in the placement context. This will deallocate memory
125+
// used by variables which were allocated in the placement context and are
126+
// never used outside of placement.
127+
clean_placement_context(g_vpr_ctx.mutable_placement());
128+
}
129+
130+
void init_placement_context(PlacementContext& place_ctx,
131+
const t_placer_opts& placer_opts,
132+
const t_noc_opts& noc_opts,
133+
const std::vector<t_direct_inf>& directs) {
134+
const AtomContext& atom_ctx = g_vpr_ctx.atom();
135+
const ClusteringContext& cluster_ctx = g_vpr_ctx.clustering();
136+
const DeviceContext& device_ctx = g_vpr_ctx.device();
137+
138+
place_ctx.cube_bb = is_cube_bb(placer_opts.place_bounding_box_mode, device_ctx.rr_graph);
139+
140+
place_ctx.compressed_block_grids = create_compressed_block_grids();
141+
142+
// Alloc and load the placement macros.
143+
place_ctx.place_macros = std::make_unique<PlaceMacros>(directs,
144+
device_ctx.physical_tile_types,
145+
cluster_ctx.clb_nlist,
146+
atom_ctx.nlist,
147+
atom_ctx.lookup);
148+
149+
/* Go through cluster blocks to calculate the tightest placement
150+
* floorplan constraint for each constrained block.
151+
*/
152+
propagate_place_constraints(*place_ctx.place_macros);
153+
154+
// Compute and store compressed floorplanning constraints.
155+
alloc_and_load_compressed_cluster_constraints();
156+
157+
/* To make sure the importance of NoC-related cost terms compared to
158+
* BB and timing cost is determine only through NoC placement weighting factor,
159+
* we normalize NoC-related cost weighting factors so that they add up to 1.
160+
* With this normalization, NoC-related cost weighting factors only determine
161+
* the relative importance of NoC cost terms with respect to each other, while
162+
* the importance of total NoC cost to conventional placement cost is determined
163+
* by NoC placement weighting factor.
164+
* FIXME: Why is this modifying the noc_opts?
165+
*/
166+
if (noc_opts.noc) {
167+
normalize_noc_cost_weighting_factor(const_cast<t_noc_opts&>(noc_opts));
168+
}
169+
}
170+
171+
void clean_placement_context(PlacementContext& place_ctx) {
172+
vtr::release_memory(place_ctx.compressed_block_grids);
173+
174+
// The cluster constraints are loaded in propagate_place_constraints and are
175+
// not used outside of placement.
176+
vtr::release_memory(g_vpr_ctx.mutable_floorplanning().cluster_constraints);
177+
178+
// The compressed cluster constraints are loaded in alloc_and_laod_compressed
179+
// cluster_constraints and are not used outside of placement.
180+
vtr::release_memory(g_vpr_ctx.mutable_floorplanning().compressed_cluster_constraints);
122181
}
123182

124183
static bool is_cube_bb(const e_place_bounding_box_mode place_bb_mode,

vpr/src/place/place.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "vpr_types.h"
55

66
class FlatPlacementInfo;
7+
class PlacementContext;
78

89
void try_place(const Netlist<>& net_list,
910
const t_placer_opts& placer_opts,
@@ -17,3 +18,32 @@ void try_place(const Netlist<>& net_list,
1718
const FlatPlacementInfo& flat_placement_info,
1819
bool is_flat);
1920

21+
/**
22+
* @brief Initialize the variables stored within the placement context. This
23+
* must be called before using the Placer class.
24+
*
25+
* @param place_ctx
26+
* The placement context to initialize.
27+
* @param placer_opts
28+
* The options passed into the placer.
29+
* @param noc_opts
30+
* The options passed into the placer for NoCs.
31+
* @param directs
32+
* A list of the direct connections in the architecture.
33+
*/
34+
void init_placement_context(PlacementContext& place_ctx,
35+
const t_placer_opts& placer_opts,
36+
const t_noc_opts& noc_opts,
37+
const std::vector<t_direct_inf>& directs);
38+
39+
/**
40+
* @brief Clean variables from the placement context which are not used outside
41+
* of placement.
42+
*
43+
* These are some variables that are stored in the placement context and are
44+
* only used in placement; while there are some that are used outside of
45+
* placement. This method frees up the memory of the variables used only within
46+
* placement.
47+
*/
48+
void clean_placement_context(PlacementContext& place_ctx);
49+

0 commit comments

Comments
 (0)