ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
rwrEva.c
Go to the documentation of this file.
1
20
21#include "rwr.h"
22#include "bool/dec/dec.h"
23#include "aig/ivy/ivy.h"
24
26
27
31
32static Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, int fPlaceEnable );
33static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
34static int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut );
35static int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
36
40
59int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUpdateLevel, int fUseZeros, int fPlaceEnable )
60{
61 int fVeryVerbose = 0;
62 Dec_Graph_t * pGraph;
63 Cut_Cut_t * pCut;//, * pTemp;
64 Abc_Obj_t * pFanin;
65 unsigned uPhase;
66 unsigned uTruthBest = 0; // Suppress "might be used uninitialized"
67 unsigned uTruth;
68 char * pPerm;
69 int Required, nNodesSaved;
70 int nNodesSaveCur = -1; // Suppress "might be used uninitialized"
71 int i, GainCur = -1, GainBest = -1;
72 abctime clk, clk2;//, Counter;
73
74 p->nNodesConsidered++;
75 // get the required times
76 Required = fUpdateLevel? Abc_ObjRequiredLevel(pNode) : ABC_INFINITY;
77
78 // get the node's cuts
79clk = Abc_Clock();
80 pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 );
81 assert( pCut != NULL );
82p->timeCut += Abc_Clock() - clk;
83
84//printf( " %d", Rwr_CutCountNumNodes(pNode, pCut) );
85/*
86 Counter = 0;
87 for ( pTemp = pCut->pNext; pTemp; pTemp = pTemp->pNext )
88 Counter++;
89 printf( "%d ", Counter );
90*/
91 // go through the cuts
92clk = Abc_Clock();
93 for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
94 {
95 // consider only 4-input cuts
96 if ( pCut->nLeaves < 4 )
97 continue;
98// Cut_CutPrint( pCut, 0 ), printf( "\n" );
99
100 // get the fanin permutation
101 uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
102 pPerm = p->pPerms4[ (int)p->pPerms[uTruth] ];
103 uPhase = p->pPhases[uTruth];
104 // collect fanins with the corresponding permutation/phase
105 Vec_PtrClear( p->vFaninsCur );
106 Vec_PtrFill( p->vFaninsCur, (int)pCut->nLeaves, 0 );
107 for ( i = 0; i < (int)pCut->nLeaves; i++ )
108 {
109 pFanin = Abc_NtkObj( pNode->pNtk, pCut->pLeaves[(int)pPerm[i]] );
110 if ( pFanin == NULL )
111 break;
112 pFanin = Abc_ObjNotCond(pFanin, ((uPhase & (1<<i)) > 0) );
113 Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
114 }
115 if ( i != (int)pCut->nLeaves )
116 {
117 p->nCutsBad++;
118 continue;
119 }
120 p->nCutsGood++;
121
122 {
123 int Counter = 0;
124 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
125 if ( Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) == 1 )
126 Counter++;
127 if ( Counter > 2 )
128 continue;
129 }
130
131clk2 = Abc_Clock();
132/*
133 printf( "Considering: (" );
134 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
135 printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) );
136 printf( ")\n" );
137*/
138 // mark the fanin boundary
139 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
140 Abc_ObjRegular(pFanin)->vFanouts.nSize++;
141
142 // label MFFC with current ID
143 Abc_NtkIncrementTravId( pNode->pNtk );
144 nNodesSaved = Abc_NodeMffcLabelAig( pNode );
145 // unmark the fanin boundary
146 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
147 Abc_ObjRegular(pFanin)->vFanouts.nSize--;
148p->timeMffc += Abc_Clock() - clk2;
149
150 // evaluate the cut
151clk2 = Abc_Clock();
152 pGraph = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, fPlaceEnable );
153p->timeEval += Abc_Clock() - clk2;
154
155 // check if the cut is better than the current best one
156 if ( pGraph != NULL && GainBest < GainCur )
157 {
158 // save this form
159 nNodesSaveCur = nNodesSaved;
160 GainBest = GainCur;
161 p->pGraph = pGraph;
162 p->fCompl = ((uPhase & (1<<4)) > 0);
163 uTruthBest = 0xFFFF & *Cut_CutReadTruth(pCut);
164 // collect fanins in the
165 Vec_PtrClear( p->vFanins );
166 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
167 Vec_PtrPush( p->vFanins, pFanin );
168 }
169 }
170p->timeRes += Abc_Clock() - clk;
171
172 if ( GainBest == -1 )
173 return -1;
174/*
175 if ( GainBest > 0 )
176 {
177 printf( "Class %d ", p->pMap[uTruthBest] );
178 printf( "Gain = %d. Node %d : ", GainBest, pNode->Id );
179 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanins, pFanin, i )
180 printf( "%d ", Abc_ObjRegular(pFanin)->Id );
181 Dec_GraphPrint( stdout, p->pGraph, NULL, NULL );
182 printf( "\n" );
183 }
184*/
185
186// printf( "%d", nNodesSaveCur - GainBest );
187/*
188 if ( GainBest > 0 )
189 {
190 if ( Rwr_CutIsBoolean( pNode, p->vFanins ) )
191 printf( "b" );
192 else
193 {
194 printf( "Node %d : ", pNode->Id );
195 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanins, pFanin, i )
196 printf( "%d ", Abc_ObjRegular(pFanin)->Id );
197 printf( "a" );
198 }
199 }
200*/
201/*
202 if ( GainBest > 0 )
203 if ( p->fCompl )
204 printf( "c" );
205 else
206 printf( "." );
207*/
208
209 // copy the leaves
210 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanins, pFanin, i )
211 Dec_GraphNode((Dec_Graph_t *)p->pGraph, i)->pFunc = pFanin;
212/*
213 printf( "(" );
214 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanins, pFanin, i )
215 printf( " %d", Abc_ObjRegular(pFanin)->vFanouts.nSize - 1 );
216 printf( " ) " );
217*/
218// printf( "%d ", Rwr_NodeGetDepth_rec( pNode, p->vFanins ) );
219
220 p->nScores[p->pMap[uTruthBest]]++;
221 p->nNodesGained += GainBest;
222 if ( fUseZeros || GainBest > 0 )
223 {
224 p->nNodesRewritten++;
225 }
226
227 // report the progress
228 if ( fVeryVerbose && GainBest > 0 )
229 {
230 printf( "Node %6s : ", Abc_ObjName(pNode) );
231 printf( "Fanins = %d. ", p->vFanins->nSize );
232 printf( "Save = %d. ", nNodesSaveCur );
233 printf( "Add = %d. ", nNodesSaveCur-GainBest );
234 printf( "GAIN = %d. ", GainBest );
235 printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum((Dec_Graph_t *)p->pGraph) : 0 );
236 printf( "Class = %d. ", p->pMap[uTruthBest] );
237 printf( "\n" );
238 }
239 return GainBest;
240}
241
253Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, int fPlaceEnable )
254{
255 extern int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax );
256 Vec_Ptr_t * vSubgraphs;
257 Dec_Graph_t * pGraphBest = NULL; // Suppress "might be used uninitialized"
258 Dec_Graph_t * pGraphCur;
259 Rwr_Node_t * pNode, * pFanin;
260 int nNodesAdded, GainBest, i, k;
261 unsigned uTruth;
262 float CostBest;//, CostCur;
263 // find the matching class of subgraphs
264 uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
265 vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] );
266 p->nSubgraphs += vSubgraphs->nSize;
267 // determine the best subgraph
268 GainBest = -1;
269 CostBest = ABC_INFINITY;
270 Vec_PtrForEachEntry( Rwr_Node_t *, vSubgraphs, pNode, i )
271 {
272 // get the current graph
273 pGraphCur = (Dec_Graph_t *)pNode->pNext;
274 // copy the leaves
275 Vec_PtrForEachEntry( Rwr_Node_t *, vFaninsCur, pFanin, k )
276 Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
277 // detect how many unlabeled nodes will be reused
278 nNodesAdded = Dec_GraphToNetworkCount( pRoot, pGraphCur, nNodesSaved, LevelMax );
279 if ( nNodesAdded == -1 )
280 continue;
281 assert( nNodesSaved >= nNodesAdded );
282/*
283 // evaluate the cut
284 if ( fPlaceEnable )
285 {
286 extern float Abc_PlaceEvaluateCut( Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins );
287
288 float Alpha = 0.5; // ???
289 float PlaceCost;
290
291 // get the placement cost of the cut
292 PlaceCost = Abc_PlaceEvaluateCut( pRoot, vFaninsCur );
293
294 // get the weigted cost of the cut
295 CostCur = nNodesSaved - nNodesAdded + Alpha * PlaceCost;
296
297 // do not allow uphill moves
298 if ( nNodesSaved - nNodesAdded < 0 )
299 continue;
300
301 // decide what cut to use
302 if ( CostBest > CostCur )
303 {
304 GainBest = nNodesSaved - nNodesAdded; // pure node cost
305 CostBest = CostCur; // cost with placement
306 pGraphBest = pGraphCur; // subgraph to be used for rewriting
307
308 // score the graph
309 if ( nNodesSaved - nNodesAdded > 0 )
310 {
311 pNode->nScore++;
312 pNode->nGain += GainBest;
313 pNode->nAdded += nNodesAdded;
314 }
315 }
316 }
317 else
318*/
319 {
320 // count the gain at this node
321 if ( GainBest < nNodesSaved - nNodesAdded )
322 {
323 GainBest = nNodesSaved - nNodesAdded;
324 pGraphBest = pGraphCur;
325
326 // score the graph
327 if ( nNodesSaved - nNodesAdded > 0 )
328 {
329 pNode->nScore++;
330 pNode->nGain += GainBest;
331 pNode->nAdded += nNodesAdded;
332 }
333 }
334 }
335 }
336 if ( GainBest == -1 )
337 return NULL;
338 *pGainBest = GainBest;
339 return pGraphBest;
340}
341
353void Rwr_CutIsBoolean_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves, int fMarkA )
354{
355 if ( Vec_PtrFind(vLeaves, pObj) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pObj)) >= 0 )
356 {
357 if ( fMarkA )
358 pObj->fMarkA = 1;
359 else
360 pObj->fMarkB = 1;
361 return;
362 }
363 assert( !Abc_ObjIsCi(pObj) );
364 Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, fMarkA );
365 Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, fMarkA );
366}
367
379int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
380{
381 Abc_Obj_t * pTemp;
382 int i, RetValue;
383 Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pTemp, i )
384 {
385 pTemp = Abc_ObjRegular(pTemp);
386 assert( !pTemp->fMarkA && !pTemp->fMarkB );
387 }
388 Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, 1 );
389 Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, 0 );
390 RetValue = 0;
391 Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pTemp, i )
392 {
393 pTemp = Abc_ObjRegular(pTemp);
394 RetValue |= pTemp->fMarkA && pTemp->fMarkB;
395 pTemp->fMarkA = pTemp->fMarkB = 0;
396 }
397 return RetValue;
398}
399
400
413{
414 int i;
415 for ( i = 0; i < (int)pCut->nLeaves; i++ )
416 if ( pCut->pLeaves[i] == pObj->Id )
417 {
418 // check if the node is collected
419 if ( pObj->fMarkC == 0 )
420 {
421 pObj->fMarkC = 1;
422 Vec_PtrPush( vNodes, pObj );
423 }
424 return;
425 }
426 assert( Abc_ObjIsNode(pObj) );
427 // check if the node is collected
428 if ( pObj->fMarkC == 0 )
429 {
430 pObj->fMarkC = 1;
431 Vec_PtrPush( vNodes, pObj );
432 }
433 // traverse the fanins
434 Rwr_CutCountNumNodes_rec( Abc_ObjFanin0(pObj), pCut, vNodes );
435 Rwr_CutCountNumNodes_rec( Abc_ObjFanin1(pObj), pCut, vNodes );
436}
437
449int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut )
450{
451 Vec_Ptr_t * vNodes;
452 int i, Counter;
453 // collect all nodes
454 vNodes = Vec_PtrAlloc( 100 );
455 for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
456 Rwr_CutCountNumNodes_rec( pObj, pCut, vNodes );
457 // clean all nodes
458 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
459 pObj->fMarkC = 0;
460 // delete and return
461 Counter = Vec_PtrSize(vNodes);
462 Vec_PtrFree( vNodes );
463 return Counter;
464}
465
466
478int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
479{
480 Abc_Obj_t * pLeaf;
481 int i, Depth0, Depth1;
482 if ( Abc_ObjIsCi(pObj) )
483 return 0;
484 Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pLeaf, i )
485 if ( pObj == Abc_ObjRegular(pLeaf) )
486 return 0;
487 Depth0 = Rwr_NodeGetDepth_rec( Abc_ObjFanin0(pObj), vLeaves );
488 Depth1 = Rwr_NodeGetDepth_rec( Abc_ObjFanin1(pObj), vLeaves );
489 return 1 + Abc_MaxInt( Depth0, Depth1 );
490}
491
492
505{
506 Vec_Ptr_t * vSubgraphs;
507 Rwr_Node_t * pNode;
508 int i, k;
509 for ( i = 0; i < p->vClasses->nSize; i++ )
510 {
511 vSubgraphs = Vec_VecEntry( p->vClasses, i );
512 Vec_PtrForEachEntry( Rwr_Node_t *, vSubgraphs, pNode, k )
513 pNode->nScore = pNode->nGain = pNode->nAdded = 0;
514 }
515}
516
517static int Gains[222];
518
530int Rwr_ScoresCompare( int * pNum1, int * pNum2 )
531{
532 if ( Gains[*pNum1] > Gains[*pNum2] )
533 return -1;
534 if ( Gains[*pNum1] < Gains[*pNum2] )
535 return 1;
536 return 0;
537}
538
551{
552 extern void Ivy_TruthDsdComputePrint( unsigned uTruth );
553 int Perm[222];
554 Vec_Ptr_t * vSubgraphs;
555 Rwr_Node_t * pNode;
556 int i, iNew, k;
557 unsigned uTruth;
558 // collect total gains
559 assert( p->vClasses->nSize == 222 );
560 for ( i = 0; i < p->vClasses->nSize; i++ )
561 {
562 Perm[i] = i;
563 Gains[i] = 0;
564 vSubgraphs = Vec_VecEntry( p->vClasses, i );
565 Vec_PtrForEachEntry( Rwr_Node_t *, vSubgraphs, pNode, k )
566 Gains[i] += pNode->nGain;
567 }
568 // sort the gains
569 qsort( Perm, (size_t)222, sizeof(int), (int (*)(const void *, const void *))Rwr_ScoresCompare );
570
571 // print classes
572 for ( i = 0; i < p->vClasses->nSize; i++ )
573 {
574 iNew = Perm[i];
575 if ( Gains[iNew] == 0 )
576 break;
577 vSubgraphs = Vec_VecEntry( p->vClasses, iNew );
578 printf( "CLASS %3d: Subgr = %3d. Total gain = %6d. ", iNew, Vec_PtrSize(vSubgraphs), Gains[iNew] );
579 uTruth = (unsigned)p->pMapInv[iNew];
580 Extra_PrintBinary( stdout, &uTruth, 16 );
581 printf( " " );
582 Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[iNew] | ((unsigned)p->pMapInv[iNew] << 16) );
583 Vec_PtrForEachEntry( Rwr_Node_t *, vSubgraphs, pNode, k )
584 {
585 if ( pNode->nScore == 0 )
586 continue;
587 printf( " %2d: S=%5d. A=%5d. G=%6d. ", k, pNode->nScore, pNode->nAdded, pNode->nGain );
588 Dec_GraphPrint( stdout, (Dec_Graph_t *)pNode->pNext, NULL, NULL );
589 }
590 }
591}
592
596
597
599
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
ABC_DLL int Abc_ObjRequiredLevel(Abc_Obj_t *pObj)
Definition abcTiming.c:1214
ABC_DLL int Abc_NodeMffcLabelAig(Abc_Obj_t *pNode)
Definition abcRefs.c:100
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
ABC_DLL void * Abc_NodeGetCutsRecursive(void *p, Abc_Obj_t *pObj, int fDag, int fTree)
Definition abcCut.c:412
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_INFINITY
MACRO DEFINITIONS ///.
Definition abc_global.h:250
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
struct Cut_ManStruct_t_ Cut_Man_t
BASIC TYPES ///.
Definition cut.h:48
struct Cut_CutStruct_t_ Cut_Cut_t
Definition cut.h:50
int Dec_GraphToNetworkCount(Abc_Obj_t *pRoot, Dec_Graph_t *pGraph, int NodeMax, int LevelMax)
Definition decAbc.c:167
void Dec_GraphPrint(FILE *pFile, Dec_Graph_t *pGraph, char *pNamesIn[], char *pNameOut)
FUNCTION DEFINITIONS ///.
Definition decPrint.c:49
struct Dec_Graph_t_ Dec_Graph_t
Definition dec.h:68
Cube * p
Definition exorList.c:222
void Extra_PrintBinary(FILE *pFile, unsigned Sign[], int nBits)
void Ivy_TruthDsdComputePrint(unsigned uTruth)
Definition ivyDsd.c:678
void Rwr_ScoresClean(Rwr_Man_t *p)
Definition rwrEva.c:504
void Rwr_ScoresReport(Rwr_Man_t *p)
Definition rwrEva.c:550
void Rwr_CutIsBoolean_rec(Abc_Obj_t *pObj, Vec_Ptr_t *vLeaves, int fMarkA)
Definition rwrEva.c:353
void Rwr_CutCountNumNodes_rec(Abc_Obj_t *pObj, Cut_Cut_t *pCut, Vec_Ptr_t *vNodes)
Definition rwrEva.c:412
int Rwr_NodeRewrite(Rwr_Man_t *p, Cut_Man_t *pManCut, Abc_Obj_t *pNode, int fUpdateLevel, int fUseZeros, int fPlaceEnable)
FUNCTION DEFINITIONS ///.
Definition rwrEva.c:59
int Rwr_ScoresCompare(int *pNum1, int *pNum2)
Definition rwrEva.c:530
struct Rwr_Man_t_ Rwr_Man_t
Definition rwr.h:47
struct Rwr_Node_t_ Rwr_Node_t
Definition rwr.h:48
unsigned fMarkC
Definition abc.h:136
Abc_Ntk_t * pNtk
Definition abc.h:130
int Id
Definition abc.h:132
unsigned fMarkB
Definition abc.h:135
unsigned fMarkA
Definition abc.h:134
int pLeaves[0]
Definition cut.h:89
unsigned nLeaves
Definition cut.h:84
Cut_Cut_t * pNext
Definition cut.h:88
short nGain
Definition rwr.h:103
short nAdded
Definition rwr.h:104
short nScore
Definition rwr.h:102
Rwr_Node_t * pNext
Definition rwr.h:112
#define assert(ex)
Definition util_old.h:213
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55