Skip to content

Commit 36ed2b2

Browse files
authored
Merge pull request #2659 from verilog-to-routing/placement_move_primitive_robert_refactoring
[vpr][place] Placement move primitive refactoring
2 parents edce4b4 + c7cbf33 commit 36ed2b2

13 files changed

+516
-515
lines changed

vpr/src/place/initial_noc_placement.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ static void noc_routers_anneal(const t_noc_opts& noc_opts) {
220220
// Generate and evaluate router moves
221221
for (int i_move = 0; i_move < N_MOVES; i_move++) {
222222
e_create_move create_move_outcome = e_create_move::ABORT;
223-
clear_move_blocks(blocks_affected);
223+
blocks_affected.clear_move_blocks();
224224
// Shrink the range limit over time
225225
float r_lim_decayed = 1.0f + (N_MOVES - i_move) * (max_r_lim / N_MOVES);
226226
create_move_outcome = propose_router_swap(blocks_affected, r_lim_decayed);

vpr/src/place/move_transactions.cpp

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
1+
#include "move_transactions.h"
12
#include "move_utils.h"
23

34
#include "globals.h"
45
#include "place_util.h"
6+
#include "vtr_assert.h"
7+
8+
t_pl_blocks_to_be_moved::t_pl_blocks_to_be_moved(size_t max_blocks){
9+
moved_blocks.reserve(max_blocks);
10+
}
11+
12+
size_t t_pl_blocks_to_be_moved::get_size_and_increment() {
13+
VTR_ASSERT_SAFE(moved_blocks.size() < moved_blocks.capacity());
14+
moved_blocks.resize(moved_blocks.size() + 1);
15+
return moved_blocks.size() - 1;
16+
}
517

618
//Records that block 'blk' should be moved to the specified 'to' location
7-
e_block_move_result record_block_move(t_pl_blocks_to_be_moved& blocks_affected, ClusterBlockId blk, t_pl_loc to) {
8-
auto res = blocks_affected.moved_to.emplace(to);
9-
if (!res.second) {
19+
e_block_move_result t_pl_blocks_to_be_moved::record_block_move(ClusterBlockId blk, t_pl_loc to) {
20+
auto [to_it, to_success] = moved_to.emplace(to);
21+
if (!to_success) {
1022
log_move_abort("duplicate block move to location");
1123
return e_block_move_result::ABORT;
1224
}
@@ -15,36 +27,57 @@ e_block_move_result record_block_move(t_pl_blocks_to_be_moved& blocks_affected,
1527

1628
t_pl_loc from = place_ctx.block_locs[blk].loc;
1729

18-
auto res2 = blocks_affected.moved_from.emplace(from);
19-
if (!res2.second) {
30+
auto [_, from_success] = moved_from.emplace(from);
31+
if (!from_success) {
32+
moved_to.erase(to_it);
2033
log_move_abort("duplicate block move from location");
2134
return e_block_move_result::ABORT;
2235
}
2336

2437
VTR_ASSERT_SAFE(to.sub_tile < int(place_ctx.grid_blocks.num_blocks_at_location({to.x, to.y, to.layer})));
2538

2639
// Sets up the blocks moved
27-
int imoved_blk = blocks_affected.num_moved_blocks;
28-
blocks_affected.moved_blocks[imoved_blk].block_num = blk;
29-
blocks_affected.moved_blocks[imoved_blk].old_loc = from;
30-
blocks_affected.moved_blocks[imoved_blk].new_loc = to;
31-
blocks_affected.num_moved_blocks++;
40+
size_t imoved_blk = get_size_and_increment();
41+
moved_blocks[imoved_blk].block_num = blk;
42+
moved_blocks[imoved_blk].old_loc = from;
43+
moved_blocks[imoved_blk].new_loc = to;
3244

3345
return e_block_move_result::VALID;
3446
}
3547

48+
//Examines the currently proposed move and determine any empty locations
49+
std::set<t_pl_loc> t_pl_blocks_to_be_moved::t_pl_blocks_to_be_moved::determine_locations_emptied_by_move() {
50+
std::set<t_pl_loc> moved_from_set;
51+
std::set<t_pl_loc> moved_to_set;
52+
53+
for (const t_pl_moved_block& moved_block : moved_blocks) {
54+
//When a block is moved its old location becomes free
55+
moved_from_set.emplace(moved_block.old_loc);
56+
57+
//But any block later moved to a position fills it
58+
moved_to_set.emplace(moved_block.new_loc);
59+
}
60+
61+
std::set<t_pl_loc> empty_locs;
62+
std::set_difference(moved_from_set.begin(), moved_from_set.end(),
63+
moved_to_set.begin(), moved_to_set.end(),
64+
std::inserter(empty_locs, empty_locs.begin()));
65+
66+
return empty_locs;
67+
}
68+
3669
//Moves the blocks in blocks_affected to their new locations
3770
void apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) {
3871
auto& place_ctx = g_vpr_ctx.mutable_placement();
3972
auto& device_ctx = g_vpr_ctx.device();
4073

4174
//Swap the blocks, but don't swap the nets or update place_ctx.grid_blocks
4275
//yet since we don't know whether the swap will be accepted
43-
for (int iblk = 0; iblk < blocks_affected.num_moved_blocks; ++iblk) {
44-
ClusterBlockId blk = blocks_affected.moved_blocks[iblk].block_num;
76+
for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) {
77+
ClusterBlockId blk = moved_block.block_num;
4578

46-
const t_pl_loc& old_loc = blocks_affected.moved_blocks[iblk].old_loc;
47-
const t_pl_loc& new_loc = blocks_affected.moved_blocks[iblk].new_loc;
79+
const t_pl_loc& old_loc = moved_block.old_loc;
80+
const t_pl_loc& new_loc = moved_block.new_loc;
4881

4982
// move the block to its new location
5083
place_ctx.block_locs[blk].loc = new_loc;
@@ -67,11 +100,11 @@ void commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) {
67100
auto& place_ctx = g_vpr_ctx.mutable_placement();
68101

69102
/* Swap physical location */
70-
for (int iblk = 0; iblk < blocks_affected.num_moved_blocks; ++iblk) {
71-
ClusterBlockId blk = blocks_affected.moved_blocks[iblk].block_num;
103+
for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) {
104+
ClusterBlockId blk = moved_block.block_num;
72105

73-
const t_pl_loc& to = blocks_affected.moved_blocks[iblk].new_loc;
74-
const t_pl_loc& from = blocks_affected.moved_blocks[iblk].old_loc;
106+
const t_pl_loc& to = moved_block.new_loc;
107+
const t_pl_loc& from = moved_block.old_loc;
75108

76109
//Remove from old location only if it hasn't already been updated by a previous block update
77110
if (place_ctx.grid_blocks.block_at_location(from) == blk) {
@@ -97,11 +130,11 @@ void revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) {
97130
auto& device_ctx = g_vpr_ctx.device();
98131

99132
// Swap the blocks back, nets not yet swapped they don't need to be changed
100-
for (int iblk = 0; iblk < blocks_affected.num_moved_blocks; ++iblk) {
101-
ClusterBlockId blk = blocks_affected.moved_blocks[iblk].block_num;
133+
for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) {
134+
ClusterBlockId blk = moved_block.block_num;
102135

103-
const t_pl_loc& old_loc = blocks_affected.moved_blocks[iblk].old_loc;
104-
const t_pl_loc& new_loc = blocks_affected.moved_blocks[iblk].new_loc;
136+
const t_pl_loc& old_loc = moved_block.old_loc;
137+
const t_pl_loc& new_loc = moved_block.new_loc;
105138

106139
// return the block to where it was before the swap
107140
place_ctx.block_locs[blk].loc = old_loc;
@@ -121,15 +154,15 @@ void revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) {
121154
}
122155

123156
//Clears the current move so a new move can be proposed
124-
void clear_move_blocks(t_pl_blocks_to_be_moved& blocks_affected) {
157+
void t_pl_blocks_to_be_moved::clear_move_blocks() {
125158
//Reset moved flags
126-
blocks_affected.moved_to.clear();
127-
blocks_affected.moved_from.clear();
159+
moved_to.clear();
160+
moved_from.clear();
128161

129-
//For run-time, we just reset num_moved_blocks to zero, but do not free the blocks_affected
162+
//For run-time, we just reset size of blocks_affected.moved_blocks to zero, but do not free the blocks_affected
130163
//array to avoid memory allocation
131164

132-
blocks_affected.num_moved_blocks = 0;
165+
moved_blocks.resize(0);
133166

134-
blocks_affected.affected_pins.clear();
167+
affected_pins.clear();
135168
}

vpr/src/place/move_transactions.h

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
#include "vpr_types.h"
44
#include "clustered_netlist_utils.h"
55

6+
enum class e_block_move_result {
7+
VALID, //Move successful
8+
ABORT, //Unable to perform move
9+
INVERT, //Try move again but with from/to inverted
10+
INVERT_VALID //Completed inverted move
11+
};
12+
613
/* Stores the information of the move for a block that is *
714
* moved during placement *
815
* block_num: the index of the moved block *
@@ -25,41 +32,45 @@ struct t_pl_moved_block {
2532
* placement, in the form of array of structs instead of struct with *
2633
* arrays for cache effifiency *
2734
*
28-
* num_moved_blocks: total number of blocks moved when *
29-
* swapping two blocks. *
3035
* moved blocks: a list of moved blocks data structure with *
3136
* information on the move. *
3237
* [0...max_blocks-1] *
3338
* affected_pins: pins affected by this move (used to *
3439
* incrementally invalidate parts of the timing *
3540
* graph. */
3641
struct t_pl_blocks_to_be_moved {
37-
explicit t_pl_blocks_to_be_moved(size_t max_blocks)
38-
: moved_blocks(max_blocks) {}
42+
explicit t_pl_blocks_to_be_moved(size_t max_blocks);
43+
t_pl_blocks_to_be_moved() = delete;
44+
t_pl_blocks_to_be_moved(const t_pl_blocks_to_be_moved&) = delete;
45+
t_pl_blocks_to_be_moved(t_pl_blocks_to_be_moved&&) = delete;
46+
47+
/**
48+
* @brief This function increments the size of the moved_blocks vector and return the index
49+
* of the newly added last elements.
50+
*/
51+
size_t get_size_and_increment();
52+
53+
/**
54+
* @brief This function clears all data structures of this struct.
55+
*/
56+
void clear_move_blocks();
57+
58+
e_block_move_result record_block_move(ClusterBlockId blk, t_pl_loc to);
59+
60+
std::set<t_pl_loc> determine_locations_emptied_by_move();
3961

40-
int num_moved_blocks = 0;
4162
std::vector<t_pl_moved_block> moved_blocks;
4263
std::unordered_set<t_pl_loc> moved_from;
4364
std::unordered_set<t_pl_loc> moved_to;
4465

4566
std::vector<ClusterPinId> affected_pins;
4667
};
4768

48-
enum class e_block_move_result {
49-
VALID, //Move successful
50-
ABORT, //Unable to perform move
51-
INVERT, //Try move again but with from/to inverted
52-
INVERT_VALID //Completed inverted move
53-
};
54-
55-
e_block_move_result record_block_move(t_pl_blocks_to_be_moved& blocks_affected, ClusterBlockId blk, t_pl_loc to);
5669

5770
void apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected);
5871

5972
void commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected);
6073

6174
void revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected);
6275

63-
void clear_move_blocks(t_pl_blocks_to_be_moved& blocks_affected);
64-
6576
#endif

vpr/src/place/move_utils.cpp

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "move_utils.h"
22

3+
#include "move_transactions.h"
34
#include "place_util.h"
45
#include "globals.h"
56

@@ -141,7 +142,7 @@ e_block_move_result record_single_block_swap(t_pl_blocks_to_be_moved& blocks_aff
141142
// Check whether the to_location is empty
142143
if (b_to == EMPTY_BLOCK_ID) {
143144
// Sets up the blocks moved
144-
outcome = record_block_move(blocks_affected, b_from, to);
145+
outcome = blocks_affected.record_block_move(b_from, to);
145146

146147
} else if (b_to != INVALID_BLOCK_ID) {
147148
// Check whether block to is compatible with from location
@@ -152,14 +153,14 @@ e_block_move_result record_single_block_swap(t_pl_blocks_to_be_moved& blocks_aff
152153
}
153154

154155
// Sets up the blocks moved
155-
outcome = record_block_move(blocks_affected, b_from, to);
156+
outcome = blocks_affected.record_block_move(b_from, to);
156157

157158
if (outcome != e_block_move_result::VALID) {
158159
return outcome;
159160
}
160161

161162
t_pl_loc from = place_ctx.block_locs[b_from].loc;
162-
outcome = record_block_move(blocks_affected, b_to, from);
163+
outcome = blocks_affected.record_block_move(b_to, from);
163164

164165
} // Finish swapping the blocks and setting up blocks_affected
165166

@@ -341,7 +342,7 @@ e_block_move_result record_macro_move(t_pl_blocks_to_be_moved& blocks_affected,
341342

342343
ClusterBlockId blk_to = place_ctx.grid_blocks.block_at_location(to);
343344

344-
record_block_move(blocks_affected, member.blk_index, to);
345+
blocks_affected.record_block_move(member.blk_index, to);
345346

346347
int imacro_to = -1;
347348
get_imacro_from_iblk(&imacro_to, blk_to, place_ctx.pl_macros);
@@ -392,7 +393,7 @@ e_block_move_result record_macro_self_swaps(t_pl_blocks_to_be_moved& blocks_affe
392393
auto& place_ctx = g_vpr_ctx.placement();
393394

394395
//Reset any partial move
395-
clear_move_blocks(blocks_affected);
396+
blocks_affected.clear_move_blocks();
396397

397398
//Collect the macros affected
398399
std::vector<int> affected_macros;
@@ -431,14 +432,14 @@ e_block_move_result record_macro_self_swaps(t_pl_blocks_to_be_moved& blocks_affe
431432
std::copy_if(displaced_blocks.begin(), displaced_blocks.end(), std::back_inserter(non_macro_displaced_blocks), is_non_macro_block);
432433

433434
//Based on the currently queued block moves, find the empty 'holes' left behind
434-
auto empty_locs = determine_locations_emptied_by_move(blocks_affected);
435+
auto empty_locs = blocks_affected.determine_locations_emptied_by_move();
435436

436437
VTR_ASSERT_SAFE(empty_locs.size() >= non_macro_displaced_blocks.size());
437438

438439
//Fit the displaced blocks into the empty locations
439440
auto loc_itr = empty_locs.begin();
440441
for (auto blk : non_macro_displaced_blocks) {
441-
outcome = record_block_move(blocks_affected, blk, *loc_itr);
442+
outcome = blocks_affected.record_block_move(blk, *loc_itr);
442443
++loc_itr;
443444
}
444445

@@ -483,27 +484,6 @@ bool is_legal_swap_to_location(ClusterBlockId blk, t_pl_loc to) {
483484
return true;
484485
}
485486

486-
//Examines the currently proposed move and determine any empty locations
487-
std::set<t_pl_loc> determine_locations_emptied_by_move(t_pl_blocks_to_be_moved& blocks_affected) {
488-
std::set<t_pl_loc> moved_from;
489-
std::set<t_pl_loc> moved_to;
490-
491-
for (int iblk = 0; iblk < blocks_affected.num_moved_blocks; ++iblk) {
492-
//When a block is moved its old location becomes free
493-
moved_from.emplace(blocks_affected.moved_blocks[iblk].old_loc);
494-
495-
//But any block later moved to a position fills it
496-
moved_to.emplace(blocks_affected.moved_blocks[iblk].new_loc);
497-
}
498-
499-
std::set<t_pl_loc> empty_locs;
500-
std::set_difference(moved_from.begin(), moved_from.end(),
501-
moved_to.begin(), moved_to.end(),
502-
std::inserter(empty_locs, empty_locs.begin()));
503-
504-
return empty_locs;
505-
}
506-
507487
#ifdef VTR_ENABLE_DEBUG_LOGGING
508488
void enable_placer_debug(const t_placer_opts& placer_opts,
509489
ClusterBlockId blk_id) {

vpr/src/place/move_utils.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@ e_block_move_result record_macro_self_swaps(t_pl_blocks_to_be_moved& blocks_affe
125125
*/
126126
bool is_legal_swap_to_location(ClusterBlockId blk, t_pl_loc to);
127127

128-
std::set<t_pl_loc> determine_locations_emptied_by_move(t_pl_blocks_to_be_moved& blocks_affected);
129-
130128
/**
131129
* @brief Propose block for the RL agent based on required block type.
132130
*

0 commit comments

Comments
 (0)