@@ -635,240 +635,65 @@ void HierRTLMP::calculateMacroTilings(Cluster* cluster)
635635 }
636636
637637 std::vector<HardMacro*> hard_macros = cluster->getHardMacros ();
638- TilingSet tilings_set;
639-
640- if (hard_macros.size () == 1 ) {
641- int width = hard_macros[0 ]->getWidth ();
642- int height = hard_macros[0 ]->getHeight ();
643-
644- TilingList tilings;
645- tilings.emplace_back (width, height);
646- cluster->setTilings (tilings);
647-
648- debugPrint (logger_,
649- MPL,
650- " coarse_shaping" ,
651- 1 ,
652- " {} has only one macro, set tiling according to macro with halo" ,
653- cluster->getName ());
654- return ;
655- }
638+ int number_of_macros = hard_macros.size ();
639+ int macro_width = hard_macros.front ()->getWidth ();
640+ int macro_height = hard_macros.front ()->getHeight ();
656641
657- if (cluster->isArrayOfInterconnectedMacros ()) {
658- setTightPackingTilings (cluster);
659- return ;
660- }
642+ TilingList tilings = generateTilingsForMacroCluster (
643+ macro_width, macro_height, number_of_macros);
661644
662- if (graphics_) {
663- graphics_->setCurrentCluster (cluster);
664- }
665-
666- // otherwise call simulated annealing to determine tilings
667- // set the action probabilities
668- const float action_sum = pos_swap_prob_ + neg_swap_prob_ + double_swap_prob_
669- + exchange_swap_prob_;
670-
671- const odb::Rect outline (
672- 0 , 0 , tree_->root ->getWidth (), tree_->root ->getHeight ());
673-
674- // update macros
675- std::vector<HardMacro> macros;
676- macros.reserve (hard_macros.size ());
677- for (auto & macro : hard_macros) {
678- macros.push_back (*macro);
679- }
680- int num_perturb_per_step = (macros.size () > num_perturb_per_step_ / 10 )
681- ? macros.size ()
682- : num_perturb_per_step_ / 10 ;
683- if (cluster->getParent () == nullptr ) {
684- num_perturb_per_step = (macros.size () > num_perturb_per_step_ / 5 )
685- ? macros.size ()
686- : num_perturb_per_step_ / 5 ;
687- }
688-
689- // To generate different macro tilings, we vary the outline constraints
690- // we first vary the outline width while keeping outline_height fixed
691- // Then we vary the outline height while keeping outline_width fixed
692- // We vary the outline of cluster to generate different tilings
693- std::vector<float > vary_factor_list{1.0 };
694- float vary_step = 1.0 / num_runs_; // change the outline by at most halfly
695- for (int i = 1 ; i < num_runs_; i++) {
696- vary_factor_list.push_back (1.0 - i * vary_step);
697- }
698- int remaining_runs = num_runs_;
699- int run_id = 0 ;
700- while (remaining_runs > 0 ) {
701- HardSAVector sa_batch;
702- const int run_thread
703- = graphics_ ? 1 : std::min (remaining_runs, num_threads_);
704- for (int i = 0 ; i < run_thread; i++) {
705- const odb::Rect new_outline (
706- 0 , 0 , outline.dx () * vary_factor_list[run_id++], outline.dy ());
707- if (graphics_) {
708- graphics_->setOutline (new_outline);
709- }
710- std::unique_ptr<SACoreHardMacro> sa
711- = std::make_unique<SACoreHardMacro>(tree_.get (),
712- new_outline,
713- macros,
714- shaping_core_weights_,
715- pos_swap_prob_ / action_sum,
716- neg_swap_prob_ / action_sum,
717- double_swap_prob_ / action_sum,
718- exchange_swap_prob_ / action_sum,
719- init_prob_,
720- max_num_step_,
721- num_perturb_per_step,
722- random_seed_ + run_id,
723- graphics_.get (),
724- logger_,
725- block_);
726- sa_batch.push_back (std::move (sa));
727- }
728- if (sa_batch.size () == 1 ) {
729- runSA<SACoreHardMacro>(sa_batch[0 ].get ());
730- } else {
731- // multi threads
732- std::vector<std::thread> threads;
733- threads.reserve (sa_batch.size ());
734- for (auto & sa : sa_batch) {
735- threads.emplace_back (runSA<SACoreHardMacro>, sa.get ());
736- }
737- for (auto & th : threads) {
738- th.join ();
739- }
740- }
741- // add macro tilings
742- for (auto & sa : sa_batch) {
743- if (sa->fitsIn (outline)) {
744- tilings_set.insert ({sa->getWidth (), sa->getHeight ()});
745- }
746- }
747- remaining_runs -= run_thread;
748- }
749- // change the outline height while keeping outline width fixed
750- remaining_runs = num_runs_;
751- run_id = 0 ;
752- while (remaining_runs > 0 ) {
753- HardSAVector sa_batch;
754- const int run_thread
755- = graphics_ ? 1 : std::min (remaining_runs, num_threads_);
756- for (int i = 0 ; i < run_thread; i++) {
757- const odb::Rect new_outline (
758- 0 , 0 , outline.dx (), outline.dy () * vary_factor_list[run_id++]);
759- if (graphics_) {
760- graphics_->setOutline (new_outline);
761- }
762- std::unique_ptr<SACoreHardMacro> sa
763- = std::make_unique<SACoreHardMacro>(tree_.get (),
764- new_outline,
765- macros,
766- shaping_core_weights_,
767- pos_swap_prob_ / action_sum,
768- neg_swap_prob_ / action_sum,
769- double_swap_prob_ / action_sum,
770- exchange_swap_prob_ / action_sum,
771- init_prob_,
772- max_num_step_,
773- num_perturb_per_step,
774- random_seed_ + run_id,
775- graphics_.get (),
776- logger_,
777- block_);
778- sa_batch.push_back (std::move (sa));
779- }
780- if (sa_batch.size () == 1 ) {
781- runSA<SACoreHardMacro>(sa_batch[0 ].get ());
782- } else {
783- // multi threads
784- std::vector<std::thread> threads;
785- threads.reserve (sa_batch.size ());
786- for (auto & sa : sa_batch) {
787- threads.emplace_back (runSA<SACoreHardMacro>, sa.get ());
788- }
789- for (auto & th : threads) {
790- th.join ();
791- }
792- }
793- // add macro tilings
794- for (auto & sa : sa_batch) {
795- if (sa->fitsIn (outline)) {
796- tilings_set.insert ({sa->getWidth (), sa->getHeight ()});
797- }
798- }
799- remaining_runs -= run_thread;
645+ if (tilings.empty ()) {
646+ tilings = generateTilingsForMacroCluster (
647+ macro_width, macro_height, number_of_macros + 1 );
800648 }
801649
802- if (tilings_set .empty ()) {
650+ if (tilings .empty ()) {
803651 logger_->error (MPL,
804652 4 ,
805- " No valid tilings for hard macro cluster: {}" ,
806- cluster->getName ());
653+ " Unable to fit cluster {} within outline. Macro height: {}, "
654+ " width: {}, number of macros: {}." ,
655+ cluster->getName (),
656+ macro_width,
657+ macro_height,
658+ number_of_macros);
807659 }
808660
809- TilingList tilings_list (tilings_set.begin (), tilings_set.end ());
810- std::ranges::sort (tilings_list, isAreaSmaller);
661+ cluster->setTilings (tilings);
811662
812- for (auto & tiling : tilings_list) {
813- debugPrint (logger_,
814- MPL,
815- " coarse_shaping" ,
816- 2 ,
817- " width: {}, height: {}" ,
818- tiling.width (),
819- tiling.height ());
820- }
821-
822- // we only keep the minimum area tiling since all the macros has the same size
823- // later this can be relaxed. But this may cause problems because the
824- // minimizing the wirelength may leave holes near the boundary
825- TilingList new_tilings_list;
826- float first_tiling_area = tilings_list.front ().area ();
827- for (auto & tiling : tilings_list) {
828- if (tiling.area () <= first_tiling_area) {
829- new_tilings_list.push_back (tiling);
663+ if (logger_->debugCheck (MPL, " coarse_shaping" , 2 )) {
664+ std::string line = " Tiling for hard cluster " + cluster->getName ()
665+ + " with " + std::to_string (number_of_macros)
666+ + " macros.\n " ;
667+ for (auto & tiling : tilings) {
668+ line += " < " + std::to_string (tiling.width ()) + " , " ;
669+ line += std::to_string (tiling.height ()) + " > " ;
830670 }
671+ line += " \n " ;
672+ debugPrint (logger_, MPL, " coarse_shaping" , 2 , " {}" , line);
831673 }
832- tilings_list = std::move (new_tilings_list);
833- cluster->setTilings (tilings_list);
834-
835- std::string line = " Tiling for hard cluster " + cluster->getName () + " " ;
836- for (auto & tiling : tilings_list) {
837- line += " < " + std::to_string (tiling.width ()) + " , " ;
838- line += std::to_string (tiling.height ()) + " > " ;
839- }
840- line += " \n " ;
841- debugPrint (logger_, MPL, " coarse_shaping" , 2 , " {}" , line);
842674}
843675
844- // Used only for arrays of interconnected macros.
845- void HierRTLMP::setTightPackingTilings (Cluster* macro_array)
676+ TilingList HierRTLMP::generateTilingsForMacroCluster (int macro_width,
677+ int macro_height,
678+ int number_of_macros)
846679{
847680 TilingList tight_packing_tilings;
848-
849- int num_macro = macro_array->getNumMacro ();
850- float macro_width = macro_array->getHardMacros ().front ()->getWidth ();
851- float macro_height = macro_array->getHardMacros ().front ()->getHeight ();
852-
853681 const odb::Rect outline = tree_->root ->getBBox ();
854682
855- int columns = 0 ;
856- for (int rows = 1 ; rows < std::sqrt (num_macro) + 1 ; rows ++) {
857- if (num_macro % rows == 0 ) {
858- columns = num_macro / rows ;
683+ int rows = 0 ;
684+ for (int cols = 1 ; cols <= number_of_macros; cols ++) {
685+ if (number_of_macros % cols == 0 ) {
686+ rows = number_of_macros / cols ;
859687
860- // We don't consider tilings for right angle rotation orientations,
861- // because they're not allowed in our macro placer.
862- // Tiling needs to fit inside outline
863- if (columns * macro_width <= outline.dx ()
688+ if (cols * macro_width <= outline.dx ()
864689 && rows * macro_height <= outline.dy ()) {
865- tight_packing_tilings.emplace_back (columns * macro_width,
690+ tight_packing_tilings.emplace_back (cols * macro_width,
866691 rows * macro_height);
867692 }
868693 }
869694 }
870695
871- macro_array-> setTilings ( tight_packing_tilings) ;
696+ return tight_packing_tilings;
872697}
873698
874699void HierRTLMP::searchAvailableRegionsForUnconstrainedPins ()
0 commit comments