ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
reoCore.c
Go to the documentation of this file.
1
18
19#include "reo.h"
20
22
23
27
28static int reoRecursiveDeref( reo_unit * pUnit );
29static int reoCheckZeroRefs( reo_plane * pPlane );
30static int reoCheckLevels( reo_man * p );
31
34
38
50void reoReorderArray( reo_man * p, DdManager * dd, DdNode * Funcs[], DdNode * FuncsRes[], int nFuncs, int * pOrder )
51{
52 int Counter, i;
53
54 // set the initial parameters
55 p->dd = dd;
56 p->pOrder = pOrder;
57 p->nTops = nFuncs;
58 // get the initial number of nodes
59 p->nNodesBeg = Cudd_SharingSize( Funcs, nFuncs );
60 // resize the internal data structures of the manager if necessary
61 reoResizeStructures( p, ddMax(dd->size,dd->sizeZ), p->nNodesBeg, nFuncs );
62 // compute the support
63 p->pSupp = Extra_VectorSupportArray( dd, Funcs, nFuncs, p->pSupp );
64 // get the number of support variables
65 p->nSupp = 0;
66 for ( i = 0; i < dd->size; i++ )
67 p->nSupp += p->pSupp[i];
68
69 // if it is the constant function, no need to reorder
70 if ( p->nSupp == 0 )
71 {
72 for ( i = 0; i < nFuncs; i++ )
73 {
74 FuncsRes[i] = Funcs[i]; Cudd_Ref( FuncsRes[i] );
75 }
76 return;
77 }
78
79 // create the internal variable maps
80 // go through variable levels in the manager
81 Counter = 0;
82 for ( i = 0; i < dd->size; i++ )
83 if ( p->pSupp[ dd->invperm[i] ] )
84 {
85 p->pMapToPlanes[ dd->invperm[i] ] = Counter;
86 p->pMapToDdVarsOrig[Counter] = dd->invperm[i];
87 if ( !p->fRemapUp )
88 p->pMapToDdVarsFinal[Counter] = dd->invperm[i];
89 else
90 p->pMapToDdVarsFinal[Counter] = dd->invperm[Counter];
91 p->pOrderInt[Counter] = Counter;
92 Counter++;
93 }
94
95 // set the initial parameters
96 p->nUnitsUsed = 0;
97 p->nNodesCur = 0;
98 p->fThisIsAdd = 0;
99 p->Signature++;
100 // transfer the function from the CUDD package into REO"s internal data structure
101 for ( i = 0; i < nFuncs; i++ )
102 p->pTops[i] = reoTransferNodesToUnits_rec( p, Funcs[i] );
103 assert( p->nNodesBeg == p->nNodesCur );
104
105 if ( !p->fThisIsAdd && p->fMinWidth )
106 {
107 printf( "An important message from the REO reordering engine:\n" );
108 printf( "The BDD given to the engine for reordering contains complemented edges.\n" );
109 printf( "Currently, such BDDs cannot be reordered for the minimum width.\n" );
110 printf( "Therefore, minimization for the number of BDD nodes is performed.\n" );
111 fflush( stdout );
112 p->fMinApl = 0;
113 p->fMinWidth = 0;
114 }
115
116 if ( p->fMinWidth )
118 else if ( p->fMinApl )
120 else
122
123 if ( p->fVerbose )
124 {
125 printf( "INITIAL:\n" );
126 if ( p->fMinWidth )
128 else if ( p->fMinApl )
130 else
132 }
133
135 // performs the reordering
136 p->nSwaps = 0;
137 p->nNISwaps = 0;
138 for ( i = 0; i < p->nIters; i++ )
139 {
140 reoReorderSift( p );
141 // print statistics after each iteration
142 if ( p->fVerbose )
143 {
144 printf( "ITER #%d:\n", i+1 );
145 if ( p->fMinWidth )
147 else if ( p->fMinApl )
149 else
151 }
152 // if the cost function did not change, stop iterating
153 if ( p->fMinWidth )
154 {
155 p->nWidthEnd = p->nWidthCur;
156 assert( p->nWidthEnd <= p->nWidthBeg );
157 if ( p->nWidthEnd == p->nWidthBeg )
158 break;
159 }
160 else if ( p->fMinApl )
161 {
162 p->nAplEnd = p->nAplCur;
163 assert( p->nAplEnd <= p->nAplBeg );
164 if ( p->nAplEnd == p->nAplBeg )
165 break;
166 }
167 else
168 {
169 p->nNodesEnd = p->nNodesCur;
170 assert( p->nNodesEnd <= p->nNodesBeg );
171 if ( p->nNodesEnd == p->nNodesBeg )
172 break;
173 }
174 }
175 assert( reoCheckLevels( p ) );
177
178s_AplBefore = p->nAplBeg;
179s_AplAfter = p->nAplEnd;
180
181 // set the initial parameters
182 p->nRefNodes = 0;
183 p->nNodesCur = 0;
184 p->Signature++;
185 // transfer the BDDs from REO's internal data structure to CUDD
186 for ( i = 0; i < nFuncs; i++ )
187 {
188 FuncsRes[i] = reoTransferUnitsToNodes_rec( p, p->pTops[i] ); Cudd_Ref( FuncsRes[i] );
189 }
190 // undo the DDs referenced for storing in the cache
191 for ( i = 0; i < p->nRefNodes; i++ )
192 Cudd_RecursiveDeref( dd, p->pRefNodes[i] );
193 // verify zero refs of the terminal nodes
194 for ( i = 0; i < nFuncs; i++ )
195 {
196 assert( reoRecursiveDeref( p->pTops[i] ) );
197 }
198 assert( reoCheckZeroRefs( &(p->pPlanes[p->nSupp]) ) );
199
200 // prepare the variable map to return to the user
201 if ( p->pOrder )
202 {
203 // i is the current level in the planes data structure
204 // p->pOrderInt[i] is the original level in the planes data structure
205 // p->pMapToDdVarsOrig[i] is the variable, into which we remap when we construct the BDD from planes
206 // p->pMapToDdVarsOrig[ p->pOrderInt[i] ] is the original BDD variable corresponding to this level
207 // Therefore, p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ]
208 // creates the permutation, which remaps the resulting BDD variable into the original BDD variable
209 for ( i = 0; i < p->nSupp; i++ )
210 p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ];
211 }
212
213 if ( p->fVerify )
214 {
215 int fVerification;
216 DdNode * FuncRemapped;
217 int * pOrder;
218
219 if ( p->pOrder == NULL )
220 {
221 pOrder = ABC_ALLOC( int, p->nSupp );
222 for ( i = 0; i < p->nSupp; i++ )
223 pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ];
224 }
225 else
226 pOrder = p->pOrder;
227
228 fVerification = 1;
229 for ( i = 0; i < nFuncs; i++ )
230 {
231 // verify the result
232 if ( p->fThisIsAdd )
233 FuncRemapped = Cudd_addPermute( dd, FuncsRes[i], pOrder );
234 else
235 FuncRemapped = Cudd_bddPermute( dd, FuncsRes[i], pOrder );
236 Cudd_Ref( FuncRemapped );
237
238 if ( FuncRemapped != Funcs[i] )
239 {
240 fVerification = 0;
241 printf( "REO: Internal verification has failed!\n" );
242 fflush( stdout );
243 }
244 Cudd_RecursiveDeref( dd, FuncRemapped );
245 }
246 if ( fVerification )
247 printf( "REO: Internal verification is okay!\n" );
248
249 if ( p->pOrder == NULL )
250 ABC_FREE( pOrder );
251 }
252
253 // recycle the data structure
254 for ( i = 0; i <= p->nSupp; i++ )
255 reoUnitsRecycleUnitList( p, p->pPlanes + i );
256}
257
269void reoResizeStructures( reo_man * p, int nDdVarsMax, int nNodesMax, int nFuncs )
270{
271 // resize data structures depending on the number of variables in the DD manager
272 if ( p->nSuppAlloc == 0 )
273 {
274 p->pSupp = ABC_ALLOC( int, nDdVarsMax + 1 );
275 p->pOrderInt = ABC_ALLOC( int, nDdVarsMax + 1 );
276 p->pMapToPlanes = ABC_ALLOC( int, nDdVarsMax + 1 );
277 p->pMapToDdVarsOrig = ABC_ALLOC( int, nDdVarsMax + 1 );
278 p->pMapToDdVarsFinal = ABC_ALLOC( int, nDdVarsMax + 1 );
279 p->pPlanes = ABC_CALLOC( reo_plane, nDdVarsMax + 1 );
280 p->pVarCosts = ABC_ALLOC( double, nDdVarsMax + 1 );
281 p->pLevelOrder = ABC_ALLOC( int, nDdVarsMax + 1 );
282 p->nSuppAlloc = nDdVarsMax + 1;
283 }
284 else if ( p->nSuppAlloc < nDdVarsMax )
285 {
286 ABC_FREE( p->pSupp );
287 ABC_FREE( p->pOrderInt );
288 ABC_FREE( p->pMapToPlanes );
289 ABC_FREE( p->pMapToDdVarsOrig );
290 ABC_FREE( p->pMapToDdVarsFinal );
291 ABC_FREE( p->pPlanes );
292 ABC_FREE( p->pVarCosts );
293 ABC_FREE( p->pLevelOrder );
294
295 p->pSupp = ABC_ALLOC( int, nDdVarsMax + 1 );
296 p->pOrderInt = ABC_ALLOC( int, nDdVarsMax + 1 );
297 p->pMapToPlanes = ABC_ALLOC( int, nDdVarsMax + 1 );
298 p->pMapToDdVarsOrig = ABC_ALLOC( int, nDdVarsMax + 1 );
299 p->pMapToDdVarsFinal = ABC_ALLOC( int, nDdVarsMax + 1 );
300 p->pPlanes = ABC_CALLOC( reo_plane, nDdVarsMax + 1 );
301 p->pVarCosts = ABC_ALLOC( double, nDdVarsMax + 1 );
302 p->pLevelOrder = ABC_ALLOC( int, nDdVarsMax + 1 );
303 p->nSuppAlloc = nDdVarsMax + 1;
304 }
305
306 // resize the data structures depending on the number of nodes
307 if ( p->nRefNodesAlloc == 0 )
308 {
309 p->nNodesMaxAlloc = nNodesMax;
310 p->nTableSize = 3*nNodesMax + 1;
311 p->nRefNodesAlloc = 3*nNodesMax + 1;
312 p->nMemChunksAlloc = (10*nNodesMax + 1)/REO_CHUNK_SIZE + 1;
313
314 p->HTable = ABC_CALLOC( reo_hash, p->nTableSize );
315 p->pRefNodes = ABC_ALLOC( DdNode *, p->nRefNodesAlloc );
316 p->pWidthCofs = ABC_ALLOC( reo_unit *, p->nRefNodesAlloc );
317 p->pMemChunks = ABC_ALLOC( reo_unit *, p->nMemChunksAlloc );
318 }
319 else if ( p->nNodesMaxAlloc < nNodesMax )
320 {
321 reo_unit ** pTemp;
322 int nMemChunksAllocPrev = p->nMemChunksAlloc;
323
324 p->nNodesMaxAlloc = nNodesMax;
325 p->nTableSize = 3*nNodesMax + 1;
326 p->nRefNodesAlloc = 3*nNodesMax + 1;
327 p->nMemChunksAlloc = (10*nNodesMax + 1)/REO_CHUNK_SIZE + 1;
328
329 ABC_FREE( p->HTable );
330 ABC_FREE( p->pRefNodes );
331 ABC_FREE( p->pWidthCofs );
332 p->HTable = ABC_CALLOC( reo_hash, p->nTableSize );
333 p->pRefNodes = ABC_ALLOC( DdNode *, p->nRefNodesAlloc );
334 p->pWidthCofs = ABC_ALLOC( reo_unit *, p->nRefNodesAlloc );
335 // p->pMemChunks should be reallocated because it contains pointers currently in use
336 pTemp = ABC_ALLOC( reo_unit *, p->nMemChunksAlloc );
337 memmove( pTemp, p->pMemChunks, sizeof(reo_unit *) * nMemChunksAllocPrev );
338 ABC_FREE( p->pMemChunks );
339 p->pMemChunks = pTemp;
340 }
341
342 // resize the data structures depending on the number of functions
343 if ( p->nTopsAlloc == 0 )
344 {
345 p->pTops = ABC_ALLOC( reo_unit *, nFuncs );
346 p->nTopsAlloc = nFuncs;
347 }
348 else if ( p->nTopsAlloc < nFuncs )
349 {
350 ABC_FREE( p->pTops );
351 p->pTops = ABC_ALLOC( reo_unit *, nFuncs );
352 p->nTopsAlloc = nFuncs;
353 }
354}
355
356
368int reoRecursiveDeref( reo_unit * pUnit )
369{
370 reo_unit * pUnitR;
371 pUnitR = Unit_Regular(pUnit);
372 pUnitR->n--;
373 if ( Unit_IsConstant(pUnitR) )
374 return 1;
375 if ( pUnitR->n == 0 )
376 {
377 reoRecursiveDeref( pUnitR->pE );
378 reoRecursiveDeref( pUnitR->pT );
379 }
380 return 1;
381}
382
394int reoCheckZeroRefs( reo_plane * pPlane )
395{
396 reo_unit * pUnit;
397 for ( pUnit = pPlane->pHead; pUnit; pUnit = pUnit->Next )
398 {
399 if ( pUnit->n != 0 )
400 {
401 assert( 0 );
402 }
403 }
404 return 1;
405}
406
418int reoCheckLevels( reo_man * p )
419{
420 reo_unit * pUnit;
421 int i;
422
423 for ( i = 0; i < p->nSupp; i++ )
424 {
425 // there are some nodes left on each level
426 assert( p->pPlanes[i].statsNodes );
427 for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next )
428 {
429 // the level is properly set
430 assert( pUnit->lev == i );
431 }
432 }
433 return 1;
434}
435
439
441
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
Cube * p
Definition exorList.c:222
int * Extra_VectorSupportArray(DdManager *dd, DdNode **F, int n, int *support)
void reoResizeStructures(reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs)
Definition reoCore.c:269
void reoReorderArray(reo_man *p, DdManager *dd, DdNode *Funcs[], DdNode *FuncsRes[], int nFuncs, int *pOrder)
FUNCTION DEFINITIONS ///.
Definition reoCore.c:50
double s_AplBefore
Definition reoCore.c:32
double s_AplAfter
Definition reoCore.c:33
reo_unit * reoTransferNodesToUnits_rec(reo_man *p, DdNode *F)
DECLARATIONS ///.
Definition reoTransfer.c:43
struct _reo_man reo_man
Definition reo.h:63
void reoProfileWidthStart(reo_man *p)
Definition reoProfile.c:130
void reoUnitsRecycleUnitList(reo_man *p, reo_plane *pPlane)
Definition reoUnits.c:87
#define Unit_IsConstant(u)
Definition reo.h:177
void reoReorderSift(reo_man *p)
DECLARATIONS ///.
Definition reoSift.c:44
void reoProfileNodesStart(reo_man *p)
DECLARATIONS ///.
Definition reoProfile.c:46
void reoProfileAplPrint(reo_man *p)
Definition reoProfile.c:305
DdNode * reoTransferUnitsToNodes_rec(reo_man *p, reo_unit *pUnit)
#define REO_CHUNK_SIZE
Definition reo.h:42
struct _reo_plane reo_plane
Definition reo.h:61
struct _reo_hash reo_hash
Definition reo.h:62
void reoProfileWidthPrint(reo_man *p)
Definition reoProfile.c:321
void reoProfileAplStart(reo_man *p)
Definition reoProfile.c:78
#define Unit_Regular(u)
Definition reo.h:174
void reoProfileNodesPrint(reo_man *p)
Definition reoProfile.c:289
struct _reo_unit reo_unit
DATA STRUCTURES ///.
Definition reo.h:60
reo_unit * pHead
Definition reo.h:90
reo_unit * Next
Definition reo.h:76
short lev
Definition reo.h:68
short n
Definition reo.h:71
reo_unit * pE
Definition reo.h:74
reo_unit * pT
Definition reo.h:75
#define assert(ex)
Definition util_old.h:213
char * memmove()