From b44a8f927b1824e36e6c08de05235440ee72f9de Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 25 Mar 2022 17:12:20 +0100 Subject: [PATCH 01/60] Fix some memory leaks --- src/aig/gia/giaCTas.c | 1 + src/base/abci/abcLutmin.c | 1 + src/base/abci/abcSaucy.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/src/aig/gia/giaCTas.c b/src/aig/gia/giaCTas.c index 3dded68b3..cd0b4f480 100644 --- a/src/aig/gia/giaCTas.c +++ b/src/aig/gia/giaCTas.c @@ -1778,6 +1778,7 @@ void Tas_ManSolveMiterNc2( Gia_Man_t * pAig, int nConfs, Gia_Man_t * pAigOld, Ve Tas_ManSatPrintStats( p ); Tas_ManStop( p ); Vec_PtrFree( vPres ); + Vec_StrFree( vStatus ); } diff --git a/src/base/abci/abcLutmin.c b/src/base/abci/abcLutmin.c index 7bac74bf5..11605eb14 100644 --- a/src/base/abci/abcLutmin.c +++ b/src/base/abci/abcLutmin.c @@ -112,6 +112,7 @@ void Abc_NtkCheckAbsorb( Abc_Ntk_t * pNtk, int nLutSize ) Counter, 100.0 * Counter / Abc_NtkNodeNum(pNtk), Counter2, 100.0 * Counter2 / Abc_NtkNodeNum(pNtk) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Vec_IntFree( vCounts ); } /**Function************************************************************* diff --git a/src/base/abci/abcSaucy.c b/src/base/abci/abcSaucy.c index e4d1cc42c..c62d6edcf 100644 --- a/src/base/abci/abcSaucy.c +++ b/src/base/abci/abcSaucy.c @@ -2483,6 +2483,8 @@ saucy_search( /* Keep running till we're out of automorphisms */ while (do_search(s)); + + ABC_FREE(g); } void From 7543778f2ca87494648a83eba915a5b9f7c2b53a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 7 Sep 2022 11:45:30 +0200 Subject: [PATCH 02/60] Enable loading of large liberty files --- src/map/scl/sclLiberty.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 49b5c2370..b448885dc 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -63,7 +63,7 @@ struct Scl_Tree_t_ { char * pFileName; // input Liberty file name char * pContents; // file contents - int nContents; // file size + long nContents; // file size int nLines; // line counter int nItems; // number of items int nItermAlloc; // number of items allocated @@ -506,10 +506,10 @@ void Scl_LibertyFixFileName( char * pFileName ) if ( *pHead == '>' ) *pHead = '\\'; } -int Scl_LibertyFileSize( char * pFileName ) +long Scl_LibertyFileSize( char * pFileName ) { FILE * pFile; - int nFileSize; + long nFileSize; pFile = fopen( pFileName, "rb" ); if ( pFile == NULL ) { @@ -521,7 +521,7 @@ int Scl_LibertyFileSize( char * pFileName ) fclose( pFile ); return nFileSize; } -char * Scl_LibertyFileContents( char * pFileName, int nContents ) +char * Scl_LibertyFileContents( char * pFileName, long nContents ) { FILE * pFile = fopen( pFileName, "rb" ); char * pContents = ABC_ALLOC( char, nContents+1 ); @@ -558,7 +558,7 @@ void Scl_LibertyStringDump( char * pFileName, Vec_Str_t * vStr ) Scl_Tree_t * Scl_LibertyStart( char * pFileName ) { Scl_Tree_t * p; - int RetValue; + long RetValue; // read the file into the buffer Scl_LibertyFixFileName( pFileName ); RetValue = Scl_LibertyFileSize( pFileName ); From 4f4bba2a47aed681a078cf5505d099d60242027a Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Fri, 30 Sep 2022 09:17:32 -0700 Subject: [PATCH 03/60] typo: Libery -> Liberty --- src/map/scl/sclLiberty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 49b5c2370..bbd05b154 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -858,7 +858,7 @@ int Scl_LibertyReadTimeUnit( Scl_Tree_t * p ) return 12; break; } - printf( "Libery parser cannot read \"time_unit\". Assuming time_unit : \"1ns\".\n" ); + printf( "Liberty parser cannot read \"time_unit\". Assuming time_unit : \"1ns\".\n" ); return 9; } void Scl_LibertyReadLoadUnit( Scl_Tree_t * p, Vec_Str_t * vOut ) @@ -878,7 +878,7 @@ void Scl_LibertyReadLoadUnit( Scl_Tree_t * p, Vec_Str_t * vOut ) else break; return; } - printf( "Libery parser cannot read \"capacitive_load_unit\". Assuming capacitive_load_unit(1, pf).\n" ); + printf( "Liberty parser cannot read \"capacitive_load_unit\". Assuming capacitive_load_unit(1, pf).\n" ); Vec_StrPutF_( vOut, 1.0 ); Vec_StrPutI_( vOut, 12 ); } From 7eff43de41bdad9216c9ab9680c9ae52baa5ea1e Mon Sep 17 00:00:00 2001 From: Jerry James Date: Wed, 16 Nov 2022 11:23:32 -0700 Subject: [PATCH 04/60] Fix two instances of use after free --- src/base/cmd/cmdLoad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c index bd511feca..1cf4d3ff9 100644 --- a/src/base/cmd/cmdLoad.c +++ b/src/base/cmd/cmdLoad.c @@ -58,8 +58,8 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv ) // check if there is the binary if ( (pFile = fopen( Vec_StrArray(vCommand), "r" )) == NULL ) { - Vec_StrFree( vCommand ); Abc_Print( -1, "Cannot run the binary \"%s\".\n\n", Vec_StrArray(vCommand) ); + Vec_StrFree( vCommand ); return 1; } fclose( pFile ); @@ -74,9 +74,9 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv ) // run the command line if ( Util_SignalSystem( Vec_StrArray(vCommand) ) ) { - Vec_StrFree( vCommand ); Abc_Print( -1, "The following command has returned non-zero exit status:\n" ); Abc_Print( -1, "\"%s\"\n", Vec_StrArray(vCommand) ); + Vec_StrFree( vCommand ); return 1; } Vec_StrFree( vCommand ); From 5a9f37cd93dfbe794ce4c0d639eef17c68a3d0cb Mon Sep 17 00:00:00 2001 From: Jerry James Date: Wed, 16 Nov 2022 11:38:38 -0700 Subject: [PATCH 05/60] Do not pass NULL to fprintf --- src/base/exor/exorUtil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/exor/exorUtil.c b/src/base/exor/exorUtil.c index 105a64903..bd0fcf277 100644 --- a/src/base/exor/exorUtil.c +++ b/src/base/exor/exorUtil.c @@ -189,7 +189,7 @@ int WriteResultIntoFile( char * pFileName ) pFile = fopen( pFileName, "w" ); if ( pFile == NULL ) { - fprintf( pFile, "\n\nCannot open the output file\n" ); + fprintf( stderr, "\n\nCannot open the output file\n" ); return 1; } From d785775f649b720d7d7abf648cc154aefaf77a67 Mon Sep 17 00:00:00 2001 From: Andrey Rogov Date: Fri, 28 Apr 2023 01:52:01 +0300 Subject: [PATCH 06/60] 1. Fix bug (using pDesign without check if == NULL) 2. Switch type of variables containing file size to (int => long) --- src/base/io/ioReadBlifMv.c | 10 +++++----- src/base/io/ioUtil.c | 4 +++- src/opt/sim/simUtils.c | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c index e5c6fe49e..c8c14581a 100644 --- a/src/base/io/ioReadBlifMv.c +++ b/src/base/io/ioReadBlifMv.c @@ -548,10 +548,10 @@ typedef struct buflist { struct buflist * next; } buflist; -char * Io_MvLoadFileBz2( char * pFileName, int * pnFileSize ) +char * Io_MvLoadFileBz2( char * pFileName, long * pnFileSize ) { FILE * pFile; - int nFileSize = 0; + long nFileSize = 0; char * pContents; BZFILE * b; int bzError, RetValue; @@ -628,12 +628,12 @@ char * Io_MvLoadFileBz2( char * pFileName, int * pnFileSize ) SeeAlso [] ***********************************************************************/ -static char * Io_MvLoadFileGz( char * pFileName, int * pnFileSize ) +static char * Io_MvLoadFileGz( char * pFileName, long * pnFileSize ) { const int READ_BLOCK_SIZE = 100000; gzFile pFile; char * pContents; - int amtRead, readBlock, nFileSize = READ_BLOCK_SIZE; + long amtRead, readBlock, nFileSize = READ_BLOCK_SIZE; pFile = gzopen( pFileName, "rb" ); // if pFileName doesn't end in ".gz" then this acts as a passthrough to fopen pContents = ABC_ALLOC( char, nFileSize ); readBlock = 0; @@ -665,7 +665,7 @@ static char * Io_MvLoadFileGz( char * pFileName, int * pnFileSize ) static char * Io_MvLoadFile( char * pFileName ) { FILE * pFile; - int nFileSize; + long nFileSize; char * pContents; int RetValue; if ( !strncmp(pFileName+strlen(pFileName)-4,".bz2",4) ) diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c index ddfcc91a8..156c9c1a4 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -157,8 +157,10 @@ Abc_Ntk_t * Io_ReadNetlist( char * pFileName, Io_FileType_t FileType, int fCheck fprintf( stdout, "Reading network from file has failed.\n" ); return NULL; } - if ( fCheck && (Abc_NtkBlackboxNum(pNtk) || Abc_NtkWhiteboxNum(pNtk)) ) + + if ( fCheck && (Abc_NtkBlackboxNum(pNtk) || Abc_NtkWhiteboxNum(pNtk)) && pNtk->pDesign ) { + int i, fCycle = 0; Abc_Ntk_t * pModel; // fprintf( stdout, "Warning: The network contains hierarchy.\n" ); diff --git a/src/opt/sim/simUtils.c b/src/opt/sim/simUtils.c index dc05df0f5..771577ca5 100644 --- a/src/opt/sim/simUtils.c +++ b/src/opt/sim/simUtils.c @@ -60,7 +60,8 @@ Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, int fClean ) int i; assert( nSize > 0 && nWords > 0 ); vInfo = Vec_PtrAlloc( nSize ); - vInfo->pArray[0] = ABC_ALLOC( unsigned, nSize * nWords ); + vInfo->pArray[0] = ABC_ALLOC( unsigned, (long)nSize * (long)nWords ); + assert( vInfo->pArray[0]); if ( fClean ) memset( vInfo->pArray[0], 0, sizeof(unsigned) * nSize * nWords ); for ( i = 1; i < nSize; i++ ) From bbdfe37bf9aaca8260e2732b0c49a9887d5c920f Mon Sep 17 00:00:00 2001 From: Rajit Manohar Date: Sat, 24 Jun 2023 12:17:57 -0400 Subject: [PATCH 07/60] fix segv when obj is a primary input --- src/map/scl/sclSize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index ab3e3f3e6..a944fdf62 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -197,7 +197,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) while ( pObj && Abc_ObjIsNode(pObj) ) { i++; - nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(pObj)->pName) ); + nLength = Abc_MaxInt( nLength, strlen((Abc_SclObjCell(pObj) ? Abc_SclObjCell(pObj)->pName : "pi")) ); pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj ); } From 62b85322eadc7cb8be3946291a67f19d29fdb3a9 Mon Sep 17 00:00:00 2001 From: Rajit Manohar Date: Sat, 24 Jun 2023 12:34:24 -0400 Subject: [PATCH 08/60] no need to call strlen on a constant --- src/map/scl/sclSize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index a944fdf62..a6bfbeac7 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -197,7 +197,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) while ( pObj && Abc_ObjIsNode(pObj) ) { i++; - nLength = Abc_MaxInt( nLength, strlen((Abc_SclObjCell(pObj) ? Abc_SclObjCell(pObj)->pName : "pi")) ); + nLength = Abc_MaxInt( nLength, Abc_SclObjCell(pObj) ? strlen(Abc_SclObjCell(pObj)->pName) : 2 /* strlen("pi") */ ); pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj ); } From 373c5eccf37e6a9a89d8f9a41e66ee7fe76ff06b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 7 Jul 2023 13:12:22 -0700 Subject: [PATCH 09/60] Experiment with multipliers. --- src/base/wlc/wlcBlast.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 4ac2f31c0..4ec1a4902 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -575,6 +575,26 @@ void Wlc_BlastMultiplier( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, Wlc_BlastFullAdderCtrl( pNew, 1, pArgC[a], pArgS[a], Carry, &Carry, &pRes[nArgB+a], 0 ); //Vec_IntWriteEntry( vRes, nArgA + nArgB, Carry ); } +void Wlc_BlastMultiplierC( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vTemp, Vec_Int_t * vRes, int fSigned ) +{ + int * pRes, * pArgC, * pArgS, a, b, Carry = !fSigned; // change + assert( nArgA > 0 && nArgB > 0 ); + assert( fSigned == 0 || fSigned == 1 ); + Vec_IntFill( vRes, nArgA + nArgB, 0 ); + pRes = Vec_IntArray( vRes ); + Vec_IntFill( vTemp, 2 * nArgA, 1 ); // change + pArgC = Vec_IntArray( vTemp ); + pArgS = pArgC + nArgA; + for ( b = 0; b < nArgB; b++ ) + for ( a = 0; a < nArgA; a++ ) + Wlc_BlastFullAdderCtrl( pNew, pArgA[a], pArgB[b], pArgS[a], pArgC[a], + &pArgC[a], a ? &pArgS[a-1] : &pRes[b], !(fSigned && ((a+1 == nArgA) ^ (b+1 == nArgB))) ); // change + pArgS[nArgA-1] = !fSigned; // change + for ( a = 0; a < nArgA; a++ ) + Wlc_BlastFullAdderCtrl( pNew, 1, pArgC[a], pArgS[a], Carry, &Carry, &pRes[nArgB+a], 0 ); + for ( b = 0; b < nArgA + nArgB; b++ ) // change + pRes[b] = Abc_LitNot(pRes[b]); +} void Wlc_BlastDivider( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes ) { int * pRes = Wlc_VecCopy( vRes, pNum, nNum ); @@ -1817,6 +1837,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla, NULL ); else Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned ); + //Wlc_BlastMultiplierC( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned ); if ( nRange > Vec_IntSize(vRes) ) Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 ); else From a82bbaa91d7e9eae9ccab2d143638df26d7aaf52 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 7 Jul 2023 14:03:35 -0700 Subject: [PATCH 10/60] Bug fix in equiv class filtering. --- src/aig/gia/giaMini.c | 7 +++++++ src/proof/cec/cecSatG2.c | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 6ba85706d..c0473fea3 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -813,6 +813,13 @@ int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc ) printf( "Equivalence classes of internal GIA are not available.\n" ); return NULL; } + else if ( 0 ) + { + int i; + for ( i = 1; i < Gia_ManObjNum(pAbc->pGia2); i++ ) + if ( Gia_ObjHasRepr(pAbc->pGia2, i) ) + printf( "Obj %3d : Repr %3d Proved %d Failed %d\n", i, Gia_ObjRepr(pAbc->pGia2, i), Gia_ObjProved(pAbc->pGia2, i), Gia_ObjFailed(pAbc->pGia2, i) ); + } if ( Gia_ManObjNum(pAbc->pGia2) != Gia_ManObjNum(pAbc->pGiaMiniAig) ) printf( "Internal GIA with equivalence classes is not directly derived from MiniAig.\n" ); // derive the set of equivalent node pairs diff --git a/src/proof/cec/cecSatG2.c b/src/proof/cec/cecSatG2.c index 00673c165..462064399 100644 --- a/src/proof/cec/cecSatG2.c +++ b/src/proof/cec/cecSatG2.c @@ -1731,7 +1731,21 @@ Gia_Obj_t * Cec4_ManFindRepr( Gia_Man_t * p, Cec4_Man_t * pMan, int iObj ) } void Gia_ManRemoveWrongChoices( Gia_Man_t * p ) { - int i, iObj, iPrev, Counter = 0; + int i = 0, iObj, iPrev, Counter = 0; + for ( iPrev = i, iObj = Gia_ObjNext(p, i); -1 < iObj; iObj = Gia_ObjNext(p, iPrev) ) + { + Gia_Obj_t * pRepr = Gia_ObjReprObj(p, iObj); + assert( pRepr = Gia_ManConst0(p) ); + if( !Gia_ObjFailed(p,iObj) && Abc_Lit2Var(Gia_ManObj(p,iObj)->Value) == Abc_Lit2Var(pRepr->Value) ) + { + iPrev = iObj; + continue; + } + Gia_ObjSetRepr( p, iObj, GIA_VOID ); + Gia_ObjSetNext( p, iPrev, Gia_ObjNext(p, iObj) ); + Gia_ObjSetNext( p, iObj, 0 ); + Counter++; + } Gia_ManForEachClass( p, i ) { for ( iPrev = i, iObj = Gia_ObjNext(p, i); -1 < iObj; iObj = Gia_ObjNext(p, iPrev) ) From e61194bbed8c2ba8aac1f2720ebe513a571ee664 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 8 Jul 2023 10:18:18 -0700 Subject: [PATCH 11/60] Bug fix. --- src/proof/cec/cecSatG2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/proof/cec/cecSatG2.c b/src/proof/cec/cecSatG2.c index 462064399..773bc6e3c 100644 --- a/src/proof/cec/cecSatG2.c +++ b/src/proof/cec/cecSatG2.c @@ -1735,7 +1735,7 @@ void Gia_ManRemoveWrongChoices( Gia_Man_t * p ) for ( iPrev = i, iObj = Gia_ObjNext(p, i); -1 < iObj; iObj = Gia_ObjNext(p, iPrev) ) { Gia_Obj_t * pRepr = Gia_ObjReprObj(p, iObj); - assert( pRepr = Gia_ManConst0(p) ); + assert( pRepr == Gia_ManConst0(p) ); if( !Gia_ObjFailed(p,iObj) && Abc_Lit2Var(Gia_ManObj(p,iObj)->Value) == Abc_Lit2Var(pRepr->Value) ) { iPrev = iObj; From c70de100023e779533aabc410f352b39f603b86c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 14 Jul 2023 20:06:22 -0700 Subject: [PATCH 12/60] Updating &saveaig command. --- src/base/abci/abc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 732b60c8f..b813917d5 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -31276,12 +31276,15 @@ usage: ***********************************************************************/ int Abc_CommandAbc9SaveAig( Abc_Frame_t * pAbc, int argc, char ** argv ) { - int c, fArea = 0; + int c, fClear = 0, fArea = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "cah" ) ) != EOF ) { switch ( c ) { + case 'c': + fClear ^= 1; + break; case 'a': fArea ^= 1; break; @@ -31296,16 +31299,24 @@ int Abc_CommandAbc9SaveAig( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Empty network.\n" ); return 1; } + if ( fClear && pAbc->pGiaSaved != NULL ) + { + Gia_ManStopP( &pAbc->pGiaSaved ); + return 0; + } if ( fArea && pAbc->pGiaSaved != NULL && Gia_ManAndNum(pAbc->pGiaSaved) <= Gia_ManAndNum(pAbc->pGia) ) return 0; + if ( !fArea && pAbc->pGiaSaved != NULL && !(Gia_ManLevelNum(pAbc->pGiaSaved) > Gia_ManLevelNum(pAbc->pGia) || (Gia_ManLevelNum(pAbc->pGiaSaved) == Gia_ManLevelNum(pAbc->pGia) && Gia_ManAndNum(pAbc->pGiaSaved) > Gia_ManAndNum(pAbc->pGia))) ) + return 0; // save the design as best Gia_ManStopP( &pAbc->pGiaSaved ); pAbc->pGiaSaved = Gia_ManDupWithAttributes( pAbc->pGia ); return 0; usage: - Abc_Print( -2, "usage: &saveaig [-ah]\n" ); + Abc_Print( -2, "usage: &saveaig [-cah]\n" ); Abc_Print( -2, "\t saves the current AIG into the internal storage\n" ); + Abc_Print( -2, "\t-c : toggle clearing the saved AIG [default = %s]\n", fClear? "yes": "no" ); Abc_Print( -2, "\t-a : toggle saving AIG with the smaller area [default = %s]\n", fArea? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; From 766f64e221fa7ec1ff6ffb7a36da62529474de1c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 14 Jul 2023 20:23:56 -0700 Subject: [PATCH 13/60] Updating 'sim' command to print input patterns. --- src/proof/fra/fraSim.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/proof/fra/fraSim.c b/src/proof/fra/fraSim.c index 2d2ee93ff..bc2180376 100644 --- a/src/proof/fra/fraSim.c +++ b/src/proof/fra/fraSim.c @@ -958,6 +958,12 @@ void Fra_SmlPrintOutputs( Fra_Sml_t * p, int nPatterns ) int i, k; for ( k = 0; k < nPatterns; k++ ) { + Aig_ManForEachCi( p->pAig, pObj, i ) + { + pSims = Fra_ObjSim( p, pObj->Id ); + printf( "%d", Abc_InfoHasBit( pSims, k ) ); + } + printf( " " ); ; Aig_ManForEachCo( p->pAig, pObj, i ) { pSims = Fra_ObjSim( p, pObj->Id ); From 5bb7fb76a71d1f8a14b9c89425af7f4b1d2e8827 Mon Sep 17 00:00:00 2001 From: Cunxi Yu Date: Sun, 16 Jul 2023 12:20:10 -0600 Subject: [PATCH 14/60] add orchestration function (local greedy); usage: orchestrate -h --- src/base/abci/abc.c | 190 ++ src/base/abci/abcOrchestration.c | 5333 ++++++++++++++++++++++++++++++ src/base/abci/module.make | 1 + 3 files changed, 5524 insertions(+) create mode 100644 src/base/abci/abcOrchestration.c diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index b813917d5..4e70d51f3 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -163,6 +163,7 @@ static int Abc_CommandLutExact ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAllExact ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTestExact ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMajGen ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandOrchestrate ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandComb ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -914,6 +915,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Synthesis", "varmin", Abc_CommandVarMin, 0 ); Cmd_CommandAdd( pAbc, "Synthesis", "faultclasses", Abc_CommandFaultClasses, 0 ); Cmd_CommandAdd( pAbc, "Synthesis", "exact", Abc_CommandExact, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "orchestrate", Abc_CommandOrchestrate, 1 ); Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_start", Abc_CommandBmsStart, 0 ); Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_stop", Abc_CommandBmsStop, 0 ); @@ -7345,6 +7347,194 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [Orchestration synthesis] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandOrchestrate( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup; + int c, RetValue; + + int nNodeSizeMax; + int nConeSizeMax; + int fUpdateLevel; + int fUseZeros_rwr; + int fUseZeros_ref; + int fUseDcs; + int RS_CUT_MIN = 4;//rs option + int RS_CUT_MAX = 16;//rs option + int nCutsMax; //rs option + int nNodesMax; //rs option + int nLevelsOdc; //rs option + + int fPrecompute; //rewrite option (not enabled) + int fPlaceEnable; //rewrite option (not enabled) + + int fVerbose; //rewrite/rs/rf verbose + int fVeryVerbose; //very verbose option for all + size_t NtkSize; + extern void Rwr_Precompute(); + + //local greedy + extern int Abc_NtkOrchLocal( Abc_Ntk_t * pNtk, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutsMax, int nNodesMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ); + //priority orch + extern int Abc_NtkOchestration( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, int sOpsOrder, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutsMax, int nNodesMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ); + // set defaults + nNodeSizeMax = 10; + nConeSizeMax = 16; + fUpdateLevel = 1; + fUseZeros_rwr = 1; + fUseZeros_ref = 1; + fUseDcs = 0; + fVerbose = 0; + fVeryVerbose = 0; + fPlaceEnable = 0; + fPrecompute = 0; + nCutsMax = 8; + nNodesMax = 1; + nLevelsOdc = 0; + + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "KNFZzlvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + nCutsMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCutsMax < 0 ) + goto usage; + break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nNodesMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nNodesMax < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + nLevelsOdc = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLevelsOdc < 0 ) + goto usage; + break; + case 'l': + fUpdateLevel ^= 1; + break; + case 'z': + fUseZeros_rwr ^= 1; + break; + case 'Z': + fUseZeros_ref ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'w': + fVeryVerbose ^= 1; + break; + case 'h': + goto usage; + break; + } + } + if ( fPrecompute ) + { + Rwr_Precompute(); + return 0; + } + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + if ( nCutsMax < RS_CUT_MIN || nCutsMax > RS_CUT_MAX ) + { + Abc_Print( -1, "Can only compute cuts for %d <= K <= %d.\n", RS_CUT_MIN, RS_CUT_MAX ); + return 1; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + Abc_Print( -1, "This command can only be applied to an AIG (run \"strash\").\n" ); + return 1; + } + if ( Abc_NtkGetChoiceNum(pNtk) ) + { + Abc_Print( -1, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" ); + return 1; + } + if ( nNodeSizeMax > 15 ) + { + Abc_Print( -1, "The cone size cannot exceed 15.\n" ); + return 1; + } + + if ( fUseDcs && nNodeSizeMax >= nConeSizeMax ) + { + Abc_Print( -1, "For don't-care to work, containing cone should be larger than collapsed node.\n" ); + return 1; + } + + // modify the current network + pDup = Abc_NtkDup( pNtk ); + RetValue = Abc_NtkOrchLocal( pNtk, fUseZeros_rwr, fUseZeros_ref, fPlaceEnable, nCutsMax, nNodesMax, nLevelsOdc, fUpdateLevel, fVerbose, fVeryVerbose, nNodeSizeMax, nConeSizeMax, fUseDcs ); + if ( RetValue == -1 ) + { + Abc_FrameReplaceCurrentNetwork( pAbc, pDup ); + printf( "An error occurred during computation. The original network is restored.\n" ); + } + else + { + Abc_NtkDelete( pDup ); + if ( RetValue == 0 ) + { + Abc_Print( 0, "Ochestration (local greedy) has failed.\n" ); + return 1; + } + } + return 0; + +usage: + Abc_Print( -2, "usage: orchestrate [-KNFZzlvwh]\n" ); + Abc_Print( -2, "\t performs technology-independent AIG synthesis using orchestration method (currently orchestrating rw/rf/rs)\n" ); + Abc_Print( -2, "\t-K : (resub)the max cut size (%d <= num <= %d) [default = %d]\n", RS_CUT_MIN, RS_CUT_MAX, nCutsMax ); + Abc_Print( -2, "\t-N : (resub)the max number of nodes to add (0 <= num <= 3) [default = %d]\n", nNodesMax ); + Abc_Print( -2, "\t-F : (resub)the number of fanout levels for ODC computation [default = %d]\n", nLevelsOdc ); + Abc_Print( -2, "\t-l : (resub/rw/refactor)toggle preserving the number of levels [default = %s]\n", fUpdateLevel? "yes": "no" ); + Abc_Print( -2, "\t-z : (rw)toggle using zero-cost replacements [default = %s]\n", fUseZeros_rwr? "yes": "no" ); + Abc_Print( -2, "\t-Z : (refactor)toggle using zero-cost replacements [default = %s]\n", fUseZeros_ref? "yes": "no" ); + Abc_Print( -2, "\t-v : (resub/rw/refactor)toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : (resub/rw/refactor)toggle detailed verbose printout [default = %s]\n", fVeryVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + + + + /**Function************************************************************* diff --git a/src/base/abci/abcOrchestration.c b/src/base/abci/abcOrchestration.c new file mode 100644 index 000000000..ba70b2f18 --- /dev/null +++ b/src/base/abci/abcOrchestration.c @@ -0,0 +1,5333 @@ +/**CFile**************************************************************** + + FileName [abcResub.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Resubstitution manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcResub.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ +#include +#include +#include +#include "base/abc/abc.h" +#include "bool/dec/dec.h" +#include "opt/rwr/rwr.h" +#include "bool/kit/kit.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk ); +extern void Abc_NodePrintCuts( Abc_Obj_t * pNode ); +extern void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); + +extern void Abc_PlaceBegin( Abc_Ntk_t * pNtk ); +extern void Abc_PlaceEnd( Abc_Ntk_t * pNtk ); +extern void Abc_PlaceUpdate( Vec_Ptr_t * vAddedCells, Vec_Ptr_t * vUpdatedNets ); + +#define ABC_RS_DIV1_MAX 150 // the max number of divisors to consider +#define ABC_RS_DIV2_MAX 500 // the max number of pair-wise divisors to consider + +typedef struct Abc_ManRes_t_ Abc_ManRes_t; +struct Abc_ManRes_t_ +{ + // paramers + int nLeavesMax; // the max number of leaves in the cone + int nDivsMax; // the max number of divisors in the cone + // representation of the cone + Abc_Obj_t * pRoot; // the root of the cone + int nLeaves; // the number of leaves + int nDivs; // the number of all divisor (including leaves) + int nMffc; // the size of MFFC + int nLastGain; // the gain the number of nodes + Vec_Ptr_t * vDivs; // the divisors + // representation of the simulation info + int nBits; // the number of simulation bits + int nWords; // the number of unsigneds for siminfo + Vec_Ptr_t * vSims; // simulation info + unsigned * pInfo; // pointer to simulation info + // observability don't-cares + unsigned * pCareSet; + // internal divisor storage + Vec_Ptr_t * vDivs1UP; // the single-node unate divisors + Vec_Ptr_t * vDivs1UN; // the single-node unate divisors + Vec_Ptr_t * vDivs1B; // the single-node binate divisors + Vec_Ptr_t * vDivs2UP0; // the double-node unate divisors + Vec_Ptr_t * vDivs2UP1; // the double-node unate divisors + Vec_Ptr_t * vDivs2UN0; // the double-node unate divisors + Vec_Ptr_t * vDivs2UN1; // the double-node unate divisors + // other data + Vec_Ptr_t * vTemp; // temporary array of nodes + // runtime statistics + abctime timeCut; + abctime timeTruth; + abctime timeRes; + abctime timeDiv; + abctime timeMffc; + abctime timeSim; + abctime timeRes1; + abctime timeResD; + abctime timeRes2; + abctime timeRes3; + abctime timeNtk; + abctime timeTotal; + // improvement statistics + int nUsedNodeC; + int nUsedNode0; + int nUsedNode1Or; + int nUsedNode1And; + int nUsedNode2Or; + int nUsedNode2And; + int nUsedNode2OrAnd; + int nUsedNode2AndOr; + int nUsedNode3OrAnd; + int nUsedNode3AndOr; + int nUsedNodeTotal; + int nTotalDivs; + int nTotalLeaves; + int nTotalGain; + int nNodesBeg; + int nNodesEnd; +}; + +// external procedures +static Abc_ManRes_t* Abc_ManResubStart( int nLeavesMax, int nDivsMax ); +static void Abc_ManResubStop( Abc_ManRes_t * p ); +static Dec_Graph_t * Abc_ManResubEval( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int nSteps, int fUpdateLevel, int fVerbose ); +static void Abc_ManResubCleanup( Abc_ManRes_t * p ); +static void Abc_ManResubPrint( Abc_ManRes_t * p ); + +// other procedures +static int Abc_ManResubCollectDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int Required ); +static void Abc_ManResubSimulate( Vec_Ptr_t * vDivs, int nLeaves, Vec_Ptr_t * vSims, int nLeavesMax, int nWords ); +static void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves ); + +static void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required ); +static void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required ); +static Dec_Graph_t * Abc_ManResubQuit( Abc_ManRes_t * p ); +static Dec_Graph_t * Abc_ManResubDivs0( Abc_ManRes_t * p ); +static Dec_Graph_t * Abc_ManResubDivs1( Abc_ManRes_t * p, int Required ); +static Dec_Graph_t * Abc_ManResubDivs12( Abc_ManRes_t * p, int Required ); +static Dec_Graph_t * Abc_ManResubDivs2( Abc_ManRes_t * p, int Required ); +static Dec_Graph_t * Abc_ManResubDivs3( Abc_ManRes_t * p, int Required ); + +static Vec_Ptr_t * Abc_CutFactorLarge( Abc_Obj_t * pNode, int nLeavesMax ); +static int Abc_CutVolumeCheck( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); + +extern abctime s_ResubTime; + +typedef struct Abc_ManRef_t_ Abc_ManRef_t; +struct Abc_ManRef_t_ +{ + int nNodeSizeMax; // the limit on the size of the supernode + int nConeSizeMax; // the limit on the size of the containing cone + int fVerbose; // the verbosity flag + Vec_Ptr_t * vVars; // truth tables + Vec_Ptr_t * vFuncs; // functions + Vec_Int_t * vMemory; // memory + Vec_Str_t * vCube; // temporary + Vec_Int_t * vForm; // temporary + Vec_Ptr_t * vVisited; // temporary + Vec_Ptr_t * vLeaves; // temporary + int nLastGain; + int nNodesConsidered; + int nNodesRefactored; + int nNodesGained; + int nNodesBeg; + int nNodesEnd; + abctime timeCut; + abctime timeTru; + abctime timeDcs; + abctime timeSop; + abctime timeFact; + abctime timeEval; + abctime timeRes; + abctime timeNtk; + abctime timeTotal; +}; +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +/** Function*********************************************************** + Rewrite +**********************************************************************/ + +int Abc_NtkRewrite3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rw, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable ) +{ + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + ProgressBar * pProgress; + Cut_Man_t * pManCut; + Rwr_Man_t * pManRwr; + Abc_Obj_t * pNode; + FILE *fpt; + Dec_Graph_t * pGraph; + int i, nNodes, nGain, fCompl; + int success = 0; + int fail = 0; + abctime clk, clkStart = Abc_Clock(); + assert( Abc_NtkIsStrash(pNtk) ); + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); +clk = Abc_Clock(); + pManCut = Abc_NtkStartCutManForRewrite( pNtk ); +Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); + pNtk->pManCut = pManCut; + + if ( fVeryVerbose ) + Rwr_ScoresClean( pManRwr ); + + pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); + nNodes = Abc_NtkObjNumMax(pNtk); + + printf("nNodes: %d\n", nNodes); + if ( pGain_rw ) *pGain_rw = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + fpt = fopen("rewrite_id_nGain.csv", "w"); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + //printf("rewrite: %d\n", pNode->Id); + Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( i >= nNodes ) + break; + if ( Abc_NodeIsPersistant(pNode) ) + { + Vec_IntPush( (*pGain_rw), -99); + fprintf(fpt, "%d, %d\n", pNode->Id, -99); + continue; + } + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + fprintf(fpt, "%d, %d\n", pNode->Id, -99); + Vec_IntPush( (*pGain_rw), -99); + continue; + } + nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros, fPlaceEnable ); + //printf("nGain3: %d id: %d\n", nGain, i); + fprintf(fpt, "%d, %d\n", pNode->Id, nGain); + Vec_IntPush( (*pGain_rw), nGain); + //printf("size of vector: %d\n", (**pGain_rw).nSize); + //printf("write nGain in vector.\n"); + + if ( !(nGain > 0 || (nGain == 0 && fUseZeros)) ){ + fail++; + continue; + } + success++; + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + //Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); + + if ( fCompl ) Dec_GraphComplement( pGraph ); + } + fclose(fpt); + printf("size of vector: %d\n", (**pGain_rw).nSize); + //printf("nGain in vector: %d\n", (**pGain_rw).pArray[61]); + Extra_ProgressBarStop( pProgress ); +Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); + pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk); + if ( fVerbose ) + Rwr_ManPrintStats( pManRwr ); + if ( fVeryVerbose ) + Rwr_ScoresReport( pManRwr ); + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCut ); + pNtk->pManCut = NULL; + + { + Abc_NtkReassignIds( pNtk ); + } + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkRewrite3: The network check has failed.\n" ); + return 0; + } + printf( "Abc_NtkRewrite3: success : %d; fail : %d\n", success, fail ); + return 1; +} + +Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk ) +{ + static Cut_Params_t Params, * pParams = &Params; + Cut_Man_t * pManCut; + Abc_Obj_t * pObj; + int i; + memset( pParams, 0, sizeof(Cut_Params_t) ); + pParams->nVarsMax = 4; // the max cut size ("k" of the k-feasible cuts) + pParams->nKeepMax = 250; // the max number of cuts kept at a node + pParams->fTruth = 1; // compute truth tables + pParams->fFilter = 1; // filter dominated cuts + pParams->fSeq = 0; // compute sequential cuts + pParams->fDrop = 0; // drop cuts on the fly + pParams->fVerbose = 0; // the verbosiness flag + pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); + pManCut = Cut_ManStart( pParams ); + if ( pParams->fDrop ) + Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) ); + Abc_NtkForEachCi( pNtk, pObj, i ) + if ( Abc_ObjFanoutNum(pObj) > 0 ) + Cut_NodeSetTriv( pManCut, pObj->Id ); + return pManCut; +} + +/******Function****************************************** + Refactor +********************************************************/ +word * Abc_NodeConeTruth_1( Vec_Ptr_t * vVars, Vec_Ptr_t * vFuncs, int nWordsMax, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited ) +{ + Abc_Obj_t * pNode; + word * pTruth0, * pTruth1, * pTruth = NULL; + int i, k, nWords = Abc_Truth6WordNum( Vec_PtrSize(vLeaves) ); + Abc_NodeConeCollect( &pRoot, 1, vLeaves, vVisited, 0 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pNode, i ) + pNode->pCopy = (Abc_Obj_t *)Vec_PtrEntry( vVars, i ); + for ( i = Vec_PtrSize(vFuncs); i < Vec_PtrSize(vVisited); i++ ) + Vec_PtrPush( vFuncs, ABC_ALLOC(word, nWordsMax) ); + Vec_PtrForEachEntry( Abc_Obj_t *, vVisited, pNode, i ) + { + assert( !Abc_ObjIsPi(pNode) ); + pTruth0 = (word *)Abc_ObjFanin0(pNode)->pCopy; + pTruth1 = (word *)Abc_ObjFanin1(pNode)->pCopy; + pTruth = (word *)Vec_PtrEntry( vFuncs, i ); + if ( Abc_ObjFaninC0(pNode) ) + { + if ( Abc_ObjFaninC1(pNode) ) + for ( k = 0; k < nWords; k++ ) + pTruth[k] = ~pTruth0[k] & ~pTruth1[k]; + else + for ( k = 0; k < nWords; k++ ) + pTruth[k] = ~pTruth0[k] & pTruth1[k]; + } + else + { + if ( Abc_ObjFaninC1(pNode) ) + for ( k = 0; k < nWords; k++ ) + pTruth[k] = pTruth0[k] & ~pTruth1[k]; + else + for ( k = 0; k < nWords; k++ ) + pTruth[k] = pTruth0[k] & pTruth1[k]; + } + pNode->pCopy = (Abc_Obj_t *)pTruth; + } + return pTruth; +} +int Abc_NodeConeIsConst0_1( word * pTruth, int nVars ) +{ + int k, nWords = Abc_Truth6WordNum( nVars ); + for ( k = 0; k < nWords; k++ ) + if ( pTruth[k] ) + return 0; + return 1; +} +int Abc_NodeConeIsConst1_1( word * pTruth, int nVars ) +{ + int k, nWords = Abc_Truth6WordNum( nVars ); + for ( k = 0; k < nWords; k++ ) + if ( ~pTruth[k] ) + return 0; + return 1; +} + + + +Dec_Graph_t * Abc_NodeRefactor_1( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose ) +{ + extern int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ); + int fVeryVerbose = 0; + int nVars = Vec_PtrSize(vFanins); + int nWordsMax = Abc_Truth6WordNum(p->nNodeSizeMax); + Dec_Graph_t * pFForm; + Abc_Obj_t * pFanin; + word * pTruth; + abctime clk; + int i, nNodesSaved, nNodesAdded, Required; + + p->nNodesConsidered++; + + Required = fUpdateLevel? Abc_ObjRequiredLevel(pNode) : ABC_INFINITY; +clk = Abc_Clock(); + pTruth = Abc_NodeConeTruth_1( p->vVars, p->vFuncs, nWordsMax, pNode, vFanins, p->vVisited ); +p->timeTru += Abc_Clock() - clk; + if ( pTruth == NULL ) + return NULL; + if ( Abc_NodeConeIsConst0_1(pTruth, nVars) || Abc_NodeConeIsConst1_1(pTruth, nVars) ) + { + p->nLastGain = Abc_NodeMffcSize( pNode ); + p->nNodesGained += p->nLastGain; + p->nNodesRefactored++; + return Abc_NodeConeIsConst0_1(pTruth, nVars) ? Dec_GraphCreateConst0() : Dec_GraphCreateConst1(); + } +clk = Abc_Clock(); + pFForm = (Dec_Graph_t *)Kit_TruthToGraph( (unsigned *)pTruth, nVars, p->vMemory ); +p->timeFact += Abc_Clock() - clk; + Vec_PtrForEachEntry( Abc_Obj_t *, vFanins, pFanin, i ) + pFanin->vFanouts.nSize++; + Abc_NtkIncrementTravId( pNode->pNtk ); + nNodesSaved = Abc_NodeMffcLabelAig( pNode ); + Vec_PtrForEachEntry( Abc_Obj_t *, vFanins, pFanin, i ) + { + pFanin->vFanouts.nSize--; + Dec_GraphNode(pFForm, i)->pFunc = pFanin; + } +clk = Abc_Clock(); + nNodesAdded = Dec_GraphToNetworkCount( pNode, pFForm, nNodesSaved, Required ); +p->timeEval += Abc_Clock() - clk; + if ( nNodesAdded == -1 || (nNodesAdded == nNodesSaved && !fUseZeros) ) + { + Dec_GraphFree( pFForm ); + return NULL; + } + + p->nLastGain = nNodesSaved - nNodesAdded; + p->nNodesGained += p->nLastGain; + p->nNodesRefactored++; + + if ( fVeryVerbose ) + { + printf( "Node %6s : ", Abc_ObjName(pNode) ); + printf( "Cone = %2d. ", vFanins->nSize ); + printf( "FF = %2d. ", 1 + Dec_GraphNodeNum(pFForm) ); + printf( "MFFC = %2d. ", nNodesSaved ); + printf( "Add = %2d. ", nNodesAdded ); + printf( "GAIN = %2d. ", p->nLastGain ); + printf( "\n" ); + } + return pFForm; +} + + + +Abc_ManRef_t * Abc_NtkManRefStart_1( int nNodeSizeMax, int nConeSizeMax, int fUseDcs, int fVerbose ) +{ + Abc_ManRef_t * p; + p = ABC_ALLOC( Abc_ManRef_t, 1 ); + memset( p, 0, sizeof(Abc_ManRef_t) ); + p->vCube = Vec_StrAlloc( 100 ); + p->vVisited = Vec_PtrAlloc( 100 ); + p->nNodeSizeMax = nNodeSizeMax; + p->nConeSizeMax = nConeSizeMax; + p->fVerbose = fVerbose; + p->vVars = Vec_PtrAllocTruthTables( Abc_MaxInt(nNodeSizeMax, 6) ); + p->vFuncs = Vec_PtrAlloc( 100 ); + p->vMemory = Vec_IntAlloc( 1 << 16 ); + return p; +} + +void Abc_NtkManRefStop_1( Abc_ManRef_t * p ) +{ + Vec_PtrFreeFree( p->vFuncs ); + Vec_PtrFree( p->vVars ); + Vec_IntFree( p->vMemory ); + Vec_PtrFree( p->vVisited ); + Vec_StrFree( p->vCube ); + ABC_FREE( p ); +} + +void Abc_NtkManRefPrintStats_1( Abc_ManRef_t * p ) +{ + printf( "Refactoring statistics:\n" ); + printf( "Nodes considered = %8d.\n", p->nNodesConsidered ); + printf( "Nodes refactored = %8d.\n", p->nNodesRefactored ); + printf( "Gain = %8d. (%6.2f %%).\n", p->nNodesBeg-p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg ); + ABC_PRT( "Cuts ", p->timeCut ); + ABC_PRT( "Resynthesis", p->timeRes ); + ABC_PRT( " BDD ", p->timeTru ); + ABC_PRT( " DCs ", p->timeDcs ); + ABC_PRT( " SOP ", p->timeSop ); + ABC_PRT( " FF ", p->timeFact ); + ABC_PRT( " Eval ", p->timeEval ); + ABC_PRT( "AIG update ", p->timeNtk ); + ABC_PRT( "TOTAL ", p->timeTotal ); +} + +int Abc_NtkRefactor3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_ref, int nNodeSizeMax, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose ) +{ + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + ProgressBar * pProgress; + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCut; + Dec_Graph_t * pFForm; + Vec_Ptr_t * vFanins; + Abc_Obj_t * pNode; + FILE *fpt; + abctime clk, clkStart = Abc_Clock(); + int i, nNodes, RetValue = 1; + + assert( Abc_NtkIsStrash(pNtk) ); + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + pManCut = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCut ); + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); + nNodes = Abc_NtkObjNumMax(pNtk); + printf("nNodes: %d\n", nNodes); + if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + fpt = fopen("refactor_id_nGain.csv", "w"); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + //printf("Refactor3 Id: %d\n", pNode->Id); + Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( Abc_NodeIsPersistant(pNode) ) + continue; + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + continue; + if ( i >= nNodes ) + break; +clk = Abc_Clock(); + vFanins = Abc_NodeFindCut( pManCut, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFForm = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + //printf("nLastGain3: %d\n", pManRef->nLastGain); + fprintf(fpt, "%d, %d\n", pNode->Id, pManRef->nLastGain); + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + + if ( pFForm == NULL ) + continue; +clk = Abc_Clock(); + +/* + if ( !Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFForm ); + RetValue = -1; + break; + } +*/ + +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFForm ); + } + fclose(fpt); + printf("size of vector: %d\n", (**pGain_ref).nSize); + //printf("nGain in vector: %d\n", (**pGain_ref).pArray[20]); + Extra_ProgressBarStop( pProgress ); +pManRef->timeTotal = Abc_Clock() - clkStart; + pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk); + + if ( fVerbose ) + Abc_NtkManRefPrintStats_1( pManRef ); + Abc_NtkManCutStop( pManCut ); + Abc_NtkManRefStop_1( pManRef ); + Abc_NtkReassignIds( pNtk ); + if ( RetValue != -1 ) + { + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkRefactor: The network check has failed.\n" ); + return 0; + } + } + return RetValue; +} +/**Function************************************************************* + + Synopsis [Performs incremental resynthesis of the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +int Abc_NtkResubstitute3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_res, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose ) +{ + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + ProgressBar * pProgress; + Abc_ManRes_t * pManRes; + Abc_ManCut_t * pManCut; + Odc_Man_t * pManOdc = NULL; + Dec_Graph_t * pFForm; + Vec_Ptr_t * vLeaves; + Abc_Obj_t * pNode; + FILE *fpt; + abctime clk, clkStart = Abc_Clock(); + abctime s_ResubTime; + int i, nNodes; + + assert( Abc_NtkIsStrash(pNtk) ); + + // cleanup the AIG + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + // start the managers + pManCut = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 ); + pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX ); + if ( nLevelsOdc > 0 ) + pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose ); + + // compute the reverse levels if level update is requested + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pNext = (Abc_Obj_t *)pNode->pData; + } + + // resynthesize each node once + pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); + nNodes = Abc_NtkObjNumMax(pNtk); + printf("nNodes: %d\n", nNodes); + if (pGain_res) *pGain_res = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + fpt = fopen("resub_id_nGain.csv", "w"); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + //printf("resub id: %d\n", pNode->Id); + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the constant node +// if ( Abc_NodeIsConst(pNode) ) +// continue; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + { + fprintf(fpt, "%d, %d\n", pNode->Id, -99); + Vec_IntPush((*pGain_res), -99); + continue; + } + // skip the nodes with many fanouts + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + fprintf(fpt, "%d, %d\n", pNode->Id, -99); + Vec_IntPush((*pGain_res), -99); + continue; + } + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; + + // compute a reconvergence-driven cut +clk = Abc_Clock(); + vLeaves = Abc_NodeFindCut( pManCut, pNode, 0 ); +// vLeaves = Abc_CutFactorLarge( pNode, nCutMax ); +pManRes->timeCut += Abc_Clock() - clk; +/* + if ( fVerbose && vLeaves ) + printf( "Node %6d : Leaves = %3d. Volume = %3d.\n", pNode->Id, Vec_PtrSize(vLeaves), Abc_CutVolumeCheck(pNode, vLeaves) ); + if ( vLeaves == NULL ) + continue; +*/ + // get the don't-cares + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } + + // evaluate this cut +clk = Abc_Clock(); + pFForm = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +// Vec_PtrFree( vLeaves ); +// Abc_ManResubCleanup( pManRes ); +pManRes->timeRes += Abc_Clock() - clk; + // put nGain in Vector + //printf("nLastGain3: %d\n", pManRes->nLastGain); + fprintf(fpt, "%d, %d\n", pNode->Id, pManRes->nLastGain); + Vec_IntPush((*pGain_res), pManRes->nLastGain); + // printf("size of vector %d\n", (**pGain).nSize); + if ( pFForm == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +/* + if ( pManRes->nLeaves == 4 && pManRes->nMffc == 2 && pManRes->nLastGain == 1 ) + { + printf( "%6d : L = %2d. V = %2d. Mffc = %2d. Divs = %3d. Up = %3d. Un = %3d. B = %3d.\n", + pNode->Id, pManRes->nLeaves, Abc_CutVolumeCheck(pNode, vLeaves), pManRes->nMffc, pManRes->nDivs, + pManRes->vDivs1UP->nSize, pManRes->vDivs1UN->nSize, pManRes->vDivs1B->nSize ); + Abc_ManResubPrintDivs( pManRes, pNode, vLeaves ); + } +*/ + +clk = Abc_Clock(); + //Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFForm ); + + } + fclose(fpt); + printf("size of vector %d\n", (**pGain_res).nSize); + //printf("nGain in vector: %d\n", (**pGain_res).pArray[20]); + Extra_ProgressBarStop( pProgress ); +pManRes->timeTotal = Abc_Clock() - clkStart; + pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk); + + // print statistics + if ( fVerbose ) + Abc_ManResubPrint( pManRes ); + + // delete the managers + Abc_ManResubStop( pManRes ); + Abc_NtkManCutStop( pManCut ); + if ( pManOdc ) Abc_NtkDontCareFree( pManOdc ); + + // clean the data field + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->pData = NULL; + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pData = pNode->pNext, pNode->pNext = NULL; + } + + // put the nodes into the DFS order and reassign their IDs + Abc_NtkReassignIds( pNtk ); +// Abc_AigCheckFaninOrder( pNtk->pManFunc ); + // fix the levels + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + // check + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkRefactor: The network check has failed.\n" ); + return 0; + } +s_ResubTime = Abc_Clock() - clkStart; + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_ManRes_t * Abc_ManResubStart( int nLeavesMax, int nDivsMax ) +{ + Abc_ManRes_t * p; + unsigned * pData; + int i, k; + assert( sizeof(unsigned) == 4 ); + p = ABC_ALLOC( Abc_ManRes_t, 1 ); + memset( p, 0, sizeof(Abc_ManRes_t) ); + p->nLeavesMax = nLeavesMax; + p->nDivsMax = nDivsMax; + p->vDivs = Vec_PtrAlloc( p->nDivsMax ); + // allocate simulation info + p->nBits = (1 << p->nLeavesMax); + p->nWords = (p->nBits <= 32)? 1 : (p->nBits / 32); + p->pInfo = ABC_ALLOC( unsigned, p->nWords * (p->nDivsMax + 1) ); + memset( p->pInfo, 0, sizeof(unsigned) * p->nWords * p->nLeavesMax ); + p->vSims = Vec_PtrAlloc( p->nDivsMax ); + for ( i = 0; i < p->nDivsMax; i++ ) + Vec_PtrPush( p->vSims, p->pInfo + i * p->nWords ); + // assign the care set + p->pCareSet = p->pInfo + p->nDivsMax * p->nWords; + Abc_InfoFill( p->pCareSet, p->nWords ); + // set elementary truth tables + for ( k = 0; k < p->nLeavesMax; k++ ) + { + pData = (unsigned *)p->vSims->pArray[k]; + for ( i = 0; i < p->nBits; i++ ) + if ( i & (1 << k) ) + pData[i>>5] |= (1 << (i&31)); + } + // create the remaining divisors + p->vDivs1UP = Vec_PtrAlloc( p->nDivsMax ); + p->vDivs1UN = Vec_PtrAlloc( p->nDivsMax ); + p->vDivs1B = Vec_PtrAlloc( p->nDivsMax ); + p->vDivs2UP0 = Vec_PtrAlloc( p->nDivsMax ); + p->vDivs2UP1 = Vec_PtrAlloc( p->nDivsMax ); + p->vDivs2UN0 = Vec_PtrAlloc( p->nDivsMax ); + p->vDivs2UN1 = Vec_PtrAlloc( p->nDivsMax ); + p->vTemp = Vec_PtrAlloc( p->nDivsMax ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManResubStop( Abc_ManRes_t * p ) +{ + Vec_PtrFree( p->vDivs ); + Vec_PtrFree( p->vSims ); + Vec_PtrFree( p->vDivs1UP ); + Vec_PtrFree( p->vDivs1UN ); + Vec_PtrFree( p->vDivs1B ); + Vec_PtrFree( p->vDivs2UP0 ); + Vec_PtrFree( p->vDivs2UP1 ); + Vec_PtrFree( p->vDivs2UN0 ); + Vec_PtrFree( p->vDivs2UN1 ); + Vec_PtrFree( p->vTemp ); + ABC_FREE( p->pInfo ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManResubPrint( Abc_ManRes_t * p ) +{ + printf( "Used constants = %6d. ", p->nUsedNodeC ); ABC_PRT( "Cuts ", p->timeCut ); + printf( "Used replacements = %6d. ", p->nUsedNode0 ); ABC_PRT( "Resub ", p->timeRes ); + printf( "Used single ORs = %6d. ", p->nUsedNode1Or ); ABC_PRT( " Div ", p->timeDiv ); + printf( "Used single ANDs = %6d. ", p->nUsedNode1And ); ABC_PRT( " Mffc ", p->timeMffc ); + printf( "Used double ORs = %6d. ", p->nUsedNode2Or ); ABC_PRT( " Sim ", p->timeSim ); + printf( "Used double ANDs = %6d. ", p->nUsedNode2And ); ABC_PRT( " 1 ", p->timeRes1 ); + printf( "Used OR-AND = %6d. ", p->nUsedNode2OrAnd ); ABC_PRT( " D ", p->timeResD ); + printf( "Used AND-OR = %6d. ", p->nUsedNode2AndOr ); ABC_PRT( " 2 ", p->timeRes2 ); + printf( "Used OR-2ANDs = %6d. ", p->nUsedNode3OrAnd ); ABC_PRT( "Truth ", p->timeTruth ); //ABC_PRT( " 3 ", p->timeRes3 ); + printf( "Used AND-2ORs = %6d. ", p->nUsedNode3AndOr ); ABC_PRT( "AIG ", p->timeNtk ); + printf( "TOTAL = %6d. ", p->nUsedNodeC + + p->nUsedNode0 + + p->nUsedNode1Or + + p->nUsedNode1And + + p->nUsedNode2Or + + p->nUsedNode2And + + p->nUsedNode2OrAnd + + p->nUsedNode2AndOr + + p->nUsedNode3OrAnd + + p->nUsedNode3AndOr + ); ABC_PRT( "TOTAL ", p->timeTotal ); + printf( "Total leaves = %8d.\n", p->nTotalLeaves ); + printf( "Total divisors = %8d.\n", p->nTotalDivs ); +// printf( "Total gain = %8d.\n", p->nTotalGain ); + printf( "Gain = %8d. (%6.2f %%).\n", p->nNodesBeg-p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +void Abc_ManResubCollectDivs_rec1( Abc_Obj_t * pNode, Vec_Ptr_t * vInternal ) +{ + // skip visited nodes + if ( Abc_NodeIsTravIdCurrent(pNode) ) + return; + Abc_NodeSetTravIdCurrent(pNode); + // collect the fanins + Abc_ManResubCollectDivs_rec1( Abc_ObjFanin0(pNode), vInternal ); + Abc_ManResubCollectDivs_rec1( Abc_ObjFanin1(pNode), vInternal ); + // collect the internal node + if ( pNode->fMarkA == 0 ) + Vec_PtrPush( vInternal, pNode ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ManResubCollectDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int Required ) +{ + Abc_Obj_t * pNode, * pFanout; + int i, k, Limit, Counter; + + Vec_PtrClear( p->vDivs1UP ); + Vec_PtrClear( p->vDivs1UN ); + Vec_PtrClear( p->vDivs1B ); + + // add the leaves of the cuts to the divisors + Vec_PtrClear( p->vDivs ); + Abc_NtkIncrementTravId( pRoot->pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pNode, i ) + { + Vec_PtrPush( p->vDivs, pNode ); + Abc_NodeSetTravIdCurrent( pNode ); + } + + // mark nodes in the MFFC + Vec_PtrForEachEntry( Abc_Obj_t *, p->vTemp, pNode, i ) + pNode->fMarkA = 1; + // collect the cone (without MFFC) + Abc_ManResubCollectDivs_rec1( pRoot, p->vDivs ); + // unmark the current MFFC + Vec_PtrForEachEntry( Abc_Obj_t *, p->vTemp, pNode, i ) + pNode->fMarkA = 0; + + // check if the number of divisors is not exceeded + if ( Vec_PtrSize(p->vDivs) - Vec_PtrSize(vLeaves) + Vec_PtrSize(p->vTemp) >= Vec_PtrSize(p->vSims) - p->nLeavesMax ) + return 0; + + // get the number of divisors to collect + Limit = Vec_PtrSize(p->vSims) - p->nLeavesMax - (Vec_PtrSize(p->vDivs) - Vec_PtrSize(vLeaves) + Vec_PtrSize(p->vTemp)); + + // explore the fanouts, which are not in the MFFC + Counter = 0; + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs, pNode, i ) + { + if ( Abc_ObjFanoutNum(pNode) > 100 ) + { +// printf( "%d ", Abc_ObjFanoutNum(pNode) ); + continue; + } + // if the fanout has both fanins in the set, add it + Abc_ObjForEachFanout( pNode, pFanout, k ) + { + if ( Abc_NodeIsTravIdCurrent(pFanout) || Abc_ObjIsCo(pFanout) || (int)pFanout->Level > Required ) + continue; + if ( Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pFanout)) && Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pFanout)) ) + { + if ( Abc_ObjFanin0(pFanout) == pRoot || Abc_ObjFanin1(pFanout) == pRoot ) + continue; + Vec_PtrPush( p->vDivs, pFanout ); + Abc_NodeSetTravIdCurrent( pFanout ); + // quit computing divisors if there is too many of them + if ( ++Counter == Limit ) + goto Quits; + } + } + } + +Quits : + // get the number of divisors + p->nDivs = Vec_PtrSize(p->vDivs); + + // add the nodes in the MFFC + Vec_PtrForEachEntry( Abc_Obj_t *, p->vTemp, pNode, i ) + Vec_PtrPush( p->vDivs, pNode ); + assert( pRoot == Vec_PtrEntryLast(p->vDivs) ); + + assert( Vec_PtrSize(p->vDivs) - Vec_PtrSize(vLeaves) <= Vec_PtrSize(p->vSims) - p->nLeavesMax ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves ) +{ + Abc_Obj_t * pFanin, * pNode; + int i, k; + // print the nodes + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs, pNode, i ) + { + if ( i < Vec_PtrSize(vLeaves) ) + { + printf( "%6d : %c\n", pNode->Id, 'a'+i ); + continue; + } + printf( "%6d : %2d = ", pNode->Id, i ); + // find the first fanin + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs, pFanin, k ) + if ( Abc_ObjFanin0(pNode) == pFanin ) + break; + if ( k < Vec_PtrSize(vLeaves) ) + printf( "%c", 'a' + k ); + else + printf( "%d", k ); + printf( "%s ", Abc_ObjFaninC0(pNode)? "\'" : "" ); + // find the second fanin + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs, pFanin, k ) + if ( Abc_ObjFanin1(pNode) == pFanin ) + break; + if ( k < Vec_PtrSize(vLeaves) ) + printf( "%c", 'a' + k ); + else + printf( "%d", k ); + printf( "%s ", Abc_ObjFaninC1(pNode)? "\'" : "" ); + if ( pNode == pRoot ) + printf( " root" ); + printf( "\n" ); + } + printf( "\n" ); +} + + +/**Function************************************************************* + + Synopsis [Performs simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManResubSimulate( Vec_Ptr_t * vDivs, int nLeaves, Vec_Ptr_t * vSims, int nLeavesMax, int nWords ) +{ + Abc_Obj_t * pObj; + unsigned * puData0, * puData1, * puData; + int i, k; + assert( Vec_PtrSize(vDivs) - nLeaves <= Vec_PtrSize(vSims) - nLeavesMax ); + // simulate + Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pObj, i ) + { + if ( i < nLeaves ) + { // initialize the leaf + pObj->pData = Vec_PtrEntry( vSims, i ); + continue; + } + // set storage for the node's simulation info + pObj->pData = Vec_PtrEntry( vSims, i - nLeaves + nLeavesMax ); + // get pointer to the simulation info + puData = (unsigned *)pObj->pData; + puData0 = (unsigned *)Abc_ObjFanin0(pObj)->pData; + puData1 = (unsigned *)Abc_ObjFanin1(pObj)->pData; + // simulate + if ( Abc_ObjFaninC0(pObj) && Abc_ObjFaninC1(pObj) ) + for ( k = 0; k < nWords; k++ ) + puData[k] = ~puData0[k] & ~puData1[k]; + else if ( Abc_ObjFaninC0(pObj) ) + for ( k = 0; k < nWords; k++ ) + puData[k] = ~puData0[k] & puData1[k]; + else if ( Abc_ObjFaninC1(pObj) ) + for ( k = 0; k < nWords; k++ ) + puData[k] = puData0[k] & ~puData1[k]; + else + for ( k = 0; k < nWords; k++ ) + puData[k] = puData0[k] & puData1[k]; + } + // normalize + Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pObj, i ) + { + puData = (unsigned *)pObj->pData; + pObj->fPhase = (puData[0] & 1); + if ( pObj->fPhase ) + for ( k = 0; k < nWords; k++ ) + puData[k] = ~puData[k]; + } +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +Dec_Graph_t * Abc_ManResubQuit0_1( Abc_Obj_t * pRoot, Abc_Obj_t * pObj ) +{ + Dec_Graph_t * pGraph; + Dec_Edge_t eRoot; + pGraph = Dec_GraphCreate( 1 ); + Dec_GraphNode( pGraph, 0 )->pFunc = pObj; + eRoot = Dec_EdgeCreate( 0, pObj->fPhase ); + Dec_GraphSetRoot( pGraph, eRoot ); + if ( pRoot->fPhase ) + Dec_GraphComplement( pGraph ); + return pGraph; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +Dec_Graph_t * Abc_ManResubQuit1_1( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1, int fOrGate ) +{ + Dec_Graph_t * pGraph; + Dec_Edge_t eRoot, eNode0, eNode1; + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj1) ); + pGraph = Dec_GraphCreate( 2 ); + Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0); + Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1); + eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ^ Abc_ObjIsComplement(pObj0) ); + eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ^ Abc_ObjIsComplement(pObj1) ); + if ( fOrGate ) + eRoot = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); + else + eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 ); + Dec_GraphSetRoot( pGraph, eRoot ); + if ( pRoot->fPhase ) + Dec_GraphComplement( pGraph ); + return pGraph; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +Dec_Graph_t * Abc_ManResubQuit21_1( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1, Abc_Obj_t * pObj2, int fOrGate ) +{ + Dec_Graph_t * pGraph; + Dec_Edge_t eRoot, eNode0, eNode1, eNode2; + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj1) ); + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj2) ); + assert( Abc_ObjRegular(pObj1) != Abc_ObjRegular(pObj2) ); + pGraph = Dec_GraphCreate( 3 ); + Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0); + Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1); + Dec_GraphNode( pGraph, 2 )->pFunc = Abc_ObjRegular(pObj2); + eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ^ Abc_ObjIsComplement(pObj0) ); + eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ^ Abc_ObjIsComplement(pObj1) ); + eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ^ Abc_ObjIsComplement(pObj2) ); + if ( fOrGate ) + { + eRoot = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); + eRoot = Dec_GraphAddNodeOr( pGraph, eNode2, eRoot ); + } + else + { + eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 ); + eRoot = Dec_GraphAddNodeAnd( pGraph, eNode2, eRoot ); + } + Dec_GraphSetRoot( pGraph, eRoot ); + if ( pRoot->fPhase ) + Dec_GraphComplement( pGraph ); + return pGraph; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +Dec_Graph_t * Abc_ManResubQuit2_1( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1, Abc_Obj_t * pObj2, int fOrGate ) +{ + Dec_Graph_t * pGraph; + Dec_Edge_t eRoot, ePrev, eNode0, eNode1, eNode2; + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj1) ); + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj2) ); + assert( Abc_ObjRegular(pObj1) != Abc_ObjRegular(pObj2) ); + pGraph = Dec_GraphCreate( 3 ); + Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0); + Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1); + Dec_GraphNode( pGraph, 2 )->pFunc = Abc_ObjRegular(pObj2); + eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ^ Abc_ObjIsComplement(pObj0) ); + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ); + eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ); + ePrev = Dec_GraphAddNodeOr( pGraph, eNode1, eNode2 ); + } + else + { + eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ^ Abc_ObjIsComplement(pObj1) ); + eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ^ Abc_ObjIsComplement(pObj2) ); + ePrev = Dec_GraphAddNodeAnd( pGraph, eNode1, eNode2 ); + } + if ( fOrGate ) + eRoot = Dec_GraphAddNodeOr( pGraph, eNode0, ePrev ); + else + eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, ePrev ); + Dec_GraphSetRoot( pGraph, eRoot ); + if ( pRoot->fPhase ) + Dec_GraphComplement( pGraph ); + return pGraph; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +Dec_Graph_t * Abc_ManResubQuit3_1( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1, Abc_Obj_t * pObj2, Abc_Obj_t * pObj3, int fOrGate ) +{ + Dec_Graph_t * pGraph; + Dec_Edge_t eRoot, ePrev0, ePrev1, eNode0, eNode1, eNode2, eNode3; + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj1) ); + assert( Abc_ObjRegular(pObj2) != Abc_ObjRegular(pObj3) ); + pGraph = Dec_GraphCreate( 4 ); + Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0); + Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1); + Dec_GraphNode( pGraph, 2 )->pFunc = Abc_ObjRegular(pObj2); + Dec_GraphNode( pGraph, 3 )->pFunc = Abc_ObjRegular(pObj3); + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) ) + { + eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ); + eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ); + ePrev0 = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); + if ( Abc_ObjIsComplement(pObj2) && Abc_ObjIsComplement(pObj3) ) + { + eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ); + eNode3 = Dec_EdgeCreate( 3, Abc_ObjRegular(pObj3)->fPhase ); + ePrev1 = Dec_GraphAddNodeOr( pGraph, eNode2, eNode3 ); + } + else + { + eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ^ Abc_ObjIsComplement(pObj2) ); + eNode3 = Dec_EdgeCreate( 3, Abc_ObjRegular(pObj3)->fPhase ^ Abc_ObjIsComplement(pObj3) ); + ePrev1 = Dec_GraphAddNodeAnd( pGraph, eNode2, eNode3 ); + } + } + else + { + eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ^ Abc_ObjIsComplement(pObj0) ); + eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ^ Abc_ObjIsComplement(pObj1) ); + ePrev0 = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 ); + if ( Abc_ObjIsComplement(pObj2) && Abc_ObjIsComplement(pObj3) ) + { + eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ); + eNode3 = Dec_EdgeCreate( 3, Abc_ObjRegular(pObj3)->fPhase ); + ePrev1 = Dec_GraphAddNodeOr( pGraph, eNode2, eNode3 ); + } + else + { + eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ^ Abc_ObjIsComplement(pObj2) ); + eNode3 = Dec_EdgeCreate( 3, Abc_ObjRegular(pObj3)->fPhase ^ Abc_ObjIsComplement(pObj3) ); + ePrev1 = Dec_GraphAddNodeAnd( pGraph, eNode2, eNode3 ); + } + } + if ( fOrGate ) + eRoot = Dec_GraphAddNodeOr( pGraph, ePrev0, ePrev1 ); + else + eRoot = Dec_GraphAddNodeAnd( pGraph, ePrev0, ePrev1 ); + Dec_GraphSetRoot( pGraph, eRoot ); + if ( pRoot->fPhase ) + Dec_GraphComplement( pGraph ); + return pGraph; +} + + + + +/**Function************************************************************* + + Synopsis [Derives single-node unate/binate divisors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required ) +{ + int fMoreDivs = 1; // bug fix by Siang-Yun Lee + Abc_Obj_t * pObj; + unsigned * puData, * puDataR; + int i, w; + Vec_PtrClear( p->vDivs1UP ); + Vec_PtrClear( p->vDivs1UN ); + Vec_PtrClear( p->vDivs1B ); + puDataR = (unsigned *)p->pRoot->pData; + Vec_PtrForEachEntryStop( Abc_Obj_t *, p->vDivs, pObj, i, p->nDivs ) + { + if ( (int)pObj->Level > Required - 1 ) + continue; + + puData = (unsigned *)pObj->pData; + // check positive containment + for ( w = 0; w < p->nWords; w++ ) +// if ( puData[w] & ~puDataR[w] ) + if ( puData[w] & ~puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs1UP, pObj ); + continue; + } + if ( fMoreDivs ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( ~puData[w] & ~puDataR[w] ) + if ( ~puData[w] & ~puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs1UP, Abc_ObjNot(pObj) ); + continue; + } + } + // check negative containment + for ( w = 0; w < p->nWords; w++ ) +// if ( ~puData[w] & puDataR[w] ) + if ( ~puData[w] & puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs1UN, pObj ); + continue; + } + if ( fMoreDivs ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( puData[w] & puDataR[w] ) + if ( puData[w] & puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs1UN, Abc_ObjNot(pObj) ); + continue; + } + } + // add the node to binates + Vec_PtrPush( p->vDivs1B, pObj ); + } +} + +/**Function************************************************************* + + Synopsis [Derives double-node unate/binate divisors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required ) +{ + Abc_Obj_t * pObj0, * pObj1; + unsigned * puData0, * puData1, * puDataR; + int i, k, w; + Vec_PtrClear( p->vDivs2UP0 ); + Vec_PtrClear( p->vDivs2UP1 ); + Vec_PtrClear( p->vDivs2UN0 ); + Vec_PtrClear( p->vDivs2UN1 ); + puDataR = (unsigned *)p->pRoot->pData; + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1B, pObj0, i ) + { + if ( (int)pObj0->Level > Required - 2 ) + continue; + + puData0 = (unsigned *)pObj0->pData; + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1B, pObj1, k, i + 1 ) + { + if ( (int)pObj1->Level > Required - 2 ) + continue; + + puData1 = (unsigned *)pObj1->pData; + + if ( Vec_PtrSize(p->vDivs2UP0) < ABC_RS_DIV2_MAX ) + { + // get positive unate divisors + for ( w = 0; w < p->nWords; w++ ) +// if ( (puData0[w] & puData1[w]) & ~puDataR[w] ) + if ( (puData0[w] & puData1[w]) & ~puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs2UP0, pObj0 ); + Vec_PtrPush( p->vDivs2UP1, pObj1 ); + } + for ( w = 0; w < p->nWords; w++ ) +// if ( (~puData0[w] & puData1[w]) & ~puDataR[w] ) + if ( (~puData0[w] & puData1[w]) & ~puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs2UP0, Abc_ObjNot(pObj0) ); + Vec_PtrPush( p->vDivs2UP1, pObj1 ); + } + for ( w = 0; w < p->nWords; w++ ) +// if ( (puData0[w] & ~puData1[w]) & ~puDataR[w] ) + if ( (puData0[w] & ~puData1[w]) & ~puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs2UP0, pObj0 ); + Vec_PtrPush( p->vDivs2UP1, Abc_ObjNot(pObj1) ); + } + for ( w = 0; w < p->nWords; w++ ) +// if ( (puData0[w] | puData1[w]) & ~puDataR[w] ) + if ( (puData0[w] | puData1[w]) & ~puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs2UP0, Abc_ObjNot(pObj0) ); + Vec_PtrPush( p->vDivs2UP1, Abc_ObjNot(pObj1) ); + } + } + + if ( Vec_PtrSize(p->vDivs2UN0) < ABC_RS_DIV2_MAX ) + { + // get negative unate divisors + for ( w = 0; w < p->nWords; w++ ) +// if ( ~(puData0[w] & puData1[w]) & puDataR[w] ) + if ( ~(puData0[w] & puData1[w]) & puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs2UN0, pObj0 ); + Vec_PtrPush( p->vDivs2UN1, pObj1 ); + } + for ( w = 0; w < p->nWords; w++ ) +// if ( ~(~puData0[w] & puData1[w]) & puDataR[w] ) + if ( ~(~puData0[w] & puData1[w]) & puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs2UN0, Abc_ObjNot(pObj0) ); + Vec_PtrPush( p->vDivs2UN1, pObj1 ); + } + for ( w = 0; w < p->nWords; w++ ) +// if ( ~(puData0[w] & ~puData1[w]) & puDataR[w] ) + if ( ~(puData0[w] & ~puData1[w]) & puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs2UN0, pObj0 ); + Vec_PtrPush( p->vDivs2UN1, Abc_ObjNot(pObj1) ); + } + for ( w = 0; w < p->nWords; w++ ) +// if ( ~(puData0[w] | puData1[w]) & puDataR[w] ) + if ( ~(puData0[w] | puData1[w]) & puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs2UN0, Abc_ObjNot(pObj0) ); + Vec_PtrPush( p->vDivs2UN1, Abc_ObjNot(pObj1) ); + } + } + } + } +// printf( "%d %d ", Vec_PtrSize(p->vDivs2UP0), Vec_PtrSize(p->vDivs2UN0) ); +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Abc_ManResubQuit( Abc_ManRes_t * p ) +{ + Dec_Graph_t * pGraph; + unsigned * upData; + int w; + upData = (unsigned *)p->pRoot->pData; + for ( w = 0; w < p->nWords; w++ ) +// if ( upData[w] ) + if ( upData[w] & p->pCareSet[w] ) // care set + break; + if ( w != p->nWords ) + return NULL; + // get constant node graph + if ( p->pRoot->fPhase ) + pGraph = Dec_GraphCreateConst1(); + else + pGraph = Dec_GraphCreateConst0(); + return pGraph; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Abc_ManResubDivs0( Abc_ManRes_t * p ) +{ + Abc_Obj_t * pObj; + unsigned * puData, * puDataR; + int i, w; + puDataR = (unsigned *)p->pRoot->pData; + Vec_PtrForEachEntryStop( Abc_Obj_t *, p->vDivs, pObj, i, p->nDivs ) + { + puData = (unsigned *)pObj->pData; + for ( w = 0; w < p->nWords; w++ ) +// if ( puData[w] != puDataR[w] ) + if ( (puData[w] ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + return Abc_ManResubQuit0_1( p->pRoot, pObj ); + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Abc_ManResubDivs1( Abc_ManRes_t * p, int Required ) +{ + Abc_Obj_t * pObj0, * pObj1; + unsigned * puData0, * puData1, * puDataR; + int i, k, w; + puDataR = (unsigned *)p->pRoot->pData; + // check positive unate divisors + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UP, pObj0, i ) + { + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UP, pObj1, k, i + 1 ) + { + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w]) != puDataR[w] ) + if ( ((~puData0[w] | ~puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w]) != puDataR[w] ) + if ( ((~puData0[w] | puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w]) != puDataR[w] ) + if ( ((puData0[w] | ~puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w]) != puDataR[w] ) + if ( ((puData0[w] | puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + if ( w == p->nWords ) + { + p->nUsedNode1Or++; + return Abc_ManResubQuit1_1( p->pRoot, pObj0, pObj1, 1 ); + } + } + } + // check negative unate divisors + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UN, pObj0, i ) + { + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UN, pObj1, k, i + 1 ) + { + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w]) != puDataR[w] ) + if ( ((~puData0[w] & ~puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + if ( Abc_ObjIsComplement(pObj0) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w]) != puDataR[w] ) + if ( ((~puData0[w] & puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w]) != puDataR[w] ) + if ( ((puData0[w] & ~puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w]) != puDataR[w] ) + if ( ((puData0[w] & puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + if ( w == p->nWords ) + { + p->nUsedNode1And++; + return Abc_ManResubQuit1_1( p->pRoot, pObj0, pObj1, 0 ); + } + } + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Abc_ManResubDivs12( Abc_ManRes_t * p, int Required ) +{ + Abc_Obj_t * pObj0, * pObj1, * pObj2, * pObjMax, * pObjMin0 = NULL, * pObjMin1 = NULL; + unsigned * puData0, * puData1, * puData2, * puDataR; + int i, k, j, w, LevelMax; + puDataR = (unsigned *)p->pRoot->pData; + // check positive unate divisors + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UP, pObj0, i ) + { + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UP, pObj1, k, i + 1 ) + { + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UP, pObj2, j, k + 1 ) + { + puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] | ~puData1[w] | ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] | ~puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] | puData1[w] | ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] | puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((puData0[w] | ~puData1[w] | ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((puData0[w] | ~puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((puData0[w] | puData1[w] | ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((puData0[w] | puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else assert( 0 ); + if ( w == p->nWords ) + { + LevelMax = Abc_MaxInt( Abc_ObjRegular(pObj0)->Level, Abc_MaxInt(Abc_ObjRegular(pObj1)->Level, Abc_ObjRegular(pObj2)->Level) ); + assert( LevelMax <= Required - 1 ); + + pObjMax = NULL; + if ( (int)Abc_ObjRegular(pObj0)->Level == LevelMax ) + pObjMax = pObj0, pObjMin0 = pObj1, pObjMin1 = pObj2; + if ( (int)Abc_ObjRegular(pObj1)->Level == LevelMax ) + { + if ( pObjMax ) continue; + pObjMax = pObj1, pObjMin0 = pObj0, pObjMin1 = pObj2; + } + if ( (int)Abc_ObjRegular(pObj2)->Level == LevelMax ) + { + if ( pObjMax ) continue; + pObjMax = pObj2, pObjMin0 = pObj0, pObjMin1 = pObj1; + } + + p->nUsedNode2Or++; + assert(pObjMin0); + assert(pObjMin1); + return Abc_ManResubQuit21_1( p->pRoot, pObjMin0, pObjMin1, pObjMax, 1 ); + } + } + } + } + // check negative unate divisors + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UN, pObj0, i ) + { + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UN, pObj1, k, i + 1 ) + { + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UN, pObj2, j, k + 1 ) + { + puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] & ~puData1[w] & ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] & ~puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] & puData1[w] & ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] & puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((puData0[w] & ~puData1[w] & ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((puData0[w] & ~puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((puData0[w] & puData1[w] & ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((puData0[w] & puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else assert( 0 ); + if ( w == p->nWords ) + { + LevelMax = Abc_MaxInt( Abc_ObjRegular(pObj0)->Level, Abc_MaxInt(Abc_ObjRegular(pObj1)->Level, Abc_ObjRegular(pObj2)->Level) ); + assert( LevelMax <= Required - 1 ); + + pObjMax = NULL; + if ( (int)Abc_ObjRegular(pObj0)->Level == LevelMax ) + pObjMax = pObj0, pObjMin0 = pObj1, pObjMin1 = pObj2; + if ( (int)Abc_ObjRegular(pObj1)->Level == LevelMax ) + { + if ( pObjMax ) continue; + pObjMax = pObj1, pObjMin0 = pObj0, pObjMin1 = pObj2; + } + if ( (int)Abc_ObjRegular(pObj2)->Level == LevelMax ) + { + if ( pObjMax ) continue; + pObjMax = pObj2, pObjMin0 = pObj0, pObjMin1 = pObj1; + } + + p->nUsedNode2And++; + assert(pObjMin0); + assert(pObjMin1); + return Abc_ManResubQuit21_1( p->pRoot, pObjMin0, pObjMin1, pObjMax, 0 ); + } + } + } + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Abc_ManResubDivs2( Abc_ManRes_t * p, int Required ) +{ + Abc_Obj_t * pObj0, * pObj1, * pObj2; + unsigned * puData0, * puData1, * puData2, * puDataR; + int i, k, w; + puDataR = (unsigned *)p->pRoot->pData; + // check positive unate divisors + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UP, pObj0, i ) + { + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs2UP0, pObj1, k ) + { + pObj2 = (Abc_Obj_t *)Vec_PtrEntry( p->vDivs2UP1, k ); + + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; + if ( Abc_ObjIsComplement(pObj0) ) + { + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] | puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] | (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (~puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] | (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] & ~puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] | (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] | (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + } + else + { + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] | puData2[w])) != puDataR[w] ) + if ( ((puData0[w] | (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (~puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((puData0[w] | (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] & ~puData2[w])) != puDataR[w] ) + if ( ((puData0[w] | (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((puData0[w] | (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + } + if ( w == p->nWords ) + { + p->nUsedNode2OrAnd++; + return Abc_ManResubQuit2_1( p->pRoot, pObj0, pObj1, pObj2, 1 ); + } + } + } + // check negative unate divisors + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UN, pObj0, i ) + { + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs2UN0, pObj1, k ) + { + pObj2 = (Abc_Obj_t *)Vec_PtrEntry( p->vDivs2UN1, k ); + + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; + if ( Abc_ObjIsComplement(pObj0) ) + { + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] | puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] & (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (~puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] & (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] & ~puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] & (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] & (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + } + else + { + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] | puData2[w])) != puDataR[w] ) + if ( ((puData0[w] & (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (~puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((puData0[w] & (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] & ~puData2[w])) != puDataR[w] ) + if ( ((puData0[w] & (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((puData0[w] & (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + } + if ( w == p->nWords ) + { + p->nUsedNode2AndOr++; + return Abc_ManResubQuit2_1( p->pRoot, pObj0, pObj1, pObj2, 0 ); + } + } + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Abc_ManResubDivs3( Abc_ManRes_t * p, int Required ) +{ + Abc_Obj_t * pObj0, * pObj1, * pObj2, * pObj3; + unsigned * puData0, * puData1, * puData2, * puData3, * puDataR; + int i, k, w = 0, Flag; + puDataR = (unsigned *)p->pRoot->pData; + // check positive unate divisors + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs2UP0, pObj0, i ) + { + pObj1 = (Abc_Obj_t *)Vec_PtrEntry( p->vDivs2UP1, i ); + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + Flag = (Abc_ObjIsComplement(pObj0) << 3) | (Abc_ObjIsComplement(pObj1) << 2); + + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs2UP0, pObj2, k, i + 1 ) + { + pObj3 = (Abc_Obj_t *)Vec_PtrEntry( p->vDivs2UP1, k ); + puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; + puData3 = (unsigned *)Abc_ObjRegular(pObj3)->pData; + + Flag = (Flag & 12) | ((int)Abc_ObjIsComplement(pObj2) << 1) | (int)Abc_ObjIsComplement(pObj3); + assert( Flag < 16 ); + switch( Flag ) + { + case 0: // 0000 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] & puData1[w]) | (puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & puData1[w]) | (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 1: // 0001 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] & puData1[w]) | (puData2[w] & ~puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & puData1[w]) | (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 2: // 0010 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] & puData1[w]) | (~puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & puData1[w]) | (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 3: // 0011 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] & puData1[w]) | (puData2[w] | puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & puData1[w]) | (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + + case 4: // 0100 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] & ~puData1[w]) | (puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & ~puData1[w]) | (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 5: // 0101 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] & ~puData1[w]) | (puData2[w] & ~puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & ~puData1[w]) | (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 6: // 0110 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] & ~puData1[w]) | (~puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & ~puData1[w]) | (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 7: // 0111 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] & ~puData1[w]) | (puData2[w] | puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & ~puData1[w]) | (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + + case 8: // 1000 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((~puData0[w] & puData1[w]) | (puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((~puData0[w] & puData1[w]) | (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 9: // 1001 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((~puData0[w] & puData1[w]) | (puData2[w] & ~puData3[w])) != puDataR[w] ) + if ( (((~puData0[w] & puData1[w]) | (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 10: // 1010 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((~puData0[w] & puData1[w]) | (~puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((~puData0[w] & puData1[w]) | (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 11: // 1011 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((~puData0[w] & puData1[w]) | (puData2[w] | puData3[w])) != puDataR[w] ) + if ( (((~puData0[w] & puData1[w]) | (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + + case 12: // 1100 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] | puData1[w]) | (puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] | puData1[w]) | (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + break; + case 13: // 1101 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] | puData1[w]) | (puData2[w] & ~puData3[w])) != puDataR[w] ) + if ( (((puData0[w] | puData1[w]) | (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 14: // 1110 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] | puData1[w]) | (~puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] | puData1[w]) | (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 15: // 1111 + for ( w = 0; w < p->nWords; w++ ) +// if ( ((puData0[w] | puData1[w]) | (puData2[w] | puData3[w])) != puDataR[w] ) + if ( (((puData0[w] | puData1[w]) | (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + + } + if ( w == p->nWords ) + { + p->nUsedNode3OrAnd++; + return Abc_ManResubQuit3_1( p->pRoot, pObj0, pObj1, pObj2, pObj3, 1 ); + } + } + } + +/* + // check negative unate divisors + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs2UN0, pObj0, i ) + { + pObj1 = Vec_PtrEntry( p->vDivs2UN1, i ); + puData0 = Abc_ObjRegular(pObj0)->pData; + puData1 = Abc_ObjRegular(pObj1)->pData; + Flag = (Abc_ObjIsComplement(pObj0) << 3) | (Abc_ObjIsComplement(pObj1) << 2); + + Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs2UN0, pObj2, k, i + 1 ) + { + pObj3 = Vec_PtrEntry( p->vDivs2UN1, k ); + puData2 = Abc_ObjRegular(pObj2)->pData; + puData3 = Abc_ObjRegular(pObj3)->pData; + + Flag = (Flag & 12) | (Abc_ObjIsComplement(pObj2) << 1) | Abc_ObjIsComplement(pObj3); + assert( Flag < 16 ); + switch( Flag ) + { + case 0: // 0000 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] & puData1[w]) & (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 1: // 0001 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] & puData1[w]) & (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 2: // 0010 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] & puData1[w]) & (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 3: // 0011 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] & puData1[w]) & (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + + case 4: // 0100 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] & ~puData1[w]) & (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 5: // 0101 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] & ~puData1[w]) & (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 6: // 0110 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] & ~puData1[w]) & (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 7: // 0111 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] & ~puData1[w]) & (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + + case 8: // 1000 + for ( w = 0; w < p->nWords; w++ ) + if ( (((~puData0[w] & puData1[w]) & (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 9: // 1001 + for ( w = 0; w < p->nWords; w++ ) + if ( (((~puData0[w] & puData1[w]) & (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 10: // 1010 + for ( w = 0; w < p->nWords; w++ ) + if ( (((~puData0[w] & puData1[w]) & (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 11: // 1011 + for ( w = 0; w < p->nWords; w++ ) + if ( (((~puData0[w] & puData1[w]) & (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + + case 12: // 1100 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] | puData1[w]) & (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 13: // 1101 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] | puData1[w]) & (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 14: // 1110 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] | puData1[w]) & (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + case 15: // 1111 + for ( w = 0; w < p->nWords; w++ ) + if ( (((puData0[w] | puData1[w]) & (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) + break; + break; + + } + if ( w == p->nWords ) + { + p->nUsedNode3AndOr++; + return Abc_ManResubQuit3_1( p->pRoot, pObj0, pObj1, pObj2, pObj3, 0 ); + } + } + } +*/ + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManResubCleanup( Abc_ManRes_t * p ) +{ + Abc_Obj_t * pObj; + int i; + Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs, pObj, i ) + pObj->pData = NULL; + Vec_PtrClear( p->vDivs ); + p->pRoot = NULL; +} + +/**Function************************************************************* + + Synopsis [Evaluates resubstution of one cut.] + + Description [Returns the graph to add if any.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Abc_ManResubEval( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int nSteps, int fUpdateLevel, int fVerbose ) +{ + extern int Abc_NodeMffcInside( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vInside ); + Dec_Graph_t * pGraph; + int Required; + abctime clk; + + Required = fUpdateLevel? Abc_ObjRequiredLevel(pRoot) : ABC_INFINITY; + + assert( nSteps >= 0 ); + assert( nSteps <= 3 ); + p->pRoot = pRoot; + p->nLeaves = Vec_PtrSize(vLeaves); + p->nLastGain = -1; + + // collect the MFFC +clk = Abc_Clock(); + p->nMffc = Abc_NodeMffcInside( pRoot, vLeaves, p->vTemp ); +p->timeMffc += Abc_Clock() - clk; + assert( p->nMffc > 0 ); + + // collect the divisor nodes +clk = Abc_Clock(); + if ( !Abc_ManResubCollectDivs( p, pRoot, vLeaves, Required ) ) + return NULL; + p->timeDiv += Abc_Clock() - clk; + + p->nTotalDivs += p->nDivs; + p->nTotalLeaves += p->nLeaves; + + // simulate the nodes +clk = Abc_Clock(); + Abc_ManResubSimulate( p->vDivs, p->nLeaves, p->vSims, p->nLeavesMax, p->nWords ); +p->timeSim += Abc_Clock() - clk; + +clk = Abc_Clock(); + // consider constants + if ( (pGraph = Abc_ManResubQuit( p )) ) + { + p->nUsedNodeC++; + p->nLastGain = p->nMffc; + return pGraph; + } + + // consider equal nodes + if ( (pGraph = Abc_ManResubDivs0( p )) ) + { +p->timeRes1 += Abc_Clock() - clk; + p->nUsedNode0++; + p->nLastGain = p->nMffc; + return pGraph; + } + if ( nSteps == 0 || p->nMffc == 1 ) + { +p->timeRes1 += Abc_Clock() - clk; + return NULL; + } + + // get the one level divisors + Abc_ManResubDivsS( p, Required ); + + // consider one node + if ( (pGraph = Abc_ManResubDivs1( p, Required )) ) + { +p->timeRes1 += Abc_Clock() - clk; + p->nLastGain = p->nMffc - 1; + return pGraph; + } +p->timeRes1 += Abc_Clock() - clk; + if ( nSteps == 1 || p->nMffc == 2 ) + return NULL; + +clk = Abc_Clock(); + // consider triples + if ( (pGraph = Abc_ManResubDivs12( p, Required )) ) + { +p->timeRes2 += Abc_Clock() - clk; + p->nLastGain = p->nMffc - 2; + return pGraph; + } +p->timeRes2 += Abc_Clock() - clk; + + // get the two level divisors +clk = Abc_Clock(); + Abc_ManResubDivsD( p, Required ); +p->timeResD += Abc_Clock() - clk; + + // consider two nodes +clk = Abc_Clock(); + if ( (pGraph = Abc_ManResubDivs2( p, Required )) ) + { +p->timeRes2 += Abc_Clock() - clk; + p->nLastGain = p->nMffc - 2; + return pGraph; + } +p->timeRes2 += Abc_Clock() - clk; + if ( nSteps == 2 || p->nMffc == 3 ) + return NULL; + + // consider two nodes +clk = Abc_Clock(); + if ( (pGraph = Abc_ManResubDivs3( p, Required )) ) + { +p->timeRes3 += Abc_Clock() - clk; + p->nLastGain = p->nMffc - 3; + return pGraph; + } +p->timeRes3 += Abc_Clock() - clk; + if ( nSteps == 3 || p->nLeavesMax == 4 ) + return NULL; + return NULL; +} + + + + +/**Function************************************************************* + + Synopsis [Computes the volume and checks if the cut is feasible.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +int Abc_CutVolumeCheck_rec_1( Abc_Obj_t * pObj ) +{ + // quit if the node is visited (or if it is a leaf) + if ( Abc_NodeIsTravIdCurrent(pObj) ) + return 0; + Abc_NodeSetTravIdCurrent(pObj); + // report the error + if ( Abc_ObjIsCi(pObj) ) + printf( "Abc_CutVolumeCheck() ERROR: The set of nodes is not a cut!\n" ); + // count the number of nodes in the leaves + return 1 + Abc_CutVolumeCheck_rec_1( Abc_ObjFanin0(pObj) ) + + Abc_CutVolumeCheck_rec_1( Abc_ObjFanin1(pObj) ); +} +/**Function************************************************************* + + Synopsis [Computes the volume and checks if the cut is feasible.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CutVolumeCheck( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ) +{ + Abc_Obj_t * pObj; + int i; + // mark the leaves + Abc_NtkIncrementTravId( pNode->pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pObj, i ) + Abc_NodeSetTravIdCurrent( pObj ); + // traverse the nodes starting from the given one and count them + return Abc_CutVolumeCheck_rec_1( pNode ); +} + +/**Function************************************************************* + + Synopsis [Computes the factor cut of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +void Abc_CutFactor_rec_1( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves ) +{ + if ( pObj->fMarkA ) + return; + if ( Abc_ObjIsCi(pObj) || (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj)) ) + { + Vec_PtrPush( vLeaves, pObj ); + pObj->fMarkA = 1; + return; + } + Abc_CutFactor_rec_1( Abc_ObjFanin0(pObj), vLeaves ); + Abc_CutFactor_rec_1( Abc_ObjFanin1(pObj), vLeaves ); +} + + +/**Function************************************************************* + + Synopsis [Computes the factor cut of the node.] + + Description [Factor-cut is the cut at a node in terms of factor-nodes. + Factor-nodes are roots of the node trees (MUXes/EXORs are counted as single nodes). + Factor-cut is unique for the given node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +Vec_Ptr_t * Abc_CutFactor_1( Abc_Obj_t * pNode ) +{ + Vec_Ptr_t * vLeaves; + Abc_Obj_t * pObj; + int i; + assert( !Abc_ObjIsCi(pNode) ); + vLeaves = Vec_PtrAlloc( 10 ); + Abc_CutFactor_rec_1( Abc_ObjFanin0(pNode), vLeaves ); + Abc_CutFactor_rec_1( Abc_ObjFanin1(pNode), vLeaves ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pObj, i ) + pObj->fMarkA = 0; + return vLeaves; +} + + +/**Function************************************************************* + + Synopsis [Cut computation.] + + Description [This cut computation works as follows: + It starts with the factor cut at the node. If the factor-cut is large, quit. + It supports the set of leaves of the cut under construction and labels all nodes + in the cut under construction, including the leaves. + It computes the factor-cuts of the leaves and checks if it is easible to add any of them. + If it is, it randomly chooses one feasible and continues.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_CutFactorLarge( Abc_Obj_t * pNode, int nLeavesMax ) +{ + Vec_Ptr_t * vLeaves, * vFactors, * vFact, * vNext; + Vec_Int_t * vFeasible; + Abc_Obj_t * pLeaf, * pTemp; + int i, k, Counter, RandLeaf; + int BestCut, BestShare; + assert( Abc_ObjIsNode(pNode) ); + // get one factor-cut + vLeaves = Abc_CutFactor_1( pNode ); + if ( Vec_PtrSize(vLeaves) > nLeavesMax ) + { + Vec_PtrFree(vLeaves); + return NULL; + } + if ( Vec_PtrSize(vLeaves) == nLeavesMax ) + return vLeaves; + // initialize the factor cuts for the leaves + vFactors = Vec_PtrAlloc( nLeavesMax ); + Abc_NtkIncrementTravId( pNode->pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pLeaf, i ) + { + Abc_NodeSetTravIdCurrent( pLeaf ); + if ( Abc_ObjIsCi(pLeaf) ) + Vec_PtrPush( vFactors, NULL ); + else + Vec_PtrPush( vFactors, Abc_CutFactor_1(pLeaf) ); + } + // construct larger factor cuts + vFeasible = Vec_IntAlloc( nLeavesMax ); + while ( 1 ) + { + BestCut = -1, BestShare = -1; + // find the next feasible cut to add + Vec_IntClear( vFeasible ); + Vec_PtrForEachEntry( Vec_Ptr_t *, vFactors, vFact, i ) + { + if ( vFact == NULL ) + continue; + // count the number of unmarked leaves of this factor cut + Counter = 0; + Vec_PtrForEachEntry( Abc_Obj_t *, vFact, pTemp, k ) + Counter += !Abc_NodeIsTravIdCurrent(pTemp); + // if the number of new leaves is smaller than the diff, it is feasible + if ( Counter <= nLeavesMax - Vec_PtrSize(vLeaves) + 1 ) + { + Vec_IntPush( vFeasible, i ); + if ( BestCut == -1 || BestShare < Vec_PtrSize(vFact) - Counter ) + BestCut = i, BestShare = Vec_PtrSize(vFact) - Counter; + } + } + // quit if there is no feasible factor cuts + if ( Vec_IntSize(vFeasible) == 0 ) + break; + // randomly choose one leaf and get its factor cut +// RandLeaf = Vec_IntEntry( vFeasible, rand() % Vec_IntSize(vFeasible) ); + // choose the cut that has most sharing with the other cuts + RandLeaf = BestCut; + + pLeaf = (Abc_Obj_t *)Vec_PtrEntry( vLeaves, RandLeaf ); + vNext = (Vec_Ptr_t *)Vec_PtrEntry( vFactors, RandLeaf ); + // unmark this leaf + Abc_NodeSetTravIdPrevious( pLeaf ); + // remove this cut from the leaves and factor cuts + for ( i = RandLeaf; i < Vec_PtrSize(vLeaves)-1; i++ ) + { + Vec_PtrWriteEntry( vLeaves, i, Vec_PtrEntry(vLeaves, i+1) ); + Vec_PtrWriteEntry( vFactors, i, Vec_PtrEntry(vFactors,i+1) ); + } + Vec_PtrShrink( vLeaves, Vec_PtrSize(vLeaves) -1 ); + Vec_PtrShrink( vFactors, Vec_PtrSize(vFactors)-1 ); + // add new leaves, compute their factor cuts + Vec_PtrForEachEntry( Abc_Obj_t *, vNext, pLeaf, i ) + { + if ( Abc_NodeIsTravIdCurrent(pLeaf) ) + continue; + Abc_NodeSetTravIdCurrent( pLeaf ); + Vec_PtrPush( vLeaves, pLeaf ); + if ( Abc_ObjIsCi(pLeaf) ) + Vec_PtrPush( vFactors, NULL ); + else + Vec_PtrPush( vFactors, Abc_CutFactor_1(pLeaf) ); + } + Vec_PtrFree( vNext ); + assert( Vec_PtrSize(vLeaves) <= nLeavesMax ); + if ( Vec_PtrSize(vLeaves) == nLeavesMax ) + break; + } + + // remove temporary storage + Vec_PtrForEachEntry( Vec_Ptr_t *, vFactors, vFact, i ) + if ( vFact ) Vec_PtrFree( vFact ); + Vec_PtrFree( vFactors ); + Vec_IntFree( vFeasible ); + return vLeaves; +} + + +int Abc_NtkOrchSA( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, Vec_Int_t **PolicyList, char * DecisionFile, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) +{ + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + ProgressBar * pProgress; + // For resub + Abc_ManRes_t * pManRes; + Abc_ManCut_t * pManCutRes; + Odc_Man_t * pManOdc = NULL; + Dec_Graph_t * pFFormRes; + Vec_Ptr_t * vLeaves; + // For rewrite + Cut_Man_t * pManCutRwr; + Rwr_Man_t * pManRwr; + Dec_Graph_t * pGraph; + // For refactor + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCutRef; + Dec_Graph_t * pFFormRef; + Vec_Ptr_t * vFanins; + Vec_Int_t * DecisionMask = Vec_IntAlloc(1); + + Abc_Obj_t * pNode; + FILE *fpt; + abctime clk, clkStart = Abc_Clock(); + abctime s_ResubTime; + int i, nNodes, nGain, fCompl, RetValue = 1; + int ops_rwr = 0; + int ops_res = 0; + int ops_ref = 0; + int ops_null = 0; + int sOpsOrder = 0; + assert( Abc_NtkIsStrash(pNtk) ); + + // cleanup the AIG + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + + // start the managers resub + pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 ); + pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX ); + if ( nLevelsOdc > 0 ) + pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose ); + // start the managers refactor + pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef ); + // start the managers rewrite + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + + // compute the reverse levels if level update is requested + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pNext = (Abc_Obj_t *)pNode->pData; + } +clk = Abc_Clock(); + pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk ); +Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); + pNtk->pManCut = pManCutRwr; + + if ( fVeryVerbose ) + Rwr_ScoresClean( pManRwr ); + + pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); + pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); + pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); + + nNodes = Abc_NtkObjNumMax(pNtk); + printf("nNodes: %d\n", nNodes); + if (pGain_res) *pGain_res = Vec_IntAlloc(1); + if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); + if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1); + for(int i=0; i < nNodes; i++){Vec_IntPush(DecisionMask, atoi("-1"));} + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + fpt = fopen(DecisionFile, "w"); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + int iterNode = pNode->Id; + Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( Abc_NodeIsPersistant(pNode) ) + { + //fprintf(fpt, "%d, %d\n", iterNode, -99); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + //fprintf(fpt, "%d, %d\n", iterNode, -99); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } + if ( i >= nNodes ) + break; + +//refactor +clk = Abc_Clock(); + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_ref), pManRef->nLastGain); +//resub + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +pManRes->timeCut += Abc_Clock() - clk; + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +pManRes->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_res), pManRes->nLastGain); +//rewrite + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + //fprintf(fpt, "%d, %s, %d, %s, %d, %s, %d\n", pNode->Id, "Oches_Res", pManRes->nLastGain, "Oches_Ref", pManRef->nLastGain, "Oches_Rwr", nGain); + + if ((**PolicyList).pArray[iterNode] == 0){sOpsOrder = 0;} + if ((**PolicyList).pArray[iterNode] == 1){sOpsOrder = 1;} + if ((**PolicyList).pArray[iterNode] == 2){sOpsOrder = 2;} + if ((**PolicyList).pArray[iterNode] == 3){sOpsOrder = 3;} + if ((**PolicyList).pArray[iterNode] == 4){sOpsOrder = 4;} + if ((**PolicyList).pArray[iterNode] == 5){sOpsOrder = 5;} + + if ( sOpsOrder == 0) + { + //printf("policy orchestration with o1."); + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + //fprintf(fpt, "%d, %d\n", iterNode, 0); + (DecisionMask)->pArray[iterNode] = 0; + continue; + } + + if (pManRes->nLastGain > 0) + { + + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + //fprintf(fpt, "%d, %d\n", iterNode, 1); + (DecisionMask)->pArray[iterNode] = 2; + continue; + } + + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + //fprintf(fpt, "%d, %d\n", iterNode, 2); + (DecisionMask)->pArray[iterNode] = 3; + continue; + } + if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + { + ops_null++; + //fprintf(fpt, "%d, %d\n", iterNode, -1); + continue; + } + } + + if ( sOpsOrder == 1) + { + //printf("policy orchestration with o2."); + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + //fprintf(fpt, "%d, %d\n", iterNode, 0); + (DecisionMask)->pArray[iterNode] = 0; + continue; + } + + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + //fprintf(fpt, "%d, %d\n", iterNode, 2); + (DecisionMask)->pArray[iterNode] = 3; + continue; + } + + if (pManRes->nLastGain > 0) + { + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + //fprintf(fpt, "%d, %d\n", iterNode, 1); + (DecisionMask)->pArray[iterNode] = 2; + continue; + } + if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + { + ops_null++; + //fprintf(fpt, "%d, %d\n", iterNode, -1); + continue; + } + } + + if ( sOpsOrder == 2) + { + //printf("policy orchestration with o3."); + if (pManRes->nLastGain > 0) + { + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + //fprintf(fpt, "%d, %d\n", iterNode, 1); + (DecisionMask)->pArray[iterNode] = 2; + continue; + } + + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + //fprintf(fpt, "%d, %d\n", iterNode, 0); + (DecisionMask)->pArray[iterNode] = 0; + continue; + } + + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + //fprintf(fpt, "%d, %d\n", iterNode, 2); + (DecisionMask)->pArray[iterNode] = 3; + continue; + } + if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + { + ops_null++; + //fprintf(fpt, "%d, %d\n", iterNode, -1); + continue; + } + } + + if ( sOpsOrder == 3) + { + //printf("policy orchestration with o4."); + if (pManRes->nLastGain > 0) + { + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + //fprintf(fpt, "%d, %d\n", iterNode, 1); + (DecisionMask)->pArray[iterNode] = 2; + continue; + } + + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + //fprintf(fpt, "%d, %d\n", iterNode, 2); + (DecisionMask)->pArray[iterNode] = 3; + continue; + } + + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + //fprintf(fpt, "%d, %d\n", iterNode, 0); + (DecisionMask)->pArray[iterNode] = 0; + continue; + } + + if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + { + ops_null++; + //fprintf(fpt, "%d, %d\n", iterNode, -1); + continue; + } + } + + if ( sOpsOrder == 4) + { + //printf("policy orchestration with o5."); + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + //fprintf(fpt, "%d, %d\n", iterNode, 2); + (DecisionMask)->pArray[iterNode] = 3; + continue; + } + + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + //fprintf(fpt, "%d, %d\n", iterNode, 0); + (DecisionMask)->pArray[iterNode] = 0; + continue; + } + + if (pManRes->nLastGain > 0) + { + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + //fprintf(fpt, "%d, %d\n", iterNode, 1); + (DecisionMask)->pArray[iterNode] = 2; + continue; + } + if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + { + ops_null++; + //fprintf(fpt, "%d, %d\n", iterNode, -1); + continue; + } + } + + if ( sOpsOrder == 5) + { + //printf("policy orchestration with o6."); + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + //fprintf(fpt, "%d, %d\n", iterNode, 2); + (DecisionMask)->pArray[iterNode] = 3; + continue; + } + + if (pManRes->nLastGain > 0) + { + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + //fprintf(fpt, "%d, %d\n", iterNode, 1); + (DecisionMask)->pArray[iterNode] = 2; + continue; + } + + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + //fprintf(fpt, "%d, %d\n", iterNode, 0); + (DecisionMask)->pArray[iterNode] = 0; + continue; + } + if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + { + ops_null++; + //fprintf(fpt, "%d, %d\n", iterNode, -1); + continue; + } + } + + } + for (int i=0; ipArray[i]);} + fclose(fpt); + /* + printf("size of vector %d\n", (**pGain_res).nSize); + printf("Nodes with rewrite: %d\n", ops_rwr); + printf("Nodes with resub: %d\n", ops_res); + printf("Nodes with refactor: %d\n", ops_ref); + printf("Nodes without updates: %d\n", ops_null); + */ + Extra_ProgressBarStop( pProgress ); +Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); + pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk); + +pManRes->timeTotal = Abc_Clock() - clkStart; + pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk); + +pManRef->timeTotal = Abc_Clock() - clkStart; + pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk); + + if ( fVerbose ){ + Abc_ManResubPrint( pManRes ); + Rwr_ManPrintStats( pManRwr ); + Abc_NtkManRefPrintStats_1( pManRef ); + } + if ( fVeryVerbose ) + Rwr_ScoresReport( pManRwr ); + + Abc_ManResubStop( pManRes ); + Abc_NtkManCutStop( pManCutRes ); + + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCutRwr ); + pNtk->pManCut = NULL; + + Abc_NtkManCutStop( pManCutRef ); + Abc_NtkManRefStop_1( pManRef ); + + if ( pManOdc ) Abc_NtkDontCareFree( pManOdc ); + + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->pData = NULL; + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pData = pNode->pNext, pNode->pNext = NULL; + } + Abc_NtkReassignIds( pNtk ); + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkOchestraction: The network check has failed.\n" ); + return 0; + } +s_ResubTime = Abc_Clock() - clkStart; + return 1; +} + +// local greedy orchestration +int Abc_NtkOrchLocal( Abc_Ntk_t * pNtk, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) +{ + ProgressBar * pProgress; + // For resub + Abc_ManRes_t * pManRes; + Abc_ManCut_t * pManCutRes; + Odc_Man_t * pManOdc = NULL; + Dec_Graph_t * pFFormRes; + Dec_Graph_t * pFFormRef_zeros; + Vec_Ptr_t * vLeaves; + // For rewrite + Cut_Man_t * pManCutRwr; + Rwr_Man_t * pManRwr; + Dec_Graph_t * pGraph; + // For refactor + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCutRef; + Dec_Graph_t * pFFormRef; + Vec_Ptr_t * vFanins; + + Abc_Obj_t * pNode, * pFanin; + int fanin_i; + //FILE * fpt; + abctime clk, clkStart = Abc_Clock(); + abctime s_ResubTime; + int i, nNodes, nGain, nGain_zeros, fCompl, RetValue = 1; + //int decisionOps = 0; + int ops_rwr = 0; + int ops_res = 0; + int ops_ref = 0; + int ops_null = 0; + assert( Abc_NtkIsStrash(pNtk) ); + + // cleanup the AIG + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + + // start the managers resub + pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 ); + pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX ); + if ( nLevelsOdc > 0 ) + pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose ); + // start the managers refactor + pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef ); + // start the managers rewrite + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + + // compute the reverse levels if level update is requested + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + + // 'Resub only' + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pNext = (Abc_Obj_t *)pNode->pData; + } + // cut manager for rewrite +clk = Abc_Clock(); + pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk ); +Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); + pNtk->pManCut = pManCutRwr; + + if ( fVeryVerbose ) + Rwr_ScoresClean( pManRwr ); + + // resynthesize each node once + // resub + pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); + // rewrite + pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); + // refactor + pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); + + nNodes = Abc_NtkObjNumMax(pNtk); + //printf("nNodes: %d\n", nNodes); + //if (pGain_res) *pGain_res = Vec_IntAlloc(1); + //if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); + //if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + int iterNode = pNode->Id; + //printf("Nodes ID: %d\n", pNode->Id); + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the constant node +// if ( Abc_NodeIsConst(pNode) ) +// continue; + // skip persistant nodes + + if ( Abc_NodeIsPersistant(pNode) ) + { + continue; + } + // skip the nodes with many fanouts + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + continue; + } + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; + +clk = Abc_Clock(); + +//Refactor + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + //pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + +// Resub + // compute a reconvergence-driven cut + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +// vLeaves = Abc_CutFactorLarge( pNode, nCutMax ); +pManRes->timeCut += Abc_Clock() - clk; + // get the don't-cares + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } + // evaluate this cut +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +// Vec_PtrFree( vLeaves ); +// Abc_ManResubCleanup( pManRes ); +pManRes->timeRes += Abc_Clock() - clk; + +// Rewrite + //nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros, fPlaceEnable ); + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + + // compare local reward and update + // if (((! (nGain < 0)) && (! (nGain < pManRes->nLastGain)) && (! (pManRes->nLastGain < pManRef->nLastGain))) || ((! (nGain < 0)) && (! (nGain < pManRef->nLastGain)) && (! (pManRef->nLastGain < pManRes->nLastGain)))){ + if (((! (nGain < 0)) && (! (nGain < pManRes->nLastGain)) && (! (nGain < pManRef->nLastGain)))){ + // update with rewrite + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + continue; + } + // if (((! (pManRes->nLastGain < 0)) && (! (pManRes->nLastGain < nGain)) && (! (nGain < pManRef->nLastGain))) || ((! (pManRes->nLastGain < 0)) && (! (pManRes->nLastGain < pManRef->nLastGain)) && (! (pManRef->nLastGain < nGain)))){ + if (((! (pManRes->nLastGain < 0)) && (! (pManRes->nLastGain < nGain)) && (! (pManRes->nLastGain < pManRef->nLastGain)))){ + // update with Resub + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + continue; + } + // if (((! (pManRef->nLastGain < 0)) && (! (pManRef->nLastGain < nGain)) && (! (nGain < pManRes->nLastGain))) || ((! (pManRef->nLastGain < 0)) && (! (pManRef->nLastGain < pManRes->nLastGain)) && (! (pManRes->nLastGain < nGain)))){ + if (((! (pManRef->nLastGain < 0)) && (! (pManRef->nLastGain < nGain)) && (! (pManRef->nLastGain < pManRes->nLastGain)))){ + // update with Refactor + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + continue; + } + else{ops_null++; continue;} + } + + /* + printf("Nodes with rewrite: %d\n", ops_rwr); + printf("Nodes with resub: %d\n", ops_res); + printf("Nodes with refactor: %d\n", ops_ref); + printf("Nodes without updates: %d\n", ops_null); + Extra_ProgressBarStop( pProgress ); + */ + +// Rewrite +Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); + pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Resub +pManRes->timeTotal = Abc_Clock() - clkStart; + pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Refactor +pManRef->timeTotal = Abc_Clock() - clkStart; + pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk); + + // print statistics + if ( fVerbose ){ + Abc_ManResubPrint( pManRes ); + Rwr_ManPrintStats( pManRwr ); + Abc_NtkManRefPrintStats_1( pManRef ); + } + if ( fVeryVerbose ) + Rwr_ScoresReport( pManRwr ); + // delete the managers + // resub + Abc_ManResubStop( pManRes ); + Abc_NtkManCutStop( pManCutRes ); + // rewrite + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCutRwr ); + pNtk->pManCut = NULL; + // refactor + Abc_NtkManCutStop( pManCutRef ); + Abc_NtkManRefStop_1( pManRef ); + + if ( pManOdc ) Abc_NtkDontCareFree( pManOdc ); + + // clean the data field + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->pData = NULL; + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pData = pNode->pNext, pNode->pNext = NULL; + } + + // put the nodes into the DFS order and reassign their IDs + Abc_NtkReassignIds( pNtk ); +// Abc_AigCheckFaninOrder( pNtk->pManFunc ); + + // fix the levels + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + // check + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkOchestraction: The network check has failed.\n" ); + return 0; + } +s_ResubTime = Abc_Clock() - clkStart; + return 1; +} + + +// priority order orchestration (runtime improved TBD) +int Abc_NtkOchestration( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, int sOpsOrder, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) +{ + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + ProgressBar * pProgress; + // For resub + Abc_ManRes_t * pManRes; + Abc_ManCut_t * pManCutRes; + Odc_Man_t * pManOdc = NULL; + Dec_Graph_t * pFFormRes; + Vec_Ptr_t * vLeaves; + // For rewrite + Cut_Man_t * pManCutRwr; + Rwr_Man_t * pManRwr; + Dec_Graph_t * pGraph; + // For refactor + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCutRef; + Dec_Graph_t * pFFormRef; + Vec_Ptr_t * vFanins; + + Abc_Obj_t * pNode; + FILE *fpt; + abctime clk, clkStart = Abc_Clock(); + abctime s_ResubTime; + int i, nNodes, nGain, fCompl; + int RetValue = 1; + int ops_rwr = 0; + int ops_res = 0; + int ops_ref = 0; + int ops_null = 0; + fUseZeros_rwr = 0; + fUseZeros_ref = 0; + clock_t begin= clock(); + assert( Abc_NtkIsStrash(pNtk) ); + + // cleanup the AIG + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + + // start the managers resub + pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 ); + pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX ); + if ( nLevelsOdc > 0 ) + pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose ); + // start the managers refactor + pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef ); + // start the managers rewrite + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + + // compute the reverse levels if level update is requested + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + + // 'Resub only' + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pNext = (Abc_Obj_t *)pNode->pData; + } + + // cut manager for rewrite +clk = Abc_Clock(); + pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk ); +Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); + pNtk->pManCut = pManCutRwr; + + if ( fVeryVerbose ) + Rwr_ScoresClean( pManRwr ); + + // resynthesize each node once + // resub + pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); + // rewrite + pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); + // refactor + pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); + +clock_t resyn_end=clock(); +double resyn_time_spent = (double)(resyn_end-begin)/CLOCKS_PER_SEC; +//printf("time %f\n", resyn_time_spent); + nNodes = Abc_NtkObjNumMax(pNtk); + //printf("nNodes: %d\n", nNodes); + if (pGain_res) *pGain_res = Vec_IntAlloc(1); + if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); + if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + fpt = fopen("Ochestration_id_ops_nGain.csv", "w"); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + //printf("Ochestration id: %d\n", pNode->Id); + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the constant node +// if ( Abc_NodeIsConst(pNode) ) +// continue; + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + { + fprintf(fpt, "%d, %s, %d\n", pNode->Id, "None" , -99); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } + // skip the nodes with many fanouts + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + fprintf(fpt, "%d, %s, %d\n", pNode->Id,"None", -99); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } +clk = Abc_Clock(); +/* + if ( sOpsOrder == 0) + { +// the order is rwr res ref + //printf("The graph update order is rwr res ref.\n"); + //printf("fUsezeros:%d \n", fUseZeros_rwr); + + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + //printf("nGain:%d\n", nGain); + Vec_IntPush( (*pGain_rwr), nGain); + if ((nGain > 0 || (nGain == 0 && fUseZeros_rwr))) + { +// Graph update with Rewrite + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + continue; + } + + else{ + //printf("Rewrite not work--resub\n"); + //check res + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +// vLeaves = Abc_CutFactorLarge( pNode, nCutMax ); +pManRes->timeCut += Abc_Clock() - clk; + // get the don't-cares + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } + // evaluate this cut +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +// Vec_PtrFree( vLeaves ); +// Abc_ManResubCleanup( pManRes ); +pManRes->timeRes += Abc_Clock() - clk; + // put nGain in Vector + Vec_IntPush((*pGain_res), pManRes->nLastGain); + if (pManRes->nLastGain > 0) + { +// Graph update with Resub + //printf("Graph Update with Resub\n"); + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + continue; + } + else{ + //check ref + //printf("Rewrite not work--ref\n"); + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { +// Graph update with Refactor + //printf("Graph Update with Refactor\n"); + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + continue; + } +//} +//} + ops_null++; + //continue; +} +*/ + + +// Update the graph with pre-defined order! + if ( sOpsOrder == 0) + { +// the order is rwr res ref + //printf("new imp: The graph update order is rwr res ref.\n"); + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { +// Graph update with Rewrite + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + continue; + } + else{ + //printf("Rewrite not work--resub\n"); + //check res + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +// vLeaves = Abc_CutFactorLarge( pNode, nCutMax ); +pManRes->timeCut += Abc_Clock() - clk; + // get the don't-cares + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } + // evaluate this cut +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +// Vec_PtrFree( vLeaves ); +// Abc_ManResubCleanup( pManRes ); +pManRes->timeRes += Abc_Clock() - clk; + // put nGain in Vector + Vec_IntPush((*pGain_res), pManRes->nLastGain); + if (pManRes->nLastGain > 0) + { +// Graph update with Resub + //printf("Graph Update with Resub\n"); + if ( pFFormRes != NULL ){ + //continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + continue;} + } + else{ + //check ref + //printf("Rewrite not work--ref\n"); + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { +// Graph update with Refactor + //printf("Graph Update with Refactor\n"); + if ( pFFormRef != NULL ){ + //continue; +clk = Abc_Clock(); + + Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain); + +/* + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +*/ + +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + continue;} + } +} +} + ops_null++; + continue; +} + + + if ( sOpsOrder == 1) + { +// the order is rwr ref res + //printf("The graph update order is rwr ref res.\n"); + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { +// Graph update with Rewrite + //printf("Graph Update with Rewrite"); + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + continue; + } + else{ + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + } + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { +// Graph update with Refactor + //printf("Graph Update with Refactor"); + if ( pFFormRef != NULL ){ + //continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + continue;} + } + else{ + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +pManRes->timeCut += Abc_Clock() - clk; + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +pManRes->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_res), pManRes->nLastGain); + } + if (pManRes->nLastGain > 0) + { +// Graph update with Resub + //printf("Graph Update with Resub"); + if ( pFFormRes != NULL ){ + //continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + continue;} + } +// No available updats + //if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + else{ + ops_null++; + continue; + } +// } +// } + } + + if ( sOpsOrder == 2) + { +// the order is res rwr ref + //printf("The graph update order is res rwr ref.\n"); + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +pManRes->timeCut += Abc_Clock() - clk; + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +pManRes->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_res), pManRes->nLastGain); + + if (pManRes->nLastGain > 0) + { +// Graph update with Resub + //printf("Graph Update with Resub"); + if ( pFFormRes != NULL ){ + //continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + continue;} + } + else{ + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { +// Graph update with Rewrite + //printf("Graph Update with Rewrite"); + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + continue; + } + else{ + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { +// Graph update with Refactor + //printf("Graph Update with Refactor"); + if ( pFFormRef != NULL ){ + //continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + continue;} + } +// No available updates + //if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + else{ + ops_null++; + continue; + } +}} + } + + if ( sOpsOrder == 3) + { +// the order is res ref rwr + //printf("The graph update order is res ref rwr.\n"); + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +pManRes->timeCut += Abc_Clock() - clk; + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +pManRes->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_res), pManRes->nLastGain); + + if (pManRes->nLastGain > 0) + { +// Graph update with Resub + //printf("Graph Update with Resub"); + if ( pFFormRes != NULL ){ + //continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + continue;} + } + else{ + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + //printf("refactor gain: %d\n", pManRef->nLastGain); + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { +// Graph update with Refactor + //printf("Graph Update with Refactor"); + if ( pFFormRef != NULL ){ + //continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + continue;} + } + else{ + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { +// Graph update with Rewrite + //printf("Graph Update with Rewrite"); + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + continue; + } + +// No available updates + // if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + else{ + ops_null++; + continue; + } +} +} + } + + if ( sOpsOrder == 4) + { +// the order is ref rwr res + //printf("The graph update order is ref rwr res.\n"); + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { +// Graph update with Refactor + //printf("Graph Update with Refactor"); + if ( pFFormRef != NULL ){ + //continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + continue;} + } + else{ + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { +// Graph update with Rewrite + //printf("Graph Update with Rewrite"); + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + continue; + } + else{ + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +pManRes->timeCut += Abc_Clock() - clk; + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +pManRes->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_res), pManRes->nLastGain); + + if (pManRes->nLastGain > 0) + { +// Graph update with Resub + //printf("Graph Update with Resub"); + if ( pFFormRes != NULL ){ + //continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + continue;} + } +// No available updates + //if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + else{ + ops_null++; + continue; + } +}} + } + + if ( sOpsOrder == 5) + { +// the order is ref res rwr + //printf("The graph update order is ref res rwr.\n"); + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + + if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref)) + { +// Graph update with Refactor + //printf("Graph Update with Refactor"); + if ( pFFormRef != NULL ){ + //continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + ops_ref++; + continue;} + } + else{ + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +pManRes->timeCut += Abc_Clock() - clk; + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +pManRes->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_res), pManRes->nLastGain); + + if (pManRes->nLastGain > 0) + { +// Graph update with Resub + //printf("Graph Update with Resub"); + if ( pFFormRes != NULL ){ + //continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + ops_res++; + continue;} + } + else{ + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + + if (nGain > 0 || (nGain == 0 && fUseZeros_rwr)) + { +// Graph update with Rewrite + //printf("Graph Update with Rewrite"); + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + ops_rwr++; + continue; + } +// No available updates + //if (! (nGain > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + else{ + ops_null++; + continue; + } +}} + } + + } + + fclose(fpt); + //printf("size of vector %d\n", (**pGain_rwr).nSize); + //printf("nGain in vector: %d\n", (**pGain_res).pArray[20]); + //printf("Nodes with rewrite: %d\n", ops_rwr); + //printf("Nodes with resub: %d\n", ops_res); + //printf("Nodes with refactor: %d\n", ops_ref); + //printf("Nodes without updates: %d\n", ops_null); + Extra_ProgressBarStop( pProgress ); +// Rewrite +Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); + pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Resub +pManRes->timeTotal = Abc_Clock() - clkStart; + pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Refactor +pManRef->timeTotal = Abc_Clock() - clkStart; + pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk); + + // print statistics + if ( fVerbose ){ + Abc_ManResubPrint( pManRes ); + Rwr_ManPrintStats( pManRwr ); + Abc_NtkManRefPrintStats_1( pManRef ); + } + if ( fVeryVerbose ) + Rwr_ScoresReport( pManRwr ); + // delete the managers + // resub + Abc_ManResubStop( pManRes ); + Abc_NtkManCutStop( pManCutRes ); + // rewrite + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCutRwr ); + pNtk->pManCut = NULL; + // refactor + Abc_NtkManCutStop( pManCutRef ); + Abc_NtkManRefStop_1( pManRef ); + + if ( pManOdc ) Abc_NtkDontCareFree( pManOdc ); + + // clean the data field + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->pData = NULL; + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pData = pNode->pNext, pNode->pNext = NULL; + } + + // put the nodes into the DFS order and reassign their IDs + Abc_NtkReassignIds( pNtk ); +// Abc_AigCheckFaninOrder( pNtk->pManFunc ); + + // fix the levels + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + // check + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkOchestraction: The network check has failed.\n" ); + return 0; + } +s_ResubTime = Abc_Clock() - clkStart; +clock_t end=clock(); +double time_spent = (double)(end-begin)/CLOCKS_PER_SEC; +//printf("time %f\n", time_spent); + return 1; +} + +// random orchestration with rw, rwz, rf, rfz, rs +int Abc_NtkOchestration3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res, Vec_Int_t **pGain_ref, Vec_Int_t **pOps_num, int fUseZeros, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) +{ + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + ProgressBar * pProgress; + // For resub + Abc_ManRes_t * pManRes; + Abc_ManCut_t * pManCutRes; + Odc_Man_t * pManOdc = NULL; + Dec_Graph_t * pFFormRes; + Dec_Graph_t * pFFormRef_zeros; + Vec_Ptr_t * vLeaves; + // For rewrite + Cut_Man_t * pManCutRwr; + Rwr_Man_t * pManRwr; + Dec_Graph_t * pGraph; + // For refactor + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCutRef; + Dec_Graph_t * pFFormRef; + Vec_Ptr_t * vFanins; + + Abc_Obj_t * pNode; + FILE *fpt; + abctime clk, clkStart = Abc_Clock(); + abctime s_ResubTime; + int i, nNodes, nGain, nGain_zeros, fCompl, RetValue = 1; + int ops_rwr = 0; + int ops_rwr_z = 0; + int ops_res = 0; + int ops_ref_z = 0; + int ops_ref = 0; + int ops_null = 0; + assert( Abc_NtkIsStrash(pNtk) ); + + // cleanup the AIG + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + + // start the managers resub + pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 ); + pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX ); + if ( nLevelsOdc > 0 ) + pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose ); + // start the managers refactor + pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef ); + // start the managers rewrite + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + + // compute the reverse levels if level update is requested + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + + // 'Resub only' + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pNext = (Abc_Obj_t *)pNode->pData; + } + // cut manager for rewrite +clk = Abc_Clock(); + pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk ); +Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); + pNtk->pManCut = pManCutRwr; + + if ( fVeryVerbose ) + Rwr_ScoresClean( pManRwr ); + + // resynthesize each node once + // resub + pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); + // rewrite + pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); + // refactor + pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); + + nNodes = Abc_NtkObjNumMax(pNtk); + //printf("nNodes: %d\n", nNodes); + if (pGain_res) *pGain_res = Vec_IntAlloc(1); + if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); + if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + fpt = fopen("Ochestration_id_ops_nGain.csv", "w"); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if (pOps_num) *pOps_num = Vec_IntAlloc(1); + //printf("Ochestration id: %d\n", pNode->Id); + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the constant node +// if ( Abc_NodeIsConst(pNode) ) +// continue; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + { + fprintf(fpt, "%d, %s, %d\n", pNode->Id, "None" , -99); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } + // skip the nodes with many fanouts + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + fprintf(fpt, "%d, %s, %d\n", pNode->Id,"None", -99); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; +clk = Abc_Clock(); + +//Refactor + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ); + pFFormRef_zeros = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + +// Resub + // compute a reconvergence-driven cut + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +// vLeaves = Abc_CutFactorLarge( pNode, nCutMax ); +pManRes->timeCut += Abc_Clock() - clk; + // get the don't-cares + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } + // evaluate this cut +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +// Vec_PtrFree( vLeaves ); +// Abc_ManResubCleanup( pManRes ); +pManRes->timeRes += Abc_Clock() - clk; + // put nGain in Vector + Vec_IntPush((*pGain_res), pManRes->nLastGain); + // printf("size of vector %d\n", (**pGain).nSize); + +// Rewrite + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros, fPlaceEnable ); + nGain_zeros = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + + //printf("Res Ochestration: %d\n", pManRes->nLastGain); + //printf("Ref Ochestration: %d\n", pManRef->nLastGain); + //printf("Rwr Ochestration: %d\n", nGain); + fprintf(fpt, "%d, %s, %d, %s, %d, %s, %d, %s, %d\n", pNode->Id, "Oches_Res", pManRes->nLastGain, "Oches_Ref", pManRef->nLastGain, "Oches_Rwr", nGain, "Oches_Rwr_Zeros", nGain_zeros); + +// Generate the valid operator array for the node + if ( nGain > 0 ) + { + Vec_IntPush((*pOps_num), 0); + } + if ( nGain_zeros > 0 ) + { + Vec_IntPush((*pOps_num), 1); + } + if ( pManRef->nLastGain > 0 ) + { + Vec_IntPush((*pOps_num), 2); + Vec_IntPush((*pOps_num), 3); + } + if ( pManRes->nLastGain > 0 ) + { + Vec_IntPush((*pOps_num), 4); + } +// No available updats + //if (! (nGain > 0 || nGain_zeros > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + //if (! (nGain > 0 ||(nGain == 0 && fUseZeros_rwr))) + //{ + //ops_null++; + //continue; + //} + if (! ((**pOps_num).nSize > 0)) + { + ops_null++; + continue; + } + + //printf("available operations: %d.\n", (**pOps_num).nSize); +// Randomly pick a operation number + //int Ops_num = 0; + int Ops_size = (**pOps_num).nSize; + int r = rand() % Ops_size; + int Ops_num = (**pOps_num).pArray[r]; + //printf("the picked operation: %d.\n", Ops_num); + +// Update the graph with random picked operation! + if ( Ops_num == 0) + { +// Graph update with Rewrite + //printf("Graph Update with Rewrite"); + ops_rwr++; + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + continue; + } + + if ( Ops_num == 1) + { +// Graph update with Rewrite -z + //printf("Graph Update with Rewrite -z"); + ops_rwr_z++; + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain_zeros ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + continue; + } + + if ( Ops_num == 2) + { +// Graph update with Refactor + //printf("Graph Update with Refactor"); + ops_ref++; + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + continue; + } + + if ( Ops_num == 3) + { +// Graph update with Refactor -z + //printf("Graph Update with Refactor"); + ops_ref_z++; + if ( pFFormRef_zeros == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef_zeros, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef_zeros ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef_zeros ); + continue; + } + + if (Ops_num == 4) + { +// Graph update with Resub + //printf("Graph Update with Resub"); + ops_res++; + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + continue; + } + + } + + fclose(fpt); + /* + printf("size of vector %d\n", (**pGain_rwr).nSize); + printf("nGain in vector: %d\n", (**pGain_res).pArray[20]); + printf("Nodes with rewrite: %d\n", ops_rwr); + printf("Nodes with rewrite -z: %d\n", ops_rwr_z); + printf("Nodes with resub: %d\n", ops_res); + printf("Nodes with refactor: %d\n", ops_ref); + printf("Nodes with refactor -z: %d\n", ops_ref_z); + printf("Nodes without updates: %d\n", ops_null); + */ + Extra_ProgressBarStop( pProgress ); +// Rewrite +Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); + pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Resub +pManRes->timeTotal = Abc_Clock() - clkStart; + pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Refactor +pManRef->timeTotal = Abc_Clock() - clkStart; + pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk); + + // print statistics + if ( fVerbose ){ + Abc_ManResubPrint( pManRes ); + Rwr_ManPrintStats( pManRwr ); + Abc_NtkManRefPrintStats_1( pManRef ); + } + if ( fVeryVerbose ) + Rwr_ScoresReport( pManRwr ); + // delete the managers + // resub + Abc_ManResubStop( pManRes ); + Abc_NtkManCutStop( pManCutRes ); + // rewrite + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCutRwr ); + pNtk->pManCut = NULL; + // refactor + Abc_NtkManCutStop( pManCutRef ); + Abc_NtkManRefStop_1( pManRef ); + + if ( pManOdc ) Abc_NtkDontCareFree( pManOdc ); + + // clean the data field + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->pData = NULL; + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pData = pNode->pNext, pNode->pNext = NULL; + } + + // put the nodes into the DFS order and reassign their IDs + Abc_NtkReassignIds( pNtk ); +// Abc_AigCheckFaninOrder( pNtk->pManFunc ); + + // fix the levels + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + // check + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkOchestraction: The network check has failed.\n" ); + return 0; + } +s_ResubTime = Abc_Clock() - clkStart; + return 1; +} + +// random orchestration with rw, rs, rf +int Abc_NtkOchestration2( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res, Vec_Int_t **pGain_ref, Vec_Int_t **pOps_num, int fUseZeros, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) +{ + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + ProgressBar * pProgress; + // For resub + Abc_ManRes_t * pManRes; + Abc_ManCut_t * pManCutRes; + Odc_Man_t * pManOdc = NULL; + Dec_Graph_t * pFFormRes; + Dec_Graph_t * pFFormRef_zeros; + Vec_Ptr_t * vLeaves; + // For rewrite + Cut_Man_t * pManCutRwr; + Rwr_Man_t * pManRwr; + Dec_Graph_t * pGraph; + // For refactor + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCutRef; + Dec_Graph_t * pFFormRef; + Vec_Ptr_t * vFanins; + + Abc_Obj_t * pNode; + FILE *fpt; + abctime clk, clkStart = Abc_Clock(); + abctime s_ResubTime; + int i, nNodes, nGain, nGain_zeros, fCompl, RetValue = 1; + int ops_rwr = 0; + int ops_res = 0; + int ops_ref = 0; + int ops_null = 0; + int rwr_ok = 0; + int res_ok = 0; + int ref_ok = 0; + int decisionOps = 0; + assert( Abc_NtkIsStrash(pNtk) ); + + // cleanup the AIG + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + + // start the managers resub + pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 ); + pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX ); + if ( nLevelsOdc > 0 ) + pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose ); + // start the managers refactor + pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef ); + // start the managers rewrite + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + + // compute the reverse levels if level update is requested + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + + // 'Resub only' + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pNext = (Abc_Obj_t *)pNode->pData; + } + // cut manager for rewrite +clk = Abc_Clock(); + pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk ); +Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); + pNtk->pManCut = pManCutRwr; + + if ( fVeryVerbose ) + Rwr_ScoresClean( pManRwr ); + + // resynthesize each node once + // resub + pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); + // rewrite + pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); + // refactor + pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); + + nNodes = Abc_NtkObjNumMax(pNtk); + //printf("nNodes: %d\n", nNodes); + if (pGain_res) *pGain_res = Vec_IntAlloc(1); + if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); + if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + fpt = fopen("Ochestration_id_ops_nGain.csv", "w"); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + //printf("Nodes ID: %d\n", pNode->Id); + rwr_ok = 0; + ref_ok = 0; + res_ok = 0; + if (pOps_num) *pOps_num = Vec_IntAlloc(1); + //printf("Ochestration id: %d\n", pNode->Id); + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the constant node +// if ( Abc_NodeIsConst(pNode) ) +// continue; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + { + fprintf(fpt, "%d, %d, %d, %d, %d\n", pNode->Id, 0, 0, 0, 0); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } + // skip the nodes with many fanouts + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + fprintf(fpt, "%d, %d, %d, %d, %d\n", pNode->Id, 0, 0, 0, 0); + Vec_IntPush((*pGain_res), -99); + Vec_IntPush((*pGain_ref), -99); + Vec_IntPush((*pGain_rwr), -99); + continue; + } + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; +clk = Abc_Clock(); + +//Refactor + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ); + pFFormRef_zeros = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + Vec_IntPush((*pGain_ref), pManRef->nLastGain); + +// Resub + // compute a reconvergence-driven cut + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +// vLeaves = Abc_CutFactorLarge( pNode, nCutMax ); +pManRes->timeCut += Abc_Clock() - clk; + // get the don't-cares + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } + // evaluate this cut +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +// Vec_PtrFree( vLeaves ); +// Abc_ManResubCleanup( pManRes ); +pManRes->timeRes += Abc_Clock() - clk; + // put nGain in Vector + Vec_IntPush((*pGain_res), pManRes->nLastGain); + // printf("size of vector %d\n", (**pGain).nSize); + +// Rewrite + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros, fPlaceEnable ); + nGain_zeros = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + Vec_IntPush( (*pGain_rwr), nGain); + + //printf("Res Ochestration: %d\n", pManRes->nLastGain); + //printf("Ref Ochestration: %d\n", pManRef->nLastGain); + //printf("Rwr Ochestration: %d\n", nGain); + fprintf(fpt, "%d, %s, %d, %s, %d, %s, %d, %s, %d\n", pNode->Id, "Oches_Res", pManRes->nLastGain, "Oches_Ref", pManRef->nLastGain, "Oches_Rwr", nGain, "Oches_Rwr_Zeros", nGain_zeros); + + //fprintf(fpt, "%d, %s, %d, %s, %d, %s, %d, %s, %d\n", pNode->Id, "Oches_Res", pManRes->nLastGain, "Oches_Ref", pManRef->nLastGain, "Oches_Rwr", nGain, "Oches_Rwr_Zeros", nGain_zeros); + +// Generate the valid operator array for the node + if ( nGain > 0 ) + { + rwr_ok = 1; + Vec_IntPush((*pOps_num), 0); + } + //if ( nGain_zeros > 0 ) + //{ + // Vec_IntPush((*pOps_num), 1); + //} + //take refactor put + + if ( pManRef->nLastGain > 0 ) + { + ref_ok = 1; + Vec_IntPush((*pOps_num), 2); + //Vec_IntPush((*pOps_num), 3); + } + + if ( pManRes->nLastGain > 0 ) + { + res_ok = 1; + Vec_IntPush((*pOps_num), 1); + } +// No available updats + //if (! (nGain > 0 || nGain_zeros > 0 || pManRef->nLastGain > 0 || pManRes->nLastGain > 0 || (nGain == 0 && fUseZeros_rwr))) + //if (! (nGain > 0 ||(nGain == 0 && fUseZeros_rwr))) + //{ + //ops_null++; + //continue; + //} + if (! ((**pOps_num).nSize > 0)) + { + fprintf(fpt, "%d, %d, %d, %d, %d\n", pNode->Id, 0, 0, 0, 0); + ops_null++; + continue; + } +/* + if (pManRes->nLastGain > 0){ + res_ok = 1; + } + if (pManRef->nLastGain > 0){ + ref_ok = 1; + } + if (nGain > 0){ + rwr_ok = 1; + } +*/ + + //printf("available operations: %d.\n", (**pOps_num).nSize); +// Randomly pick a operation number + //int Ops_num = 0; + int Ops_size = (**pOps_num).nSize; + int r = rand() % Ops_size; + int Ops_num = (**pOps_num).pArray[r]; + //printf("the picked operation: %d.\n", Ops_num); + +// Update the graph with random picked operation! + if ( Ops_num == 0) + { +// Graph update with Rewrite + //printf("Graph Update with Rewrite"); + decisionOps = 1; + ops_rwr++; + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + //printf("Nodes ID: %d\n", pNode->Id); + fprintf(fpt, "%d, %d, %d, %d, %d\n", pNode->Id, rwr_ok, ref_ok, res_ok, decisionOps); + continue; + } +/* + if ( Ops_num == 1) + { +// Graph update with Rewrite -z + //printf("Graph Update with Rewrite -z"); + ops_rwr_z++; + pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); + if ( fPlaceEnable ) + Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain_zeros ); +Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + continue; + } +*/ + if ( Ops_num == 2) + { +// Graph update with Refactor + //printf("Graph Update with Refactor"); + decisionOps = 2; + ops_ref++; + if ( pFFormRef == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef ); + fprintf(fpt, "%d, %d, %d, %d, %d\n", pNode->Id, rwr_ok, ref_ok, res_ok, decisionOps); + continue; + } +/* + if ( Ops_num == 3) + { +// Graph update with Refactor -z + //printf("Graph Update with Refactor"); + ops_ref_z++; + if ( pFFormRef_zeros == NULL ) + continue; +clk = Abc_Clock(); + if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef_zeros, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFFormRef_zeros ); + RetValue = -1; + break; + } +pManRef->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRef_zeros ); + continue; + } +*/ + + if (Ops_num == 1) + { +// Graph update with Resub + //printf("Graph Update with Resub"); + decisionOps = 3; + ops_res++; + if ( pFFormRes == NULL ) + continue; + pManRes->nTotalGain += pManRes->nLastGain; +clk = Abc_Clock(); + Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain ); +pManRes->timeNtk += Abc_Clock() - clk; + Dec_GraphFree( pFFormRes ); + fprintf(fpt, "%d, %d, %d, %d, %d\n", pNode->Id, rwr_ok, ref_ok, res_ok, decisionOps); + continue; + } + + } + + fclose(fpt); + + /* + printf("size of vector %d\n", (**pGain_rwr).nSize); + printf("nGain in vector: %d\n", (**pGain_res).pArray[20]); + printf("Nodes with rewrite: %d\n", ops_rwr); + //printf("Nodes with rewrite -z: %d\n", ops_rwr_z); + printf("Nodes with resub: %d\n", ops_res); + printf("Nodes with refactor: %d\n", ops_ref); + //printf("Nodes with refactor -z: %d\n", ops_ref_z); + printf("Nodes without updates: %d\n", ops_null); + */ + Extra_ProgressBarStop( pProgress ); +// Rewrite +Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); + pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Resub +pManRes->timeTotal = Abc_Clock() - clkStart; + pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Refactor +pManRef->timeTotal = Abc_Clock() - clkStart; + pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk); + + // print statistics + if ( fVerbose ){ + Abc_ManResubPrint( pManRes ); + Rwr_ManPrintStats( pManRwr ); + Abc_NtkManRefPrintStats_1( pManRef ); + } + if ( fVeryVerbose ) + Rwr_ScoresReport( pManRwr ); + // delete the managers + // resub + Abc_ManResubStop( pManRes ); + Abc_NtkManCutStop( pManCutRes ); + // rewrite + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCutRwr ); + pNtk->pManCut = NULL; + // refactor + Abc_NtkManCutStop( pManCutRef ); + Abc_NtkManRefStop_1( pManRef ); + + if ( pManOdc ) Abc_NtkDontCareFree( pManOdc ); + + // clean the data field + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->pData = NULL; + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pData = pNode->pNext, pNode->pNext = NULL; + } + + // put the nodes into the DFS order and reassign their IDs + Abc_NtkReassignIds( pNtk ); +// Abc_AigCheckFaninOrder( pNtk->pManFunc ); + + // fix the levels + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + // check + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkOchestraction: The network check has failed.\n" ); + return 0; + } +s_ResubTime = Abc_Clock() - clkStart; + return 1; +} + +// rw rs rf embedding generation for GNN learning +int Abc_NtkOrchGNN( Abc_Ntk_t * pNtk, char * edgelistFile, char * featFile, int fUseZeros, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) +{ + ProgressBar * pProgress; + // For resub + Abc_ManRes_t * pManRes; + Abc_ManCut_t * pManCutRes; + Odc_Man_t * pManOdc = NULL; + Dec_Graph_t * pFFormRes; + Dec_Graph_t * pFFormRef_zeros; + Vec_Ptr_t * vLeaves; + // For rewrite + Cut_Man_t * pManCutRwr; + Rwr_Man_t * pManRwr; + //Dec_Graph_t * pGraph; + // For refactor + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCutRef; + Dec_Graph_t * pFFormRef; + Vec_Ptr_t * vFanins; + + Abc_Obj_t * pNode, * pFanin; + int fanin_i; + FILE * f_el; + FILE * f_feats; + //FILE * fpt; + abctime clk, clkStart = Abc_Clock(); + abctime s_ResubTime; + int i, nNodes, nGain, nGain_zeros, fCompl, RetValue = 1; + int rwr_ok = 0; + int res_ok = 0; + int ref_ok = 0; + //int decisionOps = 0; + assert( Abc_NtkIsStrash(pNtk) ); + + // cleanup the AIG + Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc); + + // start the managers resub + pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 ); + pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX ); + if ( nLevelsOdc > 0 ) + pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose ); + // start the managers refactor + pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef ); + // start the managers rewrite + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + + // compute the reverse levels if level update is requested + if ( fUpdateLevel ) + Abc_NtkStartReverseLevels( pNtk, 0 ); + + // 'Resub only' + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pNext = (Abc_Obj_t *)pNode->pData; + } + // cut manager for rewrite +clk = Abc_Clock(); + pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk ); +Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); + pNtk->pManCut = pManCutRwr; + + if ( fVeryVerbose ) + Rwr_ScoresClean( pManRwr ); + + // resynthesize each node once + // resub + pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk); + // rewrite + pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk); + // refactor + pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); + + nNodes = Abc_NtkObjNumMax(pNtk); + //printf("nNodes: %d\n", nNodes); + //if (pGain_res) *pGain_res = Vec_IntAlloc(1); + //if (pGain_ref) *pGain_ref = Vec_IntAlloc(1); + //if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1); + + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + //fpt = fopen("GNN_Embedding.csv", "w"); + f_el = fopen(edgelistFile, "w"); + f_feats = fopen(featFile, "w"); + + Abc_NtkForEachNode( pNtk, pNode, i ) + { + int iterNode = pNode->Id; + Abc_ObjForEachFanin(pNode, pFanin, fanin_i){ + fprintf(f_el, "%d %d\n", iterNode, Abc_ObjId(pFanin)); + } + //printf("Nodes ID: %d\n", pNode->Id); + rwr_ok = 0; + ref_ok = 0; + res_ok = 0; + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the constant node +// if ( Abc_NodeIsConst(pNode) ) +// continue; + // skip persistant nodes + + if ( Abc_NodeIsPersistant(pNode) ) + { + //fprintf(f_el, "%d %d\n", iterNode, Abc_ObjId(pFanin)); + fprintf(f_feats, "%d, %d, %d, %d, %d, %d, %d, %d\n", Abc_ObjFaninC0(pNode), Abc_ObjFaninC1(pNode), -1, -1, -1, -1, -1, -1); + //fprintf(fpt, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", iterNode, Abc_ObjId(pFanin), Abc_ObjFaninC0(pNode), Abc_ObjFaninC1(pNode), -1, -1, -1, -1, -1, -1); + continue; + } + // skip the nodes with many fanouts + if ( Abc_ObjFanoutNum(pNode) > 1000 ) + { + //fprintf(f_el, "%d %d\n", iterNode, Abc_ObjId(pFanin)); + fprintf(f_feats, "%d, %d, %d, %d, %d, %d, %d, %d\n", Abc_ObjFaninC0(pNode), Abc_ObjFaninC1(pNode), -1, -1, -1, -1, -1, -1); + //fprintf(fpt, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", iterNode, Abc_ObjId(pFanin), Abc_ObjFaninC0(pNode), Abc_ObjFaninC1(pNode), -1, -1, -1, -1, -1, -1); + continue; + } + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; + +clk = Abc_Clock(); + +//Refactor + vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs ); +pManRef->timeCut += Abc_Clock() - clk; +clk = Abc_Clock(); + pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ); + pFFormRef_zeros = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose ); +pManRef->timeRes += Abc_Clock() - clk; + if (! (pManRef->nLastGain < 0) ) {ref_ok = 1;} + +// Resub + // compute a reconvergence-driven cut + vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 ); +// vLeaves = Abc_CutFactorLarge( pNode, nCutMax ); +pManRes->timeCut += Abc_Clock() - clk; + // get the don't-cares + if ( pManOdc ) + { +clk = Abc_Clock(); + Abc_NtkDontCareClear( pManOdc ); + Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet ); +pManRes->timeTruth += Abc_Clock() - clk; + } + // evaluate this cut +clk = Abc_Clock(); + pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose ); +// Vec_PtrFree( vLeaves ); +// Abc_ManResubCleanup( pManRes ); +pManRes->timeRes += Abc_Clock() - clk; + // put nGain in Vector + if (! (pManRes->nLastGain < 0) ) {res_ok = 1;} + +// Rewrite + nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros, fPlaceEnable ); + nGain_zeros = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable ); + if (! (nGain < 0) ) {rwr_ok = 1;} + + //fprintf(f_el, "%d %d\n", iterNode, Abc_ObjId(pFanin)); + fprintf(f_feats, "%d, %d, %d, %d, %d, %d, %d, %d\n", Abc_ObjFaninC0(pNode), Abc_ObjFaninC1(pNode), rwr_ok, nGain, res_ok, pManRes->nLastGain, ref_ok, pManRef->nLastGain); + //fprintf(fpt, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", iterNode, Abc_ObjId(pFanin), Abc_ObjFaninC0(pNode), Abc_ObjFaninC1(pNode), rwr_ok, nGain, res_ok, pManRes->nLastGain, ref_ok, pManRef->nLastGain); + //printf("Res Ochestration: %d\n", pManRes->nLastGain); + //printf("Ref Ochestration: %d\n", pManRef->nLastGain); + //printf("Rwr Ochestration: %d\n", nGain); + + //continue; + //} + //continue; + } + fclose(f_el); + fclose(f_feats); + //fclose(fpt); + + + Extra_ProgressBarStop( pProgress ); +// Rewrite +Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); + pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Resub +pManRes->timeTotal = Abc_Clock() - clkStart; + pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk); + +// Refactor +pManRef->timeTotal = Abc_Clock() - clkStart; + pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk); + + // print statistics + if ( fVerbose ){ + Abc_ManResubPrint( pManRes ); + Rwr_ManPrintStats( pManRwr ); + Abc_NtkManRefPrintStats_1( pManRef ); + } + if ( fVeryVerbose ) + Rwr_ScoresReport( pManRwr ); + // delete the managers + // resub + Abc_ManResubStop( pManRes ); + Abc_NtkManCutStop( pManCutRes ); + // rewrite + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCutRwr ); + pNtk->pManCut = NULL; + // refactor + Abc_NtkManCutStop( pManCutRef ); + Abc_NtkManRefStop_1( pManRef ); + + if ( pManOdc ) Abc_NtkDontCareFree( pManOdc ); + + // clean the data field + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->pData = NULL; + + if ( Abc_NtkLatchNum(pNtk) ) { + Abc_NtkForEachLatch(pNtk, pNode, i) + pNode->pData = pNode->pNext, pNode->pNext = NULL; + } + + // put the nodes into the DFS order and reassign their IDs + Abc_NtkReassignIds( pNtk ); +// Abc_AigCheckFaninOrder( pNtk->pManFunc ); + + // fix the levels + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + // check + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkOchestraction: The network check has failed.\n" ); + return 0; + } +s_ResubTime = Abc_Clock() - clkStart; + return 1; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/abci/module.make b/src/base/abci/module.make index 00143df8c..4e4690404 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -41,6 +41,7 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcNtbdd.c \ src/base/abci/abcNpn.c \ src/base/abci/abcNpnSave.c \ + src/base/abci/abcOrchestration.c \ src/base/abci/abcOdc.c \ src/base/abci/abcOrder.c \ src/base/abci/abcPart.c \ From 59cfcd224064d7d8eae70da740176c554da5427f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 18 Jul 2023 09:00:11 -0700 Subject: [PATCH 15/60] Compiler warnings. --- src/base/abci/abcOrchestration.c | 33 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/base/abci/abcOrchestration.c b/src/base/abci/abcOrchestration.c index ba70b2f18..fe83891ec 100644 --- a/src/base/abci/abcOrchestration.c +++ b/src/base/abci/abcOrchestration.c @@ -39,6 +39,8 @@ extern void Abc_PlaceBegin( Abc_Ntk_t * pNtk ); extern void Abc_PlaceEnd( Abc_Ntk_t * pNtk ); extern void Abc_PlaceUpdate( Vec_Ptr_t * vAddedCells, Vec_Ptr_t * vUpdatedNets ); +extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + #define ABC_RS_DIV1_MAX 150 // the max number of divisors to consider #define ABC_RS_DIV2_MAX 500 // the max number of pair-wise divisors to consider @@ -168,7 +170,6 @@ struct Abc_ManRef_t_ int Abc_NtkRewrite3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rw, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable ) { - extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; Cut_Man_t * pManCut; Rwr_Man_t * pManRwr; @@ -469,7 +470,6 @@ void Abc_NtkManRefPrintStats_1( Abc_ManRef_t * p ) int Abc_NtkRefactor3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_ref, int nNodeSizeMax, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose ) { - extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; Abc_ManRef_t * pManRef; Abc_ManCut_t * pManCut; @@ -571,7 +571,6 @@ pManRef->timeTotal = Abc_Clock() - clkStart; int Abc_NtkResubstitute3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_res, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose ) { - extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; Abc_ManRes_t * pManRes; Abc_ManCut_t * pManCut; @@ -2666,7 +2665,6 @@ Vec_Ptr_t * Abc_CutFactorLarge( Abc_Obj_t * pNode, int nLeavesMax ) int Abc_NtkOrchSA( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, Vec_Int_t **PolicyList, char * DecisionFile, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) { - extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; // For resub Abc_ManRes_t * pManRes; @@ -3238,7 +3236,7 @@ int Abc_NtkOrchLocal( Abc_Ntk_t * pNtk, int fUseZeros_rwr, int fUseZeros_ref, in Abc_ManCut_t * pManCutRes; Odc_Man_t * pManOdc = NULL; Dec_Graph_t * pFFormRes; - Dec_Graph_t * pFFormRef_zeros; + //Dec_Graph_t * pFFormRef_zeros; Vec_Ptr_t * vLeaves; // For rewrite Cut_Man_t * pManCutRwr; @@ -3250,12 +3248,12 @@ int Abc_NtkOrchLocal( Abc_Ntk_t * pNtk, int fUseZeros_rwr, int fUseZeros_ref, in Dec_Graph_t * pFFormRef; Vec_Ptr_t * vFanins; - Abc_Obj_t * pNode, * pFanin; - int fanin_i; + Abc_Obj_t * pNode;//, * pFanin; + //int fanin_i; //FILE * fpt; abctime clk, clkStart = Abc_Clock(); abctime s_ResubTime; - int i, nNodes, nGain, nGain_zeros, fCompl, RetValue = 1; + int i, nNodes, nGain, fCompl, RetValue = 1;//, nGain_zeros; //int decisionOps = 0; int ops_rwr = 0; int ops_res = 0; @@ -3316,7 +3314,7 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); Abc_NtkForEachNode( pNtk, pNode, i ) { - int iterNode = pNode->Id; + //int iterNode = pNode->Id; //printf("Nodes ID: %d\n", pNode->Id); Extra_ProgressBarUpdate( pProgress, i, NULL ); // skip the constant node @@ -3494,13 +3492,12 @@ s_ResubTime = Abc_Clock() - clkStart; // priority order orchestration (runtime improved TBD) int Abc_NtkOchestration( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, int sOpsOrder, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) { - extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; // For resub Abc_ManRes_t * pManRes; Abc_ManCut_t * pManCutRes; Odc_Man_t * pManOdc = NULL; - Dec_Graph_t * pFFormRes; + Dec_Graph_t * pFFormRes = NULL; Vec_Ptr_t * vLeaves; // For rewrite Cut_Man_t * pManCutRwr; @@ -3524,7 +3521,7 @@ int Abc_NtkOchestration( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pG int ops_null = 0; fUseZeros_rwr = 0; fUseZeros_ref = 0; - clock_t begin= clock(); + //clock_t begin= clock(); assert( Abc_NtkIsStrash(pNtk) ); // cleanup the AIG @@ -3572,8 +3569,8 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); // refactor pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk); -clock_t resyn_end=clock(); -double resyn_time_spent = (double)(resyn_end-begin)/CLOCKS_PER_SEC; +//clock_t resyn_end=clock(); +//double resyn_time_spent = (double)(resyn_end-begin)/CLOCKS_PER_SEC; //printf("time %f\n", resyn_time_spent); nNodes = Abc_NtkObjNumMax(pNtk); //printf("nNodes: %d\n", nNodes); @@ -4315,8 +4312,8 @@ pManRef->timeTotal = Abc_Clock() - clkStart; return 0; } s_ResubTime = Abc_Clock() - clkStart; -clock_t end=clock(); -double time_spent = (double)(end-begin)/CLOCKS_PER_SEC; +//clock_t end=clock(); +//double time_spent = (double)(end-begin)/CLOCKS_PER_SEC; //printf("time %f\n", time_spent); return 1; } @@ -4324,7 +4321,6 @@ double time_spent = (double)(end-begin)/CLOCKS_PER_SEC; // random orchestration with rw, rwz, rf, rfz, rs int Abc_NtkOchestration3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res, Vec_Int_t **pGain_ref, Vec_Int_t **pOps_num, int fUseZeros, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) { - extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; // For resub Abc_ManRes_t * pManRes; @@ -4687,7 +4683,6 @@ s_ResubTime = Abc_Clock() - clkStart; // random orchestration with rw, rs, rf int Abc_NtkOchestration2( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res, Vec_Int_t **pGain_ref, Vec_Int_t **pOps_num, int fUseZeros, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs ) { - extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; // For resub Abc_ManRes_t * pManRes; @@ -5110,7 +5105,7 @@ int Abc_NtkOrchGNN( Abc_Ntk_t * pNtk, char * edgelistFile, char * featFile, int //FILE * fpt; abctime clk, clkStart = Abc_Clock(); abctime s_ResubTime; - int i, nNodes, nGain, nGain_zeros, fCompl, RetValue = 1; + int i, nNodes, nGain, nGain_zeros;//, fCompl, RetValue = 1; int rwr_ok = 0; int res_ok = 0; int ref_ok = 0; From 927b60b7a02e8709768fdaa1301dff2b883dd0cf Mon Sep 17 00:00:00 2001 From: Scott Alfter Date: Tue, 18 Jul 2023 09:17:58 -0700 Subject: [PATCH 16/60] fix errors when compiling within Yosys: "ISO C++17 does not allow 'register' storage class specifier" --- src/bdd/cudd/cuddBddIte.c | 6 +++--- src/bdd/cudd/cuddCache.c | 6 +++--- src/bdd/cudd/cuddSat.c | 4 ++-- src/bdd/cudd/cuddSplit.c | 4 ++-- src/misc/bzlib/compress.c | 12 ++++++------ src/misc/extra/extraUtilUtil.c | 4 ++-- src/misc/zlib/crc32.c | 8 ++++---- src/misc/zlib/deflate.c | 30 +++++++++++++++--------------- src/misc/zlib/trees.c | 2 +- 9 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/bdd/cudd/cuddBddIte.c b/src/bdd/cudd/cuddBddIte.c index 2901096ca..e9d11d026 100644 --- a/src/bdd/cudd/cuddBddIte.c +++ b/src/bdd/cudd/cuddBddIte.c @@ -1203,8 +1203,8 @@ bddVarToCanonical( unsigned int * topgp, unsigned int * tophp) { - register DdNode *F, *G, *H, *r, *f, *g, *h; - register unsigned int topf, topg, toph; + DdNode *F, *G, *H, *r, *f, *g, *h; + unsigned int topf, topg, toph; DdNode *one = dd->one; int comple, change; @@ -1305,7 +1305,7 @@ bddVarToCanonicalSimple( unsigned int * topgp, unsigned int * tophp) { - register DdNode *r, *f, *g, *h; + DdNode *r, *f, *g, *h; int comple, change; f = *fp; diff --git a/src/bdd/cudd/cuddCache.c b/src/bdd/cudd/cuddCache.c index 683499420..ae9c0455b 100644 --- a/src/bdd/cudd/cuddCache.c +++ b/src/bdd/cudd/cuddCache.c @@ -229,7 +229,7 @@ cuddCacheInsert( { int posn; unsigned hash; - register DdCache *entry; + DdCache *entry; ptruint uf, ug, uh; ptruint ufc, ugc, uhc; @@ -283,7 +283,7 @@ cuddCacheInsert2( { int posn; unsigned hash; - register DdCache *entry; + DdCache *entry; hash = ddCHash2_(op,cuddF2L(f),cuddF2L(g)); // posn = ddCHash2(op,cuddF2L(f),cuddF2L(g),table->cacheShift); @@ -328,7 +328,7 @@ cuddCacheInsert1( { int posn; unsigned hash; - register DdCache *entry; + DdCache *entry; hash = ddCHash2_(op,cuddF2L(f),cuddF2L(f)); // posn = ddCHash2(op,cuddF2L(f),cuddF2L(f),table->cacheShift); diff --git a/src/bdd/cudd/cuddSat.c b/src/bdd/cudd/cuddSat.c index 976c59ab3..0f5f1056b 100644 --- a/src/bdd/cudd/cuddSat.c +++ b/src/bdd/cudd/cuddSat.c @@ -279,7 +279,7 @@ Cudd_LargestCube( DdNode * f, int * length) { - register DdNode *F; + DdNode *F; st__table *visited; DdNode *sol; cuddPathPair *rootPair; @@ -351,7 +351,7 @@ Cudd_ShortestLength( DdNode * f, int * weight) { - register DdNode *F; + DdNode *F; st__table *visited; cuddPathPair *my_pair; int complement, cost; diff --git a/src/bdd/cudd/cuddSplit.c b/src/bdd/cudd/cuddSplit.c index 70f0f0d93..f70ae1e5f 100644 --- a/src/bdd/cudd/cuddSplit.c +++ b/src/bdd/cudd/cuddSplit.c @@ -638,8 +638,8 @@ bddAnnotateMintermCount( { DdNode *N,*Nv,*Nnv; - register double min_v,min_nv; - register double min_N; + double min_v,min_nv; + double min_N; double *pmin; double *dummy; diff --git a/src/misc/bzlib/compress.c b/src/misc/bzlib/compress.c index b149a28c5..d4d5ac924 100644 --- a/src/misc/bzlib/compress.c +++ b/src/misc/bzlib/compress.c @@ -190,15 +190,15 @@ void generateMTFValues ( EState* s ) zPend = 0; } { - register UChar rtmp; - register UChar* ryy_j; - register UChar rll_i; + UChar rtmp; + UChar* ryy_j; + UChar rll_i; rtmp = yy[1]; yy[1] = yy[0]; ryy_j = &(yy[1]); rll_i = ll_i; while ( rll_i != rtmp ) { - register UChar rtmp2; + UChar rtmp2; ryy_j++; rtmp2 = rtmp; rtmp = *ryy_j; @@ -360,8 +360,8 @@ void sendMTFValues ( EState* s ) if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ - register UInt32 cost01, cost23, cost45; - register UInt16 icv; + UInt32 cost01, cost23, cost45; + UInt16 icv; cost01 = cost23 = cost45 = 0; # define BZ_ITER(nn) \ diff --git a/src/misc/extra/extraUtilUtil.c b/src/misc/extra/extraUtilUtil.c index 7a9e8fd0b..81e4d3987 100644 --- a/src/misc/extra/extraUtilUtil.c +++ b/src/misc/extra/extraUtilUtil.c @@ -97,8 +97,8 @@ void Extra_UtilGetoptReset() ***********************************************************************/ int Extra_UtilGetopt( int argc, char *argv[], const char *optstring ) { - register int c; - register const char *place; + int c; + const char *place; globalUtilOptarg = NULL; diff --git a/src/misc/zlib/crc32.c b/src/misc/zlib/crc32.c index 46c970087..c6ff6b786 100644 --- a/src/misc/zlib/crc32.c +++ b/src/misc/zlib/crc32.c @@ -269,8 +269,8 @@ unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uIn /* ========================================================================= */ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len) { - register u4 c; - register const u4 FAR *buf4; + u4 c; + const u4 FAR *buf4; c = (u4)crc; c = ~c; @@ -306,8 +306,8 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf /* ========================================================================= */ local unsigned long crc32_big(unsigned long crc, const unsigned char FAR *buf, unsigned len) { - register u4 c; - register const u4 FAR *buf4; + u4 c; + const u4 FAR *buf4; c = REV((u4)crc); c = ~c; diff --git a/src/misc/zlib/deflate.c b/src/misc/zlib/deflate.c index 934196c89..5e7150838 100644 --- a/src/misc/zlib/deflate.c +++ b/src/misc/zlib/deflate.c @@ -1027,9 +1027,9 @@ local void lm_init (deflate_state *s) local uInt longest_match(deflate_state *s, IPos cur_match) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ + Bytef *scan = s->window + s->strstart; /* current string */ + Bytef *match; /* matched string */ + int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? @@ -1044,13 +1044,13 @@ local uInt longest_match(deflate_state *s, IPos cur_match) /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); + Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + ush scan_start = *(ushf*)scan; + ush scan_end = *(ushf*)(scan+best_len-1); #else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; + Bytef *strend = s->window + s->strstart + MAX_MATCH; + Byte scan_end1 = scan[best_len-1]; + Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. @@ -1173,10 +1173,10 @@ local uInt longest_match(deflate_state *s, IPos cur_match) */ local uInt longest_match(deflate_state *s, IPos cur_match) { - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; + Bytef *scan = s->window + s->strstart; /* current string */ + Bytef *match; /* matched string */ + int len; /* length of current match */ + Bytef *strend = s->window + s->strstart + MAX_MATCH; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. @@ -1261,8 +1261,8 @@ local void check_match(deflate_state *s, IPos start, IPos match, int length) */ local void fill_window(deflate_state *s) { - register unsigned n, m; - register Posf *p; + unsigned n, m; + Posf *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; diff --git a/src/misc/zlib/trees.c b/src/misc/zlib/trees.c index b61bae816..cb2e6c677 100644 --- a/src/misc/zlib/trees.c +++ b/src/misc/zlib/trees.c @@ -1144,7 +1144,7 @@ local int detect_data_type(deflate_state *s) */ local unsigned bi_reverse(unsigned code, int len) { - register unsigned res = 0; + unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; From 82c84387fa2a9ad90e356859e9c0306b8aa4da3e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 18 Jul 2023 10:11:29 -0700 Subject: [PATCH 17/60] Compiler warnings. --- abclib.dsp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/abclib.dsp b/abclib.dsp index 0fd96a8b8..7433c5139 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -387,6 +387,10 @@ SOURCE=.\src\base\abci\abcOrder.c # End Source File # Begin Source File +SOURCE=.\src\base\abci\abcOrchestration.c +# End Source File +# Begin Source File + SOURCE=.\src\base\abci\abcPart.c # End Source File # Begin Source File From 0828ac28a04216ab5e7eda43679f90ed41cf4f94 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 18 Jul 2023 15:53:20 -0700 Subject: [PATCH 18/60] Bug fix in Verilog writer. --- src/base/io/ioWriteVerilog.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/base/io/ioWriteVerilog.c b/src/base/io/ioWriteVerilog.c index 48b15b559..5e4438a5d 100644 --- a/src/base/io/ioWriteVerilog.c +++ b/src/base/io/ioWriteVerilog.c @@ -557,10 +557,17 @@ void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds ) } else { - Vec_Int_t * vMap = Vec_IntStartFull( 2*Abc_NtkObjNumMax(pNtk) ); + //Vec_Int_t * vMap = Vec_IntStartFull( 2*Abc_NtkObjNumMax(pNtk) ); vLevels = Vec_VecAlloc( 10 ); Abc_NtkForEachNode( pNtk, pObj, i ) { + if ( Abc_ObjFaninNum(pObj) == 0 ) + { + fprintf( pFile, " assign %s = ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) ); + fprintf( pFile, "1\'b%d;\n", Abc_NodeIsConst1(pObj) ); + continue; + } + /* if ( Abc_ObjFaninNum(pObj) == 1 || Abc_ObjIsCo(Abc_ObjFanout0(Abc_ObjFanout0(pObj))) ) { int iLit = Abc_Var2Lit( Abc_ObjId( Abc_ObjFanin0(Abc_ObjFanin0(pObj)) ), Abc_NodeIsInv(pObj) ); @@ -574,6 +581,7 @@ void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds ) continue; } } + */ pFunc = (Hop_Obj_t *)pObj->pData; fprintf( pFile, " assign %s = ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) ); // set the input names @@ -595,7 +603,7 @@ void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds ) ABC_FREE( Hop_IthVar((Hop_Man_t *)pNtk->pManFunc, k)->pData ); } Vec_VecFree( vLevels ); - Vec_IntFree( vMap ); + //Vec_IntFree( vMap ); } } From 623d0f3c9ff3fb8c31d5e6a10aa50014601a51d8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 18 Jul 2023 21:00:13 -0700 Subject: [PATCH 19/60] Change in how signal names are printing in 'print_level'. --- src/base/abci/abcPrint.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index 8a2cd42e2..7b566b79d 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -1199,6 +1199,17 @@ void Abc_NtkPrintSop( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames ) SeeAlso [] ***********************************************************************/ +char * Abc_NodeGetPrintName( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFan, * pFanout = NULL; int k, nPos = 0; + if ( !Abc_ObjIsNode(pObj) ) + return Abc_ObjName(pObj); + Abc_ObjForEachFanout( pObj, pFan, k ) { + if ( Abc_ObjIsPo(pFan) ) + pFanout = pFan, nPos++; + } + return Abc_ObjName(nPos == 1 ? pFanout : pObj); +} void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes, int fVerbose ) { Abc_Obj_t * pNode; @@ -1214,7 +1225,7 @@ void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListN printf( "%2d : ", i ); Abc_NtkForEachNode( pNtk, pNode, k ) if ( (int)pNode->Level == i ) - printf( " %s", Abc_ObjName(pNode) ); + printf( " %s", Abc_NodeGetPrintName(pNode) ); printf( "\n" ); } return; From 55ed1e66980610ec43d9b122e438595c0b7018e7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 21 Jul 2023 16:15:34 -0700 Subject: [PATCH 20/60] Changing command &permute to generate random NPNP transformations. --- src/aig/gia/giaDup.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/base/abci/abc.c | 36 +++++++++++++++++++++++++++-------- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 35ad6aab9..3822497af 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -1069,6 +1069,51 @@ Gia_Man_t * Gia_ManDupPiPerm( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCreatePerm( int n ) +{ + Vec_Int_t * vPerm = Vec_IntStartNatural( n ); + int i, * pPerm = Vec_IntArray( vPerm ); + for ( i = 0; i < n; i++ ) + { + int j = Abc_Random(0) % n; + ABC_SWAP( int, pPerm[i], pPerm[j] ); + + } + return vPerm; +} +Gia_Man_t * Gia_ManDupRandPerm( Gia_Man_t * p ) +{ + Vec_Int_t * vPiPerm = Gia_ManCreatePerm( Gia_ManCiNum(p) ); + Vec_Int_t * vPoPerm = Gia_ManCreatePerm( Gia_ManCoNum(p) ); + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachPi( p, pObj, i ) + Gia_ManPi(p, Vec_IntEntry(vPiPerm,i))->Value = Gia_ManAppendCi(pNew) ^ (Abc_Random(0) & 1); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManPo(p, Vec_IntEntry(vPoPerm,i))) ^ (Abc_Random(0) & 1) ); + Vec_IntFree( vPiPerm ); + Vec_IntFree( vPoPerm ); + return pNew; +} + /**Function************************************************************* Synopsis [Appends second AIG without any changes.] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 4e70d51f3..564cb399b 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -7380,7 +7380,7 @@ int Abc_CommandOrchestrate( Abc_Frame_t * pAbc, int argc, char ** argv ) int fVerbose; //rewrite/rs/rf verbose int fVeryVerbose; //very verbose option for all - size_t NtkSize; + //size_t NtkSize; extern void Rwr_Precompute(); //local greedy @@ -43941,14 +43941,25 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Permute( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Gia_Man_t * Gia_ManDupPiPerm( Gia_Man_t * p ); + extern Gia_Man_t * Gia_ManDupRandPerm( Gia_Man_t * p ); Gia_Man_t * pTemp; - int c, fVerbose = 0; + int c, RandSeed = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Svh" ) ) != EOF ) { switch ( c ) { + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + RandSeed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( RandSeed < 0 ) + goto usage; + break; case 'v': fVerbose ^= 1; break; @@ -43960,16 +43971,25 @@ int Abc_CommandAbc9Permute( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pGia == NULL ) { - Abc_Print( -1, "Abc_CommandAbc9Posplit(): There is no AIG.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Permute(): There is no AIG.\n" ); return 1; } - pTemp = Gia_ManDupPiPerm( pAbc->pGia ); + if ( Gia_ManRegNum(pAbc->pGia) > 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9Permute(): This command does not work for sequential AIGs.\n" ); + return 1; + } + Abc_Random(1); + for ( c = 0; c < RandSeed; c++ ) + Abc_Random(0); + pTemp = Gia_ManDupRandPerm( pAbc->pGia ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &permute [-vh]\n" ); - Abc_Print( -2, "\t permutes primary inputs\n" ); + Abc_Print( -2, "usage: &permute [-S num] [-vh]\n" ); + Abc_Print( -2, "\t generates a random NPNP transformation of the combinational AIG\n" ); + Abc_Print( -2, "\t-S num : the seed used to randomize the process [default = %d]\n", RandSeed ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; From 3592078ddb19093bd426cbd8d5fd5afbf2863b4a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 21 Jul 2023 18:49:06 -0700 Subject: [PATCH 21/60] Partitioned &scorr. --- src/base/abci/abc.c | 38 +++++- src/proof/cec/cec.h | 2 + src/proof/ssw/ssw.h | 1 + src/proof/ssw/sswPart.c | 289 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 323 insertions(+), 7 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 564cb399b..baf0d7eec 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -37232,13 +37232,15 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Gia_Man_t * Cec_ManScorrCorrespondence( Gia_Man_t * p, Cec_ParCor_t * pPars ); extern Gia_Man_t * Gia_ManScorrDivideTest( Gia_Man_t * p, Cec_ParCor_t * pPars ); + extern Gia_Man_t * Gia_SignalCorrespondencePart( Gia_Man_t * p, Cec_ParCor_t * pPars ); Cec_ParCor_t Pars, * pPars = &Pars; Gia_Man_t * pTemp; int fPartition = 0; int fUseOld = 0, c; Cec_ManCorSetDefaultParams( pPars ); + pPars->nProcs = 1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "FCPXpkrecqowvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "FCGXPSpkrecqowvh" ) ) != EOF ) { switch ( c ) { @@ -37264,7 +37266,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBTLimit < 0 ) goto usage; break; - case 'P': + case 'G': if ( globalUtilOptind >= argc ) { Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); @@ -37286,6 +37288,28 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLimitMax < 0 ) goto usage; break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nProcs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nProcs < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nPartSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nPartSize < 0 ) + goto usage; + break; case 'p': fPartition ^= 1; break; @@ -37338,7 +37362,9 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 0, "The network is combinational.\n" ); return 0; } - if ( fUseOld ) + if ( pPars->nPartSize > 0 ) + pTemp = Gia_SignalCorrespondencePart( pAbc->pGia, pPars ); + else if ( fUseOld ) pTemp = Cec_ManScorrCorrespondence( pAbc->pGia, pPars ); else if ( fPartition ) pTemp = Gia_ManScorrDivideTest( pAbc->pGia, pPars ); @@ -37348,12 +37374,14 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &scorr [-FCPX num] [-pkrecqowvh]\n" ); + Abc_Print( -2, "usage: &scorr [-FCGXPS num] [-pkrecqowvh]\n" ); Abc_Print( -2, "\t performs signal correpondence computation\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); - Abc_Print( -2, "\t-P num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix ); + Abc_Print( -2, "\t-G num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix ); Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax ); + Abc_Print( -2, "\t-P num : the number of concurrent processes [default = %d]\n", pPars->nProcs ); + Abc_Print( -2, "\t-S num : the number of flops in one partition [default = %d]\n", pPars->nPartSize ); Abc_Print( -2, "\t-p : toggle using partitioning for the input AIG [default = %s]\n", fPartition? "yes": "no" ); Abc_Print( -2, "\t-k : toggle using constant correspondence [default = %s]\n", pPars->fConstCorr? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" ); diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h index 92a08b3ef..d11bca3c3 100644 --- a/src/proof/cec/cec.h +++ b/src/proof/cec/cec.h @@ -147,6 +147,8 @@ struct Cec_ParCor_t_ int nFrames; // the number of time frames int nPrefix; // the number of time frames in the prefix int nBTLimit; // conflict limit at a node + int nProcs; // the number of processes + int nPartSize; // the partition size int nLevelMax; // (scorr only) the max number of levels int nStepsMax; // (scorr only) the max number of induction steps int nLimitMax; // (scorr only) stop after this many iterations if little or no improvement diff --git a/src/proof/ssw/ssw.h b/src/proof/ssw/ssw.h index c8275b7a3..7299e37d1 100644 --- a/src/proof/ssw/ssw.h +++ b/src/proof/ssw/ssw.h @@ -42,6 +42,7 @@ struct Ssw_Pars_t_ { int nPartSize; // size of the partition int nOverSize; // size of the overlap between partitions + int nProcs; // the number of processors int nFramesK; // the induction depth int nFramesAddSim; // the number of additional frames to simulate int fConstrs; // treat the last nConstrs POs as seq constraints diff --git a/src/proof/ssw/sswPart.c b/src/proof/ssw/sswPart.c index 30afddcae..0c6e54cef 100644 --- a/src/proof/ssw/sswPart.c +++ b/src/proof/ssw/sswPart.c @@ -20,10 +20,23 @@ #include "sswInt.h" #include "aig/ioa/ioa.h" +#include "aig/gia/giaAig.h" +#include "proof/cec/cec.h" + +#ifdef ABC_USE_PTHREADS + +#ifdef _WIN32 +#include "../lib/pthread.h" +#else +#include +#include +#endif + +#endif + ABC_NAMESPACE_IMPL_START - //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -32,6 +45,141 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Performing SAT sweeping for the array of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_SignalCorrespondenceArray1( Vec_Ptr_t * vGias, Ssw_Pars_t * pPars ) +{ + Gia_Man_t * pGia; int i; + Cec_ParCor_t CorPars, * pCorPars = &CorPars; + Cec_ManCorSetDefaultParams( pCorPars ); + pCorPars->nBTLimit = pPars->nBTLimit; + pCorPars->fVerbose = pPars->fVerbose; + pCorPars->fUseCSat = 1; + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + if ( Gia_ManPiNum(pGia) > 0 ) + Cec_ManLSCorrespondenceClasses( pGia, pCorPars ); +} + +/**Function************************************************************* + + Synopsis [Performing SAT sweeping for the array of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#ifndef ABC_USE_PTHREADS + +void Ssw_SignalCorrespondenceArray( Vec_Ptr_t * vGias, Ssw_Pars_t * pPars ) +{ + Ssw_SignalCorrespondenceArray1( vGias, pPars ); +} + +#else // pthreads are used + + +#define PAR_THR_MAX 100 +typedef struct Par_ScorrThData_t_ +{ + Cec_ParCor_t CorPars; + Gia_Man_t * p; + int * pMap; + int iThread; + int nTimeOut; + int fWorking; +} Par_ScorrThData_t; + +void * Ssw_GiaWorkerThread( void * pArg ) +{ + Par_ScorrThData_t * pThData = (Par_ScorrThData_t *)pArg; + volatile int * pPlace = &pThData->fWorking; + while ( 1 ) + { + while ( *pPlace == 0 ); + assert( pThData->fWorking ); + if ( pThData->p == NULL ) + { + pthread_exit( NULL ); + assert( 0 ); + return NULL; + } + Cec_ManLSCorrespondenceClasses( pThData->p, &pThData->CorPars ); + pThData->fWorking = 0; + } + assert( 0 ); + return NULL; +} + +void Ssw_SignalCorrespondenceArray( Vec_Ptr_t * vGias, Ssw_Pars_t * pPars ) +{ + //abctime clkTotal = Abc_Clock(); + Par_ScorrThData_t ThData[PAR_THR_MAX]; + pthread_t WorkerThread[PAR_THR_MAX]; + int i, status, nProcs = pPars->nProcs; + Vec_Ptr_t * vStack; + Cec_ParCor_t CorPars, * pCorPars = &CorPars; + Cec_ManCorSetDefaultParams( pCorPars ); + if ( pPars->fVerbose ) + printf( "Running concurrent &scorr with %d processes.\n", nProcs ); + fflush( stdout ); + if ( pPars->nProcs < 2 ) + return Ssw_SignalCorrespondenceArray1( vGias, pPars ); + // subtract manager thread + nProcs--; + assert( nProcs >= 1 && nProcs <= PAR_THR_MAX ); + // start threads + for ( i = 0; i < nProcs; i++ ) + { + ThData[i].CorPars = *pCorPars; + ThData[i].iThread = i; + //ThData[i].nTimeOut = pPars->nTimeOut; + ThData[i].fWorking = 0; + status = pthread_create( WorkerThread + i, NULL, Ssw_GiaWorkerThread, (void *)(ThData + i) ); assert( status == 0 ); + } + // look at the threads + vStack = Vec_PtrDup( vGias ); + while ( Vec_PtrSize(vStack) > 0 ) + { + for ( i = 0; i < nProcs; i++ ) + { + if ( ThData[i].fWorking ) + continue; + ThData[i].p = (Gia_Man_t*)Vec_PtrPop( vStack ); + ThData[i].fWorking = 1; + break; + } + } + Vec_PtrFree( vStack ); + // wait till threads finish + for ( i = 0; i < nProcs; i++ ) + if ( ThData[i].fWorking ) + i = -1; + // stop threads + for ( i = 0; i < nProcs; i++ ) + { + assert( !ThData[i].fWorking ); + // stop + ThData[i].p = NULL; + ThData[i].fWorking = 1; + } + +} + +#endif // pthreads are used + + /**Function************************************************************* Synopsis [Performs partitioned sequential SAT sweeping.] @@ -45,7 +193,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) { - int fPrintParts = 0; + int fPrintParts = 1; char Buffer[100]; Aig_Man_t * pTemp, * pNew; Vec_Ptr_t * vResult; @@ -132,6 +280,143 @@ Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) } +/**Function************************************************************* + + Synopsis [Performs partitioned sequential SAT sweeping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Ssw_SignalCorrespondencePart2( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) +{ + int fPrintParts = 1; + //char Buffer[100]; + Aig_Man_t * pTemp, * pNew; + Vec_Ptr_t * vAigs; + Vec_Ptr_t * vGias; + Vec_Ptr_t * vMaps; + Vec_Ptr_t * vResult; + Vec_Int_t * vPart; + int * pMapBack = NULL; + int i, nCountPis, nCountRegs; + int nClasses, nPartSize, fVerbose; + abctime clk = Abc_Clock(); + if ( pPars->fConstrs ) + { + Abc_Print( 1, "Cannot use partitioned computation with constraints.\n" ); + return NULL; + } + // save parameters + nPartSize = pPars->nPartSize; pPars->nPartSize = 0; + fVerbose = pPars->fVerbose; pPars->fVerbose = 0; + // generate partitions + if ( pAig->vClockDoms ) + { + // divide large clock domains into separate partitions + vResult = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( Vec_Int_t *, (Vec_Ptr_t *)pAig->vClockDoms, vPart, i ) + { + if ( nPartSize && Vec_IntSize(vPart) > nPartSize ) + Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize ); + else + Vec_PtrPush( vResult, Vec_IntDup(vPart) ); + } + } + else + vResult = Aig_ManRegPartitionSimple( pAig, nPartSize, pPars->nOverSize ); +// vResult = Aig_ManPartitionSmartRegisters( pAig, nPartSize, 0 ); +// vResult = Aig_ManRegPartitionSmart( pAig, nPartSize ); + // collect partitions + vAigs = Vec_PtrAlloc( 100 ); + vGias = Vec_PtrAlloc( 100 ); + vMaps = Vec_PtrAlloc( 100 ); + if ( fPrintParts ) + Abc_Print( 1, "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) ); + Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i ) + { + pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack ); + Aig_ManSetRegNum( pTemp, pTemp->nRegs ); + Vec_PtrPush( vAigs, pTemp ); + Vec_PtrPush( vGias, Gia_ManFromAigSimple(pTemp) ); + Vec_PtrPush( vMaps, pMapBack ); + //sprintf( Buffer, "part%03d.aig", i ); + //Ioa_WriteAiger( pTemp, Buffer, 0, 0 ); + if ( fPrintParts ) + Abc_Print( 1, "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n", + i, Vec_IntSize(vPart), Aig_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp) ); + } + // solve partitions + Ssw_SignalCorrespondenceArray( vGias, pPars ); + // collect the results + Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); + Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i ) + { + int * pMapBack = (int *)Vec_PtrEntry( vMaps, i ); + Gia_Man_t * pGia = (Gia_Man_t *)Vec_PtrEntry( vGias, i ); + Aig_Man_t * pTemp2 = Gia_ManToAigSimple( pGia ); + pTemp = (Aig_Man_t *)Vec_PtrEntry( vAigs, i ); + Gia_ManReprToAigRepr2( pTemp2, pGia ); + // remap back + nClasses = Aig_TransferMappedClasses( pAig, pTemp2, pMapBack ); + if ( fVerbose ) + Abc_Print( 1, "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n", + i, Vec_IntSize(vPart), Aig_ManCiNum(pTemp)-Vec_IntSize(vPart), 0, 0, Aig_ManNodeNum(pTemp), 0, nClasses ); + Aig_ManStop( pTemp ); + Aig_ManStop( pTemp2 ); + Gia_ManStop( pGia ); + ABC_FREE( pMapBack ); + } + Vec_PtrFree( vAigs ); + Vec_PtrFree( vGias ); + Vec_PtrFree( vMaps ); + + // remap the AIG + pNew = Aig_ManDupRepr( pAig, 0 ); + Aig_ManSeqCleanup( pNew ); +// Aig_ManPrintStats( pAig ); +// Aig_ManPrintStats( pNew ); + Vec_VecFree( (Vec_Vec_t *)vResult ); + pPars->nPartSize = nPartSize; + pPars->fVerbose = fVerbose; + if ( fVerbose ) + { + ABC_PRT( "Total time", Abc_Clock() - clk ); + } + return pNew; +} +void Gia_ManRestoreNodeMapping( Aig_Man_t * pAig, Gia_Man_t * pGia ) +{ + Aig_Obj_t * pObjAig; int i; + assert( Gia_ManObjNum(pGia) == Aig_ManObjNum(pAig) ); + Aig_ManForEachObj( pAig, pObjAig, i ) + pObjAig->iData = Abc_Var2Lit(i, 0); +} +Gia_Man_t * Gia_SignalCorrespondencePart( Gia_Man_t * p, Cec_ParCor_t * pPars ) +{ + Gia_Man_t * pRes = NULL; + Aig_Man_t * pNew = NULL; + Aig_Man_t * pAig = Gia_ManToAigSimple(p); + Ssw_Pars_t SswPars, * pSswPars = &SswPars; + assert( pPars->nProcs > 0 ); + assert( pPars->nPartSize > 0 ); + Ssw_ManSetDefaultParams( pSswPars ); + pSswPars->nBTLimit = pPars->nBTLimit; + pSswPars->nProcs = pPars->nProcs; + pSswPars->nPartSize = pPars->nPartSize; + pSswPars->fVerbose = pPars->fVerbose; + pNew = Ssw_SignalCorrespondencePart2( pAig, pSswPars ); + Gia_ManRestoreNodeMapping( pAig, p ); + Gia_ManReprFromAigRepr2( pAig, p ); + pRes = Gia_ManFromAigSimple(pNew); + Aig_ManStop( pNew ); + Aig_ManStop( pAig ); + return pRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 0f7d05d531d807287a7ffec0216e5c95bdd4d06f Mon Sep 17 00:00:00 2001 From: phsauter Date: Sat, 22 Jul 2023 21:20:09 +0200 Subject: [PATCH 22/60] fix Segfault in retime command --- src/map/scl/sclSize.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index a6bfbeac7..e09c56e67 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -140,6 +140,9 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) Abc_Obj_t * pObj, * pPivot = Abc_SclFindCriticalCo( p, &fRise ); float maxDelay = Abc_SclObjTimeOne( p, pPivot, fRise ); p->ReportDelay = maxDelay; + // used for Floyds cycle detection algorithm + unsigned int tortoiseIndex = 0; + int tortoiseStep = 0; #ifdef WIN32 printf( "WireLoad = \"%s\" ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" ); @@ -197,7 +200,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) while ( pObj && Abc_ObjIsNode(pObj) ) { i++; - nLength = Abc_MaxInt( nLength, Abc_SclObjCell(pObj) ? strlen(Abc_SclObjCell(pObj)->pName) : 2 /* strlen("pi") */ ); + nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(pObj)->pName) ); pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj ); } @@ -221,10 +224,18 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) Vec_PtrPush( vPath, pPivot ); pObj = Abc_ObjFanin0(pPivot); while ( pObj )//&& Abc_ObjIsNode(pObj) ) - { + { Vec_PtrPush( vPath, pObj ); pPrev = pObj; pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj ); + + // move the tortoise at half the speed (trailing) + tortoiseStep = (tortoiseStep + 1) % 2; + tortoiseIndex += tortoiseStep; + // if they see the same element, we are in a loop + if(vPath->pArray[tortoiseIndex] == pObj) { + break; + } } Vec_PtrForEachEntryReverse( Abc_Obj_t *, vPath, pObj, i ) { @@ -913,3 +924,4 @@ void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose ) ABC_NAMESPACE_IMPL_END + From a620c09c401a3d219d91151f39e74943b65d7f40 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 22 Jul 2023 16:44:33 -0700 Subject: [PATCH 23/60] Adding functional comparison to &compare. --- src/aig/gia/giaSimBase.c | 52 ++++++++++++++++++++++++++++++++++++++++ src/base/abci/abc.c | 18 ++++++++++---- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 47f645413..97335d378 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -3689,6 +3689,58 @@ Vec_Str_t * Gia_ManComputeRange( Gia_Man_t * p ) return vOut; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManComparePrint( Gia_Man_t * p, Gia_Man_t * q ) +{ + Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) ); + Vec_Wrd_t * vSimsP = Gia_ManSimPatSimOut( p, vSimsPi, 0 ); + Vec_Wrd_t * vSimsQ = Gia_ManSimPatSimOut( q, vSimsPi, 0 ); + int i, k, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p), Count = 0; + Gia_Obj_t * pObjP, * pObjQ; + Gia_ManSetPhase( p ); + Gia_ManSetPhase( q ); + Gia_ManForEachObj( p, pObjP, i ) { + word * pSim = Vec_WrdEntryP( vSimsP, i * nWords ); + if ( pSim[0] & 1 ) Abc_TtNot( pSim, nWords ); + } + Gia_ManForEachObj( q, pObjQ, i ) { + word * pSim = Vec_WrdEntryP( vSimsQ, i * nWords ); + if ( pSim[0] & 1 ) Abc_TtNot( pSim, nWords ); + } + Gia_ManForEachAnd( q, pObjQ, i ) { + word * pSimQ = Vec_WrdEntryP( vSimsQ, i * nWords ); + int fFirst = 1; + Gia_ManForEachObj( p, pObjP, k ) { + word * pSimP = Vec_WrdEntryP( vSimsP, k * nWords ); + if ( !Abc_TtEqual(pSimQ, pSimP, nWords) ) + continue; + if ( fFirst ) { + printf( "%5d :", i ); + fFirst = 0; + Count++; + } + printf( " %5d(%d)", k, pObjQ->fPhase ^ pObjP->fPhase ); + } + if ( !fFirst ) + printf( "\n"); + } + printf( "Found %d equivalent nodes.\n", Count ); + Vec_WrdFree( vSimsP ); + Vec_WrdFree( vSimsQ ); + Vec_WrdFree( vSimsPi ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index baf0d7eec..d2bc978d4 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -45032,17 +45032,21 @@ usage: int Abc_CommandAbc9Compare( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern void Gia_Iso4TestTwo( Gia_Man_t * pGia0, Gia_Man_t * pGia1 ); + extern void Gia_ManComparePrint( Gia_Man_t * p, Gia_Man_t * q ); Gia_Man_t * pGia0, * pGia1; char ** pArgvNew; int nArgcNew; - int c, fVerbose = 0; + int c, fFunc = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "fvh" ) ) != EOF ) { switch ( c ) { + case 'f': + fFunc ^= 1; + break; case 'v': fVerbose ^= 1; - break; + break; case 'h': goto usage; default: @@ -45063,14 +45067,18 @@ int Abc_CommandAbc9Compare( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Compare(): Reading input files did not work.\n" ); return 1; } - Gia_Iso4TestTwo( pGia0, pGia1 ); + if ( fFunc ) + Gia_ManComparePrint( pGia0, pGia1 ); + else + Gia_Iso4TestTwo( pGia0, pGia1 ); Gia_ManStop( pGia0 ); Gia_ManStop( pGia1 ); return 0; usage: - Abc_Print( -2, "usage: &compare [-vh]\n" ); + Abc_Print( -2, "usage: &compare [-fvh]\n" ); Abc_Print( -2, "\t compared two AIGs for structural similarity\n" ); + Abc_Print( -2, "\t-f : toggle functional comparison [default = %s]\n", fFunc? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; From 0108175c6c32d3e8b693d80b9e4559a62767634d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 22 Jul 2023 17:08:01 -0700 Subject: [PATCH 24/60] Bug fix in 'dsd'. --- src/base/abci/abcDsd.c | 8 ++++---- src/bdd/dsd/dsd.h | 4 ++-- src/bdd/dsd/dsdApi.c | 4 ++-- src/bdd/dsd/dsdInt.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c index 5121a4fc4..27d86ae89 100644 --- a/src/base/abci/abcDsd.c +++ b/src/base/abci/abcDsd.c @@ -175,11 +175,11 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * // save the CI nodes in the DSD nodes Abc_AigConst1(pNtk)->pCopy = pNodeNew = Abc_NtkCreateNodeConst1(pNtkNew); - Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)(ABC_PTRINT_T)pNodeNew ); + Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (word)(ABC_PTRINT_T)pNodeNew ); Abc_NtkForEachCi( pNtk, pNode, i ) { pNodeDsd = Dsd_ManagerReadInput( pManDsd, i ); - Dsd_NodeSetMark( pNodeDsd, (int)(ABC_PTRINT_T)pNode->pCopy ); + Dsd_NodeSetMark( pNodeDsd, (word)(ABC_PTRINT_T)pNode->pCopy ); } // collect DSD nodes in DFS order (leaves and const1 are not collected) @@ -298,7 +298,7 @@ printf( "\n" ); } } pNodeNew->pData = bLocal; - Dsd_NodeSetMark( pNodeDsd, (int)(ABC_PTRINT_T)pNodeNew ); + Dsd_NodeSetMark( pNodeDsd, (word)(ABC_PTRINT_T)pNodeNew ); return pNodeNew; } @@ -417,7 +417,7 @@ void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager Abc_ObjForEachFanin( pNode, pFanin, i ) { pFaninDsd = Dsd_ManagerReadInput( pManDsd, i ); - Dsd_NodeSetMark( pFaninDsd, (int)(ABC_PTRINT_T)pFanin ); + Dsd_NodeSetMark( pFaninDsd, (word)(ABC_PTRINT_T)pFanin ); } // construct the intermediate nodes diff --git a/src/bdd/dsd/dsd.h b/src/bdd/dsd/dsd.h index 837579510..4c5cd8915 100644 --- a/src/bdd/dsd/dsd.h +++ b/src/bdd/dsd/dsd.h @@ -92,8 +92,8 @@ extern DdNode * Dsd_NodeReadSupp( Dsd_Node_t * p ); extern Dsd_Node_t ** Dsd_NodeReadDecs( Dsd_Node_t * p ); extern Dsd_Node_t * Dsd_NodeReadDec ( Dsd_Node_t * p, int i ); extern int Dsd_NodeReadDecsNum( Dsd_Node_t * p ); -extern int Dsd_NodeReadMark( Dsd_Node_t * p ); -extern void Dsd_NodeSetMark( Dsd_Node_t * p, int Mark ); +extern word Dsd_NodeReadMark( Dsd_Node_t * p ); +extern void Dsd_NodeSetMark( Dsd_Node_t * p, word Mark ); extern DdManager * Dsd_ManagerReadDd( Dsd_Manager_t * pMan ); extern Dsd_Node_t * Dsd_ManagerReadRoot( Dsd_Manager_t * pMan, int i ); extern Dsd_Node_t * Dsd_ManagerReadInput( Dsd_Manager_t * pMan, int i ); diff --git a/src/bdd/dsd/dsdApi.c b/src/bdd/dsd/dsdApi.c index 181dfb281..a94d0d26c 100644 --- a/src/bdd/dsd/dsdApi.c +++ b/src/bdd/dsd/dsdApi.c @@ -56,7 +56,7 @@ DdNode * Dsd_NodeReadSupp( Dsd_Node_t * p ) { return p->S; } Dsd_Node_t ** Dsd_NodeReadDecs( Dsd_Node_t * p ) { return p->pDecs; } Dsd_Node_t * Dsd_NodeReadDec ( Dsd_Node_t * p, int i ) { return p->pDecs[i]; } int Dsd_NodeReadDecsNum( Dsd_Node_t * p ) { return p->nDecs; } -int Dsd_NodeReadMark( Dsd_Node_t * p ) { return p->Mark; } +word Dsd_NodeReadMark( Dsd_Node_t * p ) { return p->Mark; } /**Function************************************************************* @@ -74,7 +74,7 @@ int Dsd_NodeReadMark( Dsd_Node_t * p ) { return p->Mark; } SeeAlso [] ***********************************************************************/ -void Dsd_NodeSetMark( Dsd_Node_t * p, int Mark ){ p->Mark = Mark; } +void Dsd_NodeSetMark( Dsd_Node_t * p, word Mark ){ p->Mark = Mark; } /**Function************************************************************* diff --git a/src/bdd/dsd/dsdInt.h b/src/bdd/dsd/dsdInt.h index 37e9746f5..89bfd22ee 100644 --- a/src/bdd/dsd/dsdInt.h +++ b/src/bdd/dsd/dsdInt.h @@ -57,7 +57,7 @@ struct Dsd_Node_t_ DdNode * G; // function of the node DdNode * S; // support of this function Dsd_Node_t ** pDecs; // pointer to structures for formal inputs - int Mark; // the mark used by CASE 4 of disjoint decomposition + word Mark; // the mark used by CASE 4 of disjoint decomposition short nDecs; // the number of formal inputs short nVisits; // the counter of visits }; From 683882f2bb82f5414a6cec7c735984268d451c8a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 22 Jul 2023 22:18:28 -0700 Subject: [PATCH 25/60] Experiments with stochastic synthesis. --- src/aig/gia/giaDeep.c | 1 + src/aig/gia/giaStoch.c | 185 ++++++++++++++++++++++++++++++++++++++++- src/base/abci/abc.c | 22 +++-- 3 files changed, 199 insertions(+), 9 deletions(-) diff --git a/src/aig/gia/giaDeep.c b/src/aig/gia/giaDeep.c index 815a546e4..b58169f42 100644 --- a/src/aig/gia/giaDeep.c +++ b/src/aig/gia/giaDeep.c @@ -120,6 +120,7 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in } if ( nTimeToStop && Abc_Clock() > nTimeToStop ) { + if ( !Abc_FrameIsBatchMode() ) printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i ); break; } diff --git a/src/aig/gia/giaStoch.c b/src/aig/gia/giaStoch.c index 94f539988..57775b5cc 100644 --- a/src/aig/gia/giaStoch.c +++ b/src/aig/gia/giaStoch.c @@ -22,6 +22,19 @@ #include "base/main/main.h" #include "base/cmd/cmd.h" + +#ifdef ABC_USE_PTHREADS + +#ifdef _WIN32 +#include "../lib/pthread.h" +#else +#include +#include +#endif + +#endif + + ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// @@ -32,6 +45,169 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Processing on a single core.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_StochProcessOne( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs ) +{ + Gia_Man_t * pNew; + char FileName[100], Command[1000]; + sprintf( FileName, "%06x.aig", Rand ); + Gia_AigerWrite( p, FileName, 0, 0, 0 ); + sprintf( Command, "./abc -q \"&read %s; %s; &write %s\"", FileName, pScript, FileName ); + if ( system( (char *)Command ) ) + { + fprintf( stderr, "The following command has returned non-zero exit status:\n" ); + fprintf( stderr, "\"%s\"\n", (char *)Command ); + fprintf( stderr, "Sorry for the inconvenience.\n" ); + fflush( stdout ); + unlink( FileName ); + return Gia_ManDup(p); + } + pNew = Gia_AigerRead( FileName, 0, 0, 0 ); + unlink( FileName ); + if ( pNew && Gia_ManAndNum(pNew) < Gia_ManAndNum(p) ) + return pNew; + Gia_ManStopP( &pNew ); + return Gia_ManDup(p); +} +void Gia_StochProcessArray( Vec_Ptr_t * vGias, char * pScript, int TimeSecs, int fVerbose ) +{ + Gia_Man_t * pGia, * pNew; int i; + Vec_Int_t * vRands = Vec_IntAlloc( Vec_PtrSize(vGias) ); + Abc_Random(1); + for ( i = 0; i < Vec_PtrSize(vGias); i++ ) + Vec_IntPush( vRands, Abc_Random(0) % 0x1000000 ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) + { + pNew = Gia_StochProcessOne( pGia, pScript, Vec_IntEntry(vRands, i), TimeSecs ); + Gia_ManStop( pGia ); + Vec_PtrWriteEntry( vGias, i, pNew ); + } + Vec_IntFree( vRands ); +} + +/**Function************************************************************* + + Synopsis [Processing on a many cores.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#ifndef ABC_USE_PTHREADS + +void Gia_StochProcess( Vec_Ptr_t * vGias, char * pScript, int nProcs, int TimeSecs, int fVerbose ) +{ + Gia_StochProcessArray( vGias, pScript, TimeSecs, fVerbose ); +} + +#else // pthreads are used + + +#define PAR_THR_MAX 100 +typedef struct Gia_StochThData_t_ +{ + Vec_Ptr_t * vGias; + char * pScript; + int Index; + int Rand; + int nTimeOut; + int fWorking; +} Gia_StochThData_t; + +void * Gia_StochWorkerThread( void * pArg ) +{ + Gia_StochThData_t * pThData = (Gia_StochThData_t *)pArg; + volatile int * pPlace = &pThData->fWorking; + Gia_Man_t * pGia, * pNew; + while ( 1 ) + { + while ( *pPlace == 0 ); + assert( pThData->fWorking ); + if ( pThData->Index == -1 ) + { + pthread_exit( NULL ); + assert( 0 ); + return NULL; + } + pGia = (Gia_Man_t *)Vec_PtrEntry( pThData->vGias, pThData->Index ); + pNew = Gia_StochProcessOne( pGia, pThData->pScript, pThData->Rand, pThData->nTimeOut ); + Gia_ManStop( pGia ); + Vec_PtrWriteEntry( pThData->vGias, pThData->Index, pNew ); + pThData->fWorking = 0; + } + assert( 0 ); + return NULL; +} + +void Gia_StochProcess( Vec_Ptr_t * vGias, char * pScript, int nProcs, int TimeSecs, int fVerbose ) +{ + Gia_StochThData_t ThData[PAR_THR_MAX]; + pthread_t WorkerThread[PAR_THR_MAX]; + int i, k, status; + if ( fVerbose ) + printf( "Running concurrent synthesis with %d processes.\n", nProcs ); + fflush( stdout ); + if ( nProcs < 2 ) + return Gia_StochProcessArray( vGias, pScript, TimeSecs, fVerbose ); + // subtract manager thread + nProcs--; + assert( nProcs >= 1 && nProcs <= PAR_THR_MAX ); + // start threads + Abc_Random(1); + for ( i = 0; i < nProcs; i++ ) + { + ThData[i].vGias = vGias; + ThData[i].pScript = pScript; + ThData[i].Index = -1; + ThData[i].Rand = Abc_Random(0) % 0x1000000; + ThData[i].nTimeOut = TimeSecs; + ThData[i].fWorking = 0; + status = pthread_create( WorkerThread + i, NULL, Gia_StochWorkerThread, (void *)(ThData + i) ); assert( status == 0 ); + } + // look at the threads + for ( k = 0; k < Vec_PtrSize(vGias); k++ ) + { + for ( i = 0; i < nProcs; i++ ) + { + if ( ThData[i].fWorking ) + continue; + ThData[i].Index = k; + ThData[i].fWorking = 1; + break; + } + if ( i == nProcs ) + k--; + } + // wait till threads finish + for ( i = 0; i < nProcs; i++ ) + if ( ThData[i].fWorking ) + i = -1; + // stop threads + for ( i = 0; i < nProcs; i++ ) + { + assert( !ThData[i].fWorking ); + // stop + ThData[i].Index = -1; + ThData[i].fWorking = 1; + } +} + +#endif // pthreads are used + + /**Function************************************************************* Synopsis [] @@ -184,7 +360,7 @@ Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vA pNew->vMapping = vMapping; return pNew; } -Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript ) +Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript, int nProcs, int TimeOut ) { Vec_Ptr_t * vAigs = Vec_PtrAlloc( Vec_WecSize(vCis) ); int i; for ( i = 0; i < Vec_WecSize(vCis); i++ ) @@ -192,7 +368,8 @@ Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds Gia_ManCollectNodes( p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i) ); Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i)) ); } - Gia_ManStochSynthesis( vAigs, pScript ); + //Gia_ManStochSynthesis( vAigs, pScript ); + Gia_StochProcess( vAigs, pScript, nProcs, TimeOut, 0 ); return vAigs; } Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs, int fHash ) @@ -388,7 +565,7 @@ Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds ) SeeAlso [] ***********************************************************************/ -void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript ) +void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs ) { abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0; abctime clkStart = Abc_Clock(); @@ -407,7 +584,7 @@ void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerb Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF ); Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds ); Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds ); - Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript ); + Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript, nProcs, TimeOut ); Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs ); int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew); Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index d2bc978d4..2a1550b8a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -49426,10 +49426,10 @@ usage: ***********************************************************************/ int Abc_CommandAbc9StochSyn( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript ); - int c, nMaxSize = 1000, nIters = 10, TimeOut = 0, Seed = 0, fVerbose = 0; char * pScript; + extern void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs ); + int c, nMaxSize = 1000, nIters = 10, TimeOut = 0, Seed = 0, nProcs = 1, fVerbose = 0; char * pScript; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "NITSvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NITSPvh" ) ) != EOF ) { switch ( c ) { @@ -49477,6 +49477,17 @@ int Abc_CommandAbc9StochSyn( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( Seed < 0 ) goto usage; break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + nProcs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nProcs < 0 ) + goto usage; + break; case 'v': fVerbose ^= 1; break; @@ -49497,17 +49508,18 @@ int Abc_CommandAbc9StochSyn( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } pScript = Abc_UtilStrsav( argv[globalUtilOptind] ); - Gia_ManStochSyn( nMaxSize, nIters, TimeOut, Seed, fVerbose, pScript ); + Gia_ManStochSyn( nMaxSize, nIters, TimeOut, Seed, fVerbose, pScript, nProcs ); ABC_FREE( pScript ); return 0; usage: - Abc_Print( -2, "usage: &stochsyn [-NITS ] [-tvh]