86 #define DD_MAX_SUBTABLE_SPARSITY 8
87 #define DD_SHRINK_FACTOR 2
102 static char rcsid[]
DD_UNUSED =
"$Id: cuddReorder.c,v 1.69 2009/02/21 18:24:10 fabio Exp $";
183 unsigned int nextDyn;
185 unsigned int initialSize;
186 unsigned int finalSize;
191 if (table->
keys - table->
dead < (
unsigned) minsize)
210 while (hook != NULL) {
211 int res = (hook->
f)(table,
"BDD", (
void *)heuristic);
212 if (res == 0)
return(0);
229 (void) fprintf(table->
out,
"#:I_RANDOM ");
237 (void) fprintf(table->
out,
"#:I_SIFTING ");
245 (void) fprintf(table->
out,
"#:I_WINDOW ");
248 (void) fprintf(table->
out,
"#:I_ANNEAL ");
251 (void) fprintf(table->
out,
"#:I_GENETIC ");
255 (void) fprintf(table->
out,
"#:I_LINSIFT ");
258 (void) fprintf(table->
out,
"#:I_EXACT ");
263 (void) fprintf(table->
out,
"%8d: initial size",initialSize);
277 (void) fprintf(table->
out,
"\n");
279 (void) fprintf(table->
out,
"#:F_REORDER %8d: final size\n",finalSize);
280 (void) fprintf(table->
out,
"#:T_REORDER %8g: total time (sec)\n",
282 (void) fprintf(table->
out,
"#:N_REORDER %8d: total swaps\n",
284 (void) fprintf(table->
out,
"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps);
308 while (hook != NULL) {
309 int res = (hook->
f)(table,
"BDD", (
void *)localTime);
310 if (res == 0)
return(0);
349 for (i = 0; i < table->
size; i++) {
350 if (permutation[i] != table->
invperm[i]) {
364 for (i = 0; i < table->
size; i++)
365 perm[permutation[i]] = i;
421 MMoutOfMemory = saveHandler;
422 if (mem == NULL && table->
stash != NULL) {
428 for (i = 0; i < table->
size; i++) {
442 (void) fprintf(table->
err,
443 "cuddDynamicAllocNode: out of memory");
444 (void) fprintf(table->
err,
"Memory in use = %lu\n",
449 unsigned long offset;
460 offset = (
unsigned long) mem & (32 - 1);
461 mem += (32 - offset) /
sizeof(
DdNodePtr);
464 assert(((
unsigned long) mem & (32 - 1)) == 0);
471 list[i - 1].
next = &list[i];
529 goto cuddSiftingOutOfMem;
534 goto cuddSiftingOutOfMem;
537 for (i = 0; i <
size; i++) {
549 x = table->
perm[var[i]];
557 if (!result)
goto cuddSiftingOutOfMem;
559 if (table->
keys < (
unsigned) previousSize + table->
isolated) {
560 (void) fprintf(table->
out,
"-");
561 }
else if (table->
keys > (
unsigned) previousSize + table->
isolated) {
562 (void) fprintf(table->
out,
"+");
563 (void) fprintf(table->
err,
"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->
keys - table->
isolated, var[i]);
565 (void) fprintf(table->
out,
"=");
624 assert(lower >= 0 && upper < table->
size && lower <= upper);
627 nvars = upper - lower + 1;
630 for (i = 0; i < iterate; i++) {
635 for (j = lower; j <= upper; j++) {
642 modulo = upper - pivot;
649 modulo = pivot - lower - 1;
665 if (moves == NULL)
goto cuddSwappingOutOfMem;
667 if (!result)
goto cuddSwappingOutOfMem;
668 while (moves != NULL) {
674 if (table->
keys < (
unsigned) previousSize + table->
isolated) {
675 (void) fprintf(table->
out,
"-");
676 }
else if (table->
keys > (
unsigned) previousSize + table->
isolated) {
677 (void) fprintf(table->
out,
"+");
679 (void) fprintf(table->
out,
"=");
684 (void) fprintf(table->
out,
"#:t_SWAPPING %8d: tmp size\n",
691 cuddSwappingOutOfMem:
692 while (moves != NULL) {
770 int oldxkeys, oldykeys;
771 int newxkeys, newykeys;
772 int comple, newcomplement;
778 DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
831 isolated = - ((table->
vars[xindex]->
ref == 1) +
832 (table->
vars[yindex]->
ref == 1));
839 if ((oldxkeys >= xslots || (
unsigned) xslots == table->
initSlots) &&
841 for (i = 0; i < xslots; i++) {
842 previousP = &(xlist[i]);
844 while (f != sentinel) {
852 previousP = &(f->
next);
860 *previousP = sentinel;
865 unsigned int newxslots;
869 for (i = 0; i < xslots; i++) {
871 while (f != sentinel) {
895 while ((
unsigned) oldxkeys < newxslots &&
904 MMoutOfMemory = saveHandler;
905 if (newxlist == NULL) {
906 (void) fprintf(table->
err,
"Unable to resize subtable %d for lack of memory\n", i);
911 table->
slots += ((int) newxslots - xslots);
918 ((
int) newxslots - xslots) *
sizeof(
DdNodePtr);
925 for (i = 0; i < xslots; i++) {
937 previousP = &(xlist[posn]);
939 while (f1 <
cuddT(tmp)) {
940 previousP = &(tmp->
next);
944 previousP = &(tmp->
next);
947 f->
next = *previousP;
954 table->swapSteps += oldxkeys - newxkeys;
968 if ((
int) f1->
index == yindex) {
979 if ((
int) f0->
index == yindex) {
998 previousP = &(xlist[posn]);
1000 while (f11 <
cuddT(newf1)) {
1001 previousP = &(newf1->
next);
1004 while (f11 ==
cuddT(newf1) && f01 <
cuddE(newf1)) {
1005 previousP = &(newf1->
next);
1008 if (
cuddT(newf1) == f11 &&
cuddE(newf1) == f01) {
1013 goto cuddSwapOutOfMem;
1014 newf1->
index = xindex; newf1->
ref = 1;
1021 newf1->
next = *previousP;
1045 if (newcomplement) {
1052 previousP = &(xlist[posn]);
1054 while (f10 <
cuddT(newf0)) {
1055 previousP = &(newf0->
next);
1058 while (f10 ==
cuddT(newf0) && f00 <
cuddE(newf0)) {
1059 previousP = &(newf0->
next);
1062 if (
cuddT(newf0) == f10 &&
cuddE(newf0) == f00) {
1067 goto cuddSwapOutOfMem;
1068 newf0->
index = xindex; newf0->
ref = 1;
1075 newf0->
next = *previousP;
1081 if (newcomplement) {
1093 previousP = &(ylist[posn]);
1095 while (newf1 <
cuddT(tmp)) {
1096 previousP = &(tmp->
next);
1099 while (newf1 ==
cuddT(tmp) && newf0 <
cuddE(tmp)) {
1100 previousP = &(tmp->
next);
1103 f->
next = *previousP;
1111 for (i = 0; i < yslots; i++) {
1112 previousP = &(ylist[i]);
1114 while (f != sentinel) {
1125 previousP = &(f->
next);
1129 *previousP = sentinel;
1134 (void) fprintf(table->
out,
"Swapping %d and %d\n",x,y);
1138 for (i = 0; i < yslots; i++) {
1140 while (f != sentinel) {
1147 if (count != newykeys) {
1148 (void) fprintf(table->
out,
1149 "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",
1150 oldykeys,newykeys,count);
1153 (void) fprintf(table->
out,
1154 "Error in id's of ylist\twrong id's = %d\n",
1158 for (i = 0; i < xslots; i++) {
1160 while (f != sentinel) {
1167 if (count != newxkeys) {
1168 (void) fprintf(table->
out,
1169 "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",
1170 oldxkeys,newxkeys,count);
1173 (void) fprintf(table->
out,
1174 "Error in id's of xlist\twrong id's = %d\n",
1178 isolated += (table->
vars[xindex]->
ref == 1) +
1179 (table->
vars[yindex]->
ref == 1);
1212 table->
perm[xindex] = y; table->
perm[yindex] = x;
1215 table->
keys += newxkeys + newykeys - oldxkeys - oldykeys;
1220 (void) fprintf(table->
err,
"Error: cuddSwapInPlace out of memory\n");
1260 if (table->
size == 0)
1271 if (invperm == NULL) {
1275 for (i = 0; i < table->
sizeZ; i +=
M) {
1277 int index = indexZ /
M;
1278 invperm[i /
M] = index;
1287 for (i = 0; i < table->
size; i++) {
1293 if (result == 0)
return(0);
1329 return((*ptrX) - (*ptrY));
1360 tmp = x; x = y; y = tmp;
1371 if ( xNext == yNext) {
1373 if (size == 0)
goto ddSwapAnyOutOfMem;
1375 if (move == NULL)
goto ddSwapAnyOutOfMem;
1383 if (size == 0)
goto ddSwapAnyOutOfMem;
1385 if (move == NULL)
goto ddSwapAnyOutOfMem;
1393 if (size == 0)
goto ddSwapAnyOutOfMem;
1395 if (move == NULL)
goto ddSwapAnyOutOfMem;
1402 tmp = x; x = y; y = tmp;
1404 }
else if (x == yNext) {
1407 if (size == 0)
goto ddSwapAnyOutOfMem;
1409 if (move == NULL)
goto ddSwapAnyOutOfMem;
1416 tmp = x; x = y; y = tmp;
1420 if (size == 0)
goto ddSwapAnyOutOfMem;
1422 if (move == NULL)
goto ddSwapAnyOutOfMem;
1430 if (size == 0)
goto ddSwapAnyOutOfMem;
1432 if (move == NULL)
goto ddSwapAnyOutOfMem;
1445 if (xNext > yRef)
break;
1447 if ((
double) size > table->
maxGrowth * (
double) limitSize)
break;
1448 if (size < limitSize) limitSize =
size;
1452 if (size == 0)
goto ddSwapAnyOutOfMem;
1454 if (move == NULL)
goto ddSwapAnyOutOfMem;
1465 while (moves != NULL) {
1512 if (!result)
goto ddSiftingAuxOutOfMem;
1514 }
else if (x == xHigh) {
1520 if (!result)
goto ddSiftingAuxOutOfMem;
1522 }
else if ((x - xLow) > (xHigh - x)) {
1526 if (moveDown != NULL) {
1533 if (!result)
goto ddSiftingAuxOutOfMem;
1539 if (moveUp != NULL) {
1546 if (!result)
goto ddSiftingAuxOutOfMem;
1549 while (moveDown != NULL) {
1550 move = moveDown->
next;
1554 while (moveUp != NULL) {
1555 move = moveUp->
next;
1562 ddSiftingAuxOutOfMem:
1564 while (moveDown != NULL) {
1565 move = moveDown->
next;
1571 while (moveUp != NULL) {
1572 move = moveUp->
next;
1624 for (x = xLow + 1; x < y; x++) {
1627 isolated = table->
vars[xindex]->
ref == 1;
1631 isolated = table->
vars[yindex]->
ref == 1;
1635 while (x >= xLow && L <= limitSize) {
1639 for (z = xLow + 1; z < y; z++) {
1642 isolated = table->
vars[zindex]->
ref == 1;
1646 isolated = table->
vars[yindex]->
ref == 1;
1651 if (size == 0)
goto ddSiftingUpOutOfMem;
1654 isolated = table->
vars[xindex]->
ref == 1;
1658 if (move == NULL)
goto ddSiftingUpOutOfMem;
1664 if ((
double) size > (double) limitSize * table->
maxGrowth)
break;
1665 if (size < limitSize) limitSize =
size;
1671 ddSiftingUpOutOfMem:
1672 while (moves != NULL) {
1719 for (y = xHigh; y > x; y--) {
1722 isolated = table->
vars[yindex]->
ref == 1;
1728 while (y <= xHigh && size - R < limitSize) {
1731 for (z = xHigh; z > x; z--) {
1734 isolated = table->
vars[zindex]->
ref == 1;
1743 isolated = table->
vars[yindex]->
ref == 1;
1747 if (size == 0)
goto ddSiftingDownOutOfMem;
1749 if (move == NULL)
goto ddSiftingDownOutOfMem;
1755 if ((
double) size > (double) limitSize * table->
maxGrowth)
break;
1756 if (size < limitSize) limitSize =
size;
1762 ddSiftingDownOutOfMem:
1763 while (moves != NULL) {
1795 for (move = moves; move != NULL; move = move->
next) {
1796 if (move->
size < size) {
1801 for (move = moves; move != NULL; move = move->
next) {
1802 if (move->
size == size)
return(1);
1804 if (!res)
return(0);
1841 for (i = 0; i < table->
size; i++) {
1847 if (res == 0)
return(0);
1869 (void) fflush(table->
out);
1917 (void) fprintf(table->
out,
"#:I_SHUFFLE %8d: initial size\n",
1922 numvars = table->
size;
1924 for (level = 0; level <
numvars; level++) {
1925 index = permutation[level];
1926 position = table->
perm[index];
1930 result =
ddSiftUp(table,position,level);
1931 if (!result)
return(0);
1933 if (table->
keys < (
unsigned) previousSize + table->
isolated) {
1934 (void) fprintf(table->
out,
"-");
1935 }
else if (table->
keys > (
unsigned) previousSize + table->
isolated) {
1936 (void) fprintf(table->
out,
"+");
1938 (void) fprintf(table->
out,
"=");
1945 (void) fprintf(table->
out,
"\n");
1947 (void) fprintf(table->
out,
"#:F_SHUFFLE %8d: final size\n",finalSize);
1948 (void) fprintf(table->
out,
"#:T_SHUFFLE %8g: total time (sec)\n",
1950 (void) fprintf(table->
out,
"#:N_SHUFFLE %8d: total swaps\n",
1952 (void) fprintf(table->
out,
"#:M_SHUFFLE %8d: NI swaps\n",ddTotalNISwaps);
2014 if (treenode == NULL)
return;
2015 treenode->
low = ((int) treenode->
index < table->
size) ?
2017 if (treenode->
child != NULL) {
2020 if (treenode->
younger != NULL)
2051 int index, level, minLevel, maxLevel, minIndex;
2053 if (treenode == NULL)
return(1);
2059 for (i = treenode->
low; i < treenode->low + treenode->
size; i++) {
2061 level = perm[index];
2062 if (level < minLevel) {
2066 if (level > maxLevel)
2069 size = maxLevel - minLevel + 1;
2070 if (minIndex == -1)
return(0);
2071 if (size == treenode->
size) {
2072 treenode->
low = minLevel;
2073 treenode->
index = minIndex;
2078 if (treenode->
child != NULL) {
2082 if (treenode->
younger != NULL) {
2110 int index, level, minLevel, maxLevel;
2112 if (treenode == NULL)
return(1);
2114 minLevel = table->
size;
2117 for (i = treenode->
low; i < treenode->low + treenode->
size; i++) {
2119 level = perm[index];
2120 if (level < minLevel)
2122 if (level > maxLevel)
2125 size = maxLevel - minLevel + 1;
2126 if (size != treenode->
size)
2129 if (treenode->
child != NULL) {
2133 if (treenode->
younger != NULL) {
static int ddCheckPermuation(DdManager *table, MtrNode *treenode, int *perm, int *invperm)
void cuddCacheFlush(DdManager *table)
unsigned short DdHalfWord
static Move * ddSiftingDown(DdManager *table, int x, int xHigh)
void Cudd_OutOfMem(long size)
#define cuddDeallocMove(unique, node)
Cudd_ReorderingType autoMethod
unsigned int peakLiveNodes
int cuddSwapping(DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
static Move * ddSwapAny(DdManager *table, int x, int y)
DdNode * cuddDynamicAllocNode(DdManager *table)
DdHook * preReorderingHook
static char rcsid[] DD_UNUSED
int(* DD_QSFP)(const void *, const void *)
unsigned int maxCacheHard
int cuddInitInteract(DdManager *table)
#define Cudd_Regular(node)
static int ddSiftingAux(DdManager *table, int x, int xLow, int xHigh)
static int ddSiftUp(DdManager *table, int x, int xLow)
int cuddSifting(DdManager *table, int lower, int upper)
#define ABC_ALLOC(type, num)
static void bddFixTree(DdManager *table, MtrNode *treenode)
word M(word f1, word f2, int n)
#define DD_MAX_SUBTABLE_DENSITY
int Cudd_ShuffleHeap(DdManager *table, int *permutation)
int ddTotalNumberSwapping
int cuddGarbageCollect(DdManager *unique, int clearCache)
Cudd_VariableType varType
#define Cudd_IsComplement(node)
void cuddLocalCacheClearAll(DdManager *manager)
DdHook * postReorderingHook
int cuddNextLow(DdManager *table, int x)
int cuddNextHigh(DdManager *table, int x)
static int ddReorderPostprocess(DdManager *table)
static int ddUniqueCompare(int *ptrX, int *ptrY)
Cudd_LazyGroupType varToBeGrouped
static int ddUpdateMtrTree(DdManager *table, MtrNode *treenode, int *perm, int *invperm)
#define ABC_NAMESPACE_IMPL_END
#define DD_MAX_CACHE_TO_SLOTS_RATIO
int cuddTreeSifting(DdManager *table, Cudd_ReorderingType method)
#define cuddDeallocNode(unique, node)
int cuddBddAlignToZdd(DdManager *table)
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
#define ABC_NAMESPACE_IMPL_START
static int ddReorderPreprocess(DdManager *table)
int cuddSwapInPlace(DdManager *table, int x, int y)
static int ddSiftingBackward(DdManager *table, int size, Move *moves)
static int ddShuffle(DdManager *table, int *permutation)
int cuddZddAlignToBdd(DdManager *table)
int cuddTestInteract(DdManager *table, int x, int y)
static Move * ddSiftingUp(DdManager *table, int y, int xLow)