Skip to content

Commit 6bc58a1

Browse files
committed
Add logic to rescale bucketing for wirelength driven routing.
Signed-off-by: Keith Rothman <[email protected]>
1 parent 6693bca commit 6bc58a1

File tree

2 files changed

+77
-10
lines changed

2 files changed

+77
-10
lines changed

vpr/src/route/bucket.cpp

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ void Bucket::init(const DeviceGrid& grid) {
1616

1717
heap_head_ = std::numeric_limits<size_t>::max();
1818
heap_tail_ = 0;
19+
20+
conv_factor_ = kDefaultConvFactor;
21+
22+
min_cost_ = std::numeric_limits<float>::max();
23+
max_cost_ = std::numeric_limits<float>::min();
1924
}
2025

2126
void Bucket::free() {
@@ -46,6 +51,9 @@ t_heap** Bucket::heap_ = nullptr;
4651
size_t Bucket::heap_size_ = 0;
4752
size_t Bucket::heap_head_ = std::numeric_limits<size_t>::max();
4853
size_t Bucket::heap_tail_ = 0;
54+
float Bucket::min_cost_ = 0.f;
55+
float Bucket::max_cost_ = 0.f;
56+
float Bucket::conv_factor_ = 0.f;
4957

5058
void Bucket::clear() {
5159
if (heap_head_ != std::numeric_limits<size_t>::max()) {
@@ -55,19 +63,74 @@ void Bucket::clear() {
5563
heap_tail_ = 0;
5664
}
5765

66+
void Bucket::check_scaling() {
67+
float min_cost = min_cost_;
68+
float max_cost = max_cost_;
69+
VTR_ASSERT(max_cost != std::numeric_limits<float>::min());
70+
if (min_cost == std::numeric_limits<float>::max()) {
71+
min_cost = max_cost;
72+
}
73+
auto min_bucket = cost_to_int(min_cost);
74+
auto max_bucket = cost_to_int(max_cost);
75+
76+
if (min_bucket < 0 || max_bucket < 0 || max_bucket > 1000000) {
77+
// If min and max are close to each other, assume 3 orders of
78+
// magnitude between min and max.
79+
//
80+
// If min and max are at least 3 orders of magnitude apart, scale
81+
// soley based on max cost.
82+
conv_factor_ = 50000.f / max_cost_ / std::max(1.f, 1000.f / (max_cost_ / min_cost_));
83+
84+
VTR_ASSERT(cost_to_int(min_cost_) >= 0);
85+
VTR_ASSERT(cost_to_int(max_cost_) >= 0);
86+
VTR_ASSERT(cost_to_int(max_cost_) < 1000000);
87+
88+
// Reheap after adjusting scaling.
89+
if (heap_head_ != std::numeric_limits<size_t>::max()) {
90+
std::vector<t_heap*> reheap;
91+
for (size_t bucket = heap_head_; bucket <= heap_tail_; ++bucket) {
92+
for (t_heap* item = heap_[bucket]; item != nullptr; item = item->next_bucket) {
93+
reheap.push_back(item);
94+
}
95+
}
96+
97+
std::fill(heap_ + heap_head_, heap_ + heap_tail_ + 1, nullptr);
98+
heap_head_ = std::numeric_limits<size_t>::max();
99+
heap_tail_ = 0;
100+
101+
for (t_heap* item : reheap) {
102+
push(item);
103+
}
104+
}
105+
}
106+
}
107+
58108
void Bucket::push(t_heap* hptr) {
59109
float cost = hptr->cost;
60110
if (!std::isfinite(cost)) {
61111
return;
62112
}
63113

64-
//heap_::verify_extract_top();
114+
bool check_scale = false;
115+
// Exclude 0 cost from min_cost to provide useful scaling factor.
116+
if (cost < min_cost_ && cost > 0) {
117+
min_cost_ = cost;
118+
check_scale = true;
119+
}
120+
if (cost > max_cost_) {
121+
max_cost_ = cost;
122+
check_scale = true;
123+
}
124+
125+
if (check_scale) {
126+
check_scaling();
127+
}
65128

66129
// Which bucket should this go into?
67130
auto int_cost = cost_to_int(cost);
68131

69132
if (int_cost < 0) {
70-
VTR_LOG_WARN("Cost is negative? cost = %g\n", cost);
133+
VTR_LOG_WARN("Cost is negative? cost = %g, bucket = %d\n", cost, int_cost);
71134
int_cost = 0;
72135
}
73136

@@ -90,8 +153,6 @@ void Bucket::push(t_heap* hptr) {
90153
if (uint_cost > heap_tail_) {
91154
heap_tail_ = uint_cost;
92155
}
93-
94-
//heap_::verify_extract_top();
95156
}
96157

97158
t_heap* Bucket::pop() {

vpr/src/route/bucket.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,11 @@ class Bucket {
223223
private:
224224
// Factor used to convert cost from float to int. Should be scaled to
225225
// enable sufficent precision in bucketting.
226-
static constexpr float kConvFactor = 1e12;
226+
static constexpr float kDefaultConvFactor = 1e12;
227227

228228
// Convert cost from float to integer bucket id.
229229
static int cost_to_int(float cost) {
230-
return (int)(cost * kConvFactor);
230+
return (int)(cost * conv_factor_);
231231
}
232232

233233
// Simple fast random function used for randomizing item selection on pop.
@@ -236,17 +236,23 @@ class Bucket {
236236
return seed_;
237237
}
238238

239+
static void check_scaling();
240+
239241
// Expand the number of buckets.
240242
//
241243
// Only call if insufficient bucets exist.
242244
static void expand(size_t required_number_of_buckets);
243245

244246
static size_t seed_; /* Seed for fast_rand, should be non-zero */
245247

246-
static t_heap** heap_; /* Buckets for linked lists*/
247-
static size_t heap_size_; /* Number of buckets */
248-
static size_t heap_head_; /* First non-empty bucket */
249-
static size_t heap_tail_; /* Last non-empty bucket */
248+
static t_heap** heap_; /* Buckets for linked lists*/
249+
static size_t heap_size_; /* Number of buckets */
250+
static size_t heap_head_; /* First non-empty bucket */
251+
static size_t heap_tail_; /* Last non-empty bucket */
252+
static float conv_factor_; /* Cost bucket scaling factor */
253+
254+
static float min_cost_; /* Smallest cost seen */
255+
static float max_cost_; /* Large cost seen */
250256
};
251257

252258
inline bool is_empty_heap() {

0 commit comments

Comments
 (0)