From 1180c819a0efdc2842011fdc411f436097a9443e Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 9 Jan 2024 18:59:34 -0300 Subject: [PATCH 01/11] mpl2: rename and cleaning Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 118 ++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 9ed8541b5b7..145461eac62 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2230,12 +2230,12 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) } // Traverse the physical hierarchy tree in a DFS manner (post-order) - std::vector leaf_clusters; + std::vector mixed_leaves; for (auto& child : root_cluster->getChildren()) { setInstProperty(child); if (child->getNumMacro() > 0) { if (child->getChildren().empty()) { - leaf_clusters.push_back(child); + mixed_leaves.push_back(child); } else { breakMixedLeafCluster(child); } @@ -2244,41 +2244,42 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) } } - // after this step, the std cells and macros for leaf cluster has been - // seperated. We need to update the metrics of the design if necessary - // for each leaf clusters with macros, first group macros based on - // connection signatures and macro sizes - for (auto& cluster : leaf_clusters) { - // based on the type of current cluster, - Cluster* parent_cluster = cluster; // std cell dominated cluster - // add a subtree if the cluster is macro dominated cluster - // based macro_dominated_cluster_threshold_ (defualt = 0.01) - if (cluster->getNumStdCell() * macro_dominated_cluster_threshold_ - < cluster->getNumMacro()) { - parent_cluster = cluster->getParent(); // replacement + // We need to update the metrics of the design if necessary + // for each leaf clusters with macros. + for (auto& mixed_leaf : mixed_leaves) { + Cluster* parent = mixed_leaf; + + // Split by replacement if macro dominated. + if (mixed_leaf->getNumStdCell() * macro_dominated_cluster_threshold_ + < mixed_leaf->getNumMacro()) { + parent = mixed_leaf->getParent(); } - // Map macros into the HardMacro objects - // and get all the HardMacros - mapMacroInCluster2HardMacro(cluster); - std::vector hard_macros = cluster->getHardMacros(); + mapMacroInCluster2HardMacro(mixed_leaf); - // create a cluster for each macro + std::vector hard_macros = mixed_leaf->getHardMacros(); std::vector macro_clusters; + + // createOneMacroClusterForEachMacro for (auto& hard_macro : hard_macros) { std::string cluster_name = hard_macro->getName(); - Cluster* macro_cluster = new Cluster(cluster_id_, cluster_name, logger_); - macro_cluster->addLeafMacro(hard_macro->getInst()); - setInstProperty(macro_cluster); - setClusterMetrics(macro_cluster); - cluster_map_[cluster_id_++] = macro_cluster; + Cluster* single_macro_cluster + = new Cluster(cluster_id_, cluster_name, logger_); + + single_macro_cluster->addLeafMacro(hard_macro->getInst()); + + setInstProperty(single_macro_cluster); + setClusterMetrics(single_macro_cluster); + + cluster_map_[cluster_id_++] = single_macro_cluster; + // modify the physical hierachy tree - macro_cluster->setParent(parent_cluster); - parent_cluster->addChild(macro_cluster); - macro_clusters.push_back(macro_cluster); + single_macro_cluster->setParent(parent); + parent->addChild(single_macro_cluster); + macro_clusters.push_back(single_macro_cluster); } - // classify macros based on size + // classifyMacrosBasedOnSize std::vector macro_size_class(hard_macros.size(), -1); for (int i = 0; i < hard_macros.size(); i++) { if (macro_size_class[i] == -1) { @@ -2290,14 +2291,14 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) } } } - for (int i = 0; i < hard_macros.size(); i++) { macro_size_class[i] = (macro_size_class[i] == -1) ? i : macro_size_class[i]; } - // classify macros based on connection signature calculateConnection(); + + // classifyMacrosBasedOnConnSignature std::vector macro_signature_class(hard_macros.size(), -1); for (int i = 0; i < hard_macros.size(); i++) { if (macro_signature_class[i] == -1) { @@ -2314,8 +2315,6 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) } } } - - // print the connnection signature if (logger_->debugCheck(MPL, "multilevel_autoclustering", 2)) { logger_->report("\nPrint Connection Signature\n"); for (auto& cluster : macro_clusters) { @@ -2327,8 +2326,7 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) } } - // macros with the same size and the same connection signature - // belong to the same class + // groupSingleMacroClusters std::vector macro_class(hard_macros.size(), -1); for (int i = 0; i < hard_macros.size(); i++) { if (macro_class[i] == -1) { @@ -2356,42 +2354,42 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) } } - // clear the hard macros in current leaf cluster - cluster->clearHardMacros(); - // Restore the structure of physical hierarchical tree - // Thus the order of leaf clusters will not change the final - // macro grouping results (This is very important !!! - // Don't touch the next line SetInstProperty command!!!) - setInstProperty(cluster); + mixed_leaf->clearHardMacros(); + // IMPORTANT: Restore the structure of physical hierarchical tree. Thus the + // order of leaf clusters will not change the final macro grouping results. + setInstProperty(mixed_leaf); + + // Never use SetInstProperty in the following lines for the reason above! std::vector virtual_conn_clusters; - // Never use SetInstProperty Command in following lines - // for above reason!!! - // based on different types of designs, we handle differently - // whether a replacement or a subtree - // Deal with the standard cell cluster - if (parent_cluster == cluster) { - // If we need a subtree , add standard cell cluster - std::string std_cell_cluster_name = cluster->getName(); + + if (parent == mixed_leaf) { + std::string std_cell_cluster_name = mixed_leaf->getName(); Cluster* std_cell_cluster = new Cluster(cluster_id_, std_cell_cluster_name, logger_); - std_cell_cluster->copyInstances(*cluster); + + std_cell_cluster->copyInstances(*mixed_leaf); std_cell_cluster->clearLeafMacros(); std_cell_cluster->setClusterType(StdCellCluster); + setClusterMetrics(std_cell_cluster); + cluster_map_[cluster_id_++] = std_cell_cluster; + // modify the physical hierachy tree - std_cell_cluster->setParent(parent_cluster); - parent_cluster->addChild(std_cell_cluster); + std_cell_cluster->setParent(parent); + parent->addChild(std_cell_cluster); virtual_conn_clusters.push_back(std_cell_cluster->getId()); } else { - // If we need add a replacement - cluster->clearLeafMacros(); - cluster->setClusterType(StdCellCluster); - setClusterMetrics(cluster); - virtual_conn_clusters.push_back(cluster->getId()); // In this case, we do not to modify the physical hierarchy tree + mixed_leaf->clearLeafMacros(); + mixed_leaf->setClusterType(StdCellCluster); + + setClusterMetrics(mixed_leaf); + + virtual_conn_clusters.push_back(mixed_leaf->getId()); } + // Deal with macro clusters for (int i = 0; i < macro_class.size(); i++) { if (macro_class[i] != i) { @@ -2399,14 +2397,14 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) } macro_clusters[i]->setClusterType(HardMacroCluster); setClusterMetrics(macro_clusters[i]); - virtual_conn_clusters.push_back(cluster->getId()); + virtual_conn_clusters.push_back(mixed_leaf->getId()); } // add virtual connections for (int i = 0; i < virtual_conn_clusters.size(); i++) { for (int j = i + 1; j < virtual_conn_clusters.size(); j++) { - parent_cluster->addVirtualConnection(virtual_conn_clusters[i], - virtual_conn_clusters[j]); + parent->addVirtualConnection(virtual_conn_clusters[i], + virtual_conn_clusters[j]); } } } From 11dace95084a0a0721172f3bf261fbf61c3038e2 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 10:31:36 -0300 Subject: [PATCH 02/11] mpl2: split single-macro cluster creation to its own function Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 43 +++++++++++++++++++++---------------- src/mpl2/src/hier_rtlmp.h | 3 +++ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 145461eac62..1a4ae6a8925 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2260,24 +2260,7 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) std::vector hard_macros = mixed_leaf->getHardMacros(); std::vector macro_clusters; - // createOneMacroClusterForEachMacro - for (auto& hard_macro : hard_macros) { - std::string cluster_name = hard_macro->getName(); - Cluster* single_macro_cluster - = new Cluster(cluster_id_, cluster_name, logger_); - - single_macro_cluster->addLeafMacro(hard_macro->getInst()); - - setInstProperty(single_macro_cluster); - setClusterMetrics(single_macro_cluster); - - cluster_map_[cluster_id_++] = single_macro_cluster; - - // modify the physical hierachy tree - single_macro_cluster->setParent(parent); - parent->addChild(single_macro_cluster); - macro_clusters.push_back(single_macro_cluster); - } + createOneClusterForEachMacro(parent, hard_macros, macro_clusters); // classifyMacrosBasedOnSize std::vector macro_size_class(hard_macros.size(), -1); @@ -2412,6 +2395,30 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) setInstProperty(root_cluster); } +void HierRTLMP::createOneClusterForEachMacro( + Cluster* parent, + const std::vector& hard_macros, + std::vector& macro_clusters) +{ + for (auto& hard_macro : hard_macros) { + std::string cluster_name = hard_macro->getName(); + Cluster* single_macro_cluster + = new Cluster(cluster_id_, cluster_name, logger_); + + single_macro_cluster->addLeafMacro(hard_macro->getInst()); + + setInstProperty(single_macro_cluster); + setClusterMetrics(single_macro_cluster); + + cluster_map_[cluster_id_++] = single_macro_cluster; + + // modify the physical hierachy tree + single_macro_cluster->setParent(parent); + parent->addChild(single_macro_cluster); + macro_clusters.push_back(single_macro_cluster); + } +} + // Map all the macros into their HardMacro objects for all the clusters void HierRTLMP::mapMacroInCluster2HardMacro(Cluster* cluster) { diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 7f0973f28cf..c0f2dc0db5b 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -204,6 +204,9 @@ class HierRTLMP void updateSubTree(Cluster* parent); void breakLargeFlatCluster(Cluster* parent); void breakMixedLeafCluster(Cluster* root_cluster); + void createOneClusterForEachMacro(Cluster* parent, + const std::vector& hard_macros, + std::vector& macro_clusters); void mapMacroInCluster2HardMacro(Cluster* cluster); // Coarse Shaping From 1c3f6b278c8b2c54a62c589b766a34f30f74d6af Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 10:42:23 -0300 Subject: [PATCH 03/11] mpl2: split size classification into its own function / rename size_class Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 38 ++++++++++++++++++++----------------- src/mpl2/src/hier_rtlmp.h | 2 ++ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 1a4ae6a8925..74e9530d45a 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2262,22 +2262,8 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) createOneClusterForEachMacro(parent, hard_macros, macro_clusters); - // classifyMacrosBasedOnSize - std::vector macro_size_class(hard_macros.size(), -1); - for (int i = 0; i < hard_macros.size(); i++) { - if (macro_size_class[i] == -1) { - for (int j = i + 1; j < hard_macros.size(); j++) { - if ((macro_size_class[j] == -1) - && ((*hard_macros[i]) == (*hard_macros[j]))) { - macro_size_class[j] = i; - } - } - } - } - for (int i = 0; i < hard_macros.size(); i++) { - macro_size_class[i] - = (macro_size_class[i] == -1) ? i : macro_size_class[i]; - } + std::vector size_class(hard_macros.size(), -1); + classifyMacrosBySize(hard_macros, size_class); calculateConnection(); @@ -2315,7 +2301,7 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) if (macro_class[i] == -1) { macro_class[i] = i; for (int j = i + 1; j < hard_macros.size(); j++) { - if (macro_class[j] == -1 && macro_size_class[i] == macro_size_class[j] + if (macro_class[j] == -1 && size_class[i] == size_class[j] && macro_signature_class[i] == macro_signature_class[j]) { macro_class[j] = i; debugPrint(logger_, @@ -2419,6 +2405,24 @@ void HierRTLMP::createOneClusterForEachMacro( } } +void HierRTLMP::classifyMacrosBySize(const std::vector& hard_macros, + std::vector& size_class) +{ + for (int i = 0; i < hard_macros.size(); i++) { + if (size_class[i] == -1) { + for (int j = i + 1; j < hard_macros.size(); j++) { + if ((size_class[j] == -1) && ((*hard_macros[i]) == (*hard_macros[j]))) { + size_class[j] = i; + } + } + } + } + + for (int i = 0; i < hard_macros.size(); i++) { + size_class[i] = (size_class[i] == -1) ? i : size_class[i]; + } +} + // Map all the macros into their HardMacro objects for all the clusters void HierRTLMP::mapMacroInCluster2HardMacro(Cluster* cluster) { diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index c0f2dc0db5b..ec0da87b071 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -207,6 +207,8 @@ class HierRTLMP void createOneClusterForEachMacro(Cluster* parent, const std::vector& hard_macros, std::vector& macro_clusters); + void classifyMacrosBySize(const std::vector& hard_macros, + std::vector& size_class); void mapMacroInCluster2HardMacro(Cluster* cluster); // Coarse Shaping From 8900e75b32d06ef7289bfc08dc777b682731f157 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 10:54:01 -0300 Subject: [PATCH 04/11] mpl2: split signature classification into its own function / rename signature_class Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 62 ++++++++++++++++++++----------------- src/mpl2/src/hier_rtlmp.h | 3 ++ 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 74e9530d45a..a9e7c373a28 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2267,33 +2267,8 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) calculateConnection(); - // classifyMacrosBasedOnConnSignature - std::vector macro_signature_class(hard_macros.size(), -1); - for (int i = 0; i < hard_macros.size(); i++) { - if (macro_signature_class[i] == -1) { - macro_signature_class[i] = i; - for (int j = i + 1; j < hard_macros.size(); j++) { - if (macro_signature_class[j] != -1) { - continue; - } - bool flag = macro_clusters[i]->isSameConnSignature( - *macro_clusters[j], signature_net_threshold_); - if (flag) { - macro_signature_class[j] = i; - } - } - } - } - if (logger_->debugCheck(MPL, "multilevel_autoclustering", 2)) { - logger_->report("\nPrint Connection Signature\n"); - for (auto& cluster : macro_clusters) { - logger_->report("Macro Signature: {}", cluster->getName()); - for (auto& [cluster_id, weight] : cluster->getConnection()) { - logger_->report( - " {} {} ", cluster_map_[cluster_id]->getName(), weight); - } - } - } + std::vector signature_class(hard_macros.size(), -1); + classifyMacrosByConnSignature(macro_clusters, signature_class); // groupSingleMacroClusters std::vector macro_class(hard_macros.size(), -1); @@ -2302,7 +2277,7 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) macro_class[i] = i; for (int j = i + 1; j < hard_macros.size(); j++) { if (macro_class[j] == -1 && size_class[i] == size_class[j] - && macro_signature_class[i] == macro_signature_class[j]) { + && signature_class[i] == signature_class[j]) { macro_class[j] = i; debugPrint(logger_, MPL, @@ -2423,6 +2398,37 @@ void HierRTLMP::classifyMacrosBySize(const std::vector& hard_macros, } } +void HierRTLMP::classifyMacrosByConnSignature( + const std::vector& macro_clusters, + std::vector& signature_class) +{ + for (int i = 0; i < macro_clusters.size(); i++) { + if (signature_class[i] == -1) { + signature_class[i] = i; + for (int j = i + 1; j < macro_clusters.size(); j++) { + if (signature_class[j] != -1) { + continue; + } + + if (macro_clusters[i]->isSameConnSignature(*macro_clusters[j], + signature_net_threshold_)) { + signature_class[j] = i; + } + } + } + } + + if (logger_->debugCheck(MPL, "multilevel_autoclustering", 2)) { + logger_->report("\nPrint Connection Signature\n"); + for (auto& cluster : macro_clusters) { + logger_->report("Macro Signature: {}", cluster->getName()); + for (auto& [cluster_id, weight] : cluster->getConnection()) { + logger_->report(" {} {} ", cluster_map_[cluster_id]->getName(), weight); + } + } + } +} + // Map all the macros into their HardMacro objects for all the clusters void HierRTLMP::mapMacroInCluster2HardMacro(Cluster* cluster) { diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index ec0da87b071..cd5197eb09d 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -209,6 +209,9 @@ class HierRTLMP std::vector& macro_clusters); void classifyMacrosBySize(const std::vector& hard_macros, std::vector& size_class); + void classifyMacrosByConnSignature( + const std::vector& macro_clusters, + std::vector& signature_class); void mapMacroInCluster2HardMacro(Cluster* cluster); // Coarse Shaping From 3a6e66e67acdaedee2d229dc89640c557fb693e4 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 11:17:02 -0300 Subject: [PATCH 05/11] mpl2: split single-macro macro clusters grouping into its own function / comment fix Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 70 +++++++++++++++++++++---------------- src/mpl2/src/hier_rtlmp.h | 4 +++ 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index a9e7c373a28..93f4aac8c20 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2211,9 +2211,8 @@ void HierRTLMP::breakLargeFlatCluster(Cluster* parent) breakLargeFlatCluster(cluster_part_1); } -// Break mixed leaf clusters into a standard-cell cluster and hard-macro -// clusters. -// Merge macros based on connection signatures and footprints. +// Break mixed leaves into standard-cell and hard-macro clusters. +// Merge macros based on connection signature and footprint. // Based on types of designs, we support two types of breaking up: // Suppose current cluster is A. // 1) Replace A by A1, A2, A3 @@ -2221,8 +2220,6 @@ void HierRTLMP::breakLargeFlatCluster(Cluster* parent) // A -> A // | | | // A1 A2 A3 -// Split macros and std cells in the leaf clusters. In the normal operation, -// we call this function after creating the physical hierarchy. void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) { if (root_cluster->getChildren().empty() || root_cluster->getNumMacro() == 0) { @@ -2270,33 +2267,11 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) std::vector signature_class(hard_macros.size(), -1); classifyMacrosByConnSignature(macro_clusters, signature_class); - // groupSingleMacroClusters std::vector macro_class(hard_macros.size(), -1); - for (int i = 0; i < hard_macros.size(); i++) { - if (macro_class[i] == -1) { - macro_class[i] = i; - for (int j = i + 1; j < hard_macros.size(); j++) { - if (macro_class[j] == -1 && size_class[i] == size_class[j] - && signature_class[i] == signature_class[j]) { - macro_class[j] = i; - debugPrint(logger_, - MPL, - "multilevel_autoclustering", - 1, - "merge {} with {}", - macro_clusters[i]->getName(), - macro_clusters[j]->getName()); - bool delete_flag = false; - macro_clusters[i]->mergeCluster(*macro_clusters[j], delete_flag); - if (delete_flag) { - // remove the merged macro cluster - cluster_map_.erase(macro_clusters[j]->getId()); - delete macro_clusters[j]; - } - } - } - } - } + // Use both size and connection signature classifications to group + // single-macro macro clusters into the same cluster. + groupSingleMacroClusters( + macro_clusters, size_class, signature_class, macro_class); mixed_leaf->clearHardMacros(); @@ -2429,6 +2404,39 @@ void HierRTLMP::classifyMacrosByConnSignature( } } +void HierRTLMP::groupSingleMacroClusters( + const std::vector& macro_clusters, + const std::vector& size_class, + const std::vector& signature_class, + std::vector& macro_class) +{ + for (int i = 0; i < macro_clusters.size(); i++) { + if (macro_class[i] == -1) { + macro_class[i] = i; + for (int j = i + 1; j < macro_clusters.size(); j++) { + if (macro_class[j] == -1 && size_class[i] == size_class[j] + && signature_class[i] == signature_class[j]) { + macro_class[j] = i; + debugPrint(logger_, + MPL, + "multilevel_autoclustering", + 1, + "merge {} with {}", + macro_clusters[i]->getName(), + macro_clusters[j]->getName()); + bool delete_merged = false; + macro_clusters[i]->mergeCluster(*macro_clusters[j], delete_merged); + if (delete_merged) { + // remove the merged macro cluster + cluster_map_.erase(macro_clusters[j]->getId()); + delete macro_clusters[j]; + } + } + } + } + } +} + // Map all the macros into their HardMacro objects for all the clusters void HierRTLMP::mapMacroInCluster2HardMacro(Cluster* cluster) { diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index cd5197eb09d..4b6dd2ae3ed 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -212,6 +212,10 @@ class HierRTLMP void classifyMacrosByConnSignature( const std::vector& macro_clusters, std::vector& signature_class); + void groupSingleMacroClusters(const std::vector& macro_clusters, + const std::vector& size_class, + const std::vector& signature_class, + std::vector& macro_class); void mapMacroInCluster2HardMacro(Cluster* cluster); // Coarse Shaping From 197b3a47bf5de7a303a962e645b18336007461d0 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 11:21:16 -0300 Subject: [PATCH 06/11] mpl2: definitions order Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 82 ++++++++++++++++++------------------- src/mpl2/src/hier_rtlmp.h | 2 +- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 93f4aac8c20..71967b043bf 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2331,6 +2331,47 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) setInstProperty(root_cluster); } +// Map all the macros into their HardMacro objects for all the clusters +void HierRTLMP::mapMacroInCluster2HardMacro(Cluster* cluster) +{ + if (cluster->getClusterType() == StdCellCluster) { + return; + } + + std::vector hard_macros; + for (const auto& macro : cluster->getLeafMacros()) { + hard_macros.push_back(hard_macro_map_[macro]); + } + for (const auto& module : cluster->getDbModules()) { + getHardMacros(module, hard_macros); + } + cluster->specifyHardMacros(hard_macros); +} + +// Get all the hard macros in a logical module +void HierRTLMP::getHardMacros(odb::dbModule* module, + std::vector& hard_macros) +{ + for (odb::dbInst* inst : module->getInsts()) { + const sta::LibertyCell* liberty_cell = network_->libertyCell(inst); + if (liberty_cell == nullptr) { + continue; + } + odb::dbMaster* master = inst->getMaster(); + // check if the instance is a pad or empty block (such as marker) + if (master->isPad() || master->isCover()) { + continue; + } + if (master->isBlock()) { + hard_macros.push_back(hard_macro_map_[inst]); + } + } + + for (odb::dbModInst* inst : module->getChildren()) { + getHardMacros(inst->getMaster(), hard_macros); + } +} + void HierRTLMP::createOneClusterForEachMacro( Cluster* parent, const std::vector& hard_macros, @@ -2437,47 +2478,6 @@ void HierRTLMP::groupSingleMacroClusters( } } -// Map all the macros into their HardMacro objects for all the clusters -void HierRTLMP::mapMacroInCluster2HardMacro(Cluster* cluster) -{ - if (cluster->getClusterType() == StdCellCluster) { - return; - } - - std::vector hard_macros; - for (const auto& macro : cluster->getLeafMacros()) { - hard_macros.push_back(hard_macro_map_[macro]); - } - for (const auto& module : cluster->getDbModules()) { - getHardMacros(module, hard_macros); - } - cluster->specifyHardMacros(hard_macros); -} - -// Get all the hard macros in a logical module -void HierRTLMP::getHardMacros(odb::dbModule* module, - std::vector& hard_macros) -{ - for (odb::dbInst* inst : module->getInsts()) { - const sta::LibertyCell* liberty_cell = network_->libertyCell(inst); - if (liberty_cell == nullptr) { - continue; - } - odb::dbMaster* master = inst->getMaster(); - // check if the instance is a pad or empty block (such as marker) - if (master->isPad() || master->isCover()) { - continue; - } - if (master->isBlock()) { - hard_macros.push_back(hard_macro_map_[inst]); - } - } - - for (odb::dbModInst* inst : module->getChildren()) { - getHardMacros(inst->getMaster(), hard_macros); - } -} - // Print Physical Hierarchy tree in a DFS manner void HierRTLMP::printPhysicalHierarchyTree(Cluster* parent, int level) { diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 4b6dd2ae3ed..a78582eec6c 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -204,6 +204,7 @@ class HierRTLMP void updateSubTree(Cluster* parent); void breakLargeFlatCluster(Cluster* parent); void breakMixedLeafCluster(Cluster* root_cluster); + void mapMacroInCluster2HardMacro(Cluster* cluster); void createOneClusterForEachMacro(Cluster* parent, const std::vector& hard_macros, std::vector& macro_clusters); @@ -216,7 +217,6 @@ class HierRTLMP const std::vector& size_class, const std::vector& signature_class, std::vector& macro_class); - void mapMacroInCluster2HardMacro(Cluster* cluster); // Coarse Shaping void runCoarseShaping(); From 69941f0f4d1df5389ff8ed34214db6c03a0ade20 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 11:30:39 -0300 Subject: [PATCH 07/11] mpl2: split std cell cluster addition to subtree into its own function Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 40 ++++++++++++++++++++++--------------- src/mpl2/src/hier_rtlmp.h | 5 ++++- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 71967b043bf..9899d36e807 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2283,22 +2283,7 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) std::vector virtual_conn_clusters; if (parent == mixed_leaf) { - std::string std_cell_cluster_name = mixed_leaf->getName(); - Cluster* std_cell_cluster - = new Cluster(cluster_id_, std_cell_cluster_name, logger_); - - std_cell_cluster->copyInstances(*mixed_leaf); - std_cell_cluster->clearLeafMacros(); - std_cell_cluster->setClusterType(StdCellCluster); - - setClusterMetrics(std_cell_cluster); - - cluster_map_[cluster_id_++] = std_cell_cluster; - - // modify the physical hierachy tree - std_cell_cluster->setParent(parent); - parent->addChild(std_cell_cluster); - virtual_conn_clusters.push_back(std_cell_cluster->getId()); + addStdCellClusterToSubTree(parent, mixed_leaf, virtual_conn_clusters); } else { // In this case, we do not to modify the physical hierarchy tree mixed_leaf->clearLeafMacros(); @@ -2478,6 +2463,29 @@ void HierRTLMP::groupSingleMacroClusters( } } +void HierRTLMP::addStdCellClusterToSubTree( + Cluster* parent, + Cluster* mixed_leaf, + std::vector& virtual_conn_clusters) +{ + std::string std_cell_cluster_name = mixed_leaf->getName(); + Cluster* std_cell_cluster + = new Cluster(cluster_id_, std_cell_cluster_name, logger_); + + std_cell_cluster->copyInstances(*mixed_leaf); + std_cell_cluster->clearLeafMacros(); + std_cell_cluster->setClusterType(StdCellCluster); + + setClusterMetrics(std_cell_cluster); + + cluster_map_[cluster_id_++] = std_cell_cluster; + + // modify the physical hierachy tree + std_cell_cluster->setParent(parent); + parent->addChild(std_cell_cluster); + virtual_conn_clusters.push_back(std_cell_cluster->getId()); +} + // Print Physical Hierarchy tree in a DFS manner void HierRTLMP::printPhysicalHierarchyTree(Cluster* parent, int level) { diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index a78582eec6c..f64da882e94 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -204,7 +204,7 @@ class HierRTLMP void updateSubTree(Cluster* parent); void breakLargeFlatCluster(Cluster* parent); void breakMixedLeafCluster(Cluster* root_cluster); - void mapMacroInCluster2HardMacro(Cluster* cluster); + void mapMacroInCluster2HardMacro(Cluster* cluster); void createOneClusterForEachMacro(Cluster* parent, const std::vector& hard_macros, std::vector& macro_clusters); @@ -217,6 +217,9 @@ class HierRTLMP const std::vector& size_class, const std::vector& signature_class, std::vector& macro_class); + void addStdCellClusterToSubTree(Cluster* parent, + Cluster* mixed_leaf, + std::vector& virtual_conn_clusters); // Coarse Shaping void runCoarseShaping(); From 0e1d396cebd8cf6e2b21ae63d15fc9cbb33854c4 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 13:31:05 -0300 Subject: [PATCH 08/11] mpl2: split std cell cluster replacement to its own function Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 20 +++++++++++++------- src/mpl2/src/hier_rtlmp.h | 2 ++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 9899d36e807..a82705aa226 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2285,13 +2285,7 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) if (parent == mixed_leaf) { addStdCellClusterToSubTree(parent, mixed_leaf, virtual_conn_clusters); } else { - // In this case, we do not to modify the physical hierarchy tree - mixed_leaf->clearLeafMacros(); - mixed_leaf->setClusterType(StdCellCluster); - - setClusterMetrics(mixed_leaf); - - virtual_conn_clusters.push_back(mixed_leaf->getId()); + replaceByStdCellCluster(mixed_leaf, virtual_conn_clusters); } // Deal with macro clusters @@ -2486,6 +2480,18 @@ void HierRTLMP::addStdCellClusterToSubTree( virtual_conn_clusters.push_back(std_cell_cluster->getId()); } +// We don't modify the physical hierarchy when spliting by replacement +void HierRTLMP::replaceByStdCellCluster(Cluster* mixed_leaf, + std::vector& virtual_conn_clusters) +{ + mixed_leaf->clearLeafMacros(); + mixed_leaf->setClusterType(StdCellCluster); + + setClusterMetrics(mixed_leaf); + + virtual_conn_clusters.push_back(mixed_leaf->getId()); +} + // Print Physical Hierarchy tree in a DFS manner void HierRTLMP::printPhysicalHierarchyTree(Cluster* parent, int level) { diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index f64da882e94..4461110ff89 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -220,6 +220,8 @@ class HierRTLMP void addStdCellClusterToSubTree(Cluster* parent, Cluster* mixed_leaf, std::vector& virtual_conn_clusters); + void replaceByStdCellCluster(Cluster* mixed_leaf, + std::vector& virtual_conn_clusters); // Coarse Shaping void runCoarseShaping(); From 2eaf8145467d732bceebf8a0c9da398d58e83b59 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 13:43:18 -0300 Subject: [PATCH 09/11] mpl2: create function for splitting mixed leaves individually Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 103 +++++++++++++++++++----------------- src/mpl2/src/hier_rtlmp.h | 1 + 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index a82705aa226..42965e645c5 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2241,73 +2241,78 @@ void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) } } - // We need to update the metrics of the design if necessary - // for each leaf clusters with macros. for (auto& mixed_leaf : mixed_leaves) { - Cluster* parent = mixed_leaf; + breakMixedLeaf(mixed_leaf); + } - // Split by replacement if macro dominated. - if (mixed_leaf->getNumStdCell() * macro_dominated_cluster_threshold_ - < mixed_leaf->getNumMacro()) { - parent = mixed_leaf->getParent(); - } + // Set the inst property back + setInstProperty(root_cluster); +} - mapMacroInCluster2HardMacro(mixed_leaf); +void HierRTLMP::breakMixedLeaf(Cluster* mixed_leaf) +{ + Cluster* parent = mixed_leaf; - std::vector hard_macros = mixed_leaf->getHardMacros(); - std::vector macro_clusters; + // Split by replacement if macro dominated. + if (mixed_leaf->getNumStdCell() * macro_dominated_cluster_threshold_ + < mixed_leaf->getNumMacro()) { + parent = mixed_leaf->getParent(); + } - createOneClusterForEachMacro(parent, hard_macros, macro_clusters); + mapMacroInCluster2HardMacro(mixed_leaf); - std::vector size_class(hard_macros.size(), -1); - classifyMacrosBySize(hard_macros, size_class); + std::vector hard_macros = mixed_leaf->getHardMacros(); + std::vector macro_clusters; - calculateConnection(); + createOneClusterForEachMacro(parent, hard_macros, macro_clusters); - std::vector signature_class(hard_macros.size(), -1); - classifyMacrosByConnSignature(macro_clusters, signature_class); + std::vector size_class(hard_macros.size(), -1); + classifyMacrosBySize(hard_macros, size_class); - std::vector macro_class(hard_macros.size(), -1); - // Use both size and connection signature classifications to group - // single-macro macro clusters into the same cluster. - groupSingleMacroClusters( - macro_clusters, size_class, signature_class, macro_class); + calculateConnection(); - mixed_leaf->clearHardMacros(); + std::vector signature_class(hard_macros.size(), -1); + classifyMacrosByConnSignature(macro_clusters, signature_class); - // IMPORTANT: Restore the structure of physical hierarchical tree. Thus the - // order of leaf clusters will not change the final macro grouping results. - setInstProperty(mixed_leaf); + std::vector macro_class(hard_macros.size(), -1); + // Use both size and connection signature classifications to group + // single-macro macro clusters into the same cluster. + groupSingleMacroClusters( + macro_clusters, size_class, signature_class, macro_class); - // Never use SetInstProperty in the following lines for the reason above! - std::vector virtual_conn_clusters; + mixed_leaf->clearHardMacros(); - if (parent == mixed_leaf) { - addStdCellClusterToSubTree(parent, mixed_leaf, virtual_conn_clusters); - } else { - replaceByStdCellCluster(mixed_leaf, virtual_conn_clusters); - } + // IMPORTANT: Restore the structure of physical hierarchical tree. Thus the + // order of leaf clusters will not change the final macro grouping results. + setInstProperty(mixed_leaf); - // Deal with macro clusters - for (int i = 0; i < macro_class.size(); i++) { - if (macro_class[i] != i) { - continue; // this macro cluster has been merged - } - macro_clusters[i]->setClusterType(HardMacroCluster); - setClusterMetrics(macro_clusters[i]); - virtual_conn_clusters.push_back(mixed_leaf->getId()); + // Never use SetInstProperty in the following lines for the reason above! + std::vector virtual_conn_clusters; + + // Deal with the std cells + if (parent == mixed_leaf) { + addStdCellClusterToSubTree(parent, mixed_leaf, virtual_conn_clusters); + } else { + replaceByStdCellCluster(mixed_leaf, virtual_conn_clusters); + } + + // Deal with the macros + for (int i = 0; i < macro_class.size(); i++) { + if (macro_class[i] != i) { + continue; // this macro cluster has been merged } + macro_clusters[i]->setClusterType(HardMacroCluster); + setClusterMetrics(macro_clusters[i]); + virtual_conn_clusters.push_back(mixed_leaf->getId()); + } - // add virtual connections - for (int i = 0; i < virtual_conn_clusters.size(); i++) { - for (int j = i + 1; j < virtual_conn_clusters.size(); j++) { - parent->addVirtualConnection(virtual_conn_clusters[i], - virtual_conn_clusters[j]); - } + // add virtual connections + for (int i = 0; i < virtual_conn_clusters.size(); i++) { + for (int j = i + 1; j < virtual_conn_clusters.size(); j++) { + parent->addVirtualConnection(virtual_conn_clusters[i], + virtual_conn_clusters[j]); } } - // Set the inst property back - setInstProperty(root_cluster); } // Map all the macros into their HardMacro objects for all the clusters diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 4461110ff89..5497f463bbb 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -204,6 +204,7 @@ class HierRTLMP void updateSubTree(Cluster* parent); void breakLargeFlatCluster(Cluster* parent); void breakMixedLeafCluster(Cluster* root_cluster); + void breakMixedLeaf(Cluster* mixed_leaf); void mapMacroInCluster2HardMacro(Cluster* cluster); void createOneClusterForEachMacro(Cluster* parent, const std::vector& hard_macros, From eae1cde7b32a2d5e564616ecb6991959fbb4d5e6 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 13:59:57 -0300 Subject: [PATCH 10/11] mpl2: split mixed leaves traversal searching + split function into two functions: one for traversal searching and other for splitting Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 62 ++++++++++++++++++++++++------------- src/mpl2/src/hier_rtlmp.h | 6 +++- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 42965e645c5..b339302b167 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -539,7 +539,10 @@ void HierRTLMP::runMultilevelAutoclustering() } else { multilevelAutocluster(root_cluster_); - breakMixedLeafCluster(root_cluster_); + + std::vector> mixed_leaves; + fetchMixedLeaves(root_cluster_, mixed_leaves); + breakMixedLeaves(mixed_leaves); if (graphics_) { graphics_->finishedClustering(root_cluster_); @@ -2211,42 +2214,57 @@ void HierRTLMP::breakLargeFlatCluster(Cluster* parent) breakLargeFlatCluster(cluster_part_1); } -// Break mixed leaves into standard-cell and hard-macro clusters. -// Merge macros based on connection signature and footprint. -// Based on types of designs, we support two types of breaking up: -// Suppose current cluster is A. -// 1) Replace A by A1, A2, A3 -// 2) Type 2: Create a subtree: -// A -> A -// | | | -// A1 A2 A3 -void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) +// Traverse the physical hierarchy tree in a DFS manner (post-order) +void HierRTLMP::fetchMixedLeaves( + Cluster* parent, + std::vector>& mixed_leaves) { - if (root_cluster->getChildren().empty() || root_cluster->getNumMacro() == 0) { + if (parent->getChildren().empty() || parent->getNumMacro() == 0) { return; } - // Traverse the physical hierarchy tree in a DFS manner (post-order) - std::vector mixed_leaves; - for (auto& child : root_cluster->getChildren()) { + std::vector sister_mixed_leaves; + + for (auto& child : parent->getChildren()) { setInstProperty(child); if (child->getNumMacro() > 0) { if (child->getChildren().empty()) { - mixed_leaves.push_back(child); + sister_mixed_leaves.push_back(child); } else { - breakMixedLeafCluster(child); + fetchMixedLeaves(child, mixed_leaves); } } else { child->setClusterType(StdCellCluster); } } - for (auto& mixed_leaf : mixed_leaves) { - breakMixedLeaf(mixed_leaf); - } + // We push the leaves after finishing searching the children so + // that each vector of clusters represents the children of one + // parent. + mixed_leaves.push_back(sister_mixed_leaves); +} - // Set the inst property back - setInstProperty(root_cluster); +// Break mixed leaves into standard-cell and hard-macro clusters. +// Merge macros based on connection signature and footprint. +// Based on types of designs, we support two types of breaking up: +// Suppose current cluster is A. +// 1) Replace A by A1, A2, A3 +// 2) Type 2: Create a subtree: +// A -> A +// | | | +// A1 A2 A3 +void HierRTLMP::breakMixedLeaves( + const std::vector>& mixed_leaves) +{ + for (const std::vector& sister_mixed_leaves : mixed_leaves) { + Cluster* parent = sister_mixed_leaves[0]->getParent(); + + for (Cluster* mixed_leaf : sister_mixed_leaves) { + breakMixedLeaf(mixed_leaf); + } + + setInstProperty(parent); + } } void HierRTLMP::breakMixedLeaf(Cluster* mixed_leaf) diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 5497f463bbb..18cb999d836 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -203,7 +203,11 @@ class HierRTLMP void mergeClusters(std::vector& candidate_clusters); void updateSubTree(Cluster* parent); void breakLargeFlatCluster(Cluster* parent); - void breakMixedLeafCluster(Cluster* root_cluster); + + void fetchMixedLeaves(Cluster* parent, + std::vector>& mixed_leaves); + void breakMixedLeaves(const std::vector>& mixed_leaves); + void breakMixedLeaf(Cluster* mixed_leaf); void mapMacroInCluster2HardMacro(Cluster* cluster); void createOneClusterForEachMacro(Cluster* parent, From 2313edfcd84a3abef491eee061a1161a3748b8ee Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 10 Jan 2024 14:10:07 -0300 Subject: [PATCH 11/11] mpl2: fixing comments Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index b339302b167..97f149db9fe 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2244,15 +2244,6 @@ void HierRTLMP::fetchMixedLeaves( mixed_leaves.push_back(sister_mixed_leaves); } -// Break mixed leaves into standard-cell and hard-macro clusters. -// Merge macros based on connection signature and footprint. -// Based on types of designs, we support two types of breaking up: -// Suppose current cluster is A. -// 1) Replace A by A1, A2, A3 -// 2) Type 2: Create a subtree: -// A -> A -// | | | -// A1 A2 A3 void HierRTLMP::breakMixedLeaves( const std::vector>& mixed_leaves) { @@ -2267,6 +2258,14 @@ void HierRTLMP::breakMixedLeaves( } } +// Break mixed leaf into standard-cell and hard-macro clusters. +// Merge macros based on connection signature and footprint. +// Based on types of designs, we support two types of breaking up: +// 1) Replace cluster A by A1, A2, A3 +// 2) Create a subtree: +// A -> A +// | | | +// A1 A2 A3 void HierRTLMP::breakMixedLeaf(Cluster* mixed_leaf) { Cluster* parent = mixed_leaf; @@ -2294,7 +2293,7 @@ void HierRTLMP::breakMixedLeaf(Cluster* mixed_leaf) std::vector macro_class(hard_macros.size(), -1); // Use both size and connection signature classifications to group - // single-macro macro clusters into the same cluster. + // single-macro macro clusters into the same macro cluster. groupSingleMacroClusters( macro_clusters, size_class, signature_class, macro_class);