Skip to content

[Place] Expand search range for sparse blocks #2960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 63 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
0c355d8
[type] add is_fixed to t_bb
amin1377 Apr 1, 2025
42d06e7
[vpr][type] add comments for t_bb
amin1377 Apr 1, 2025
b80abb5
[place] expand search range if the number of blocks in the column is …
amin1377 Apr 1, 2025
0f038dc
make format
amin1377 Apr 1, 2025
271640b
[base][types] remove is_fixed from t_bb
amin1377 Apr 2, 2025
a2ae770
[vpr][place] adjust search range in another function
amin1377 Apr 2, 2025
01b55e8
[vpr][place] fix a typo
amin1377 Apr 2, 2025
df7a0c4
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 Apr 3, 2025
75e9474
[vpr][place] fix a typo
amin1377 Apr 3, 2025
2e4dc59
[vpr][place] clean up the code
amin1377 Apr 3, 2025
34c7571
[vpr][place] don't continue if there is no compatible block in the gi…
amin1377 Apr 3, 2025
c94c8b8
[vpr][place] check lower_iter afer adjustment
amin1377 Apr 3, 2025
512eb7c
[vpr][place] add adjust_search_range
amin1377 Apr 3, 2025
1da6e6d
[vpr][place] add adjust_search_range
amin1377 Apr 3, 2025
a1d67f7
make format
amin1377 Apr 3, 2025
9c4057a
Merge branch 'master' into placement_search_range
amin1377 Apr 24, 2025
a27a74f
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 Apr 26, 2025
58a3522
[vpr][place] use is_io_type to determine whether a block is of the ty…
amin1377 Apr 26, 2025
43e33fa
[libs][libarch] add is_io_type for logical types
amin1377 Apr 26, 2025
3ea75f2
[vpr][place] add comment for adjust_search_range
amin1377 Apr 26, 2025
ac7a821
[test] update strong results
amin1377 Apr 26, 2025
6871fc9
[test] update srong odin
amin1377 Apr 26, 2025
84790cf
[test] update basic_timing results
amin1377 Apr 26, 2025
9f8e498
[test] update parmys and odin res
amin1377 Apr 26, 2025
e2b0c9d
[test] update nightly test 1 res
amin1377 Apr 28, 2025
cf86a33
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 May 1, 2025
a97d8db
[vpr][place] don't skip the x if search range min is below the y found
amin1377 May 1, 2025
2dc79c9
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 May 12, 2025
fe99d5e
[vpr][place] search for another column if block is not io and lower_b…
amin1377 May 13, 2025
f9e8517
[vpr][place] remove adjust search range and adjust it inside find_com…
amin1377 May 14, 2025
dae25cc
[vpr][place] use a constexpr to compare the number of blocks in column
amin1377 May 14, 2025
ade994b
[vpr][place] pass block_constraint parameter to relevant functions in…
amin1377 May 14, 2025
96e9cc5
make format
amin1377 May 14, 2025
4a6e333
[vpr][place] move MIN_BLK_PER_COLUMN_EXPAND into the routine
amin1377 May 14, 2025
caaf456
make format
amin1377 May 14, 2025
af29e9d
[vpr][place] expand search range if block is io
amin1377 May 14, 2025
7070d1b
Revert "[vpr][place] expand search range if block is io"
amin1377 May 14, 2025
7c96daa
Revert "make format"
amin1377 May 14, 2025
057d0a9
Revert "[vpr][place] move MIN_BLK_PER_COLUMN_EXPAND into the routine"
amin1377 May 14, 2025
8c4a49b
Revert "make format"
amin1377 May 14, 2025
d416295
Revert "[vpr][place] pass block_constraint parameter to relevant func…
amin1377 May 14, 2025
4152246
Revert "[vpr][place] use a constexpr to compare the number of blocks …
amin1377 May 14, 2025
cfa8210
Revert "[vpr][place] remove adjust search range and adjust it inside …
amin1377 May 14, 2025
17ec4a0
[vpr][place] move adjust_search_range to move_utils.h so it can be ac…
amin1377 May 14, 2025
5e8a495
[vpr][place] add adjust search range to find centriod neighbour
amin1377 May 14, 2025
36e1eb6
[vpr][place] remove a special case in find_compatible_compressed_loc_…
amin1377 May 15, 2025
59a08eb
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 May 15, 2025
f8a002d
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 May 21, 2025
a63e5d8
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 May 26, 2025
5888193
[libs][utils] remove redundant helper functions
amin1377 May 26, 2025
7fd8611
[libs][physical_types] add is_io to logical block
amin1377 May 26, 2025
c45e572
[vpr][place] use logic block is_io
amin1377 May 26, 2025
fc9c6a5
[vpr][place] update initial placement to limit set search range based…
amin1377 May 26, 2025
51f9e6b
[vpr][place] adjust search range if number of blocks in the column is…
amin1377 May 26, 2025
dcb2ef9
[vpr][place] pass search_range by value
amin1377 May 26, 2025
147eadc
make format
amin1377 May 26, 2025
8ebd39a
[vpr][place] replace auto key word with variable type
amin1377 May 27, 2025
7fc5583
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 May 30, 2025
30d01da
[test] update golden results
amin1377 May 30, 2025
593263d
update golden results
amin1377 May 30, 2025
8955b02
[test] update golden result
amin1377 Jun 2, 2025
a15f70a
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-ve…
amin1377 Jun 2, 2025
f382bb5
[test][nightly_test_3] change seed from 5 to 3
amin1377 Jun 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion libs/libarchfpga/src/physical_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,20 @@ bool t_logical_block_type::is_empty() const {
return name == std::string(EMPTY_BLOCK_NAME);
}

bool t_logical_block_type::is_io() const {
// Iterate over all equivalent tiles and return true if any
// of them are IO tiles
for (t_physical_tile_type_ptr tile : equivalent_tiles) {
if (tile->is_io()) {
return true;
}
}
return false;
}

const t_port* t_logical_block_type::get_port(std::string_view port_name) const {
for (int i = 0; i < pb_type->num_ports; i++) {
auto port = pb_type->ports[i];
const t_port& port = pb_type->ports[i];
if (port_name == port.name) {
return &pb_type->ports[port.index];
}
Expand Down
3 changes: 3 additions & 0 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,9 @@ struct t_logical_block_type {
// Is this t_logical_block_type empty?
bool is_empty() const;

// Returns true if this logical block type is an IO block
bool is_io() const;

public:
/**
* @brief Returns the logical block port given the port name and the corresponding logical block type
Expand Down
7 changes: 7 additions & 0 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,13 @@ struct t_net_power {
/**
* @brief Stores a 3D bounding box in terms of the minimum and
* maximum coordinates: x, y, layer
*
* @var xmin: The minimum x-coordinate of the bounding box
* @var xmax: The maximum x-coordinate of the bounding box
* @var ymin: The minimum y-coordinate of the bounding box
* @var ymax: The maximum y-coordinate of the bounding box
* @var layer_min: The minimum layer of the bounding box
* @var layer_max: The maximum layer of the bounding box
*/
struct t_bb {
t_bb() = default;
Expand Down
40 changes: 31 additions & 9 deletions vpr/src/place/initial_placement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ static std::vector<ClusterBlockId> find_centroid_loc(const t_pl_macro& pl_macro,
*
* @return true if the function can find any location near the centroid one, false otherwise.
*/
static bool find_centroid_neighbor(t_pl_loc& centroid_loc,
static bool find_centroid_neighbor(ClusterBlockId block_id,
t_pl_loc& centroid_loc,
t_logical_block_type_ptr block_type,
bool search_for_empty,
int r_lim,
Expand All @@ -212,7 +213,8 @@ static bool find_centroid_neighbor(t_pl_loc& centroid_loc,

/**
* @brief tries to place a macro at a centroid location of its placed connections.
*
*
* @param block_id The block to be placed.
* @param pl_macro The macro to be placed.
* @param pr The PartitionRegion of the macro - represents its floorplanning constraints, is the size of the whole chip if the macro is not
* constrained.
Expand All @@ -225,7 +227,8 @@ static bool find_centroid_neighbor(t_pl_loc& centroid_loc,
*
* @return true if the macro gets placed, false if not.
*/
static bool try_centroid_placement(const t_pl_macro& pl_macro,
static bool try_centroid_placement(ClusterBlockId block_id,
const t_pl_macro& pl_macro,
const PartitionRegion& pr,
t_logical_block_type_ptr block_type,
e_pad_loc_type pad_loc_type,
Expand Down Expand Up @@ -400,7 +403,8 @@ bool find_subtile_in_location(t_pl_loc& centroid,
return false;
}

static bool find_centroid_neighbor(t_pl_loc& centroid_loc,
static bool find_centroid_neighbor(ClusterBlockId block_id,
t_pl_loc& centroid_loc,
t_logical_block_type_ptr block_type,
bool search_for_empty,
int rlim,
Expand All @@ -425,6 +429,18 @@ static bool find_centroid_neighbor(t_pl_loc& centroid_loc,

int delta_cx = search_range.xmax - search_range.xmin;

bool block_constrained = is_cluster_constrained(block_id);

if (block_constrained) {
bool intersect = intersect_range_limit_with_floorplan_constraints(block_id,
search_range,
delta_cx,
centroid_loc_layer_num);
if (!intersect) {
return false;
}
}

//Block has not been placed yet, so the "from" coords will be (-1, -1)
int cx_from = OPEN;
int cy_from = OPEN;
Expand All @@ -441,7 +457,8 @@ static bool find_centroid_neighbor(t_pl_loc& centroid_loc,
centroid_loc_layer_num,
search_for_empty,
blk_loc_registry,
rng);
rng,
block_constrained);

if (!legal) {
return false;
Expand Down Expand Up @@ -832,7 +849,8 @@ static inline t_pl_loc find_nearest_compatible_loc(const t_flat_pl_loc& src_flat
return best_loc;
}

static bool try_centroid_placement(const t_pl_macro& pl_macro,
static bool try_centroid_placement(ClusterBlockId block_id,
const t_pl_macro& pl_macro,
const PartitionRegion& pr,
t_logical_block_type_ptr block_type,
e_pad_loc_type pad_loc_type,
Expand Down Expand Up @@ -889,7 +907,7 @@ static bool try_centroid_placement(const t_pl_macro& pl_macro,
//centroid suggestion was either occupied or does not match block type
//try to find a near location that meet these requirements
if (!found_legal_subtile) {
bool neighbor_legal_loc = find_centroid_neighbor(centroid_loc, block_type, false, rlim, blk_loc_registry, rng);
bool neighbor_legal_loc = find_centroid_neighbor(block_id, centroid_loc, block_type, false, rlim, blk_loc_registry, rng);
if (!neighbor_legal_loc) { //no neighbor candidate found
return false;
}
Expand Down Expand Up @@ -1065,6 +1083,9 @@ bool try_place_macro_randomly(const t_pl_macro& pl_macro,

bool legal;

// is_fixed_range is true since even if the block is not constrained,
// the search range covers the entire region, so there is no need for
// the search range to be adjusted
legal = find_compatible_compressed_loc_in_range(block_type,
delta_cx,
{cx_from, cy_from, selected_layer},
Expand All @@ -1076,7 +1097,8 @@ bool try_place_macro_randomly(const t_pl_macro& pl_macro,
selected_layer,
/*search_for_empty=*/false,
blk_loc_registry,
rng);
rng,
/*is_range_fixed=*/true);

if (!legal) {
//No valid position found
Expand Down Expand Up @@ -1300,7 +1322,7 @@ static bool place_macro(int macros_max_num_tries,

if (!macro_placed) {
VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\t\t\tTry centroid placement\n");
macro_placed = try_centroid_placement(pl_macro, pr, block_type, pad_loc_type, block_scores, blk_loc_registry, flat_placement_info, rng);
macro_placed = try_centroid_placement(blk_id, pl_macro, pr, block_type, pad_loc_type, block_scores, blk_loc_registry, flat_placement_info, rng);
}
VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\t\t\tMacro is placed: %d\n", macro_placed);
// If macro is not placed yet, try to place the macro randomly for the max number of random tries
Expand Down
95 changes: 65 additions & 30 deletions vpr/src/place/move_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@
//Note: The flag is only effective if compiled with VTR_ENABLE_DEBUG_LOGGING
bool f_placer_breakpoint_reached = false;

/**
* @brief Adjust the search range based on how many blocks are in the column.
* If the number of blocks in the column is less than MIN_NUM_BLOCKS_IN_COLUMN,
* expand the search range to cover the entire column.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should explain a bit about why and how you adjust the search range.

Copy link
Contributor Author

@amin1377 amin1377 Apr 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the following:

* If the block is an IO block, we expand the search range to cover the whole column
 * We found empirically that this is a good strategy for IO blocks, given they are located in
 * the periphery for most FPGA architectures

* @param block_type The type of the block to move
* @param compressed_column_num The compressed column to move the block to
* @param to_layer_num The layer that the block is moving to
* @param is_range_fixed Whether the search range is fixed (e.g., in case of placement constraints)
* @param search_range The search range to adjust
*
*/
static void adjust_search_range(t_logical_block_type_ptr block_type,
const int compressed_column_num,
const int to_layer_num,
const bool is_range_fixed,
t_bb& search_range);

//Accessor for f_placer_breakpoint_reached
bool placer_breakpoint_reached() {
return f_placer_breakpoint_reached;
Expand Down Expand Up @@ -666,10 +684,9 @@ bool find_to_loc_uniform(t_logical_block_type_ptr type,
rlim);
int delta_cx = search_range.xmax - search_range.xmin;

t_physical_tile_loc to_compressed_loc;
bool legal = false;
bool block_constrained = is_cluster_constrained(b_from);

if (is_cluster_constrained(b_from)) {
if (block_constrained) {
bool intersect = intersect_range_limit_with_floorplan_constraints(b_from,
search_range,
delta_cx,
Expand All @@ -678,6 +695,9 @@ bool find_to_loc_uniform(t_logical_block_type_ptr type,
return false;
}
}

t_physical_tile_loc to_compressed_loc;
bool legal = false;
//TODO: For now, we only move the blocks on the same tile
legal = find_compatible_compressed_loc_in_range(type,
delta_cx,
Expand All @@ -688,7 +708,8 @@ bool find_to_loc_uniform(t_logical_block_type_ptr type,
to_layer_num,
/*search_for_empty=*/false,
blk_loc_registry,
rng);
rng,
block_constrained);

if (!legal) {
//No valid position found
Expand Down Expand Up @@ -758,10 +779,9 @@ bool find_to_loc_median(t_logical_block_type_ptr blk_type,
to_layer_num,
to_layer_num);

t_physical_tile_loc to_compressed_loc;
bool legal = false;
bool block_constrained = is_cluster_constrained(b_from);

if (is_cluster_constrained(b_from)) {
if (block_constrained) {
bool intersect = intersect_range_limit_with_floorplan_constraints(b_from,
search_range,
delta_cx,
Expand All @@ -771,6 +791,8 @@ bool find_to_loc_median(t_logical_block_type_ptr blk_type,
}
}

t_physical_tile_loc to_compressed_loc;
bool legal = false;
legal = find_compatible_compressed_loc_in_range(blk_type,
delta_cx,
from_compressed_locs[to_layer_num],
Expand All @@ -780,7 +802,8 @@ bool find_to_loc_median(t_logical_block_type_ptr blk_type,
to_layer_num,
/*search_for_empty=*/false,
blk_loc_registry,
rng);
rng,
block_constrained);

if (!legal) {
//No valid position found
Expand Down Expand Up @@ -847,10 +870,9 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
}
delta_cx = search_range.xmax - search_range.xmin;

t_physical_tile_loc to_compressed_loc;
bool legal = false;
bool block_constrained = is_cluster_constrained(b_from);

if (is_cluster_constrained(b_from)) {
if (block_constrained) {
bool intersect = intersect_range_limit_with_floorplan_constraints(b_from,
search_range,
delta_cx,
Expand All @@ -860,7 +882,10 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
}
}

//TODO: For now, we only move the blocks on the same tile
t_physical_tile_loc to_compressed_loc;
bool legal = false;

//TODO: For now, we only move the blocks on the same layer
legal = find_compatible_compressed_loc_in_range(blk_type,
delta_cx,
from_compressed_loc[to_layer_num],
Expand All @@ -870,7 +895,8 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
to_layer_num,
/*search_for_empty=*/false,
blk_loc_registry,
rng);
rng,
block_constrained);

if (!legal) {
//No valid position found
Expand Down Expand Up @@ -964,7 +990,8 @@ bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type,
int to_layer_num,
bool search_for_empty,
const BlkLocRegistry& blk_loc_registry,
vtr::RngContainer& rng) {
vtr::RngContainer& rng,
const bool is_range_fixed) {
//TODO For the time being, the blocks only moved in the same layer. This assertion should be removed after VPR is updated to move blocks between layers
VTR_ASSERT(to_layer_num == from_loc.layer_num);
const auto& compressed_block_grid = g_vpr_ctx.placement().compressed_block_grids[type->index];
Expand Down Expand Up @@ -999,28 +1026,17 @@ bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type,
//The candidates are stored in a flat_map so we can efficiently find the set of valid
//candidates with upper/lower bound.
const auto& block_rows = compressed_block_grid.get_column_block_map(to_loc.x, to_layer_num);
adjust_search_range(type,
to_loc.x,
to_layer_num,
is_range_fixed,
search_range);
auto y_lower_iter = block_rows.lower_bound(search_range.ymin);
if (y_lower_iter == block_rows.end()) {
continue;
}

auto y_upper_iter = block_rows.upper_bound(search_range.ymax);

if (y_lower_iter->first > search_range.ymin) {
//No valid blocks at this x location which are within rlim_y
//
if (type->index != 1)
continue;
else {
//Fall back to allow the whole y range
y_lower_iter = block_rows.begin();
y_upper_iter = block_rows.end();

search_range.ymin = y_lower_iter->first;
search_range.ymax = (y_upper_iter - 1)->first;
}
}

int y_range = std::distance(y_lower_iter, y_upper_iter);
VTR_ASSERT(y_range >= 0);

Expand Down Expand Up @@ -1199,6 +1215,25 @@ bool intersect_range_limit_with_floorplan_constraints(ClusterBlockId b_from,
return true;
}

static void adjust_search_range(t_logical_block_type_ptr block_type,
const int compressed_column_num,
const int to_layer_num,
const bool is_range_fixed,
t_bb& search_range) {
// The value is chosen empirically to expand the search range for sparse blocks,
// or blocks located on the perimeter of the FPGA (e.g., IO blocks)
constexpr int MIN_NUM_BLOCKS_IN_COLUMN = 3;

const auto& compressed_block_grid = g_vpr_ctx.placement().compressed_block_grids[block_type->index];

size_t num_blocks_in_column = compressed_block_grid.get_column_block_map(compressed_column_num, to_layer_num).size();

if (num_blocks_in_column < MIN_NUM_BLOCKS_IN_COLUMN && !is_range_fixed) {
search_range.ymin = 0;
search_range.ymax = compressed_block_grid.get_num_rows(to_layer_num) - 1;
}
}

std::string e_move_result_to_string(e_move_result move_outcome) {
switch (move_outcome) {
case e_move_result::REJECTED:
Expand Down
4 changes: 3 additions & 1 deletion vpr/src/place/move_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ int find_empty_compatible_subtile(t_logical_block_type_ptr type,
* is_median: true if this is called from find_to_loc_median
* to_layer_num: the layer number of the new location (set by the caller)
* search_for_empty: indicates that the returned location must be empty
* is_range_fixed: indicates that the search range is fixed and should not be adjusted
*/
bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type,
int delta_cx,
Expand All @@ -337,7 +338,8 @@ bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type,
int to_layer_num,
bool search_for_empty,
const BlkLocRegistry& blk_loc_registry,
vtr::RngContainer& rng);
vtr::RngContainer& rng,
const bool is_range_fixed);

/**
* @brief Get the the compressed loc from the uncompressed loc (grid_loc)
Expand Down
Loading
Loading