Skip to content

Commit 695d205

Browse files
[APPack] Iterative Re-Packing
Being based off the packer, APPack also uses iterative re-packing when a dense enough clustering cannot be found. APPack has some special options that it can use to increase the density of clustering further without hurting quality as much as the default flow. Updated the iterative re-packing algorithm to use these options if needed. Having this safer fall-back has allowed me to tune some numbers that I knew would improve the quality of most circuits but was causing a few circuits to fail packing. These few that were failing should now hit this fall-back paths which resolves this issue.
1 parent 06beac6 commit 695d205

File tree

9 files changed

+268
-92
lines changed

9 files changed

+268
-92
lines changed

vpr/src/analytical_place/flat_placement_density_manager.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,20 @@ static PrimitiveVector calc_bin_underfill(const PrimitiveVector& bin_utilization
5959
* The command-line arguments provided by the user.
6060
* @param physical_tile_types
6161
* A vector of all physical tile types in the architecture.
62+
* @param device_grid
63+
* The current physical device grid of the FPGA.
6264
*/
6365
static std::vector<float> get_physical_type_target_densities(const std::vector<std::string>& target_density_arg_strs,
64-
const std::vector<t_physical_tile_type>& physical_tile_types) {
66+
const std::vector<t_physical_tile_type>& physical_tile_types,
67+
const DeviceGrid& device_grid) {
6568
// Get the target densisty of each physical block type.
66-
// TODO: Create auto feature to automatically select target densities based
67-
// on properties of the architecture. Need to sweep to find reasonable
68-
// values.
6969
std::vector<float> phy_ty_target_density(physical_tile_types.size(), 1.0f);
7070

71+
// By default (auto), make the CLB target density 80%, leaving the other
72+
// blocks at 100%.
73+
t_logical_block_type_ptr logic_block_type = infer_logic_block_type(device_grid);
74+
phy_ty_target_density[logic_block_type->index] = 0.8f;
75+
7176
// Set to auto if no user args are provided.
7277
if (target_density_arg_strs.size() == 0)
7378
return phy_ty_target_density;
@@ -123,7 +128,8 @@ FlatPlacementDensityManager::FlatPlacementDensityManager(const APNetlist& ap_net
123128

124129
// Get the target densisty of each physical block type.
125130
std::vector<float> phy_ty_target_densities = get_physical_type_target_densities(target_density_arg_strs,
126-
physical_tile_types);
131+
physical_tile_types,
132+
device_grid);
127133
VTR_LOG("Partial legalizer is using target densities:");
128134
for (const t_physical_tile_type& phy_ty : physical_tile_types) {
129135
VTR_LOG(" %s:%.1f", phy_ty.name.c_str(), phy_ty_target_densities[phy_ty.index]);

vpr/src/base/flat_placement_utils.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
* @brief Utility methods for working with flat placements.
77
*/
88

9+
#include <algorithm>
910
#include <cstdlib>
11+
#include "device_grid.h"
1012
#include "flat_placement_types.h"
13+
#include "physical_types.h"
1114

1215
/**
1316
* @brief Returns the manhattan distance (L1 distance) between two flat
@@ -17,3 +20,31 @@ inline float get_manhattan_distance(const t_flat_pl_loc& loc_a,
1720
const t_flat_pl_loc& loc_b) {
1821
return std::abs(loc_a.x - loc_b.x) + std::abs(loc_a.y - loc_b.y) + std::abs(loc_a.layer - loc_b.layer);
1922
}
23+
24+
/**
25+
* @brief Returns the L1 distance something at the given flat location would
26+
* need to move to be within the bounds of a tile at the given tile loc.
27+
*/
28+
inline float get_manhattan_distance_to_tile(const t_flat_pl_loc& src_flat_loc,
29+
const t_physical_tile_loc& tile_loc,
30+
const DeviceGrid& device_grid) {
31+
// Get the bounds of the tile.
32+
// Note: The get_tile_bb function will not work in this case since it
33+
// subtracts 1 from the width and height.
34+
auto tile_type = device_grid.get_physical_type(tile_loc);
35+
float tile_xmin = tile_loc.x - device_grid.get_width_offset(tile_loc);
36+
float tile_xmax = tile_xmin + tile_type->width;
37+
float tile_ymin = tile_loc.y - device_grid.get_height_offset(tile_loc);
38+
float tile_ymax = tile_ymin + tile_type->height;
39+
40+
// Get the closest point in the bounding box (including the edges) to
41+
// the src_flat_loc. To do this, we project the point in L1 space.
42+
float proj_x = std::clamp(src_flat_loc.x, tile_xmin, tile_xmax);
43+
float proj_y = std::clamp(src_flat_loc.y, tile_ymin, tile_ymax);
44+
45+
// Then compute the L1 distance from the src_flat_loc to the projected
46+
// position. This will be the minimum distance this point needs to move.
47+
float dx = std::abs(proj_x - src_flat_loc.x);
48+
float dy = std::abs(proj_y - src_flat_loc.y);
49+
return dx + dy;
50+
}

vpr/src/pack/appack_context.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ struct t_appack_options {
5656
// Distance threshold which decides when to use quadratic decay or inverted
5757
// sqrt decay. If the distance is less than this threshold, quadratic decay
5858
// is used. Inverted sqrt is used otherwise.
59-
static constexpr float dist_th = 1.75f;
59+
static constexpr float dist_th = 2.0f;
6060
// Attenuation value at the threshold.
61-
static constexpr float attenuation_th = 0.35f;
61+
static constexpr float attenuation_th = 0.25f;
6262

6363
// Using the distance threshold and the attenuation value at that point, we
6464
// can compute the other two terms. This is to keep the attenuation function
@@ -82,7 +82,9 @@ struct t_appack_options {
8282
// search within the cluster's tile. Setting this to a higher number would
8383
// allow APPack to search farther away; but may bring in molecules which
8484
// do not "want" to be in the cluster.
85-
static constexpr float max_unrelated_tile_distance = 5.0f;
85+
//
86+
// [block_type_index] -> unrelated_tile_distance
87+
std::vector<float> max_unrelated_tile_distance;
8688

8789
// Unrelated clustering occurs after all other candidate selection methods
8890
// have failed. This parameter sets how many time we will attempt unrelated
@@ -93,7 +95,13 @@ struct t_appack_options {
9395
// NOTE: A similar option exists in the candidate selector class. This was
9496
// duplicated since it is very likely that APPack would need a
9597
// different value for this option than the non-APPack flow.
96-
static constexpr int max_unrelated_clustering_attempts = 10;
98+
//
99+
// [block_type_index] -> max_unrelated_attempts
100+
std::vector<int> max_unrelated_clustering_attempts;
101+
// By default, we perform 10 unrelated clustering attempts. This is used
102+
// to aggresivly resolve density while adhering to the GP solution as much
103+
// as possible.
104+
static constexpr int default_max_unrelated_clustering_attempts = 10;
97105

98106
// TODO: Investigate adding flat placement info to seed selection.
99107
};
@@ -122,6 +130,15 @@ struct APPackContext : public Context {
122130
logical_block_types,
123131
device_grid);
124132
}
133+
134+
// By default, when unrelated clustering is on, search for unrelated molecules
135+
// that are within 1 tile from the centroid of the cluster.
136+
// NOTE: Molecules within the same tile as the centroid are considered to have
137+
// 0 distance. The distance is computed relative to the bounds of the
138+
// tile containing the centroid.
139+
appack_options.max_unrelated_tile_distance.resize(logical_block_types.size(), 1.0);
140+
appack_options.max_unrelated_clustering_attempts.resize(logical_block_types.size(),
141+
appack_options.default_max_unrelated_clustering_attempts);
125142
}
126143

127144
/**

vpr/src/pack/appack_max_dist_th_manager.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,18 @@ static bool has_memory_pbs(const t_pb_type* pb_type);
2929
void APPackMaxDistThManager::init(const std::vector<std::string>& max_dist_ths,
3030
const std::vector<t_logical_block_type>& logical_block_types,
3131
const DeviceGrid& device_grid) {
32+
// Compute the max device distance based on the width and height of the
33+
// device. This is the L1 (manhattan) distance.
34+
max_distance_on_device_ = device_grid.width() + device_grid.height();
35+
3236
// Automatically set the max distance thresholds.
3337
auto_set_max_distance_thresholds(logical_block_types, device_grid);
3438

3539
// If the max distance threshold strings have been set (they are not set to
3640
// auto), set the max distance thresholds based on the user-provided strings.
3741
VTR_ASSERT(!max_dist_ths.empty());
3842
if (max_dist_ths.size() != 1 || max_dist_ths[0] != "auto") {
39-
set_max_distance_thresholds_from_strings(max_dist_ths, logical_block_types, device_grid);
43+
set_max_distance_thresholds_from_strings(max_dist_ths, logical_block_types);
4044
}
4145

4246
// Set the initilized flag to true.
@@ -57,18 +61,15 @@ void APPackMaxDistThManager::init(const std::vector<std::string>& max_dist_ths,
5761

5862
void APPackMaxDistThManager::auto_set_max_distance_thresholds(const std::vector<t_logical_block_type>& logical_block_types,
5963
const DeviceGrid& device_grid) {
60-
// Compute the max device distance based on the width and height of the
61-
// device. This is the L1 (manhattan) distance.
62-
float max_device_distance = device_grid.width() + device_grid.height();
6364

6465
// Compute the max distance thresholds of the different logical block types.
65-
float default_max_distance_th = std::max(default_max_dist_th_scale_ * max_device_distance,
66+
float default_max_distance_th = std::max(default_max_dist_th_scale_ * max_distance_on_device_,
6667
default_max_dist_th_offset_);
67-
float logic_block_max_distance_th = std::max(logic_block_max_dist_th_scale_ * max_device_distance,
68+
float logic_block_max_distance_th = std::max(logic_block_max_dist_th_scale_ * max_distance_on_device_,
6869
logic_block_max_dist_th_offset_);
69-
float memory_max_distance_th = std::max(memory_max_dist_th_scale_ * max_device_distance,
70+
float memory_max_distance_th = std::max(memory_max_dist_th_scale_ * max_distance_on_device_,
7071
memory_max_dist_th_offset_);
71-
float io_block_max_distance_th = std::max(io_max_dist_th_scale_ * max_device_distance,
72+
float io_block_max_distance_th = std::max(io_max_dist_th_scale_ * max_distance_on_device_,
7273
io_max_dist_th_offset_);
7374

7475
// Set all logical block types to have the default max distance threshold.
@@ -138,8 +139,7 @@ static bool has_memory_pbs(const t_pb_type* pb_type) {
138139

139140
void APPackMaxDistThManager::set_max_distance_thresholds_from_strings(
140141
const std::vector<std::string>& max_dist_ths,
141-
const std::vector<t_logical_block_type>& logical_block_types,
142-
const DeviceGrid& device_grid) {
142+
const std::vector<t_logical_block_type>& logical_block_types) {
143143

144144
std::vector<std::string> lb_type_names;
145145
std::unordered_map<std::string, int> lb_type_name_to_index;
@@ -167,8 +167,7 @@ void APPackMaxDistThManager::set_max_distance_thresholds_from_strings(
167167
}
168168

169169
// Compute the max distance threshold the user selected.
170-
float max_device_distance = device_grid.width() + device_grid.height();
171-
float logical_block_max_dist_th = std::max(max_device_distance * logical_block_max_dist_th_scale,
170+
float logical_block_max_dist_th = std::max(max_distance_on_device_ * logical_block_max_dist_th_scale,
172171
logical_block_max_dist_th_offset);
173172

174173
int lb_ty_index = lb_type_name_to_index[lb_name];

vpr/src/pack/appack_max_dist_th_manager.h

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ class APPackMaxDistThManager {
3939

4040
// This is the default scale and offset. Logical blocks that we do not
4141
// recognize as being of the special categories will have this threshold.
42-
static constexpr float default_max_dist_th_scale_ = 0.35f;
43-
static constexpr float default_max_dist_th_offset_ = 15.0f;
42+
static constexpr float default_max_dist_th_scale_ = 0.1f;
43+
static constexpr float default_max_dist_th_offset_ = 10.0f;
4444

4545
// Logic blocks (such as CLBs and LABs) tend to have more resources on the
4646
// device, thus they have tighter thresholds. This was found to work well.
47-
static constexpr float logic_block_max_dist_th_scale_ = 0.1f;
47+
static constexpr float logic_block_max_dist_th_scale_ = 0.06f;
4848
static constexpr float logic_block_max_dist_th_offset_ = 15.0f;
4949

5050
// Memory blocks (i.e. blocks that contain pb_types of the memory class)
@@ -80,7 +80,7 @@ class APPackMaxDistThManager {
8080
const DeviceGrid& device_grid);
8181

8282
/**
83-
* @brief Get the max distance threshold of the given lobical block type.
83+
* @brief Get the max distance threshold of the given logical block type.
8484
*/
8585
inline float get_max_dist_threshold(const t_logical_block_type& logical_block_ty) const {
8686
VTR_ASSERT_SAFE_MSG(is_initialized_,
@@ -91,6 +91,31 @@ class APPackMaxDistThManager {
9191
return logical_block_dist_thresholds_[logical_block_ty.index];
9292
}
9393

94+
/**
95+
* @brief Get the maximum distance possible on the device. This is the
96+
* manhattan distance from the bottom-left corner of the device to
97+
* the top-right.
98+
*/
99+
inline float get_max_device_distance() const {
100+
VTR_ASSERT_SAFE_MSG(is_initialized_,
101+
"APPackMaxDistThManager has not been initialized, cannot call this method");
102+
103+
return max_distance_on_device_;
104+
}
105+
106+
/**
107+
* @brief Set the max distance threshold of the given logical block type.
108+
*/
109+
inline void set_max_dist_threshold(const t_logical_block_type& logical_block_ty,
110+
float new_threshold) {
111+
VTR_ASSERT_SAFE_MSG(is_initialized_,
112+
"APPackMaxDistThManager has not been initialized, cannot call this method");
113+
VTR_ASSERT_SAFE_MSG((size_t)logical_block_ty.index < logical_block_dist_thresholds_.size(),
114+
"Logical block type does not have a max distance threshold");
115+
116+
logical_block_dist_thresholds_[logical_block_ty.index] = new_threshold;
117+
}
118+
94119
private:
95120
/**
96121
* @brief Helper method that initializes the thresholds of all logical
@@ -105,13 +130,17 @@ class APPackMaxDistThManager {
105130
* strings.
106131
*/
107132
void set_max_distance_thresholds_from_strings(const std::vector<std::string>& max_dist_ths,
108-
const std::vector<t_logical_block_type>& logical_block_types,
109-
const DeviceGrid& device_grid);
133+
const std::vector<t_logical_block_type>& logical_block_types);
110134

111135
/// @brief A flag which shows if the thesholds have been computed or not.
112136
bool is_initialized_ = false;
113137

114138
/// @brief The max distance thresholds of all logical blocks in the architecture.
115139
/// This is initialized in the constructor and accessed during packing.
116140
std::vector<float> logical_block_dist_thresholds_;
141+
142+
/// @brief This is the maximum minhattan distance possible on the device. This
143+
/// is the distance of traveling from the bottom-left corner of the device
144+
/// to the top right.
145+
float max_distance_on_device_;
117146
};

0 commit comments

Comments
 (0)