22 #if !defined(NO_HMETIS) 
   56                     int count_1 [], 
int count_2 []);
 
   73   if (g_place_rootPartition) 
free(g_place_rootPartition);
 
   75   g_place_rootPartition->
m_level = 0;
 
   76   g_place_rootPartition->
m_area = 0;
 
   79   g_place_rootPartition->
m_done = 
false;
 
   80   g_place_rootPartition->
m_leaf = 
true;
 
   91         g_place_rootPartition->
m_area += area;
 
  151   bool degenerate = 
false;
 
  152   int nonzeroCount = 0;
 
  158   if (p->
m_done) 
return true;
 
  218   if (nonzeroCount == 0)
 
  231   if (nonzeroCount == 0)
 
  236     printf(
"QPART-35 : WARNING: degenerate partition generated\n");
 
  259 #if defined(NO_HMETIS) 
  260   printf(
"QPAR_02 : \t\tERROR: hMetis not available.  Ignoring.\n");
 
  265   int *edgeConnections = NULL;
 
  269   int numConnections = 0;
 
  281   printf(
"QPAR-02 : \t\trepartitioning with hMetis\n");
 
  288       edgeDegree[++numEdges] = numConnections;
 
  298         partitionAssignment[c] = 0;
 
  300         partitionAssignment[c] = 1;
 
  310         partitionAssignment[cell->
m_id] = -1;
 
  321         partitionAssignment[cell->
m_id] = -1;
 
  332         partitionAssignment[c] = 0;
 
  334         partitionAssignment[c] = 1;
 
  344         partitionAssignment[cell->
m_id] = -1;
 
  355         partitionAssignment[cell->
m_id] = -1;
 
  367   options[7] = 12261980; 
 
  370   edgeConnections = (
int *)
malloc(
sizeof(
int)*numConnections);
 
  380                edgeDegree, edgeConnections, NULL,
 
  382                options, partitionAssignment, &afterCuts);
 
  402     if (partitionAssignment[cell->
m_id] == 0) {
 
  419   free(edgeConnections);
 
  422   free(partitionAssignment);
 
  440     int count_1[m_design->nets.length()];
 
  441     memset(count_1, 0, 
sizeof(
int)*m_design->nets.length());
 
  442     int count_2[m_design->nets.length()];
 
  443     memset(count_2, 0, 
sizeof(
int)*m_design->nets.length());
 
  445     FM_cell target[m_design->cells.length()];
 
  452     int before_cuts = 0, current_cuts = 0;
 
  456     double halfArea = parent->
m_area / 2.0;
 
  463     if (parent->vertical) {
 
  469     for(h::list<ConcreteCell *>::iterator it = rootPartition->m_members.begin(); !it; it++) {
 
  470         cell_id = (*it)->getID();
 
  471         if ((*it)->temp_x < initial_cut)
 
  472         target[cell_id].loc = -1;
 
  474         target[cell_id].loc = -2;
 
  475         target[cell_id].cell = *it;
 
  476         target[cell_id].gain = 0;
 
  480     for(h::list<ConcreteCell *>::iterator it = parent->
m_sub1->
m_members.begin(); !it; it++) {
 
  481         cell_id = (*it)->getID();
 
  485         target[cell_id].loc = 1;
 
  490     for(h::list<ConcreteCell *>::iterator it = parent->
m_sub2->
m_members.begin(); !it; it++) {
 
  491         cell_id = (*it)->getID();
 
  495         target[cell_id].loc = 2;
 
  500     for(h::hash_map<ConcreteNet *>::iterator n_it = m_design->nets.begin(); !n_it; n_it++) {
 
  501         for(ConcretePinList::iterator p_it = (net = *n_it)->getPins().begin(); !p_it; p_it++)
 
  502         if (abs(target[(*p_it)->getCell()->getID()].loc) == 1)
 
  503             count_1[net->getID()]++;
 
  504         else if (abs(target[(*p_it)->getCell()->getID()].loc) == 2)
 
  505             count_2[net->getID()]++;
 
  506         else if ((*p_it)->getCell()->temp_x < initial_cut) 
 
  507             count_1[net->getID()]++;
 
  509             count_2[net->getID()]++;
 
  510         if (count_1[net->getID()] > 0 && count_2[net->getID()] > 0) before_cuts++;
 
  519     for(h::list<ConcreteCell *>::iterator it = rootPartition->m_members.begin(); !it; it++) {
 
  520         cell_id = (*it)->getID();
 
  521         if ((*it)->temp_y < initial_cut)
 
  522         target[cell_id].loc = -1;
 
  524         target[cell_id].loc = -2;
 
  525         target[cell_id].cell = *it;
 
  526         target[cell_id].gain = 0;
 
  530     for(h::list<ConcreteCell *>::iterator it = parent->
m_sub1->
m_members.begin(); !it; it++) {
 
  531         cell_id = (*it)->getID();
 
  535         target[cell_id].loc = 1;
 
  540     for(h::list<ConcreteCell *>::iterator it = parent->
m_sub2->
m_members.begin(); !it; it++) {
 
  541         cell_id = (*it)->getID();
 
  545         target[cell_id].loc = 2;
 
  550     for(h::hash_map<ConcreteNet *>::iterator n_it = m_design->nets.begin(); !n_it; n_it++) {
 
  551         for(ConcretePinList::iterator p_it = (net = *n_it)->getPins().begin(); !p_it; p_it++)
 
  552         if (abs(target[(*p_it)->getCell()->getID()].loc) == 1)
 
  553             count_1[net->getID()]++;
 
  554         else if (abs(target[(*p_it)->getCell()->getID()].loc) == 2)
 
  555             count_2[net->getID()]++;
 
  556         else if ((*p_it)->getCell()->temp_y < initial_cut) 
 
  557             count_1[net->getID()]++;
 
  559             count_2[net->getID()]++;
 
  560         if (count_1[net->getID()] > 0 && count_2[net->getID()] > 0) before_cuts++;
 
  565     for(
long id=0; 
id < m_design->cells.length(); 
id++)
 
  566     if (target[
id].
loc > 0) {
 
  571         for(ConcretePinMap::iterator p_it = target[
id].
cell->getPins().begin(); !p_it; p_it++)
 
  572         if ((*p_it)->isAttached()) {
 
  573             int n_id = (*p_it)->getNet()->getID();
 
  574             if (target[
id].
loc == 1 && count_1[n_id] == 1) target[id].gain++;
 
  575             if (target[
id].
loc == 1 && count_2[n_id] == 0) target[id].gain--;
 
  576             if (target[
id].
loc == 2 && count_1[n_id] == 0) target[id].gain--;
 
  577             if (target[
id].
loc == 2 && count_2[n_id] == 1) target[id].gain++;
 
  580         assert(target[
id].
cell->getPins().length() >= abs(target[
id].
gain));
 
  584         max_gain = 
max(max_gain, bin_num);
 
  587         target[id].next = bin[bin_num];
 
  589         if (bin[bin_num] != 0)
 
  590         bin[bin_num]->prev = &target[id];
 
  591         bin[bin_num] = &target[id];
 
  595     current_cuts = before_cuts;
 
  611         max_gain = 
max(max_gain, bin_num);
 
  613         locked = current->
next;
 
  617         if (bin[bin_num] != 0)
 
  618         bin[bin_num]->
prev = current;
 
  619         current->
next = bin[bin_num];
 
  620         bin[bin_num] = current;
 
  628     while(bin[max_gain] == 0 && max_gain > 0) max_gain--;
 
  634         FM_cell *current = bin[bin_num];
 
  637         while (bin_num > 0 && (current == 0 || 
 
  638         (current->
loc==1 && current->
cell->getArea()+parent->
m_sub2->
m_area > halfArea+areaFlexibility) ||
 
  639         (current->
loc==2 && current->
cell->getArea()+parent->
m_sub1->
m_area > halfArea+areaFlexibility))) {
 
  641         if (current == 0) current = bin[--bin_num]; 
else current = current->
next;       
 
  651         if (current->
loc == 1) {
 
  657         for(ConcretePinMap::iterator p_it = current->
cell->getPins().begin(); 
 
  660             if (!(*p_it)->isAttached()) 
 
  662             net = (*p_it)->getNet();
 
  664             count_1[net->getID()]--;
 
  665             count_2[net->getID()]++;
 
  670             if (count_1[net->getID()] == 0) { current_cuts--; 
FM_updateGains(net, 2, -1, target, bin, count_1, count_2); }
 
  671             if (count_2[net->getID()] == 1) { current_cuts++; 
FM_updateGains(net, 1, -1, target, bin, count_1, count_2); }
 
  682         for(ConcretePinMap::iterator p_it = current->
cell->getPins().begin(); 
 
  685             if (!(*p_it)->isAttached()) 
 
  687             net = (*p_it)->getNet();
 
  688             count_2[net->getID()]--;
 
  689             count_1[net->getID()]++;
 
  693             if (count_2[net->getID()] == 0) { current_cuts--; 
FM_updateGains(net, 2, -1, target, bin, count_1, count_2); }
 
  694             if (count_1[net->getID()] == 1) { current_cuts++; 
FM_updateGains(net, 1, -1, target, bin, count_1, count_2); }
 
  718         if (bin[bin_num] == current)
 
  719         bin[bin_num] = current->
next;
 
  720         if (current->
prev != 0)
 
  722         if (current->
next != 0)
 
  742         locked->
prev = current;
 
  749         while(bin[max_gain] == 0 && max_gain > 0) max_gain--;
 
  756     cout << 
"FIDM-20 : \tbalance before " << parent->
m_sub1->
m_members.length() << 
"/" 
  762     for(h::list<ConcreteCell *>::iterator it = parent->
m_members.begin(); !it; it++) {
 
  763     if (target[(*it)->getID()].loc == 1 || target[(*it)->getID()].loc == -1) {
 
  776     cout << 
"FIDM-21 : \tloc: " << initial_cut <<  
" targetting: " << targets*100/parent->
m_members.length() << 
"%" << endl;
 
  777     cout << 
"FIDM-22 : \tstarting cuts= " << before_cuts << 
" final cuts= " << current_cuts << endl;
 
  786                     int count_1 [], 
int count_2 []) {
 
  788     for(ConcretePinList::iterator it = net->getPins().begin(); !it; it++) {
 
  789     FM_cell *current = &(target[(*it)->getCell()->getID()]);
 
  792     int old_gain = current->
gain;
 
  796     for(ConcretePinMap::iterator p_it = current->
cell->getPins().begin(); !p_it; p_it++)
 
  797         if ((*p_it)->isAttached()) {
 
  798         int n_id = (*p_it)->getNet()->getID();
 
  799         if (current->
loc == 1 && count_1[n_id] == 1) current->
gain++;
 
  800         if (current->
loc == 1 && count_2[n_id] == 0) current->
gain--;
 
  801         if (current->
loc == 2 && count_1[n_id] == 0) current->
gain--;
 
  802         if (current->
loc == 2 && count_2[n_id] == 1) current->
gain++;
 
  808         if (bin[bin_num] == current)
 
  809         bin[bin_num] = current->
next;
 
  810         if (current->
prev != 0)
 
  812         if (current->
next != 0)
 
  817         current->
next = bin[bin_num];
 
  818         if (bin[bin_num] != 0)
 
  819         bin[bin_num]->
prev = current;
 
  820         bin[bin_num] = current;
 
  835   float halfArea, area;
 
  847   halfArea = parent->
m_area*0.5;
 
  881   int current_cuts = 0;
 
  882   int minimum_cuts = INT_MAX;
 
  884   double currentArea = 0, halfArea = parent->
m_area * 0.5;
 
  886   double newLine, oldLine = -DBL_MAX;
 
  888   for(ConcreteNetList::iterator n_it = m_design->nets.begin(); !n_it; n_it++)
 
  890   for(h::list<ConcreteCell *>::iterator i = parent->
m_members.begin();
 
  893     for(ConcretePinMap::iterator j = (*i)->getPins().begin();
 
  896       if((*j)->isAttached()) {
 
  897     (*j)->getNet()->m_mark = 1;
 
  902   if (parent->vertical) {
 
  904     int all1 = 0, all2 = 0;
 
  905     h::list<ConcreteCell *>::iterator 
local = parent->
m_members.begin();
 
  906     for(; !local.isDone(); local++) {
 
  907       currentArea += (*local)->getArea();
 
  908       if (currentArea < halfArea-areaFlexibility)
 
  910       if (currentArea > halfArea+areaFlexibility)
 
  912       newLine = (*local)->temp_x;
 
  919       while(all2 < 
g_place_numNets && allNetsR2[all2]->getBoundingBox().right() <= newLine) {
 
  920     if(allNetsR2[all2]->m_mark) {
 
  925       if (current_cuts < minimum_cuts) {
 
  926     minimum_cuts = current_cuts;
 
  927     minimum_location = *
local;
 
  934     int all1 = 0, all2 = 0;
 
  935     h::list<ConcreteCell *>::iterator 
local = parent->
m_members.begin();
 
  936     for(; !local.isDone(); local++) {
 
  937       currentArea += (*local)->getArea();
 
  938       if (currentArea < halfArea-areaFlexibility)
 
  940       if (currentArea > halfArea+areaFlexibility)
 
  942       newLine = (*local)->temp_y;
 
  955       if (current_cuts < minimum_cuts) {
 
  956     minimum_cuts = current_cuts;
 
  957     minimum_location = *
local;
 
  962   if (minimum_location == NULL) {
 
  965   h::list<ConcreteCell *>::iterator it = parent->
m_members.begin();
 
  968   for(; *it != minimum_location; it++) {
 
 1056   int numNewCells1 = 0, numNewCells2 = 0;
 
 1073     for(c=0; c<numNewCells; c++)
 
 1074       if (newCells[c]->m_x < cut_loc)
 
 1075         newCells1[numNewCells1++] = newCells[c];
 
 1077         newCells2[numNewCells2++] = newCells[c];
 
 1080     for(c=0; c<numNewCells; c++)
 
 1081       if (newCells[c]->m_y < cut_loc)
 
 1082         newCells1[numNewCells1++] = newCells[c];
 
 1084         newCells2[numNewCells2++] = newCells[c];    
 
 1105   int numNewCells = 0;
 
 1109   assert(g_place_rootPartition);
 
 1118   while(!allCells[c++]);
 
 1119   while(!g_place_rootPartition->
m_members[c2++]);
 
 1122     while(c2 < g_place_rootPartition->m_numMembers &&
 
 1123           allCells[c]->m_id > g_place_rootPartition->
m_members[c2]->
m_id) c2++;
 
 1124     while(c < g_place_numCells && 
 
 1128       newCells[numNewCells++] = allCells[c];
 
 1133   printf(
"QPRT-50 : \tincremental partitioning with %d new cells\n", numNewCells);
 
void partitionEqualArea(Partition *parent)
Splits a partition into two halves of equal area. 
int cellSortByX(const void *a, const void *b)
Sorts cells by either position coordinate. 
struct Partition * m_sub1
bool refinePartition(Partition *p)
Splits any large leaves within a partition. 
ABC_NAMESPACE_IMPL_START int g_place_numPartitions
int cellSortByY(const void *a, const void *b)
static ABC_NAMESPACE_HEADER_START void HMETIS_PartRecursive(int nvtxs, int nhedges, int *vwgts, int *eptr, int *eind, int *hewgts, int nparts, int nbfactor, int *options, int *part, int *edgecnt)
ConcreteNet ** g_place_concreteNets
int netSortByR(const void *a, const void *b)
void partitionScanlineMincut(Partition *parent)
Scans the cells within a partition from left to right and chooses the min-cut. 
#define MAX_PARTITION_NONSYMMETRY
void resizePartition(Partition *p)
Recomputes the bounding boxes of the child partitions based on their relative areas. 
int netSortByB(const void *a, const void *b)
ConcreteCell ** g_place_concreteCells
void reallocPartitions()
Reallocates the partitions based on placement information. 
struct Partition * m_sub2
ABC_NAMESPACE_IMPL_START Partition * g_place_rootPartition
float getCellArea(const ConcreteCell *cell)
void reallocPartition(Partition *p)
Reallocates a partition and all of its children. 
#define REPARTITION_HMETIS
void incrementalSubpartition(Partition *p, ConcreteCell *newCells[], const int numNewCells)
Adds new cells to an existing partition. Partition sizes/locations are unchanged. ...
void presortNets()
Sorts nets by corner positions. 
int netSortByT(const void *a, const void *b)
static int partition(int *a, int n, int m)
#define ABC_NAMESPACE_IMPL_END
int cellSortByID(const void *a, const void *b)
void FM_updateGains(ConcreteNet *net, int partition, int inc, FM_cell target[], FM_cell *bin[], int count_1[], int count_2[])
void repartitionHMetis(Partition *parent)
Repartitions the two subpartitions using the hMetis min-cut library. 
void repartitionFM(Partition *parent)
Fiduccia-Matheyses mincut partitioning algorithm. 
ConcreteCell ** m_members
#define ABC_NAMESPACE_IMPL_START
#define REPARTITION_TARGET_FRACTION
#define LARGEST_FINAL_SIZE
void incrementalPartition()
Adds new cells to an existing partition. Partition sizes/locations are unchanged. ...
#define REPARTITION_LEVEL_DEPTH
ABC_NAMESPACE_IMPL_START int g_place_numCells
void initPartitioning()
Initializes data structures necessary for partitioning. 
bool refinePartitions()
Splits large leaf partitions. 
#define PARTITION_AREA_ONLY
int netSortByL(const void *a, const void *b)
Sorts nets by position of one of its corners.