1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2021, The Regents of the University of California
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 // list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 // this list of conditions and the following disclaimer in the documentation
15 // and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE
25 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 ///////////////////////////////////////////////////////////////////////////////
33
34 #include <algorithm>
35 #include <cfloat>
36 #include <cmath>
37 #include <fstream>
38 #include <random>
39 #include <string>
40 #include <thread>
41 #include <unordered_map>
42 #include <vector>
43
44 #include "block_placement.h"
45 #include "pin_alignment.h"
46 #include "shape_engine.h"
47 #include "util.h"
48 #include "utl/Logger.h"
49
50 namespace pin_alignment {
51 using std::abs;
52 using std::cout;
53 using std::endl;
54 using std::exp;
55 using std::fstream;
56 using std::getline;
57 using std::ios;
58 using std::log;
59 using std::max;
60 using std::min;
61 using std::pair;
62 using std::pow;
63 using std::sort;
64 using std::stof;
65 using std::string;
66 using std::swap;
67 using std::thread;
68 using std::to_string;
69 using std::unordered_map;
70 using std::vector;
71
72 using block_placement::Net;
73 using shape_engine::Cluster;
74 using shape_engine::Macro;
75
76 using utl::Logger;
77 using utl::MPL;
78
SimulatedAnnealingCore(const std::vector<shape_engine::Macro> & macros,const std::vector<block_placement::Net * > & nets,const std::unordered_map<std::string,std::pair<float,float>> & terminal_position,float cooling_rate,float outline_width,float outline_height,float init_prob,float rej_ratio,int max_num_step,int k,float c,int perturb_per_step,float alpha,float beta,float gamma,float flip_prob,float pos_swap_prob,float neg_swap_prob,float double_swap_prob,unsigned seed)79 SimulatedAnnealingCore::SimulatedAnnealingCore(
80 const std::vector<shape_engine::Macro>& macros,
81 const std::vector<block_placement::Net*>& nets,
82 const std::unordered_map<std::string, std::pair<float, float>>&
83 terminal_position,
84 float cooling_rate,
85 float outline_width,
86 float outline_height,
87 float init_prob,
88 float rej_ratio,
89 int max_num_step,
90 int k,
91 float c,
92 int perturb_per_step,
93 float alpha,
94 float beta,
95 float gamma,
96 float flip_prob,
97 float pos_swap_prob,
98 float neg_swap_prob,
99 float double_swap_prob,
100 unsigned seed)
101 {
102 outline_width_ = outline_width;
103 outline_height_ = outline_height;
104
105 init_prob_ = init_prob;
106 rej_ratio_ = rej_ratio;
107 max_num_step_ = max_num_step;
108 k_ = k;
109 c_ = c;
110 perturb_per_step_ = perturb_per_step;
111 alpha_ = alpha;
112 beta_ = beta;
113 gamma_ = gamma;
114
115 cooling_rate_ = cooling_rate;
116
117 flip_prob_ = flip_prob;
118 pos_swap_prob_ = flip_prob_ + pos_swap_prob;
119 neg_swap_prob_ = pos_swap_prob_ + neg_swap_prob;
120 double_swap_prob_ = neg_swap_prob_ + double_swap_prob;
121
122 nets_ = nets;
123 terminal_position_ = terminal_position;
124
125 for (int i = 0; i < macros.size(); i++) {
126 pos_seq_.push_back(i);
127 neg_seq_.push_back(i);
128
129 pre_pos_seq_.push_back(i);
130 pre_neg_seq_.push_back(i);
131
132 macros_.push_back(shape_engine::Macro(macros[i]));
133
134 macro_map_.insert(std::pair<std::string, int>(macros[i].GetName(), i));
135 }
136
137 std::mt19937 randGen(seed);
138 generator_ = randGen;
139 std::uniform_real_distribution<float> distribution(0.0, 1.0);
140 distribution_ = distribution;
141
142 if (macros_.size() == 1) {
143 width_ = macros_[0].GetWidth();
144 height_ = macros_[0].GetHeight();
145 area_ = width_ * height_;
146 } else {
147 // Initialize init_T_, norm_area_, norm_wirelength, norm_outline_penalty_
148 Initialize();
149 }
150 }
151
Run()152 void SimulatedAnnealingCore::Run()
153 {
154 if (macros_.size() > 1)
155 FastSA();
156 else
157 SingleFlip();
158 }
159
IsFeasible() const160 bool SimulatedAnnealingCore::IsFeasible() const
161 {
162 const float tolerance = 0.01;
163 return width_ <= outline_width_ * (1 + tolerance)
164 && height_ <= outline_height_ * (1 + tolerance);
165 }
166
WriteFloorplan(const std::string & file_name) const167 void SimulatedAnnealingCore::WriteFloorplan(const std::string& file_name) const
168 {
169 std::ofstream file(file_name);
170 for (const auto& macro : macros_) {
171 file << macro.GetX() << " ";
172 file << macro.GetY() << " ";
173 file << macro.GetX() + macro.GetWidth() << " ";
174 file << macro.GetY() + macro.GetHeight() << " ";
175 file << std::endl;
176 }
177 }
178
PackFloorplan()179 void SimulatedAnnealingCore::PackFloorplan()
180 {
181 for (auto& macro : macros_) {
182 macro.SetX(0.0);
183 macro.SetY(0.0);
184 }
185
186 // calculate X position
187 vector<pair<int, int>> match(macros_.size());
188 for (int i = 0; i < pos_seq_.size(); i++) {
189 match[pos_seq_[i]].first = i;
190 match[neg_seq_[i]].second = i;
191 }
192
193 vector<float> length(macros_.size(), 0.0);
194
195 for (int i = 0; i < pos_seq_.size(); i++) {
196 int b = pos_seq_[i];
197 int p = match[b].second;
198 macros_[b].SetX(length[p]);
199 float t = macros_[b].GetX() + macros_[b].GetWidth();
200 for (int j = p; j < neg_seq_.size(); j++)
201 if (t > length[j])
202 length[j] = t;
203 else
204 break;
205 }
206
207 width_ = length[macros_.size() - 1];
208
209 // calulate Y position
210 vector<int> pos_seq(pos_seq_.size());
211 int num_blocks = pos_seq_.size();
212 for (int i = 0; i < num_blocks; i++)
213 pos_seq[i] = pos_seq_[num_blocks - 1 - i];
214
215 for (int i = 0; i < num_blocks; i++) {
216 match[pos_seq[i]].first = i;
217 match[neg_seq_[i]].second = i;
218 }
219
220 for (int i = 0; i < num_blocks; i++)
221 length[i] = 0.0;
222
223 for (int i = 0; i < num_blocks; i++) {
224 int b = pos_seq[i];
225 int p = match[b].second;
226 macros_[b].SetY(length[p]);
227 float t = macros_[b].GetY() + macros_[b].GetHeight();
228 for (int j = p; j < num_blocks; j++)
229 if (t > length[j])
230 length[j] = t;
231 else
232 break;
233 }
234
235 height_ = length[num_blocks - 1];
236 area_ = width_ * height_;
237 }
238
SingleSwap(bool flag)239 void SimulatedAnnealingCore::SingleSwap(bool flag)
240 {
241 int index1 = (int) (floor((distribution_) (generator_) *macros_.size()));
242 int index2 = (int) (floor((distribution_) (generator_) *macros_.size()));
243 while (index1 == index2) {
244 index2 = (int) (floor((distribution_) (generator_) *macros_.size()));
245 }
246
247 if (flag)
248 swap(pos_seq_[index1], pos_seq_[index2]);
249 else
250 swap(neg_seq_[index1], neg_seq_[index2]);
251 }
252
DoubleSwap()253 void SimulatedAnnealingCore::DoubleSwap()
254 {
255 int index1 = (int) (floor((distribution_) (generator_) *macros_.size()));
256 int index2 = (int) (floor((distribution_) (generator_) *macros_.size()));
257 while (index1 == index2) {
258 index2 = (int) (floor((distribution_) (generator_) *macros_.size()));
259 }
260
261 swap(pos_seq_[index1], pos_seq_[index2]);
262 swap(neg_seq_[index1], neg_seq_[index2]);
263 }
264
Flip()265 void SimulatedAnnealingCore::Flip()
266 {
267 for (int i = 0; i < macros_.size(); i++)
268 macros_[i].Flip(flip_flag_);
269 }
270
SingleFlip()271 void SimulatedAnnealingCore::SingleFlip()
272 {
273 CalculateWirelength();
274 float wirelength_best = wirelength_;
275 int action_id = 0;
276 flip_flag_ = true;
277 macros_[0].Flip(flip_flag_);
278 CalculateWirelength();
279 if (wirelength_best > wirelength_) {
280 wirelength_ = wirelength_best;
281 action_id = 1;
282 }
283
284 flip_flag_ = false;
285 macros_[0].Flip(flip_flag_);
286 CalculateWirelength();
287 if (wirelength_best > wirelength_) {
288 wirelength_ = wirelength_best;
289 action_id = 2;
290 }
291
292 flip_flag_ = true;
293 macros_[0].Flip(flip_flag_);
294 CalculateWirelength();
295 if (wirelength_best > wirelength_) {
296 wirelength_ = wirelength_best;
297 action_id = 3;
298 }
299
300 if (action_id == 3) {
301 return;
302 } else {
303 flip_flag_ = false;
304 macros_[0].Flip(flip_flag_);
305 if (action_id == 0) {
306 CalculateWirelength();
307 return;
308 } else {
309 flip_flag_ = true;
310 macros_[0].Flip(flip_flag_);
311 if (action_id == 1) {
312 CalculateWirelength();
313 return;
314 } else {
315 flip_flag_ = false;
316 macros_[0].Flip(flip_flag_);
317 CalculateWirelength();
318 return;
319 }
320 }
321 }
322 }
323
Perturb()324 void SimulatedAnnealingCore::Perturb()
325 {
326 if (macros_.size() == 1) {
327 Flip();
328 return;
329 }
330
331 pre_pos_seq_ = pos_seq_;
332 pre_neg_seq_ = neg_seq_;
333 pre_width_ = width_;
334 pre_height_ = height_;
335 pre_area_ = area_;
336 pre_wirelength_ = wirelength_;
337 pre_outline_penalty_ = outline_penalty_;
338
339 float op = (distribution_) (generator_);
340 if (op <= flip_prob_) {
341 action_id_ = 1;
342 float prob = (distribution_) (generator_);
343 if (prob <= 0.5)
344 flip_flag_ = true;
345 else
346 flip_flag_ = false;
347
348 Flip();
349 } else if (op <= pos_swap_prob_) {
350 action_id_ = 2;
351 SingleSwap(true);
352 } else if (op <= neg_swap_prob_) {
353 action_id_ = 3;
354 SingleSwap(false);
355 } else {
356 action_id_ = 4;
357 DoubleSwap();
358 }
359
360 PackFloorplan();
361 }
362
Restore()363 void SimulatedAnnealingCore::Restore()
364 {
365 if (action_id_ == 1) {
366 Flip();
367 } else {
368 pos_seq_ = pre_pos_seq_;
369 neg_seq_ = pre_neg_seq_;
370 }
371
372 width_ = pre_width_;
373 height_ = pre_height_;
374 area_ = pre_area_;
375 wirelength_ = pre_wirelength_;
376 outline_penalty_ = pre_outline_penalty_;
377 }
378
CalculateOutlinePenalty()379 void SimulatedAnnealingCore::CalculateOutlinePenalty()
380 {
381 outline_penalty_ = 0.0;
382
383 if (width_ > outline_width_ && height_ > outline_height_)
384 outline_penalty_ = width_ * height_ - outline_width_ * outline_height_;
385 else if (width_ > outline_width_ && height_ <= outline_height_)
386 outline_penalty_ = (width_ - outline_width_) * outline_height_;
387 else if (width_ <= outline_width_ && height_ > outline_height_)
388 outline_penalty_ = outline_width_ * (height_ - outline_height_);
389 else
390 outline_penalty_ = 0.0;
391 }
392
CalculateWirelength()393 void SimulatedAnnealingCore::CalculateWirelength()
394 {
395 wirelength_ = 0.0;
396 for (Net* net : nets_) {
397 vector<string> blocks = net->blocks_;
398 vector<string> terminals = net->terminals_;
399
400 if (blocks.size() == 0)
401 continue;
402
403 int weight = net->weight_;
404 float lx = FLT_MAX;
405 float ly = FLT_MAX;
406 float ux = 0.0;
407 float uy = 0.0;
408
409 for (int i = 0; i < blocks.size(); i++) {
410 float x = macros_[macro_map_[blocks[i]]].GetX()
411 + macros_[macro_map_[blocks[i]]].GetPinX();
412 float y = macros_[macro_map_[blocks[i]]].GetY()
413 + macros_[macro_map_[blocks[i]]].GetPinY();
414 lx = min(lx, x);
415 ly = min(ly, y);
416 ux = max(ux, x);
417 uy = max(uy, y);
418 }
419
420 for (int i = 0; i < terminals.size(); i++) {
421 float x = terminal_position_[terminals[i]].first;
422 float y = terminal_position_[terminals[i]].second;
423 lx = min(lx, x);
424 ly = min(ly, y);
425 ux = max(ux, x);
426 uy = max(uy, y);
427 }
428
429 wirelength_ += (abs(ux - lx) + abs(uy - ly)) * weight;
430 }
431 }
432
NormCost(float area,float wirelength,float outline_penalty) const433 float SimulatedAnnealingCore::NormCost(float area,
434 float wirelength,
435 float outline_penalty) const
436 {
437 float cost = alpha_ * area / norm_area_;
438 if (norm_wirelength_ > 0.0)
439 cost += beta_ * wirelength_ / norm_wirelength_;
440
441 if (norm_outline_penalty_ > 0.0)
442 cost += gamma_ * outline_penalty_ / norm_outline_penalty_;
443
444 return cost;
445 }
446
Initialize()447 void SimulatedAnnealingCore::Initialize()
448 {
449 vector<float> area_list;
450 vector<float> wirelength_list;
451 vector<float> outline_penalty_list;
452
453 norm_area_ = 0.0;
454 norm_wirelength_ = 0.0;
455 norm_outline_penalty_ = 0.0;
456
457 for (int i = 0; i < perturb_per_step_; i++) {
458 Perturb();
459 CalculateWirelength();
460 CalculateOutlinePenalty();
461
462 area_list.push_back(area_);
463 wirelength_list.push_back(wirelength_);
464 outline_penalty_list.push_back(outline_penalty_);
465
466 norm_area_ += area_;
467 norm_wirelength_ += wirelength_;
468 norm_outline_penalty_ = outline_penalty_;
469 }
470
471 norm_area_ = norm_area_ / perturb_per_step_;
472 norm_wirelength_ = norm_wirelength_ / perturb_per_step_;
473 norm_outline_penalty_ = norm_outline_penalty_ / perturb_per_step_;
474
475 vector<float> norm_cost_list;
476 float norm_cost = 0.0;
477 for (int i = 0; i < area_list.size(); i++) {
478 norm_cost
479 = NormCost(area_list[i], wirelength_list[i], outline_penalty_list[i]);
480 norm_cost_list.push_back(norm_cost);
481 }
482
483 float delta_cost = 0.0;
484 for (int i = 1; i < norm_cost_list.size(); i++)
485 delta_cost += abs(norm_cost_list[i] - norm_cost_list[i - 1]);
486
487 delta_cost = delta_cost / (norm_cost_list.size() - 1);
488 init_T_ = (-1) * delta_cost / log(init_prob_);
489 }
490
FastSA()491 void SimulatedAnnealingCore::FastSA()
492 {
493 int step = 1;
494
495 float pre_cost = NormCost(area_, wirelength_, outline_penalty_);
496 float cost = pre_cost;
497 float delta_cost = 0.0;
498 // vector<Macro> best_macros;
499 float best_cost = cost;
500 // vector<int> best_pos_seq = pos_seq_;
501 // vector<int> best_neg_seq = neg_seq_;
502
503 float rej_num = 0.0;
504 float T = init_T_;
505 float rej_threshold = rej_ratio_ * perturb_per_step_;
506
507 while (step <= max_num_step_ && rej_num <= rej_threshold) {
508 rej_num = 0.0;
509 for (int i = 0; i < perturb_per_step_; i++) {
510 Perturb();
511 CalculateWirelength();
512 CalculateOutlinePenalty();
513 cost = NormCost(area_, wirelength_, outline_penalty_);
514
515 delta_cost = cost - pre_cost;
516 float num = distribution_(generator_);
517 float prob = (delta_cost > 0.0) ? exp((-1) * delta_cost / T) : 1;
518
519 if (delta_cost <= 0 || num <= prob) {
520 pre_cost = cost;
521 if (cost < best_cost) {
522 best_cost = cost;
523 // best_pos_seq = pos_seq_;
524 // best_neg_seq = neg_seq_;
525 // best_macros = macros_;
526 }
527 } else {
528 rej_num += 1.0;
529 Restore();
530 }
531 }
532
533 step++;
534
535 // T = T * 0.99;
536 T = T * cooling_rate_;
537 }
538
539 // macros_ = best_macros;
540 // pos_seq_ = best_pos_seq;
541 // neg_seq_ = best_neg_seq;
542
543 PackFloorplan();
544 }
545
Run(SimulatedAnnealingCore * sa)546 void Run(SimulatedAnnealingCore* sa)
547 {
548 sa->Run();
549 }
550
ParseMacroFile(vector<Macro> & macros,float halo_width,const string & file_name)551 void ParseMacroFile(vector<Macro>& macros,
552 float halo_width,
553 const string& file_name)
554 {
555 unordered_map<string, pair<float, float>> pin_loc;
556 fstream f;
557 string line;
558 vector<string> content;
559 f.open(file_name, ios::in);
560 while (getline(f, line))
561 content.push_back(line);
562
563 f.close();
564 for (int i = 0; i < content.size(); i++) {
565 vector<string> words = Split(content[i]);
566 string name = words[0];
567 float pin_x = stof(words[3]) + halo_width;
568 float pin_y = stof(words[4]) + halo_width;
569 pin_loc[name] = pair<float, float>(pin_x, pin_y);
570 }
571
572 for (int i = 0; i < macros.size(); i++) {
573 float pin_x = pin_loc[macros[i].GetName()].first;
574 float pin_y = pin_loc[macros[i].GetName()].second;
575 macros[i].SetPinPosition(pin_x, pin_y);
576 }
577 }
578
PinAlignmentSingleCluster(const char * report_directory,Cluster * cluster,const unordered_map<string,pair<float,float>> & terminal_position,const vector<Net * > & nets,Logger * logger,float halo_width,int num_thread,int num_run,unsigned seed)579 bool PinAlignmentSingleCluster(
580 const char *report_directory,
581 Cluster* cluster,
582 const unordered_map<string, pair<float, float>>& terminal_position,
583 const vector<Net*>& nets,
584 Logger* logger,
585 float halo_width,
586 int num_thread,
587 int num_run,
588 unsigned seed)
589 {
590 // parameterse related to fastSA
591 float init_prob = 0.95;
592 float rej_ratio = 0.99;
593 int max_num_step = 5000;
594 int k = 5;
595 float c = 100.0;
596 float alpha = 0.3;
597 float beta = 0.4;
598 float gamma = 0.3;
599 float flip_prob = 0.2;
600 float pos_swap_prob = 0.3;
601 float neg_swap_prob = 0.3;
602 float double_swap_prob = 0.2;
603
604 string name = cluster->GetName();
605 for (int j = 0; j < name.size(); j++)
606 if (name[j] == '/')
607 name[j] = '*';
608
609 logger->info(MPL, 3002, "Pin_Aligment Working on macro_clutser: {}", name);
610
611 float lx = cluster->GetX();
612 float ly = cluster->GetY();
613 float ux = lx + cluster->GetWidth();
614 float uy = ly + cluster->GetHeight();
615 float outline_width = ux - lx;
616 float outline_height = uy - ly;
617
618 // deal with macros
619 vector<Macro> macros = cluster->GetMacros();
620 //string macro_file = string("./rtl_mp/") + name + string(".txt.block");
621 string macro_file = string(report_directory) + string("/") + name + string(".txt.block");
622 ParseMacroFile(macros, halo_width, macro_file);
623
624 int perturb_per_step = 2 * macros.size();
625
626 std::mt19937 rand_generator(seed);
627 vector<int> seed_list;
628 for (int j = 0; j < num_thread; j++)
629 seed_list.push_back((unsigned) rand_generator());
630
631 int remaining_run = num_run;
632 int run_thread = num_thread;
633 int sa_id = 0;
634
635 vector<SimulatedAnnealingCore*> sa_vector;
636 vector<thread> threads;
637 while (remaining_run > 0) {
638 run_thread = num_thread;
639 if (remaining_run < num_thread)
640 run_thread = remaining_run;
641
642 for (int j = 0; j < run_thread; j++) {
643 float cooling_rate = 0.995;
644 if (run_thread >= 2) {
645 cooling_rate = 0.995 - j * (0.995 - 0.985) / (run_thread - 1);
646 }
647
648 SimulatedAnnealingCore* sa = new SimulatedAnnealingCore(macros,
649 nets,
650 terminal_position,
651 cooling_rate,
652 outline_width,
653 outline_height,
654 init_prob,
655 rej_ratio,
656 max_num_step,
657 k,
658 c,
659 perturb_per_step,
660 alpha,
661 beta,
662 gamma,
663 flip_prob,
664 pos_swap_prob,
665 neg_swap_prob,
666 double_swap_prob,
667 seed_list[j]);
668
669 sa_vector.push_back(sa);
670 }
671
672 for (int j = 0; j < run_thread; j++)
673 threads.push_back(thread(Run, sa_vector[sa_id++]));
674
675 for (auto& th : threads)
676 th.join();
677
678 threads.clear();
679 remaining_run = remaining_run - run_thread;
680 }
681
682 int min_id = -1;
683 float wirelength = FLT_MAX;
684
685 // for(int j = 0; j < sa_vector.size(); j++) {
686 // string file_name = string("./rtl_mp/") + name + string("_") +
687 // to_string(j) + string("_final.txt");
688 // sa_vector[j]->WriteFloorplan(file_name);
689 //}
690
691 for (int j = 0; j < sa_vector.size(); j++)
692 if (sa_vector[j]->IsFeasible())
693 if (wirelength > sa_vector[j]->GetWirelength())
694 min_id = j;
695
696 if (min_id == -1) {
697 // throw std::invalid_argument(std::string("Invalid Floorplan. Please
698 // increase the num_run!!!"));
699 logger->info(MPL,
700 3003,
701 "Pin_Alignment Cannot generate valid floorplan for current "
702 "cluster!!!");
703 return false;
704 } else {
705 cluster->SetMacros(sa_vector[min_id]->GetMacros());
706 }
707
708 for (int j = 0; j < sa_vector.size(); j++)
709 delete sa_vector[j];
710
711 logger->info(MPL, 3004, "Pin_Aligment finish macro_clutser: {}", name);
712
713 return true;
714 }
715
716 // Pin Alignment Engine
PinAlignment(const vector<Cluster * > & clusters,Logger * logger,const char * report_directory,float halo_width,int num_thread,int num_run,unsigned seed)717 bool PinAlignment(const vector<Cluster*>& clusters,
718 Logger* logger,
719 const char *report_directory,
720 float halo_width,
721 int num_thread,
722 int num_run,
723 unsigned seed)
724 {
725 logger->info(MPL, 3001, "Pin_Aligment Starts");
726
727 unordered_map<string, pair<float, float>> terminal_position;
728 vector<Net*> nets;
729
730 // int info_id = 2;
731 for (int i = 0; i < clusters.size(); i++) {
732 if (clusters[i]->GetNumMacro() > 0) {
733 string name = clusters[i]->GetName();
734 for (int j = 0; j < name.size(); j++)
735 if (name[j] == '/')
736 name[j] = '*';
737
738 float lx = clusters[i]->GetX();
739 float ly = clusters[i]->GetY();
740
741 for (int j = 0; j < clusters.size(); j++) {
742 if (j != i) {
743 string terminal_name = clusters[j]->GetName();
744 float terminal_x
745 = clusters[j]->GetX() + clusters[j]->GetWidth() / 2.0;
746 float terminal_y
747 = clusters[j]->GetY() + clusters[j]->GetHeight() / 2.0;
748 terminal_x -= lx;
749 terminal_y -= ly;
750 terminal_position[terminal_name]
751 = pair<float, float>(terminal_x, terminal_y);
752 }
753 }
754
755 // deal with nets
756 // vector<Net*> nets;
757 //string net_file = string("./rtl_mp/") + name + string(".txt.net");
758 string net_file = string(report_directory) + string("/") + name + string(".txt.net");
759 block_placement::ParseNetFile(nets, terminal_position, net_file.c_str());
760
761 bool flag = PinAlignmentSingleCluster(report_directory,
762 clusters[i],
763 terminal_position,
764 nets,
765 logger,
766 halo_width,
767 num_thread,
768 num_run,
769 seed);
770
771 if (flag == false)
772 return false;
773
774 terminal_position.clear();
775 for (int j = 0; j < nets.size(); j++) {
776 delete nets[j];
777 }
778
779 nets.clear();
780 }
781 }
782
783 return true;
784 }
785 } // namespace pin_alignment
786