00001
00019 #include "reo.h"
00020
00024
00025 #define CALLOC(type, num) ((type *) calloc((long)(num), (long)sizeof(type)))
00026
00027 static int reoRecursiveDeref( reo_unit * pUnit );
00028 static int reoCheckZeroRefs( reo_plane * pPlane );
00029 static int reoCheckLevels( reo_man * p );
00030
00031 double s_AplBefore;
00032 double s_AplAfter;
00033
00037
00049 void reoReorderArray( reo_man * p, DdManager * dd, DdNode * Funcs[], DdNode * FuncsRes[], int nFuncs, int * pOrder )
00050 {
00051 int Counter, i;
00052
00053
00054 p->dd = dd;
00055 p->pOrder = pOrder;
00056 p->nTops = nFuncs;
00057
00058 p->nNodesBeg = Cudd_SharingSize( Funcs, nFuncs );
00059
00060 reoResizeStructures( p, ddMax(dd->size,dd->sizeZ), p->nNodesBeg, nFuncs );
00061
00062 p->pSupp = Extra_VectorSupportArray( dd, Funcs, nFuncs, p->pSupp );
00063
00064 p->nSupp = 0;
00065 for ( i = 0; i < dd->size; i++ )
00066 p->nSupp += p->pSupp[i];
00067
00068
00069 if ( p->nSupp == 0 )
00070 {
00071 for ( i = 0; i < nFuncs; i++ )
00072 {
00073 FuncsRes[i] = Funcs[i]; Cudd_Ref( FuncsRes[i] );
00074 }
00075 return;
00076 }
00077
00078
00079
00080 Counter = 0;
00081 for ( i = 0; i < dd->size; i++ )
00082 if ( p->pSupp[ dd->invperm[i] ] )
00083 {
00084 p->pMapToPlanes[ dd->invperm[i] ] = Counter;
00085 p->pMapToDdVarsOrig[Counter] = dd->invperm[i];
00086 if ( !p->fRemapUp )
00087 p->pMapToDdVarsFinal[Counter] = dd->invperm[i];
00088 else
00089 p->pMapToDdVarsFinal[Counter] = dd->invperm[Counter];
00090 p->pOrderInt[Counter] = Counter;
00091 Counter++;
00092 }
00093
00094
00095 p->nUnitsUsed = 0;
00096 p->nNodesCur = 0;
00097 p->fThisIsAdd = 0;
00098 p->Signature++;
00099
00100 for ( i = 0; i < nFuncs; i++ )
00101 p->pTops[i] = reoTransferNodesToUnits_rec( p, Funcs[i] );
00102 assert( p->nNodesBeg == p->nNodesCur );
00103
00104 if ( !p->fThisIsAdd && p->fMinWidth )
00105 {
00106 printf( "An important message from the REO reordering engine:\n" );
00107 printf( "The BDD given to the engine for reordering contains complemented edges.\n" );
00108 printf( "Currently, such BDDs cannot be reordered for the minimum width.\n" );
00109 printf( "Therefore, minimization for the number of BDD nodes is performed.\n" );
00110 fflush( stdout );
00111 p->fMinApl = 0;
00112 p->fMinWidth = 0;
00113 }
00114
00115 if ( p->fMinWidth )
00116 reoProfileWidthStart(p);
00117 else if ( p->fMinApl )
00118 reoProfileAplStart(p);
00119 else
00120 reoProfileNodesStart(p);
00121
00122 if ( p->fVerbose )
00123 {
00124 printf( "INITIAL: " );
00125 if ( p->fMinWidth )
00126 reoProfileWidthPrint(p);
00127 else if ( p->fMinApl )
00128 reoProfileAplPrint(p);
00129 else
00130 reoProfileNodesPrint(p);
00131 }
00132
00134
00135 p->nSwaps = 0;
00136 p->nNISwaps = 0;
00137 for ( i = 0; i < p->nIters; i++ )
00138 {
00139 reoReorderSift( p );
00140
00141 if ( p->fVerbose )
00142 {
00143 printf( "ITER #%d: ", i+1 );
00144 if ( p->fMinWidth )
00145 reoProfileWidthPrint(p);
00146 else if ( p->fMinApl )
00147 reoProfileAplPrint(p);
00148 else
00149 reoProfileNodesPrint(p);
00150 }
00151
00152 if ( p->fMinWidth )
00153 {
00154 p->nWidthEnd = p->nWidthCur;
00155 assert( p->nWidthEnd <= p->nWidthBeg );
00156 if ( p->nWidthEnd == p->nWidthBeg )
00157 break;
00158 }
00159 else if ( p->fMinApl )
00160 {
00161 p->nAplEnd = p->nAplCur;
00162 assert( p->nAplEnd <= p->nAplBeg );
00163 if ( p->nAplEnd == p->nAplBeg )
00164 break;
00165 }
00166 else
00167 {
00168 p->nNodesEnd = p->nNodesCur;
00169 assert( p->nNodesEnd <= p->nNodesBeg );
00170 if ( p->nNodesEnd == p->nNodesBeg )
00171 break;
00172 }
00173 }
00174 assert( reoCheckLevels( p ) );
00176
00177 s_AplBefore = p->nAplBeg;
00178 s_AplAfter = p->nAplEnd;
00179
00180
00181 p->nRefNodes = 0;
00182 p->nNodesCur = 0;
00183 p->Signature++;
00184
00185 for ( i = 0; i < nFuncs; i++ )
00186 {
00187 FuncsRes[i] = reoTransferUnitsToNodes_rec( p, p->pTops[i] ); Cudd_Ref( FuncsRes[i] );
00188 }
00189
00190 for ( i = 0; i < p->nRefNodes; i++ )
00191 Cudd_RecursiveDeref( dd, p->pRefNodes[i] );
00192
00193 for ( i = 0; i < nFuncs; i++ )
00194 {
00195 assert( reoRecursiveDeref( p->pTops[i] ) );
00196 }
00197 assert( reoCheckZeroRefs( &(p->pPlanes[p->nSupp]) ) );
00198
00199
00200 if ( p->pOrder )
00201 {
00202
00203
00204
00205
00206
00207
00208 for ( i = 0; i < p->nSupp; i++ )
00209 p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ];
00210 }
00211
00212 if ( p->fVerify )
00213 {
00214 int fVerification;
00215 DdNode * FuncRemapped;
00216 int * pOrder;
00217
00218 if ( p->pOrder == NULL )
00219 {
00220 pOrder = ALLOC( int, p->nSupp );
00221 for ( i = 0; i < p->nSupp; i++ )
00222 pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ];
00223 }
00224 else
00225 pOrder = p->pOrder;
00226
00227 fVerification = 1;
00228 for ( i = 0; i < nFuncs; i++ )
00229 {
00230
00231 if ( p->fThisIsAdd )
00232 FuncRemapped = Cudd_addPermute( dd, FuncsRes[i], pOrder );
00233 else
00234 FuncRemapped = Cudd_bddPermute( dd, FuncsRes[i], pOrder );
00235 Cudd_Ref( FuncRemapped );
00236
00237 if ( FuncRemapped != Funcs[i] )
00238 {
00239 fVerification = 0;
00240 printf( "REO: Internal verification has failed!\n" );
00241 fflush( stdout );
00242 }
00243 Cudd_RecursiveDeref( dd, FuncRemapped );
00244 }
00245 if ( fVerification )
00246 printf( "REO: Internal verification is okay!\n" );
00247
00248 if ( p->pOrder == NULL )
00249 free( pOrder );
00250 }
00251
00252
00253 for ( i = 0; i <= p->nSupp; i++ )
00254 reoUnitsRecycleUnitList( p, p->pPlanes + i );
00255 }
00256
00268 void reoResizeStructures( reo_man * p, int nDdVarsMax, int nNodesMax, int nFuncs )
00269 {
00270
00271 if ( p->nSuppAlloc == 0 )
00272 {
00273 p->pSupp = ALLOC( int, nDdVarsMax + 1 );
00274 p->pOrderInt = ALLOC( int, nDdVarsMax + 1 );
00275 p->pMapToPlanes = ALLOC( int, nDdVarsMax + 1 );
00276 p->pMapToDdVarsOrig = ALLOC( int, nDdVarsMax + 1 );
00277 p->pMapToDdVarsFinal = ALLOC( int, nDdVarsMax + 1 );
00278 p->pPlanes = CALLOC( reo_plane, nDdVarsMax + 1 );
00279 p->pVarCosts = ALLOC( double, nDdVarsMax + 1 );
00280 p->pLevelOrder = ALLOC( int, nDdVarsMax + 1 );
00281 p->nSuppAlloc = nDdVarsMax + 1;
00282 }
00283 else if ( p->nSuppAlloc < nDdVarsMax )
00284 {
00285 free( p->pSupp );
00286 free( p->pOrderInt );
00287 free( p->pMapToPlanes );
00288 free( p->pMapToDdVarsOrig );
00289 free( p->pMapToDdVarsFinal );
00290 free( p->pPlanes );
00291 free( p->pVarCosts );
00292 free( p->pLevelOrder );
00293
00294 p->pSupp = ALLOC( int, nDdVarsMax + 1 );
00295 p->pOrderInt = ALLOC( int, nDdVarsMax + 1 );
00296 p->pMapToPlanes = ALLOC( int, nDdVarsMax + 1 );
00297 p->pMapToDdVarsOrig = ALLOC( int, nDdVarsMax + 1 );
00298 p->pMapToDdVarsFinal = ALLOC( int, nDdVarsMax + 1 );
00299 p->pPlanes = CALLOC( reo_plane, nDdVarsMax + 1 );
00300 p->pVarCosts = ALLOC( double, nDdVarsMax + 1 );
00301 p->pLevelOrder = ALLOC( int, nDdVarsMax + 1 );
00302 p->nSuppAlloc = nDdVarsMax + 1;
00303 }
00304
00305
00306 if ( p->nRefNodesAlloc == 0 )
00307 {
00308 p->nNodesMaxAlloc = nNodesMax;
00309 p->nTableSize = 3*nNodesMax + 1;
00310 p->nRefNodesAlloc = 3*nNodesMax + 1;
00311 p->nMemChunksAlloc = (10*nNodesMax + 1)/REO_CHUNK_SIZE + 1;
00312
00313 p->HTable = CALLOC( reo_hash, p->nTableSize );
00314 p->pRefNodes = ALLOC( DdNode *, p->nRefNodesAlloc );
00315 p->pWidthCofs = ALLOC( reo_unit *, p->nRefNodesAlloc );
00316 p->pMemChunks = ALLOC( reo_unit *, p->nMemChunksAlloc );
00317 }
00318 else if ( p->nNodesMaxAlloc < nNodesMax )
00319 {
00320 void * pTemp;
00321 int nMemChunksAllocPrev = p->nMemChunksAlloc;
00322
00323 p->nNodesMaxAlloc = nNodesMax;
00324 p->nTableSize = 3*nNodesMax + 1;
00325 p->nRefNodesAlloc = 3*nNodesMax + 1;
00326 p->nMemChunksAlloc = (10*nNodesMax + 1)/REO_CHUNK_SIZE + 1;
00327
00328 free( p->HTable );
00329 free( p->pRefNodes );
00330 free( p->pWidthCofs );
00331 p->HTable = CALLOC( reo_hash, p->nTableSize );
00332 p->pRefNodes = ALLOC( DdNode *, p->nRefNodesAlloc );
00333 p->pWidthCofs = ALLOC( reo_unit *, p->nRefNodesAlloc );
00334
00335 pTemp = ALLOC( reo_unit *, p->nMemChunksAlloc );
00336 memmove( pTemp, p->pMemChunks, sizeof(reo_unit *) * nMemChunksAllocPrev );
00337 free( p->pMemChunks );
00338 p->pMemChunks = pTemp;
00339 }
00340
00341
00342 if ( p->nTopsAlloc == 0 )
00343 {
00344 p->pTops = ALLOC( reo_unit *, nFuncs );
00345 p->nTopsAlloc = nFuncs;
00346 }
00347 else if ( p->nTopsAlloc < nFuncs )
00348 {
00349 free( p->pTops );
00350 p->pTops = ALLOC( reo_unit *, nFuncs );
00351 p->nTopsAlloc = nFuncs;
00352 }
00353 }
00354
00355
00367 int reoRecursiveDeref( reo_unit * pUnit )
00368 {
00369 reo_unit * pUnitR;
00370 pUnitR = Unit_Regular(pUnit);
00371 pUnitR->n--;
00372 if ( Unit_IsConstant(pUnitR) )
00373 return 1;
00374 if ( pUnitR->n == 0 )
00375 {
00376 reoRecursiveDeref( pUnitR->pE );
00377 reoRecursiveDeref( pUnitR->pT );
00378 }
00379 return 1;
00380 }
00381
00393 int reoCheckZeroRefs( reo_plane * pPlane )
00394 {
00395 reo_unit * pUnit;
00396 for ( pUnit = pPlane->pHead; pUnit; pUnit = pUnit->Next )
00397 {
00398 if ( pUnit->n != 0 )
00399 {
00400 assert( 0 );
00401 }
00402 }
00403 return 1;
00404 }
00405
00417 int reoCheckLevels( reo_man * p )
00418 {
00419 reo_unit * pUnit;
00420 int i;
00421
00422 for ( i = 0; i < p->nSupp; i++ )
00423 {
00424
00425 assert( p->pPlanes[i].statsNodes );
00426 for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next )
00427 {
00428
00429 assert( pUnit->lev == i );
00430 }
00431 }
00432 return 1;
00433 }
00434
00438