Skip to content

Commit 9f27196

Browse files
Yulang LuoAlexandreSinger
Yulang Luo
authored andcommitted
[analytical placer][b2b] fixed initalize placement and tried constant
converges better but worth than clique and star
1 parent 0943592 commit 9f27196

File tree

2 files changed

+53
-18
lines changed

2 files changed

+53
-18
lines changed

vpr/src/place/analytical_placement/AnalyticalSolver.cpp

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -211,29 +211,54 @@ void QPHybridSolver::solve(unsigned iteration, PartialPlacement &p_placement) {
211211
}
212212
}
213213

214-
void B2BSolver::initialize_placement(PartialPlacement &p_placement) {
214+
void B2BSolver::initialize_placement_random_normal(PartialPlacement &p_placement) {
215+
size_t grid_width = g_vpr_ctx.device().grid.width();
216+
size_t grid_height = g_vpr_ctx.device().grid.height();
217+
// std::random_device rd;
218+
// std::mt19937 gen(rd());
219+
std::mt19937 gen(1894650209824387);
220+
std::normal_distribution<> disx((double)grid_width / 2, 1.0);
221+
std::normal_distribution<> disy((double)grid_height / 2, 1.0);
222+
for (size_t i = 0; i < p_placement.num_moveable_nodes; i++) {
223+
double x, y;
224+
do {
225+
x = disx(gen);
226+
y = disy(gen);
227+
} while (!(x < grid_width && y < grid_height && x >= 0 && y >= 0));
228+
p_placement.node_loc_x[i] = x;
229+
p_placement.node_loc_y[i] = y;
230+
}
231+
}
232+
233+
void B2BSolver::initialize_placement_random_uniform(PartialPlacement &p_placement) {
215234
size_t grid_width = g_vpr_ctx.device().grid.width();
216235
size_t grid_height = g_vpr_ctx.device().grid.height();
217236
// std::random_device rd;
218237
// std::mt19937 gen(rd());
219238
std::mt19937 gen(1894650209824387);
220-
// std::normal_distribution<> disx((double)grid_width / 2, 1.0);
221-
// std::normal_distribution<> disy((double)grid_height / 2, 1.0);
222239
std::uniform_real_distribution<> disx(0.0, std::nextafter(grid_width, 0.0));
223240
std::uniform_real_distribution<> disy(0.0, std::nextafter(grid_height, 0.0));
224241
for (size_t i = 0; i < p_placement.num_moveable_nodes; i++) {
225-
// double x, y;
226-
// do {
227-
// x = disx(gen);
228-
// y = disy(gen);
229-
// } while (!(x < grid_width && y < grid_height && x >= 0 && y >= 0));
230-
// p_placement.node_loc_x[i] = x;
231-
// p_placement.node_loc_y[i] = y;
232242
p_placement.node_loc_x[i] = disx(gen);
233243
p_placement.node_loc_y[i] = disy(gen);
234244
}
235245
}
236246

247+
void B2BSolver::initialize_placement_least_dense(PartialPlacement &p_placement) {
248+
size_t grid_width = g_vpr_ctx.device().grid.width();
249+
size_t grid_height = g_vpr_ctx.device().grid.height();
250+
unsigned cols = std::ceil(std::sqrt(p_placement.num_moveable_nodes * grid_height / static_cast<double>(grid_width)));
251+
unsigned rows = std::ceil(p_placement.num_moveable_nodes / static_cast<double>(cols));
252+
double x_gap = grid_width / static_cast<double>(cols + 1);
253+
double y_gap = grid_height / static_cast<double>(rows + 1);
254+
for (int r = 1; r <= static_cast<int>(rows); r++) {
255+
for (int c = 1; c <= static_cast<int>(cols); c++) {
256+
p_placement.node_loc_x[(r-1)*cols + c -1] = c * x_gap;
257+
p_placement.node_loc_x[(r-1)*cols + c -1] = r * y_gap;
258+
}
259+
}
260+
}
261+
237262
// This function return the two nodes on the bound of a netlist, (max, min)
238263
std::pair<size_t, size_t> B2BSolver::boundNode(std::vector<size_t>& node_ids, std::vector<double>& node_locs){
239264
auto compare = [&node_locs](int a, int b) {
@@ -345,7 +370,8 @@ void B2BSolver::populate_matrix(PartialPlacement &p_placement) {
345370

346371
void B2BSolver::populate_matrix_anchor(PartialPlacement& p_placement, unsigned iteration) {
347372
double epsilon = 1e-6;
348-
double coeff_pseudo_anchor = 0.001 * std::exp((double)iteration/32.0);
373+
double coeff_pseudo_anchor = 0.001 * std::exp((double)iteration/29.0);
374+
// double coeff_pseudo_anchor = std::exp((double)iteration/1.0);
349375
for (size_t i = 0; i < p_placement.num_moveable_nodes; i++){
350376
// Anchor node are always 2 pins.
351377
double pseudo_w_x = coeff_pseudo_anchor*2.0/std::max(std::abs(p_placement.node_loc_x[i] - node_loc_x_legalized[i]), epsilon);
@@ -369,7 +395,9 @@ void B2BSolver::populate_matrix_anchor(PartialPlacement& p_placement, unsigned i
369395
// This function is the inner loop that alternate between building matrix based on placement, and solving model to get placement.
370396
void B2BSolver::b2b_solve_loop(unsigned iteration, PartialPlacement &p_placement){
371397
double previous_hpwl, current_hpwl = std::numeric_limits<double>::max();
398+
unsigned counter = 0;
372399
do{
400+
counter++;
373401
previous_hpwl = current_hpwl;
374402
VTR_LOG("placement hpwl in b2b loop: %f\n", p_placement.get_HPWL());
375403
VTR_ASSERT(p_placement.is_valid_partial_placement() && "did not produce a valid placement in b2b solve loop");
@@ -386,9 +414,10 @@ void B2BSolver::b2b_solve_loop(unsigned iteration, PartialPlacement &p_placement
386414
cg_x.compute(A_sparse_x);
387415
cg_y.compute(A_sparse_y);
388416
// Not worth the time
389-
// cg_x.setMaxIterations(cg_x.maxIterations() * 10);
417+
// having more cg iteration does not help with over convergence
418+
// cg_x.setMaxIterations(cg_x.maxIterations() * 100);
390419
// cg_x.setTolerance(cg_x.tolerance() * 100);
391-
// cg_y.setMaxIterations(cg_y.maxIterations() * 10);
420+
// cg_y.setMaxIterations(cg_y.maxIterations() * 100);
392421
// cg_y.setTolerance(cg_y.tolerance() * 100);
393422
VTR_ASSERT(cg_x.info() == Eigen::Success && "Conjugate Gradient failed at compute for A_x!");
394423
VTR_ASSERT(cg_y.info() == Eigen::Success && "Conjugate Gradient failed at compute for A_y!");
@@ -401,13 +430,17 @@ void B2BSolver::b2b_solve_loop(unsigned iteration, PartialPlacement &p_placement
401430
p_placement.node_loc_y[node_id] = y[node_id];
402431
}
403432
current_hpwl = p_placement.get_HPWL();
404-
}while(current_hpwl < (previous_hpwl - 10));
433+
// This would not work because sometimes they stay in close proximity before growing or shrinking
434+
// }while(std::abs(current_hpwl - previous_hpwl) < 5 && counter < 100);
435+
// current_hpwl > previous_hpwl - 10 would not work when this tries to grow and converge to legalized solution
436+
// simplest one for now
437+
}while(counter < 30);
405438
}
406439

407440
void B2BSolver::solve(unsigned iteration, PartialPlacement &p_placement) {
408441
// Need an initial placement to decide who are the bounding nodes.
409442
if (iteration == 0){
410-
initialize_placement(p_placement);
443+
initialize_placement_least_dense(p_placement);
411444
size_t ASize = p_placement.num_moveable_nodes;
412445
A_sparse_x = Eigen::SparseMatrix<double>(ASize, ASize);
413446
A_sparse_y = Eigen::SparseMatrix<double>(ASize, ASize);
@@ -427,6 +460,6 @@ void B2BSolver::solve(unsigned iteration, PartialPlacement &p_placement) {
427460
p_placement.node_loc_y = node_loc_y_solved;
428461
b2b_solve_loop(iteration, p_placement);
429462
// store solved position in data structure of this class
430-
node_loc_x_solved = p_placement.node_loc_x;
431-
node_loc_y_solved = p_placement.node_loc_y;
463+
// node_loc_x_solved = p_placement.node_loc_x;
464+
// node_loc_y_solved = p_placement.node_loc_y;
432465
}

vpr/src/place/analytical_placement/AnalyticalSolver.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ class B2BSolver : public AnalyticalSolver {
4040
public:
4141
void solve(unsigned iteration, PartialPlacement &p_placement) final;
4242
void b2b_solve_loop(unsigned iteration, PartialPlacement &p_placement);
43-
void initialize_placement(PartialPlacement &p_placement);
43+
void initialize_placement_random_normal(PartialPlacement &p_placement);
44+
void initialize_placement_random_uniform(PartialPlacement &p_placement);
45+
void initialize_placement_least_dense(PartialPlacement &p_placement);
4446
void populate_matrix(PartialPlacement &p_placement);
4547
void populate_matrix_anchor(PartialPlacement& p_placement, unsigned iteration);
4648
std::pair<size_t, size_t> boundNode(std::vector<size_t> &node_id, std::vector<double> &node_loc);

0 commit comments

Comments
 (0)