abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
place_gordian.h File Reference
#include "place_base.h"
#include "place_qpsolver.h"

Go to the source code of this file.

Data Structures

struct  Partition
 

Macros

#define ABC__phys__place__place_gordian_h
 
#define CLIQUE_PENALTY   1.0
 
#define IGNORE_NETSIZE   20
 
#define LARGEST_FINAL_SIZE   20
 
#define PARTITION_AREA_ONLY   true
 
#define REALLOCATE_PARTITIONS   false
 
#define FINAL_REALLOCATE_PARTITIONS   false
 
#define IGNORE_COG   false
 
#define MAX_PARTITION_NONSYMMETRY   0.30
 
#define REPARTITION_LEVEL_DEPTH   4
 
#define REPARTITION_TARGET_FRACTION   0.15
 
#define REPARTITION_FM   false
 
#define REPARTITION_HMETIS   true
 
#define FM_MAX_BIN   10
 
#define FM_MAX_PASSES   10
 

Typedefs

typedef struct Partition Partition
 

Functions

void initPartitioning ()
 Initializes data structures necessary for partitioning. More...
 
void incrementalPartition ()
 Adds new cells to an existing partition. Partition sizes/locations are unchanged. More...
 
bool refinePartitions ()
 Splits large leaf partitions. More...
 
void reallocPartitions ()
 Reallocates the partitions based on placement information. More...
 
bool refinePartition (Partition *p)
 Splits any large leaves within a partition. More...
 
void resizePartition (Partition *p)
 Recomputes the bounding boxes of the child partitions based on their relative areas. More...
 
void reallocPartition (Partition *p)
 Reallocates a partition and all of its children. More...
 
void repartitionHMetis (Partition *parent)
 Repartitions the two subpartitions using the hMetis min-cut library. More...
 
void repartitionFM (Partition *parent)
 Fiduccia-Matheyses mincut partitioning algorithm. More...
 
void partitionScanlineMincut (Partition *parent)
 Scans the cells within a partition from left to right and chooses the min-cut. More...
 
void partitionEqualArea (Partition *parent)
 Splits a partition into two halves of equal area. More...
 
void sanitizePlacement ()
 Moves any cells that are outside of the core bounds to the nearest location within. More...
 
void constructQuadraticProblem ()
 Constructs the matrices necessary to do analytical placement. More...
 
void solveQuadraticProblem (bool useCOG)
 Calls quadratic solver. More...
 

Variables

int g_place_numPartitions
 
qps_problem_tg_place_qpProb
 
Partitiong_place_rootPartition
 

Macro Definition Documentation

#define ABC__phys__place__place_gordian_h

Definition at line 11 of file place_gordian.h.

#define CLIQUE_PENALTY   1.0

Definition at line 21 of file place_gordian.h.

#define FINAL_REALLOCATE_PARTITIONS   false

Definition at line 28 of file place_gordian.h.

#define FM_MAX_BIN   10

Definition at line 39 of file place_gordian.h.

#define FM_MAX_PASSES   10

Definition at line 40 of file place_gordian.h.

#define IGNORE_COG   false

Definition at line 29 of file place_gordian.h.

#define IGNORE_NETSIZE   20

Definition at line 22 of file place_gordian.h.

#define LARGEST_FINAL_SIZE   20

Definition at line 25 of file place_gordian.h.

#define MAX_PARTITION_NONSYMMETRY   0.30

Definition at line 30 of file place_gordian.h.

#define PARTITION_AREA_ONLY   true

Definition at line 26 of file place_gordian.h.

#define REALLOCATE_PARTITIONS   false

Definition at line 27 of file place_gordian.h.

#define REPARTITION_FM   false

Definition at line 35 of file place_gordian.h.

#define REPARTITION_HMETIS   true

Definition at line 36 of file place_gordian.h.

#define REPARTITION_LEVEL_DEPTH   4

Definition at line 33 of file place_gordian.h.

#define REPARTITION_TARGET_FRACTION   0.15

Definition at line 34 of file place_gordian.h.

Typedef Documentation

typedef struct Partition Partition

Function Documentation

void constructQuadraticProblem ( )

Constructs the matrices necessary to do analytical placement.

Definition at line 53 of file place_genqp.c.

53  {
54  int maxConnections = 1;
55  int ignoreNum = 0;
56  int n,t,c,c2,p;
57  ConcreteCell *cell;
58  ConcreteNet *net;
59  int *cell_numTerms = calloc(g_place_numCells, sizeof(int));
60  ConcreteNet ***cell_terms = calloc(g_place_numCells, sizeof(ConcreteNet**));
61  bool incremental = false;
62  int nextIndex = 1;
63  int *seen = calloc(g_place_numCells, sizeof(int));
64  float weight;
65  int last_index;
66 
67  // create problem object
68  if (!g_place_qpProb) {
70  g_place_qpProb->area = NULL;
71  g_place_qpProb->x = NULL;
72  g_place_qpProb->y = NULL;
73  g_place_qpProb->fixed = NULL;
74  g_place_qpProb->connect = NULL;
76  }
77 
78  // count the maximum possible number of non-sparse entries
79  for(n=0; n<g_place_numNets; n++) if (g_place_concreteNets[n]) {
81  if (net->m_numTerms > IGNORE_NETSIZE) {
82  ignoreNum++;
83  }
84  else {
85  maxConnections += net->m_numTerms*(net->m_numTerms-1);
86  for(t=0; t<net->m_numTerms; t++) {
87  c = net->m_terms[t]->m_id;
88  p = ++cell_numTerms[c];
89  cell_terms[c] = (ConcreteNet**)realloc(cell_terms[c], p*sizeof(ConcreteNet*));
90  cell_terms[c][p-1] = net;
91  }
92  }
93  }
94  if(ignoreNum) {
95  printf("QMAN-10 : \t\t%d large nets ignored\n", ignoreNum);
96  }
97 
98  // initialize the data structures
100  maxConnections += g_place_numCells + 1;
101 
103  sizeof(float)*g_place_numCells);// "area" matrix
105  sizeof(float)*maxConnections); // "weight" matrix
107  sizeof(int)*maxConnections); // "connectivity" matrix
109  sizeof(int)*g_place_numCells); // "fixed" matrix
110 
111  // initialize or keep preexisting locations
112  if (g_place_qpProb->x != NULL && g_place_qpProb->y != NULL) {
113  printf("QMAN-10 :\tperforming incremental placement\n");
114  incremental = true;
115  }
116  g_place_qpProb->x = (float*)realloc(g_place_qpProb->x, sizeof(float)*g_place_numCells);
117  g_place_qpProb->y = (float*)realloc(g_place_qpProb->y, sizeof(float)*g_place_numCells);
118 
119  // form a row for each cell
120  // build data
121  for(c = 0; c < g_place_numCells; c++) if (g_place_concreteCells[c]) {
122  cell = g_place_concreteCells[c];
123 
124  // fill in the characteristics for this cell
125  g_place_qpProb->area[c] = getCellArea(cell);
126  if (cell->m_fixed || cell->m_parent->m_pad) {
127  g_place_qpProb->x[c] = cell->m_x;
128  g_place_qpProb->y[c] = cell->m_y;
129  g_place_qpProb->fixed[c] = 1;
130  } else {
131  if (!incremental) {
134  }
135  g_place_qpProb->fixed[c] = 0;
136  }
137 
138  // update connectivity matrices
139  last_index = nextIndex;
140  for(n=0; n<cell_numTerms[c]; n++) {
141  net = cell_terms[c][n];
142  weight = net->m_weight / splitPenalty(net->m_numTerms);
143  for(t=0; t<net->m_numTerms; t++) {
144  c2 = net->m_terms[t]->m_id;
145  if (c2 == c) continue;
146  if (seen[c2] < last_index) {
147  // not seen
148  g_place_qpProb->connect[nextIndex-1] = c2;
149  g_place_qpProb->edge_weight[nextIndex-1] = weight;
150  seen[c2] = nextIndex;
151  nextIndex++;
152  } else {
153  // seen
154  g_place_qpProb->edge_weight[seen[c2]-1] += weight;
155  }
156  }
157  }
158  g_place_qpProb->connect[nextIndex-1] = -1;
159  g_place_qpProb->edge_weight[nextIndex-1] = -1.0;
160  nextIndex++;
161  } else {
162  // fill in dummy values for connectivity matrices
163  g_place_qpProb->connect[nextIndex-1] = -1;
164  g_place_qpProb->edge_weight[nextIndex-1] = -1.0;
165  nextIndex++;
166  }
167 
168  free(cell_numTerms);
169  free(cell_terms);
170  free(seen);
171 }
char * malloc()
AbstractCell * m_parent
Definition: place_base.h:57
VOID_HACK free()
ConcreteNet ** g_place_concreteNets
Definition: place_base.c:35
float h
Definition: place_base.h:36
float x
Definition: place_base.h:35
static Llb_Mgr_t * p
Definition: llb3Image.c:950
float splitPenalty(int pins)
Returns a weight for all of the edges in the clique for a multipin net.
Definition: place_genqp.c:37
float m_weight
Definition: place_base.h:74
float y
Definition: place_base.h:35
ConcreteCell ** g_place_concreteCells
Definition: place_base.c:33
char * realloc()
qps_float_t * y
float getCellArea(const ConcreteCell *cell)
Definition: place_base.c:99
bool m_fixed
Definition: place_base.h:59
qps_float_t * area
ConcreteCell ** m_terms
Definition: place_base.h:72
qps_float_t * x
#define IGNORE_NETSIZE
Definition: place_gordian.h:22
qps_float_t * edge_weight
int m_numTerms
Definition: place_base.h:71
Rect g_place_coreBounds
Definition: place_base.c:30
float w
Definition: place_base.h:36
int g_place_numNets
Definition: place_base.c:27
ABC_NAMESPACE_IMPL_START qps_problem_t * g_place_qpProb
Definition: place_genqp.c:28
char * calloc()
ABC_NAMESPACE_IMPL_START int g_place_numCells
Definition: place_base.c:26
void incrementalPartition ( )

Adds new cells to an existing partition. Partition sizes/locations are unchanged.

The function recurses, adding new cells to appropriate subpartitions.

Definition at line 1103 of file place_partition.c.

1103  {
1104  int c = 0, c2 = 0;
1105  int numNewCells = 0;
1106  ConcreteCell **allCells = (ConcreteCell **)malloc(sizeof(ConcreteCell*)*g_place_numCells),
1107  **newCells = (ConcreteCell **)malloc(sizeof(ConcreteCell*)*g_place_numCells);
1108 
1110 
1111  // update cell list of root partition
1113  qsort(allCells, g_place_numCells, sizeof(ConcreteCell*), cellSortByID);
1115  sizeof(ConcreteCell*), cellSortByID);
1116 
1117  // scan sorted lists and collect cells not in partitions
1118  while(!allCells[c++]);
1119  while(!g_place_rootPartition->m_members[c2++]);
1120 
1121  for(; c<g_place_numCells; c++, 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 &&
1126  allCells[c]->m_id < g_place_rootPartition->m_members[c2]->m_id)) {
1127  // a new cell!
1128  newCells[numNewCells++] = allCells[c];
1129  c++;
1130  }
1131  }
1132 
1133  printf("QPRT-50 : \tincremental partitioning with %d new cells\n", numNewCells);
1134  if (numNewCells>0) incrementalSubpartition(g_place_rootPartition, newCells, numNewCells);
1135 
1136  free(allCells);
1137  free(newCells);
1138 }
char * malloc()
VOID_HACK free()
char * memcpy()
ConcreteCell ** g_place_concreteCells
Definition: place_base.c:33
ABC_NAMESPACE_IMPL_START Partition * g_place_rootPartition
void incrementalSubpartition(Partition *p, ConcreteCell *newCells[], const int numNewCells)
Adds new cells to an existing partition. Partition sizes/locations are unchanged. ...
int cellSortByID(const void *a, const void *b)
Definition: place_base.c:338
ConcreteCell ** m_members
Definition: place_gordian.h:49
int m_numMembers
Definition: place_gordian.h:48
#define assert(ex)
Definition: util_old.h:213
ABC_NAMESPACE_IMPL_START int g_place_numCells
Definition: place_base.c:26
void initPartitioning ( )

Initializes data structures necessary for partitioning.

Creates a valid g_place_rootPartition.

Definition at line 67 of file place_partition.c.

67  {
68  int i;
69  float area;
70 
71  // create root partition
81 
82  // add all of the cells to this partition
85  for (i=0; i<g_place_numCells; i++)
86  if (g_place_concreteCells[i]) {
87  if (!g_place_concreteCells[i]->m_fixed) {
92  }
93  }
94 }
char * malloc()
ABC_NAMESPACE_IMPL_START int g_place_numPartitions
Definition: place_gordian.c:28
VOID_HACK free()
ConcreteCell ** g_place_concreteCells
Definition: place_base.c:33
ABC_NAMESPACE_IMPL_START Partition * g_place_rootPartition
float getCellArea(const ConcreteCell *cell)
Definition: place_base.c:99
bool m_vertical
Definition: place_gordian.h:51
ConcreteCell ** m_members
Definition: place_gordian.h:49
Rect g_place_coreBounds
Definition: place_base.c:30
Rect m_bounds
Definition: place_gordian.h:50
int m_numMembers
Definition: place_gordian.h:48
ABC_NAMESPACE_IMPL_START int g_place_numCells
Definition: place_base.c:26
float m_area
Definition: place_gordian.h:54
void partitionEqualArea ( Partition parent)

Splits a partition into two halves of equal area.

Definition at line 834 of file place_partition.c.

834  {
835  float halfArea, area;
836  int i=0;
837 
838  // which way to sort?
839  if (parent->m_vertical)
840  // sort by X position
841  qsort(parent->m_members, parent->m_numMembers, sizeof(ConcreteCell*), cellSortByX);
842  else
843  // sort by Y position
844  qsort(parent->m_members, parent->m_numMembers, sizeof(ConcreteCell*), cellSortByY);
845 
846  // split the list
847  halfArea = parent->m_area*0.5;
848  parent->m_sub1->m_area = 0.0;
849  parent->m_sub1->m_numMembers = 0;
850  parent->m_sub1->m_members = (ConcreteCell**)realloc(parent->m_sub1->m_members,
851  sizeof(ConcreteCell*)*parent->m_numMembers);
852  parent->m_sub2->m_area = 0.0;
853  parent->m_sub2->m_numMembers = 0;
854  parent->m_sub2->m_members = (ConcreteCell**)realloc(parent->m_sub2->m_members,
855  sizeof(ConcreteCell*)*parent->m_numMembers);
856 
857  for(; parent->m_sub1->m_area < halfArea; i++)
858  if (parent->m_members[i]) {
859  area = getCellArea(parent->m_members[i]);
860  parent->m_sub1->m_members[parent->m_sub1->m_numMembers++] = parent->m_members[i];
861  parent->m_sub1->m_area += area;
862  }
863  for(; i<parent->m_numMembers; i++)
864  if (parent->m_members[i]) {
865  area = getCellArea(parent->m_members[i]);
866  parent->m_sub2->m_members[parent->m_sub2->m_numMembers++] = parent->m_members[i];
867  parent->m_sub2->m_area += area;
868  }
869 
870 }
int cellSortByX(const void *a, const void *b)
Sorts cells by either position coordinate.
Definition: place_base.c:314
struct Partition * m_sub1
Definition: place_gordian.h:56
int cellSortByY(const void *a, const void *b)
Definition: place_base.c:326
char * realloc()
struct Partition * m_sub2
Definition: place_gordian.h:56
float getCellArea(const ConcreteCell *cell)
Definition: place_base.c:99
bool m_vertical
Definition: place_gordian.h:51
ConcreteCell ** m_members
Definition: place_gordian.h:49
int m_numMembers
Definition: place_gordian.h:48
float m_area
Definition: place_gordian.h:54
void partitionScanlineMincut ( Partition parent)

Scans the cells within a partition from left to right and chooses the min-cut.

Definition at line 879 of file place_partition.c.

879  {
880 #if 0
881  int current_cuts = 0;
882  int minimum_cuts = INT_MAX;
883  ConcreteCell *minimum_location = NULL;
884  double currentArea = 0, halfArea = parent->m_area * 0.5;
885  double areaFlexibility = parent->m_area * MAX_PARTITION_NONSYMMETRY;
886  double newLine, oldLine = -DBL_MAX;
887 
888  for(ConcreteNetList::iterator n_it = m_design->nets.begin(); !n_it; n_it++)
889  (*n_it)->m_mark = 0;
890  for(h::list<ConcreteCell *>::iterator i = parent->m_members.begin();
891  !i.isDone(); i++) {
892  assert(*i);
893  for(ConcretePinMap::iterator j = (*i)->getPins().begin();
894  !j.isDone(); j++) {
895  assert(*j);
896  if((*j)->isAttached()) {
897  (*j)->getNet()->m_mark = 1;
898  }
899  }
900  }
901 
902  if (parent->vertical) {
903  parent->m_members.sort(sortByX);
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)
909  continue;
910  if (currentArea > halfArea+areaFlexibility)
911  break;
912  newLine = (*local)->temp_x;
913  while(all1 < g_place_numNets && allNetsL2[all1]->getBoundingBox().left() <= newLine) {
914  if(allNetsL2[all1]->m_mark) {
915  current_cuts++;
916  }
917  all1++;
918  }
919  while(all2 < g_place_numNets && allNetsR2[all2]->getBoundingBox().right() <= newLine) {
920  if(allNetsR2[all2]->m_mark) {
921  current_cuts--;
922  }
923  all2++;
924  }
925  if (current_cuts < minimum_cuts) {
926  minimum_cuts = current_cuts;
927  minimum_location = *local;
928  }
929  oldLine = newLine;
930  }
931  }
932  else {
933  parent->m_members.sort(sortByY);
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)
939  continue;
940  if (currentArea > halfArea+areaFlexibility)
941  break;
942  newLine = (*local)->temp_y;
943  while(all1 < g_place_numNets && allNetsB2[all1]->getBoundingBox().top() <= newLine) {
944  if(allNetsB2[all1]->m_mark) {
945  current_cuts++;
946  }
947  all1++;
948  }
949  while(all2 < g_place_numNets && allNetsT2[all2]->getBoundingBox().bottom() <= newLine) {
950  if(allNetsT2[all2]->m_mark) {
951  current_cuts--;
952  }
953  all2++;
954  }
955  if (current_cuts < minimum_cuts) {
956  minimum_cuts = current_cuts;
957  minimum_location = *local;
958  }
959  oldLine = newLine;
960  }
961  }
962  if (minimum_location == NULL) {
963  return partitionEqualArea(parent);
964  }
965  h::list<ConcreteCell *>::iterator it = parent->m_members.begin();
966  parent->m_sub1->m_members.clear();
967  parent->m_sub1->m_area = 0;
968  for(; *it != minimum_location; it++) {
969  parent->m_sub1->m_members.push_front(*it);
970  parent->m_sub1->m_area += (*it)->getArea();
971  }
972  parent->m_sub2->m_members.clear();
973  parent->m_sub2->m_area = 0;
974  for(; !it; it++) {
975  parent->m_sub2->m_members.push_front(*it);
976  parent->m_sub2->m_area += (*it)->getArea();
977  }
978 #endif
979 }
void partitionEqualArea(Partition *parent)
Splits a partition into two halves of equal area.
struct Partition * m_sub1
Definition: place_gordian.h:56
ConcreteNet ** allNetsT2
#define MAX_PARTITION_NONSYMMETRY
Definition: place_gordian.h:30
ConcreteNet ** allNetsR2
struct Partition * m_sub2
Definition: place_gordian.h:56
ConcreteNet ** allNetsL2
ConcreteNet ** allNetsB2
#define local
Definition: adler32.c:17
ConcreteCell ** m_members
Definition: place_gordian.h:49
int g_place_numNets
Definition: place_base.c:27
#define assert(ex)
Definition: util_old.h:213
float m_area
Definition: place_gordian.h:54
void reallocPartition ( Partition p)

Reallocates a partition and all of its children.

Definition at line 988 of file place_partition.c.

988  {
989 
990  if (p->m_leaf) {
991  return;
992  }
993 
994  // --- INITIAL PARTITION
995 
998  else
1000 
1001  resizePartition(p);
1002 
1003  // --- PARTITION IMPROVEMENT
1004  if (p->m_level < REPARTITION_LEVEL_DEPTH) {
1005  if (REPARTITION_HMETIS)
1006  repartitionHMetis(p);
1007 
1008  resizePartition(p);
1009  }
1010 
1013 }
void partitionEqualArea(Partition *parent)
Splits a partition into two halves of equal area.
struct Partition * m_sub1
Definition: place_gordian.h:56
void partitionScanlineMincut(Partition *parent)
Scans the cells within a partition from left to right and chooses the min-cut.
void resizePartition(Partition *p)
Recomputes the bounding boxes of the child partitions based on their relative areas.
struct Partition * m_sub2
Definition: place_gordian.h:56
void reallocPartition(Partition *p)
Reallocates a partition and all of its children.
#define REPARTITION_HMETIS
Definition: place_gordian.h:36
void repartitionHMetis(Partition *parent)
Repartitions the two subpartitions using the hMetis min-cut library.
#define REPARTITION_LEVEL_DEPTH
Definition: place_gordian.h:33
#define PARTITION_AREA_ONLY
Definition: place_gordian.h:26
void reallocPartitions ( )

Reallocates the partitions based on placement information.

Definition at line 138 of file place_partition.c.

138  {
139 
141 }
ABC_NAMESPACE_IMPL_START Partition * g_place_rootPartition
void reallocPartition(Partition *p)
Reallocates a partition and all of its children.
bool refinePartition ( Partition p)

Splits any large leaves within a partition.

Definition at line 150 of file place_partition.c.

150  {
151  bool degenerate = false;
152  int nonzeroCount = 0;
153  int i;
154 
155  assert(p);
156 
157  // is this partition completed?
158  if (p->m_done) return true;
159 
160  // is this partition a non-leaf node?
161  if (!p->m_leaf) {
162  p->m_done = refinePartition(p->m_sub1);
163  p->m_done &= refinePartition(p->m_sub2);
164  return p->m_done;
165  }
166 
167  // leaf...
168  // create two new subpartitions
170  p->m_sub1 = malloc(sizeof(Partition));
171  p->m_sub1->m_level = p->m_level+1;
172  p->m_sub1->m_leaf = true;
173  p->m_sub1->m_done = false;
174  p->m_sub1->m_area = 0;
175  p->m_sub1->m_vertical = !p->m_vertical;
176  p->m_sub1->m_numMembers = 0;
177  p->m_sub1->m_members = NULL;
178  p->m_sub2 = malloc(sizeof(Partition));
179  p->m_sub2->m_level = p->m_level+1;
180  p->m_sub2->m_leaf = true;
181  p->m_sub2->m_done = false;
182  p->m_sub2->m_area = 0;
183  p->m_sub2->m_vertical = !p->m_vertical;
184  p->m_sub2->m_numMembers = 0;
185  p->m_sub2->m_members = NULL;
186  p->m_leaf = false;
187 
188  // --- INITIAL PARTITION
189 
192  else
194 
195  resizePartition(p);
196 
197  // --- PARTITION IMPROVEMENT
198 
199  if (p->m_level < REPARTITION_LEVEL_DEPTH) {
200  if (REPARTITION_FM)
201  repartitionFM(p);
202  else if (REPARTITION_HMETIS)
204  }
205 
206  resizePartition(p);
207 
208  // fix imbalances due to zero-area cells
209  for(i=0; i<p->m_sub1->m_numMembers; i++)
210  if (p->m_sub1->m_members[i])
211  if (getCellArea(p->m_sub1->m_members[i]) > 0) {
212  nonzeroCount++;
213  }
214 
215  // is this leaf now done?
216  if (nonzeroCount <= LARGEST_FINAL_SIZE)
217  p->m_sub1->m_done = true;
218  if (nonzeroCount == 0)
219  degenerate = true;
220 
221  nonzeroCount = 0;
222  for(i=0; i<p->m_sub2->m_numMembers; i++)
223  if (p->m_sub2->m_members[i])
224  if (getCellArea(p->m_sub2->m_members[i]) > 0) {
225  nonzeroCount++;
226  }
227 
228  // is this leaf now done?
229  if (nonzeroCount <= LARGEST_FINAL_SIZE)
230  p->m_sub2->m_done = true;
231  if (nonzeroCount == 0)
232  degenerate = true;
233 
234  // have we found a degenerate partitioning?
235  if (degenerate) {
236  printf("QPART-35 : WARNING: degenerate partition generated\n");
238  resizePartition(p);
239  p->m_sub1->m_done = true;
240  p->m_sub2->m_done = true;
241  }
242 
243  // is this parent now finished?
244  if (p->m_sub1->m_done && p->m_sub2->m_done) p->m_done = true;
245 
246  return p->m_done;
247 }
void partitionEqualArea(Partition *parent)
Splits a partition into two halves of equal area.
struct Partition * m_sub1
Definition: place_gordian.h:56
char * malloc()
bool refinePartition(Partition *p)
Splits any large leaves within a partition.
ABC_NAMESPACE_IMPL_START int g_place_numPartitions
Definition: place_gordian.c:28
void partitionScanlineMincut(Partition *parent)
Scans the cells within a partition from left to right and chooses the min-cut.
void resizePartition(Partition *p)
Recomputes the bounding boxes of the child partitions based on their relative areas.
struct Partition * m_sub2
Definition: place_gordian.h:56
float getCellArea(const ConcreteCell *cell)
Definition: place_base.c:99
#define REPARTITION_HMETIS
Definition: place_gordian.h:36
bool m_vertical
Definition: place_gordian.h:51
#define REPARTITION_FM
Definition: place_gordian.h:35
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
Definition: place_gordian.h:49
#define LARGEST_FINAL_SIZE
Definition: place_gordian.h:25
#define REPARTITION_LEVEL_DEPTH
Definition: place_gordian.h:33
int m_numMembers
Definition: place_gordian.h:48
#define assert(ex)
Definition: util_old.h:213
#define PARTITION_AREA_ONLY
Definition: place_gordian.h:26
float m_area
Definition: place_gordian.h:54
bool refinePartitions ( )

Splits large leaf partitions.

Definition at line 126 of file place_partition.c.

126  {
127 
129 }
bool refinePartition(Partition *p)
Splits any large leaves within a partition.
ABC_NAMESPACE_IMPL_START Partition * g_place_rootPartition
void repartitionFM ( Partition parent)

Fiduccia-Matheyses mincut partitioning algorithm.

UNIMPLEMENTED (well, un-C-ified)

Definition at line 435 of file place_partition.c.

435  {
436 #if 0
437  assert(!parent->leaf && parent->m_sub1->leaf && parent->m_sub2->leaf);
438 
439  // count of each net's number of cells in each bipartition
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());
444 
445  FM_cell target[m_design->cells.length()];
446  memset(target, 0, sizeof(FM_cell)*m_design->cells.length());
447  FM_cell *bin[FM_MAX_BIN+1];
448  FM_cell *locked = 0;
449  memset(bin, 0, sizeof(FM_cell *)*(FM_MAX_BIN+1));
450 
451  int max_gain = 0;
452  int before_cuts = 0, current_cuts = 0;
453  double initial_cut;
454  int targets = 0;
455  long cell_id;
456  double halfArea = parent->m_area / 2.0;
457  double areaFlexibility = parent->m_area * MAX_PARTITION_NONSYMMETRY;
458  ConcreteNet *net;
459 
460  // INITIALIZATION
461  // select cells to partition
462 
463  if (parent->vertical) {
464  // vertical
465 
466  initial_cut = parent->m_sub2->m_bounds.x;
467 
468  // initialize all cells
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;
473  else
474  target[cell_id].loc = -2;
475  target[cell_id].cell = *it;
476  target[cell_id].gain = 0;
477  }
478 
479  // initialize cells in partition 1
480  for(h::list<ConcreteCell *>::iterator it = parent->m_sub1->m_members.begin(); !it; it++) {
481  cell_id = (*it)->getID();
482  // pay attention to cells that are close to the cut
483  if (abs((*it)->temp_x-initial_cut) < parent->m_bounds.w*REPARTITION_TARGET_FRACTION) {
484  targets++;
485  target[cell_id].loc = 1;
486  }
487  }
488 
489  // initialize cells in partition 2
490  for(h::list<ConcreteCell *>::iterator it = parent->m_sub2->m_members.begin(); !it; it++) {
491  cell_id = (*it)->getID();
492  // pay attention to cells that are close to the cut
493  if (abs((*it)->temp_x-initial_cut) < parent->m_bounds.w*REPARTITION_TARGET_FRACTION) {
494  targets++;
495  target[cell_id].loc = 2;
496  }
497  }
498 
499  // count the number of cells on each side of the partition for every net
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()]++;
508  else
509  count_2[net->getID()]++;
510  if (count_1[net->getID()] > 0 && count_2[net->getID()] > 0) before_cuts++;
511  }
512 
513  } else {
514  // horizontal
515 
516  initial_cut = parent->m_sub2->m_bounds.y;
517 
518  // initialize all cells
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;
523  else
524  target[cell_id].loc = -2;
525  target[cell_id].cell = *it;
526  target[cell_id].gain = 0;
527  }
528 
529  // initialize cells in partition 1
530  for(h::list<ConcreteCell *>::iterator it = parent->m_sub1->m_members.begin(); !it; it++) {
531  cell_id = (*it)->getID();
532  // pay attention to cells that are close to the cut
533  if (abs((*it)->temp_y-initial_cut) < parent->m_bounds.h*REPARTITION_TARGET_FRACTION) {
534  targets++;
535  target[cell_id].loc = 1;
536  }
537  }
538 
539  // initialize cells in partition 2
540  for(h::list<ConcreteCell *>::iterator it = parent->m_sub2->m_members.begin(); !it; it++) {
541  cell_id = (*it)->getID();
542  // pay attention to cells that are close to the cut
543  if (abs((*it)->temp_y-initial_cut) < parent->m_bounds.h*REPARTITION_TARGET_FRACTION) {
544  targets++;
545  target[cell_id].loc = 2;
546  }
547  }
548 
549  // count the number of cells on each side of the partition for every net
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()]++;
558  else
559  count_2[net->getID()]++;
560  if (count_1[net->getID()] > 0 && count_2[net->getID()] > 0) before_cuts++;
561  }
562  }
563 
564  // INITIAL GAIN CALCULATION
565  for(long id=0; id < m_design->cells.length(); id++)
566  if (target[id].loc > 0) {
567  assert(target[id].cell != 0);
568  assert(target[id].gain == 0);
569 
570  // examine counts for the net on each pin
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++;
578  }
579 
580  assert(target[id].cell->getPins().length() >= abs(target[id].gain));
581 
582  // add it to a bin
583  int bin_num = min(max(0, target[id].gain),FM_MAX_BIN);
584  max_gain = max(max_gain, bin_num);
585 
586  assert(bin_num >= 0 && bin_num <= FM_MAX_BIN);
587  target[id].next = bin[bin_num];
588  target[id].prev = 0;
589  if (bin[bin_num] != 0)
590  bin[bin_num]->prev = &target[id];
591  bin[bin_num] = &target[id];
592  }
593 
594  // OUTER F-M LOOP
595  current_cuts = before_cuts;
596  int num_moves = 1;
597  int pass = 0;
598  while(num_moves > 0 && pass < FM_MAX_PASSES) {
599  pass++;
600  num_moves = 0;
601 
602  // check_list(bin, locked, targets); // DEBUG
603 
604  // move all locked cells back
605  int moved_back = 0;
606  while(locked != 0) {
607  FM_cell *current = locked;
608  current->locked = false;
609 
610  int bin_num = min(max(0, current->gain),FM_MAX_BIN);
611  max_gain = max(max_gain, bin_num);
612 
613  locked = current->next;
614  if (locked != 0)
615  locked->prev = 0;
616 
617  if (bin[bin_num] != 0)
618  bin[bin_num]->prev = current;
619  current->next = bin[bin_num];
620  bin[bin_num] = current;
621 
622  moved_back++;
623  }
624  // cout << "\tmoved back: " << moved_back << endl;
625  // check_list(bin, locked, targets); // DEBUG
626 
627  max_gain = FM_MAX_BIN;
628  while(bin[max_gain] == 0 && max_gain > 0) max_gain--;
629 
630  // INNER F-M LOOP (single pass)
631  while(1) {
632 
633  int bin_num = FM_MAX_BIN;
634  FM_cell *current = bin[bin_num];
635 
636  // look for next cell to move
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))) {
640 
641  if (current == 0) current = bin[--bin_num]; else current = current->next;
642  }
643  if (bin_num == 0)
644  break;
645 
646  num_moves++;
647  current->locked = true;
648  // cout << "moving cell " << current->cell->getID() << " gain=" << current->gain << " pins= " << current->cell->getPins().length() << " from " << current->loc;
649 
650  // change partition marking and areas
651  if (current->loc == 1) {
652  current->loc = 2;
653  parent->m_sub1->m_area -= current->cell->getArea();
654  parent->m_sub2->m_area += current->cell->getArea();
655 
656  // update partition counts on all nets attached to this cell
657  for(ConcretePinMap::iterator p_it = current->cell->getPins().begin();
658  !p_it; p_it++) {
659 
660  if (!(*p_it)->isAttached()) // ignore unattached pins
661  continue;
662  net = (*p_it)->getNet();
663 
664  count_1[net->getID()]--;
665  count_2[net->getID()]++;
666 
667  // cout << "\tnet " << net->getID() << " was " << count_1[net->getID()]+1 << "/" << count_2[net->getID()]-1 << " now " << count_1[net->getID()] << "/" << count_2[net->getID()] << endl;
668 
669  // if net becomes critical, update gains on attached cells and resort bins
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); }
672 
673  // check_list(bin, locked, targets); // DEBUG
674  }
675 
676  } else {
677  current->loc = 1;
678  parent->m_sub2->m_area -= current->cell->getArea();
679  parent->m_sub1->m_area += current->cell->getArea();
680 
681  // update gains on all nets attached to this cell
682  for(ConcretePinMap::iterator p_it = current->cell->getPins().begin();
683  !p_it; p_it++) {
684 
685  if (!(*p_it)->isAttached()) // ignore unattached pins
686  continue;
687  net = (*p_it)->getNet();
688  count_2[net->getID()]--;
689  count_1[net->getID()]++;
690 
691  // cout << "\tnet " << net->getID() << " was " << count_1[net->getID()]-1 << "/" << count_2[net->getID()]+1 << " now " << count_1[net->getID()] << "/" << count_2[net->getID()] << endl;
692 
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); }
695 
696  // check_list(bin, locked, targets); // DEBUG
697  }
698  }
699 
700  //cout << " cuts=" << current_cuts << endl;
701 
702  // move current to locked
703 
704 /*
705  cout << "b=" << bin[bin_num] << " ";
706  cout << current->prev << "-> ";
707  if (current->prev == 0)
708  cout << "X";
709  else cout << current->prev->next;
710  cout << "=" << current << "=";
711  if (current->next == 0)
712  cout << "X";
713  else
714  cout << current->next->prev;
715  cout << " ->" << current->next << endl;
716 */
717 
718  if (bin[bin_num] == current)
719  bin[bin_num] = current->next;
720  if (current->prev != 0)
721  current->prev->next = current->next;
722  if (current->next != 0)
723  current->next->prev = current->prev;
724 
725 /*
726  cout << "b=" << bin[bin_num] << " ";
727  cout << current->prev << "-> ";
728  if (current->prev == 0)
729  cout << "X";
730  else cout << current->prev->next;
731  cout << "=" << current << "=";
732  if (current->next == 0)
733  cout << "X";
734  else
735  cout << current->next->prev;
736  cout << " ->" << current->next << endl;
737 */
738 
739  current->prev = 0;
740  current->next = locked;
741  if (locked != 0)
742  locked->prev = current;
743  locked = current;
744 
745  // check_list(bin, locked, targets); // DEBUG
746 
747  // update max_gain
748  max_gain = FM_MAX_BIN;
749  while(bin[max_gain] == 0 && max_gain > 0) max_gain--;
750  }
751 
752  // cout << "\tcurrent cuts= " << current_cuts << " moves= " << num_moves << endl;
753  }
754 
755  // reassign members to subpartitions
756  cout << "FIDM-20 : \tbalance before " << parent->m_sub1->m_members.length() << "/"
757  << parent->m_sub2->m_members.length() << " ";
758  parent->m_sub1->m_members.clear();
759  parent->m_sub1->m_area = 0;
760  parent->m_sub2->m_members.clear();
761  parent->m_sub2->m_area = 0;
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) {
764  parent->m_sub1->m_members.push_back(*it);
765  parent->m_sub1->m_area += (*it)->getArea();
766  }
767  else {
768  parent->m_sub2->m_members.push_back(*it);
769  parent->m_sub2->m_area += (*it)->getArea();
770  }
771  }
772  cout << " after " << parent->m_sub1->m_members.length() << "/"
773  << parent->m_sub2->m_members.length() << endl;
774 
775 
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;
778 #endif
779 }
char * memset()
struct Partition * m_sub1
Definition: place_gordian.h:56
float h
Definition: place_base.h:36
float x
Definition: place_base.h:35
#define FM_MAX_PASSES
Definition: place_gordian.h:40
struct FM_cell * next
#define MAX_PARTITION_NONSYMMETRY
Definition: place_gordian.h:30
float y
Definition: place_base.h:35
struct Partition * m_sub2
Definition: place_gordian.h:56
#define FM_MAX_BIN
Definition: place_gordian.h:39
static double max
Definition: cuddSubsetHB.c:134
void FM_updateGains(ConcreteNet *net, int partition, int inc, FM_cell target[], FM_cell *bin[], int count_1[], int count_2[])
ConcreteCell ** m_members
Definition: place_gordian.h:49
float w
Definition: place_base.h:36
#define REPARTITION_TARGET_FRACTION
Definition: place_gordian.h:34
Rect m_bounds
Definition: place_gordian.h:50
#define assert(ex)
Definition: util_old.h:213
ConcreteCell * cell
struct FM_cell * prev
float m_area
Definition: place_gordian.h:54
void repartitionHMetis ( Partition parent)

Repartitions the two subpartitions using the hMetis min-cut library.

The number of cut nets between the two partitions will be minimized.

Definition at line 258 of file place_partition.c.

258  {
259 #if defined(NO_HMETIS)
260  printf("QPAR_02 : \t\tERROR: hMetis not available. Ignoring.\n");
261 #else
262 
263  int n,c,t, i;
264  float area;
265  int *edgeConnections = NULL;
266  int *partitionAssignment = (int *)calloc(g_place_numCells, sizeof(int));
267  int *vertexWeights = (int *)calloc(g_place_numCells, sizeof(int));
268  int *edgeDegree = (int *)malloc(sizeof(int)*(g_place_numNets+1));
269  int numConnections = 0;
270  int numEdges = 0;
271  float initial_cut;
272  int targets = 0;
273  ConcreteCell *cell = NULL;
274  int options[9];
275  int afterCuts = 0;
276 
277  assert(parent);
278  assert(parent->m_sub1);
279  assert(parent->m_sub2);
280 
281  printf("QPAR-02 : \t\trepartitioning with hMetis\n");
282 
283  // count edges
284  edgeDegree[0] = 0;
285  for(n=0; n<g_place_numNets; n++) if (g_place_concreteNets[n])
286  if (g_place_concreteNets[n]->m_numTerms > 1) {
287  numConnections += g_place_concreteNets[n]->m_numTerms;
288  edgeDegree[++numEdges] = numConnections;
289  }
290 
291  if (parent->m_vertical) {
292  // vertical
293  initial_cut = parent->m_sub2->m_bounds.x;
294 
295  // initialize all cells
296  for(c=0; c<g_place_numCells; c++) if (g_place_concreteCells[c]) {
297  if (g_place_concreteCells[c]->m_x < initial_cut)
298  partitionAssignment[c] = 0;
299  else
300  partitionAssignment[c] = 1;
301  }
302 
303  // initialize cells in partition 1
304  for(t=0; t<parent->m_sub1->m_numMembers; t++) if (parent->m_sub1->m_members[t]) {
305  cell = parent->m_sub1->m_members[t];
306  vertexWeights[cell->m_id] = getCellArea(cell);
307  // pay attention to cells that are close to the cut
308  if (abs(cell->m_x-initial_cut) < parent->m_bounds.w*REPARTITION_TARGET_FRACTION) {
309  targets++;
310  partitionAssignment[cell->m_id] = -1;
311  }
312  }
313 
314  // initialize cells in partition 2
315  for(t=0; t<parent->m_sub2->m_numMembers; t++) if (parent->m_sub2->m_members[t]) {
316  cell = parent->m_sub2->m_members[t];
317  vertexWeights[cell->m_id] = getCellArea(cell);
318  // pay attention to cells that are close to the cut
319  if (abs(cell->m_x-initial_cut) < parent->m_bounds.w*REPARTITION_TARGET_FRACTION) {
320  targets++;
321  partitionAssignment[cell->m_id] = -1;
322  }
323  }
324 
325  } else {
326  // horizontal
327  initial_cut = parent->m_sub2->m_bounds.y;
328 
329  // initialize all cells
330  for(c=0; c<g_place_numCells; c++) if (g_place_concreteCells[c]) {
331  if (g_place_concreteCells[c]->m_y < initial_cut)
332  partitionAssignment[c] = 0;
333  else
334  partitionAssignment[c] = 1;
335  }
336 
337  // initialize cells in partition 1
338  for(t=0; t<parent->m_sub1->m_numMembers; t++) if (parent->m_sub1->m_members[t]) {
339  cell = parent->m_sub1->m_members[t];
340  vertexWeights[cell->m_id] = getCellArea(cell);
341  // pay attention to cells that are close to the cut
342  if (abs(cell->m_y-initial_cut) < parent->m_bounds.h*REPARTITION_TARGET_FRACTION) {
343  targets++;
344  partitionAssignment[cell->m_id] = -1;
345  }
346  }
347 
348  // initialize cells in partition 2
349  for(t=0; t<parent->m_sub2->m_numMembers; t++) if (parent->m_sub2->m_members[t]) {
350  cell = parent->m_sub2->m_members[t];
351  vertexWeights[cell->m_id] = getCellArea(cell);
352  // pay attention to cells that are close to the cut
353  if (abs(cell->m_y-initial_cut) < parent->m_bounds.h*REPARTITION_TARGET_FRACTION) {
354  targets++;
355  partitionAssignment[cell->m_id] = -1;
356  }
357  }
358  }
359 
360  options[0] = 1; // any non-default values?
361  options[1] = 3; // num bisections
362  options[2] = 1; // grouping scheme
363  options[3] = 1; // refinement scheme
364  options[4] = 1; // cycle refinement scheme
365  options[5] = 0; // reconstruction scheme
366  options[6] = 0; // fixed assignments?
367  options[7] = 12261980; // random seed
368  options[8] = 0; // debugging level
369 
370  edgeConnections = (int *)malloc(sizeof(int)*numConnections);
371 
372  i = 0;
373  for(n=0; n<g_place_numNets; n++) if (g_place_concreteNets[n]) {
374  if (g_place_concreteNets[n]->m_numTerms > 1)
375  for(t=0; t<g_place_concreteNets[n]->m_numTerms; t++)
376  edgeConnections[i++] = g_place_concreteNets[n]->m_terms[t]->m_id;
377  }
378 
379  HMETIS_PartRecursive(g_place_numCells, numEdges, vertexWeights,
380  edgeDegree, edgeConnections, NULL,
381  2, (int)(100*MAX_PARTITION_NONSYMMETRY),
382  options, partitionAssignment, &afterCuts);
383 
384  /*
385  printf("HMET-20 : \t\t\tbalance before %d / %d ... ", parent->m_sub1->m_numMembers,
386  parent->m_sub2->m_numMembers);
387  */
388 
389  // reassign members to subpartitions
390  parent->m_sub1->m_numMembers = 0;
391  parent->m_sub1->m_area = 0;
392  parent->m_sub2->m_numMembers = 0;
393  parent->m_sub2->m_area = 0;
394  parent->m_sub1->m_members = (ConcreteCell**)realloc(parent->m_sub1->m_members,
395  sizeof(ConcreteCell*)*parent->m_numMembers);
396  parent->m_sub2->m_members = (ConcreteCell**)realloc(parent->m_sub2->m_members,
397  sizeof(ConcreteCell*)*parent->m_numMembers);
398 
399  for(t=0; t<parent->m_numMembers; t++) if (parent->m_members[t]) {
400  cell = parent->m_members[t];
401  area = getCellArea(cell);
402  if (partitionAssignment[cell->m_id] == 0) {
403  parent->m_sub1->m_members[parent->m_sub1->m_numMembers++] = cell;
404  parent->m_sub1->m_area += area;
405  }
406  else {
407  parent->m_sub2->m_members[parent->m_sub2->m_numMembers++] = cell;
408  parent->m_sub2->m_area += area;
409  }
410  }
411  /*
412  printf("after %d / %d\n", parent->m_sub1->m_numMembers,
413  parent->m_sub2->m_numMembers);
414  */
415 
416  // cout << "HMET-21 : \t\t\tloc: " << initial_cut << " targetting: " << targets*100/parent->m_members.length() << "%" << endl;
417  // cout << "HMET-22 : \t\t\tstarting cuts= " << beforeCuts << " final cuts= " << afterCuts << endl;
418 
419  free(edgeConnections);
420  free(vertexWeights);
421  free(edgeDegree);
422  free(partitionAssignment);
423 #endif
424 }
struct Partition * m_sub1
Definition: place_gordian.h:56
char * malloc()
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)
Definition: libhmetis.h:10
VOID_HACK free()
ConcreteNet ** g_place_concreteNets
Definition: place_base.c:35
float h
Definition: place_base.h:36
float x
Definition: place_base.h:35
#define MAX_PARTITION_NONSYMMETRY
Definition: place_gordian.h:30
float y
Definition: place_base.h:35
ConcreteCell ** g_place_concreteCells
Definition: place_base.c:33
char * realloc()
struct Partition * m_sub2
Definition: place_gordian.h:56
float getCellArea(const ConcreteCell *cell)
Definition: place_base.c:99
bool m_vertical
Definition: place_gordian.h:51
ConcreteCell ** m_members
Definition: place_gordian.h:49
int m_numTerms
Definition: place_base.h:71
float w
Definition: place_base.h:36
int g_place_numNets
Definition: place_base.c:27
#define REPARTITION_TARGET_FRACTION
Definition: place_gordian.h:34
char * calloc()
Rect m_bounds
Definition: place_gordian.h:50
int m_numMembers
Definition: place_gordian.h:48
#define assert(ex)
Definition: util_old.h:213
ABC_NAMESPACE_IMPL_START int g_place_numCells
Definition: place_base.c:26
float m_area
Definition: place_gordian.h:54
void resizePartition ( Partition p)

Recomputes the bounding boxes of the child partitions based on their relative areas.

Definition at line 1022 of file place_partition.c.

1022  {
1023  // compute the new bounding box
1024  p->m_sub1->m_bounds.x = p->m_bounds.x;
1025  p->m_sub1->m_bounds.y = p->m_bounds.y;
1026  if (p->m_vertical) {
1027  p->m_sub1->m_bounds.w = p->m_bounds.w*(p->m_sub1->m_area/p->m_area);
1028  p->m_sub1->m_bounds.h = p->m_bounds.h;
1029  p->m_sub2->m_bounds.x = p->m_bounds.x + p->m_sub1->m_bounds.w;
1030  p->m_sub2->m_bounds.w = p->m_bounds.w*(p->m_sub2->m_area/p->m_area);
1031  p->m_sub2->m_bounds.y = p->m_bounds.y;
1032  p->m_sub2->m_bounds.h = p->m_bounds.h;
1033  } else {
1034  p->m_sub1->m_bounds.h = p->m_bounds.h*(p->m_sub1->m_area/p->m_area);
1035  p->m_sub1->m_bounds.w = p->m_bounds.w;
1036  p->m_sub2->m_bounds.y = p->m_bounds.y + p->m_sub1->m_bounds.h;
1037  p->m_sub2->m_bounds.h = p->m_bounds.h*(p->m_sub2->m_area/p->m_area);
1038  p->m_sub2->m_bounds.x = p->m_bounds.x;
1039  p->m_sub2->m_bounds.w = p->m_bounds.w;
1040  }
1041 }
struct Partition * m_sub1
Definition: place_gordian.h:56
float h
Definition: place_base.h:36
float x
Definition: place_base.h:35
float y
Definition: place_base.h:35
struct Partition * m_sub2
Definition: place_gordian.h:56
bool m_vertical
Definition: place_gordian.h:51
float w
Definition: place_base.h:36
Rect m_bounds
Definition: place_gordian.h:50
float m_area
Definition: place_gordian.h:54
void sanitizePlacement ( )

Moves any cells that are outside of the core bounds to the nearest location within.

Definition at line 125 of file place_gordian.c.

125  {
126  int c;
127  float order_width = g_place_rowHeight;
128  float x, y, edge, w, h;
129 
130  printf("QCLN-10 : \tsanitizing placement\n");
131 
132  for(c=0; c<g_place_numCells; c++) if (g_place_concreteCells[c]) {
134  if (cell->m_fixed || cell->m_parent->m_pad) {
135  continue;
136  }
137  // the new locations of the cells will be distributed within
138  // a small margin inside the border so that ordering is preserved
139  order_width = g_place_rowHeight;
140 
141  x = cell->m_x, y = cell->m_y,
142  w = cell->m_parent->m_width, h = cell->m_parent->m_height;
143 
144  if ((edge=x-w*0.5) < g_place_coreBounds.x) {
145  x = g_place_coreBounds.x+w*0.5 +
146  order_width/(1.0+g_place_coreBounds.x-edge);
147  }
148  else if ((edge=x+w*0.5) > g_place_coreBounds.x+g_place_coreBounds.w) {
150  order_width/(1.0+edge-g_place_coreBounds.x-g_place_coreBounds.w);
151  }
152  if ((edge=y-h*0.5) < g_place_coreBounds.y) {
153  y = g_place_coreBounds.y+h*0.5 +
154  order_width/(1.0+g_place_coreBounds.y-edge);
155  }
156  else if ((edge=y+h*0.5) > g_place_coreBounds.y+g_place_coreBounds.h) {
158  order_width/(1.0+edge-g_place_coreBounds.x-g_place_coreBounds.w);
159  }
160  cell->m_x = x;
161  cell->m_y = y;
162  }
163 }
AbstractCell * m_parent
Definition: place_base.h:57
float h
Definition: place_base.h:36
float x
Definition: place_base.h:35
float m_width
Definition: place_base.h:45
float y
Definition: place_base.h:35
ConcreteCell ** g_place_concreteCells
Definition: place_base.c:33
bool m_fixed
Definition: place_base.h:59
float m_height
Definition: place_base.h:45
Rect g_place_coreBounds
Definition: place_base.c:30
float w
Definition: place_base.h:36
ABC_NAMESPACE_IMPL_START int g_place_numCells
Definition: place_base.c:26
float g_place_rowHeight
Definition: place_base.c:28
void solveQuadraticProblem ( bool  useCOG)

Calls quadratic solver.

Definition at line 275 of file place_genqp.c.

275  {
276  int c;
277 
279 
283 
284  // memset(g_place_qpProb->x, 0, sizeof(float)*g_place_numCells);
285  // memset(g_place_qpProb->y, 0, sizeof(float)*g_place_numCells);
286 
288 
289  if (useCOG)
291  else
292  g_place_qpProb->cog_num = 0;
293 
295 
297 
299 
300  // set the positions
301  for(c = 0; c < g_place_numCells; c++) if (g_place_concreteCells[c]) {
304  }
305 
306  // clean up
310 
311  free(COG_rev);
312 }
char * malloc()
void qps_solve(qps_problem_t *p)
ABC_NAMESPACE_IMPL_START int g_place_numPartitions
Definition: place_gordian.c:28
VOID_HACK free()
void qps_clean(qps_problem_t *p)
ConcreteCell ** g_place_concreteCells
Definition: place_base.c:33
qps_float_t * y
qps_float_t * x
qps_float_t * cog_x
int generateCoGConstraints(reverseCOG COG_rev[])
Generates center of gravity constraints.
Definition: place_genqp.c:186
ABC_NAMESPACE_IMPL_START qps_problem_t * g_place_qpProb
Definition: place_genqp.c:28
qps_float_t * cog_y
void qps_init(qps_problem_t *p)
ABC_NAMESPACE_IMPL_START int g_place_numCells
Definition: place_base.c:26

Variable Documentation

int g_place_numPartitions

Definition at line 28 of file place_gordian.c.

qps_problem_t* g_place_qpProb

Definition at line 28 of file place_genqp.c.

Partition* g_place_rootPartition

Definition at line 34 of file place_partition.c.