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 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 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
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
5 changes: 5 additions & 0 deletions libs/libarchfpga/src/physical_types_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,11 @@ bool is_io_type(t_physical_tile_type_ptr type) {
|| is_output_type(type);
}

bool is_io_type(t_logical_block_type_ptr type) {
auto physical_tile = pick_physical_type(type);
return is_io_type(physical_tile);
}

std::string block_type_pin_index_to_name(t_physical_tile_type_ptr type, int pin_physical_num, bool is_flat) {
int max_ptc = get_tile_pin_max_ptc(type, is_flat);
VTR_ASSERT(pin_physical_num < max_ptc);
Expand Down
3 changes: 3 additions & 0 deletions libs/libarchfpga/src/physical_types_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ bool is_output_type(t_physical_tile_type_ptr type);
///@brief Returns true if the given physical tile type can implement either a .input or .output block type
bool is_io_type(t_physical_tile_type_ptr type);

///@brief Returns true if the given logical block type is an IO block
bool is_io_type(t_logical_block_type_ptr type);

/**
* @brief Returns the corresponding physical pin based on the input parameters:
*
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 @@ -422,6 +422,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
112 changes: 64 additions & 48 deletions vpr/src/place/move_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,52 @@ void set_placer_breakpoint_reached(bool flag) {
f_placer_breakpoint_reached = flag;
}

/**
* @brief Adjust the search range based on the block type and constraints
*
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

* If the block is an IO block, we expand the search range to include all blocks in the 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 block_id The block ID of the moving block
* @param search_range The search range to adjust
* @param delta_cx The delta x of the search range
* @param to_layer_num The layer that the block is moving to
*
* @return true if the search range was adjusted, false otherwise
*/
static bool adjust_search_range(t_logical_block_type_ptr block_type,
ClusterBlockId block_id,
t_bb& search_range,
int& delta_cx,
int to_layer_num) {

auto block_constrained = is_cluster_constrained(block_id);

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

if (is_io_type(block_type) && !block_constrained) {
/* We empirically found that for the IO blocks,
* Given their sparsity, we expand the y-axis search range
* to include all blocks in the column
*/
const t_compressed_block_grid& compressed_block_grid = g_vpr_ctx.placement().compressed_block_grids[block_type->index];
Copy link
Contributor

Choose a reason for hiding this comment

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

You could make this code work well for area-IO (e.g. stratix 10 where IOs are in columns) and for other sparse blocks by just checking if the number of blocks in the compressed columns is less than some threshold. I suspect you don't actually need to check if it is an IO block -- IOs are just an example of this kind of pattern.

(I still like the utility to check if a logical block type is an IO though).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually tried that a while ago by not specifying the block type and simply expanding the search range if the number of blocks in the chosen column was less than 3. However, after making that change, in the example I mentioned earlier, we encountered the same issue where the IO blocks became scattered between the top and bottom edges.

search_range.ymin = 0;
search_range.ymax = compressed_block_grid.get_num_rows(to_layer_num) - 1;
}

return true;
}

e_create_move create_move(t_pl_blocks_to_be_moved& blocks_affected,
ClusterBlockId b_from,
t_pl_loc to,
Expand Down Expand Up @@ -669,18 +715,13 @@ bool find_to_loc_uniform(t_logical_block_type_ptr type,
rlim);
int delta_cx = search_range.xmax - search_range.xmin;

bool adjust_search_range_res = adjust_search_range(type, b_from, search_range, delta_cx, to_layer_num);
if (!adjust_search_range_res) {
return false;
}

t_physical_tile_loc to_compressed_loc;
bool legal = false;

if (is_cluster_constrained(b_from)) {
bool intersect = intersect_range_limit_with_floorplan_constraints(b_from,
search_range,
delta_cx,
to_layer_num);
if (!intersect) {
return false;
}
}
//TODO: For now, we only move the blocks on the same tile
legal = find_compatible_compressed_loc_in_range(type,
delta_cx,
Expand Down Expand Up @@ -761,19 +802,13 @@ 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;

if (is_cluster_constrained(b_from)) {
bool intersect = intersect_range_limit_with_floorplan_constraints(b_from,
search_range,
delta_cx,
to_layer_num);
if (!intersect) {
return false;
}
bool adjust_search_range_res = adjust_search_range(blk_type, b_from, search_range, delta_cx, to_layer_num);
if (!adjust_search_range_res) {
return false;
}

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 Down Expand Up @@ -850,20 +885,15 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
}
delta_cx = search_range.xmax - search_range.xmin;

bool adjust_search_range_res = adjust_search_range(blk_type, b_from, search_range, delta_cx, to_layer_num);
if (!adjust_search_range_res) {
return false;
}

t_physical_tile_loc to_compressed_loc;
bool legal = false;

if (is_cluster_constrained(b_from)) {
bool intersect = intersect_range_limit_with_floorplan_constraints(b_from,
search_range,
delta_cx,
to_layer_num);
if (!intersect) {
return false;
}
}

//TODO: For now, we only move the blocks on the same tile
//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 Down Expand Up @@ -961,7 +991,7 @@ int find_empty_compatible_subtile(t_logical_block_type_ptr type,
bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type,
const int delta_cx,
const t_physical_tile_loc& from_loc,
t_bb search_range,
const t_bb& search_range,
t_physical_tile_loc& to_loc,
bool is_median,
int to_layer_num,
Expand Down Expand Up @@ -1006,24 +1036,10 @@ bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type,
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;
}
continue;
}

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

Expand Down
3 changes: 2 additions & 1 deletion vpr/src/place/move_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,11 +328,12 @@ 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
* fixed_search_range: 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,
const t_physical_tile_loc& from_loc,
t_bb search_range,
const t_bb& search_range,
t_physical_tile_loc& to_loc,
bool is_median,
int to_layer_num,
Expand Down
Loading