Skip to content

Commit cd79e68

Browse files
Merge pull request #3171 from AlexandreSinger/feature-ap-iterative-repacking
[APPack] Iterative Re-Packing
2 parents 605fb00 + 982b15a commit cd79e68

File tree

9 files changed

+282
-94
lines changed

9 files changed

+282
-94
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: 27 additions & 7 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,18 +82,28 @@ 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
88-
// have failed. This parameter sets how many time we will attempt unrelated
89-
// clustering between failures of unrelated clustering. If this is set to
90-
// 1, and unrelated clustering failed for a cluster, it will not be attempted
90+
// have failed. This attempts to cluster in molecules that are not attracted
91+
// (using the packer's heuristics) to the molecules within a given cluster.
92+
// This parameter sets how many times we will attempt unrelated
93+
// clustering between failures of unrelated clustering. If a molecule used
94+
// for unrelated clustering failed to cluster it will not be attempted
9195
// again for that cluster (note: if it succeeds, the number of attempts get
9296
// reset).
9397
// NOTE: A similar option exists in the candidate selector class. This was
9498
// duplicated since it is very likely that APPack would need a
9599
// different value for this option than the non-APPack flow.
96-
static constexpr int max_unrelated_clustering_attempts = 10;
100+
//
101+
// [block_type_index] -> max_unrelated_attempts
102+
std::vector<int> max_unrelated_clustering_attempts;
103+
// By default, we perform 10 unrelated clustering attempts. This is used
104+
// to aggresivly resolve density while adhering to the GP solution as much
105+
// as possible.
106+
static constexpr int default_max_unrelated_clustering_attempts = 10;
97107

98108
// TODO: Investigate adding flat placement info to seed selection.
99109
};
@@ -122,6 +132,16 @@ struct APPackContext : public Context {
122132
logical_block_types,
123133
device_grid);
124134
}
135+
136+
// Set the max unrelated tile distances for all logical block types.
137+
// By default, we set this to a low value to only allow unrelated molecules
138+
// that are very close to the cluster being created.
139+
// NOTE: Molecules within the same tile as the centroid are considered to have
140+
// 0 distance. The distance is computed relative to the bounds of the
141+
// tile containing the centroid.
142+
appack_options.max_unrelated_tile_distance.resize(logical_block_types.size(), 1.0);
143+
appack_options.max_unrelated_clustering_attempts.resize(logical_block_types.size(),
144+
appack_options.default_max_unrelated_clustering_attempts);
125145
}
126146

127147
/**

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 manhattan 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)