From cf5d4ad07f87e936a114afca483ed66ffb1a2120 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 21 Dec 2016 15:34:02 +0700 Subject: [PATCH 01/61] Converting some errors into warnings. --- src/base/abci/abc.c | 4 ++-- src/base/abci/abcMfs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dabeb9822..fb3017902 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -19532,7 +19532,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( Abc_NtkIsComb(pNtk) ) { - Abc_Print( -1, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" ); + Abc_Print( 0, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" ); return 0; } @@ -31954,7 +31954,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( Gia_ManRegNum(pAbc->pGia) == 0 ) { - Abc_Print( -1, "The network is combinational.\n" ); + Abc_Print( 0, "The network is combinational.\n" ); return 0; } pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars ); diff --git a/src/base/abci/abcMfs.c b/src/base/abci/abcMfs.c index e33d6c73a..d44ca1a0e 100644 --- a/src/base/abci/abcMfs.c +++ b/src/base/abci/abcMfs.c @@ -259,7 +259,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars ) if ( nFaninMax > 6 ) { Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" ); - return 0; + return 1; } if ( !Abc_NtkHasSop(pNtk) ) if ( !Abc_NtkToSop( pNtk, -1, ABC_INFINITY ) ) From b56a532682e34ae440bc6ffa939e82d06cf06e62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 22 Dec 2016 17:27:32 +0700 Subject: [PATCH 02/61] Several changes in arithmetic circuit manipulation. --- abclib.dsp | 4 + src/aig/gia/gia.h | 2 +- src/aig/gia/giaDup.c | 112 ++++++++++++++++--- src/aig/gia/giaShow.c | 12 ++- src/base/abci/abc.c | 12 ++- src/proof/acec/acecBo.c | 216 +++++++++++++++++++++++++++++++++++++ src/proof/acec/acecCl.c | 95 +++++++++++++++- src/proof/acec/module.make | 1 + 8 files changed, 430 insertions(+), 24 deletions(-) create mode 100644 src/proof/acec/acecBo.c diff --git a/abclib.dsp b/abclib.dsp index 9b1c9d945..1d08c9508 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5463,6 +5463,10 @@ SOURCE=.\src\proof\acec\acec.h # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecBo.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecCl.c # End Source File # Begin Source File diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index bf7bf3490..ac40f9754 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1403,7 +1403,7 @@ extern Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); /*=== giaShow.c ===========================================================*/ -extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ); +extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ); /*=== giaShrink.c ===========================================================*/ extern Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose ); extern Gia_Man_t * Gia_ManMapShrink6( Gia_Man_t * p, int nFanoutMax, int fKeepLevel, int fVerbose ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 7ced54a4a..c58596b2f 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3377,6 +3377,26 @@ Gia_Man_t * Gia_ManDupOuts( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ +Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gia_Obj_t * pObj; int i, Id; + Vec_Wec_t * vSuppsNo = Vec_WecStart( Vec_IntSize(vNodes) ); + Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) ); + Gia_ManForEachCiId( p, Id, i ) + Vec_IntPush( Vec_WecEntry(vSupps, Id), i ); + Gia_ManForEachAnd( p, pObj, Id ) + Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, Id)), + Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, Id)), + Vec_WecEntry(vSupps, Id) ); + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Vec_IntAppend( Vec_WecEntry(vSuppsNo, i), Vec_WecEntry(vSupps, Gia_ObjId(p, pObj)) ); + Vec_WecFree( vSupps ); + if ( fVerbose ) + Abc_PrintTime( 1, "Support computation", Abc_Clock() - clk ); + return vSuppsNo; +} + Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose ) { abctime clk = Abc_Clock(); @@ -3679,6 +3699,81 @@ Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupDemiterOrderXors2( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + int i, iObj, * pPerm; + Vec_Int_t * vSizes = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vXors, iObj, i ) + Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) ); + pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) ); + Vec_IntClear( vSizes ); + for ( i = 0; i < Vec_IntSize(vXors); i++ ) + Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) ); + ABC_FREE( pPerm ); + Vec_IntClear( vXors ); + Vec_IntAppend( vXors, vSizes ); + Vec_IntFree( vSizes ); +} +int Gia_ManDupDemiterFindMin( Vec_Wec_t * vSupps, Vec_Int_t * vTakenIns, Vec_Int_t * vTakenOuts ) +{ + Vec_Int_t * vLevel; + int i, k, iObj, iObjBest = -1; + int Count, CountBest = ABC_INFINITY; + Vec_WecForEachLevel( vSupps, vLevel, i ) + { + if ( Vec_IntEntry(vTakenOuts, i) ) + continue; + Count = 0; + Vec_IntForEachEntry( vLevel, iObj, k ) + Count += !Vec_IntEntry(vTakenIns, iObj); + if ( CountBest > Count ) + { + CountBest = Count; + iObjBest = i; + } + } + return iObjBest; +} +void Gia_ManDupDemiterOrderXors( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + extern Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose ); + Vec_Wec_t * vSupps = Gia_ManCreateNodeSupps( p, vXors, 0 ); + Vec_Int_t * vTakenIns = Vec_IntStart( Gia_ManCiNum(p) ); + Vec_Int_t * vTakenOuts = Vec_IntStart( Vec_IntSize(vXors) ); + Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXors) ); + int i, k, iObj; + // add outputs in the order of increasing supports + for ( i = 0; i < Vec_IntSize(vXors); i++ ) + { + int Index = Gia_ManDupDemiterFindMin( vSupps, vTakenIns, vTakenOuts ); + assert( Index >= 0 && Index < Vec_IntSize(vXors) ); + Vec_IntPush( vOrder, Vec_IntEntry(vXors, Index) ); + assert( !Vec_IntEntry( vTakenOuts, Index ) ); + Vec_IntWriteEntry( vTakenOuts, Index, 1 ); + Vec_IntForEachEntry( Vec_WecEntry(vSupps, Index), iObj, k ) + Vec_IntWriteEntry( vTakenIns, iObj, 1 ); + } + Vec_WecFree( vSupps ); + Vec_IntFree( vTakenIns ); + Vec_IntFree( vTakenOuts ); + // reload + Vec_IntClear( vXors ); + Vec_IntAppend( vXors, vOrder ); + Vec_IntFree( vOrder ); +} + + /**Function************************************************************* Synopsis [] @@ -3781,8 +3876,8 @@ void Gia_ManCollectTopXors_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXo } Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) { - int i, iObj, iObj2, fFlip, * pPerm, Count1 = 0; - Vec_Int_t * vXors, * vSizes, * vPart[2], * vOrder; + int i, iObj, iObj2, fFlip, Count1 = 0; + Vec_Int_t * vXors, * vPart[2], * vOrder; Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0); assert( Gia_ManCoNum(p) == 1 ); vXors = Vec_IntAlloc( 100 ); @@ -3791,17 +3886,8 @@ Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) else Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); // order by support size - vSizes = Vec_IntAlloc( 100 ); - Vec_IntForEachEntry( vXors, iObj, i ) - Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) ); - pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) ); - Vec_IntClear( vSizes ); - for ( i = 0; i < Vec_IntSize(vXors); i++ ) - Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) ); - ABC_FREE( pPerm ); - Vec_IntClear( vXors ); - Vec_IntAppend( vXors, vSizes ); - Vec_IntFree( vSizes ); + Gia_ManDupDemiterOrderXors( p, vXors ); + //Vec_IntPrint( vXors ); Vec_IntReverseOrder( vXors ); // from MSB to LSB // divide into groups Gia_ManCleanMark01(p); diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index afc58bf8e..afd36fff2 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -713,11 +713,13 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds ) { Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { + if ( fFadds && Vec_IntEntry(vAdds, 6*i+2) == 0 ) + continue; Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i ); Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i ); } @@ -800,9 +802,9 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v SeeAlso [] ***********************************************************************/ -void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors ) +void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { - Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds ); + Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder ); @@ -810,7 +812,7 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); } -void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) +void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); @@ -837,7 +839,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) fclose( pFile ); // generate the file if ( fAdders ) - Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors ); + Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fb3017902..7866b22d7 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -28592,15 +28592,18 @@ usage: int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) { Vec_Int_t * vBold = NULL; - int c, fAdders = 0; + int c, fAdders = 0, fFadds = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "afh" ) ) != EOF ) { switch ( c ) { case 'a': fAdders ^= 1; break; + case 'f': + fFadds ^= 1; + break; case 'h': goto usage; default: @@ -28623,14 +28626,15 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManForEachLut( pAbc->pGia, c ) Vec_IntPush( vBold, c ); } - Gia_ManShow( pAbc->pGia, vBold, fAdders ); + Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds ); Vec_IntFreeP( &vBold ); return 0; usage: - Abc_Print( -2, "usage: &show [-ah]\n" ); + Abc_Print( -2, "usage: &show [-afh]\n" ); Abc_Print( -2, "\t shows the current GIA using GSView\n" ); Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle only showing full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } diff --git a/src/proof/acec/acecBo.c b/src/proof/acec/acecBo.c new file mode 100644 index 000000000..9cddcd132 --- /dev/null +++ b/src/proof/acec/acecBo.c @@ -0,0 +1,216 @@ +/**CFile**************************************************************** + + FileName [acecBo.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Core procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecBo.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/vec/vecWec.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_DetectBoothXorMux( Gia_Man_t * p, Gia_Obj_t * pMux, Gia_Obj_t * pXor, int pIns[3] ) +{ + Gia_Obj_t * pFan0, * pFan1; + Gia_Obj_t * pDat0, * pDat1, * pCtrl; + if ( !Gia_ObjIsMuxType(pMux) || !Gia_ObjIsMuxType(pXor) ) + return 0; + if ( !Gia_ObjRecognizeExor( pXor, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Gia_ObjId(p, pFan0) > Gia_ObjId(p, pFan1) ) + ABC_SWAP( Gia_Obj_t *, pFan0, pFan1 ); + if ( !(pCtrl = Gia_ObjRecognizeMux( pMux, &pDat0, &pDat1 )) ) + return 0; + pDat0 = Gia_Regular(pDat0); + pDat1 = Gia_Regular(pDat1); + pCtrl = Gia_Regular(pCtrl); + if ( !Gia_ObjIsAnd(pDat0) || !Gia_ObjIsAnd(pDat1) ) + return 0; + if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjFaninId0p(p, pDat1) || + Gia_ObjFaninId1p(p, pDat0) != Gia_ObjFaninId1p(p, pDat1) ) + return 0; + if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjId(p, pFan0) || + Gia_ObjFaninId1p(p, pDat0) != Gia_ObjId(p, pFan1) ) + return 0; + pIns[0] = Gia_ObjId(p, pFan0); + pIns[1] = Gia_ObjId(p, pFan1); + pIns[2] = Gia_ObjId(p, pCtrl); + return 1; +} +int Acec_DetectBoothXorFanin( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + //int Id = Gia_ObjId(p, pObj); + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( !Gia_ObjFaninC0(pObj) || !Gia_ObjFaninC1(pObj) ) + return 0; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( !Gia_ObjIsAnd(pFan0) || !Gia_ObjIsAnd(pFan1) ) + return 0; + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin0(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin1(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin0(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin1(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1)); + return 1; + } + return 0; +} +int Acec_DetectBoothOne( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Acec_DetectBoothXorFanin( p, pFan0, pIns ) && pIns[2] == Gia_ObjId(p, pFan1) ) + return 1; + if ( Acec_DetectBoothXorFanin( p, pFan1, pIns ) && pIns[2] == Gia_ObjId(p, pFan0) ) + return 1; + return 0; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_DetectBoothTwoXor( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( Gia_ObjRecognizeExor( Gia_ObjFanin0(pObj), &pFan0, &pFan1 ) ) + { + pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + pIns[2] = -1; + pIns[3] = 0; + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pObj)); + return 1; + } + if ( Gia_ObjRecognizeExor( Gia_ObjFanin1(pObj), &pFan0, &pFan1 ) ) + { + pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + pIns[2] = -1; + pIns[3] = 0; + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pObj)); + return 1; + } + return 0; +} +int Acec_DetectBoothTwo( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Acec_DetectBoothTwoXor( p, pFan0, pIns ) ) + { + pIns[2] = Gia_ObjId(p, pFan1); + return 1; + } + if ( Acec_DetectBoothTwoXor( p, pFan1, pIns ) ) + { + pIns[2] = Gia_ObjId(p, pFan0); + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_DetectBoothTest( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, pIns[5]; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Acec_DetectBoothOne(p, pObj, pIns) && !Acec_DetectBoothTwo(p, pObj, pIns) ) + continue; + printf( "obj = %4d : b0 = %4d b1 = %4d b2 = %4d a0 = %4d a1 = %4d\n", + i, pIns[0], pIns[1], pIns[2], pIns[3], pIns[4] ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index b60c2bf9e..63483d57d 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -127,7 +127,7 @@ Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p ) break; } Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) ); - Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan1)) : Gia_ObjId(p, Gia_Regular(pFan0)) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan0)) : Gia_ObjId(p, Gia_Regular(pFan1)) ); Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan10)) : Gia_ObjId(p, Gia_Regular(pFan00)) ); Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan11)) : Gia_ObjId(p, Gia_Regular(pFan01)) ); } @@ -173,10 +173,101 @@ int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf ) if ( Lit0 != -1 && Lit1 != -1 ) { assert( Lit0 == Lit1 ); + printf( "Problem for leaf %d\n", Leaf ); return Lit0; } return Lit0 != -1 ? Lit0 : Lit1; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_DetectComputeSuppOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Int_t * vNods ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( pObj->fMark0 ) + { + Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin0(pObj), vSupp, vNods ); + Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin1(pObj), vSupp, vNods ); + Vec_IntPush( vNods, Gia_ObjId(p, pObj) ); +} +void Acec_DetectComputeSupports( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) +{ + Vec_Int_t * vNods = Vec_IntAlloc( 100 ); + Vec_Int_t * vPols = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); int i, k, Node, Pol; + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 1; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 1; + } + for ( i = 1; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Vec_IntClear( vSupp ); + Gia_ManIncrementTravId( p ); + + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0; + Acec_DetectComputeSuppOne_rec( p, Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) ), vSupp, vNods ); + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1; + + Vec_IntSort( vSupp, 0 ); + + printf( "Out %4d : %4d \n", i, Vec_IntEntry(vRootXorSet, 4*i+1) ); + Vec_IntPrint( vSupp ); + + printf( "Cone:\n" ); + Vec_IntForEachEntry( vNods, Node, k ) + Gia_ObjPrint( p, Gia_ManObj(p, Node) ); + + + Vec_IntClear( vPols ); + Vec_IntForEachEntry( vSupp, Node, k ) + Vec_IntPush( vPols, Acec_DetectLitPolarity(p, Vec_IntEntry(vRootXorSet, 4*i+1), Node) ); + + Vec_IntForEachEntryTwo( vSupp, vPols, Node, Pol, k ) + printf( "%d(%d) ", Node, Abc_LitIsCompl(Pol) ); + + printf( "\n" ); + + Vec_IntPrint( vSupp ); + } + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 0; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 0; + } + Vec_IntFree( vSupp ); + Vec_IntFree( vPols ); + Vec_IntFree( vNods ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) { Gia_Man_t * pNew; @@ -236,6 +327,8 @@ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) vRootXorSet = Acec_CollectXorTops( p ); if ( vRootXorSet ) { + Acec_DetectComputeSupports( p, vRootXorSet ); + pNew = Acec_DetectXorBuildNew( p, vRootXorSet ); Vec_IntFree( vRootXorSet ); } diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index df6db6956..4003695e5 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -1,6 +1,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecCore.c \ src/proof/acec/acecCo.c \ + src/proof/acec/acecBo.c \ src/proof/acec/acecRe.c \ src/proof/acec/acecPa.c \ src/proof/acec/acecPo.c \ From 7d0648e24098ed0e6a0a1471a52946303c351c87 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 23 Dec 2016 00:23:17 +0700 Subject: [PATCH 03/61] Correcting API names for inputing/outputing MiniLut. --- src/aig/miniaig/abcapis.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/aig/miniaig/abcapis.h b/src/aig/miniaig/abcapis.h index 38c0591dc..f412f5aef 100644 --- a/src/aig/miniaig/abcapis.h +++ b/src/aig/miniaig/abcapis.h @@ -54,9 +54,9 @@ extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig ); extern void * Abc_NtkOutputMiniAig( void * pAbc ); extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops ); -// procedures to input/output 'mini AIG' -extern void Abc_NtkInputMiniLut( void * pAbc, void * pMiniLut ); -extern void * Abc_NtkOutputMiniLut( void * pAbc ); +// procedures to input/output 'mini LUT' +extern void Abc_FrameGiaInputMiniLut( void * pAbc, void * pMiniLut ); +extern void * Abc_FrameGiaOutputMiniLut( void * pAbc ); // procedures to set CI/CO arrival/required times extern void Abc_NtkSetCiArrivalTime( void * pAbc, int iCi, float Rise, float Fall ); From b9dfb992c78e3c8786dee303e4a9994d46b6990a Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Thu, 22 Dec 2016 18:15:29 -0800 Subject: [PATCH 04/61] (1) Makefile: added a shared library target, (2) no longer compile the main function as part of libabc.a --- Makefile | 8 +++++++- readme.md | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2385431ce..d45978a9d 100644 --- a/Makefile +++ b/Makefile @@ -139,6 +139,8 @@ OBJ := \ $(patsubst %.c, %.o, $(filter %.c, $(SRC))) \ $(patsubst %.y, %.o, $(filter %.y, $(SRC))) +LIBOBJ := $(filter-out src/base/main/main.o,$(OBJ)) + DEP := $(OBJ:.o=.d) # implicit rules @@ -186,11 +188,15 @@ $(PROG): $(OBJ) @echo "$(MSG_PREFIX)\`\` Building binary:" $(notdir $@) $(VERBOSE)$(LD) -o $@ $^ $(LIBS) -lib$(PROG).a: $(OBJ) +lib$(PROG).a: $(LIBOBJ) @echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@) $(VERBOSE)ar rv $@ $? $(VERBOSE)ranlib $@ +lib$(PROG).so: $(LIBOBJ) + @echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@) + $(VERBOSE)$(CXX) -shared -o $@ $^ $(LIBS) + docs: @echo "$(MSG_PREFIX)\`\` Building documentation." $(notdir $@) $(VERBOSE)doxygen doxygen.conf diff --git a/readme.md b/readme.md index c7a6816db..ca9a90bae 100644 --- a/readme.md +++ b/readme.md @@ -53,6 +53,13 @@ The current version of ABC can be compiled with C compiler or C++ compiler. * To compile as C++ code with namespaces: make sure that `CC=g++` and `ABC_NAMESPACE` is set to the name of the requested namespace. For example, add `-DABC_NAMESPACE=xxx` to OPTFLAGS. +## Building a shared library + + * Compile the code as position-independent by adding `ABC_USE_PIC=1`. + * Build the `libabc.so` target: + + make ABC_USE_PIC=1 libabc.so + ## Bug reporting: Please try to reproduce all the reported bugs and unexpected features using the latest From ac3216cf238dab066b12ddb1eac57c6682e34d2b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 25 Dec 2016 15:58:54 +0700 Subject: [PATCH 05/61] Updates to delay optimization project. --- abclib.dsp | 4 + src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCore.c | 166 +++++++++++++++++++------- src/opt/sbd/sbdInt.h | 11 ++ src/opt/sbd/sbdLut.c | 255 ++++++++++++++++++++++++++++++++++++++++ src/opt/sbd/sbdSat.c | 4 - src/opt/sbd/sbdWin.c | 177 +++++++++++++++++++++++++--- 7 files changed, 555 insertions(+), 63 deletions(-) create mode 100644 src/opt/sbd/sbdLut.c diff --git a/abclib.dsp b/abclib.dsp index 1d08c9508..e5583ddfa 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2763,6 +2763,10 @@ SOURCE=.\src\opt\sbd\sbdInt.h # End Source File # Begin Source File +SOURCE=.\src\opt\sbd\sbdLut.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\sbd\sbdSat.c # End Source File # Begin Source File diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index d966e577e..0320d3818 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -1,5 +1,6 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ + src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index b6ec70f9d..563e6e98b 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -54,10 +54,12 @@ struct Sbd_Man_t_ abctime timeTotal; // target node int Pivot; // target node + int DivCutoff; // the place where D-2 divisors begin Vec_Int_t * vTfo; // TFO (excludes node, includes roots) - precomputed Vec_Int_t * vRoots; // TFO root nodes Vec_Int_t * vWinObjs; // TFI + Pivot + sideTFI + TFO (including roots) Vec_Int_t * vObj2Var; // SAT variables for the window (indexes of objects in vWinObjs) + Vec_Int_t * vDivSet; // divisor variables Vec_Int_t * vDivVars; // divisor variables Vec_Int_t * vDivValues; // SAT variables values for the divisor variables Vec_Wec_t * vDivLevels; // divisors collected by levels @@ -200,6 +202,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) p->vRoots = Vec_IntAlloc( 100 ); p->vWinObjs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); p->vObj2Var = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vDivSet = Vec_IntAlloc( 100 ); p->vDivVars = Vec_IntAlloc( 100 ); p->vDivValues = Vec_IntAlloc( 100 ); p->vDivLevels = Vec_WecAlloc( 100 ); @@ -234,6 +237,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vRoots ); Vec_IntFree( p->vWinObjs ); Vec_IntFree( p->vObj2Var ); + Vec_IntFree( p->vDivSet ); Vec_IntFree( p->vDivVars ); Vec_IntFree( p->vDivValues ); Vec_WecFree( p->vDivLevels ); @@ -318,12 +322,11 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) Vec_WecInit( p->vDivLevels, LevelMax + 1 ); Vec_IntForEachEntry( p->vWinObjs, Node, i ) Vec_WecPush( p->vDivLevels, Vec_IntEntry(p->vLutLevs, Node), Node ); - // sort primary inputs - Vec_IntSort( Vec_WecEntry(p->vDivLevels, 0), 0 ); // reload divisors Vec_IntClear( p->vWinObjs ); Vec_WecForEachLevel( p->vDivLevels, vLevel, i ) { + Vec_IntSort( vLevel, 0 ); Vec_IntForEachEntry( vLevel, Node, k ) { Vec_IntWriteEntry( p->vObj2Var, Node, Vec_IntSize(p->vWinObjs) ); @@ -334,8 +337,26 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) nTimeValidDivs = Vec_IntSize(p->vWinObjs); } assert( nTimeValidDivs > 0 ); - Vec_IntFill( p->vDivValues, Abc_MinInt(63, nTimeValidDivs), 0 ); - //printf( "%d ", Abc_MinInt(63, nTimeValidDivs) ); + Vec_IntClear( p->vDivVars ); + p->DivCutoff = -1; + Vec_IntForEachEntryStartStop( p->vWinObjs, Node, i, Abc_MaxInt(0, nTimeValidDivs-63), nTimeValidDivs ) + { + if ( p->DivCutoff == -1 && Vec_IntEntry(p->vLutLevs, Node) == LevelMax - 2 ) + p->DivCutoff = Vec_IntSize(p->vDivVars); + Vec_IntPush( p->vDivVars, i ); + } + if ( p->DivCutoff == -1 ) + p->DivCutoff = 0; + // verify + assert( Vec_IntSize(p->vDivVars) < 64 ); + Vec_IntForEachEntryStart( p->vDivVars, Node, i, p->DivCutoff ) + assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); + Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) + assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); + Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); + //printf( "%d ", Vec_IntSize(p->vDivVars) ); +// printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", +// Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); } void Sbd_ManWindowSim_rec( Sbd_Man_t * p, int NodeInit ) { @@ -408,6 +429,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); Sbd_ManUpdateOrder( p, Pivot ); + assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); + assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); // simulate node Gia_ManObj(p->pGia, Pivot)->fMark0 = 1; Abc_TtCopy( Sbd_ObjSim1(p, Pivot), Sbd_ObjSim0(p, Pivot), p->pPars->nWords, 1 ); @@ -440,8 +463,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) p->timeWin += Abc_Clock() - clk; // propagate controlability to fanins for the TFI nodes starting from the pivot Sbd_ManPropagateControl( p, Pivot ); - assert( Vec_IntSize(p->vDivValues) < 64 ); - return (int)(Vec_IntSize(p->vDivValues) >= 64); + assert( Vec_IntSize(p->vDivValues) <= 64 ); + return (int)(Vec_IntSize(p->vDivValues) > 64); } /**Function************************************************************* @@ -466,8 +489,8 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) int RetValue, i, iObj, Ind, fFindOnset, nCares[2] = {0}; abctime clk = Abc_Clock(); extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); - p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; if ( p->pSat == NULL ) { @@ -836,11 +859,11 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi { int c0, c1, c2, c3; word Target = Cover[nDivs]; - Vec_IntClear( p->vDivVars ); + Vec_IntClear( p->vDivSet ); for ( c0 = 0; c0 < nDivs; c0++ ) if ( Cover[c0] == Target ) { - Vec_IntPush( p->vDivVars, c0 ); + Vec_IntPush( p->vDivSet, c0 ); return 1; } @@ -848,8 +871,8 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi for ( c1 = c0+1; c1 < nDivs; c1++ ) if ( (Cover[c0] | Cover[c1]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); return 1; } @@ -858,9 +881,9 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi for ( c2 = c1+1; c2 < nDivs; c2++ ) if ( (Cover[c0] | Cover[c1] | Cover[c2]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); - Vec_IntPush( p->vDivVars, c2 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); + Vec_IntPush( p->vDivSet, c2 ); return 1; } @@ -871,10 +894,10 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi { if ( (Cover[c0] | Cover[c1] | Cover[c2] | Cover[c3]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); - Vec_IntPush( p->vDivVars, c2 ); - Vec_IntPush( p->vDivVars, c3 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); + Vec_IntPush( p->vDivSet, c2 ); + Vec_IntPush( p->vDivSet, c3 ); return 1; } } @@ -891,11 +914,11 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) if ( nDivs < 8 || p->pPars->fCover ) return Sbd_ManFindCandsSimple( p, Cover, nDivs ); - Vec_IntClear( p->vDivVars ); + Vec_IntClear( p->vDivSet ); for ( c0 = 0; c0 < nDivs; c0++ ) if ( Cover[c0] == Target ) { - Vec_IntPush( p->vDivVars, c0 ); + Vec_IntPush( p->vDivSet, c0 ); return 1; } @@ -903,8 +926,8 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) for ( c1 = c0+1; c1 < nDivs; c1++ ) if ( (Cover[c0] | Cover[c1]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); return 1; } @@ -923,9 +946,9 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) for ( c2 = c1+1; c2 < Limits[2]; c2++ ) if ( (Cover[Order[c0]] | Cover[Order[c1]] | Cover[Order[c2]]) == Target ) { - Vec_IntPush( p->vDivVars, Order[c0] ); - Vec_IntPush( p->vDivVars, Order[c1] ); - Vec_IntPush( p->vDivVars, Order[c2] ); + Vec_IntPush( p->vDivSet, Order[c0] ); + Vec_IntPush( p->vDivSet, Order[c1] ); + Vec_IntPush( p->vDivSet, Order[c2] ); return 1; } @@ -936,10 +959,10 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) { if ( (Cover[Order[c0]] | Cover[Order[c1]] | Cover[Order[c2]] | Cover[Order[c3]]) == Target ) { - Vec_IntPush( p->vDivVars, Order[c0] ); - Vec_IntPush( p->vDivVars, Order[c1] ); - Vec_IntPush( p->vDivVars, Order[c2] ); - Vec_IntPush( p->vDivVars, Order[c3] ); + Vec_IntPush( p->vDivSet, Order[c0] ); + Vec_IntPush( p->vDivSet, Order[c1] ); + Vec_IntPush( p->vDivSet, Order[c2] ); + Vec_IntPush( p->vDivSet, Order[c3] ); return 1; } } @@ -952,10 +975,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) int fVerbose = 0; abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); int nIters, nItersMax = 32; - extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp ); + extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; - int i, k, n, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; + int i, k, n, Node, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; int nDivs = Vec_IntSize(p->vDivValues); int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); @@ -969,11 +992,11 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) Sbd_ManPrintObj( p, Pivot ); // collect bit-matrices - for ( i = 0; i < nDivs; i++ ) + Vec_IntForEachEntry( p->vDivVars, Node, i ) { - MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, i) ); - MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, i) ); - MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, i) ); + MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, Node) ); + MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, Node) ); + MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, Node) ); } MatrS[63-i] = *Sbd_ObjSim0( p, Pivot ); MatrC[0][63-i] = *Sbd_ObjSim2( p, Pivot ); @@ -1067,10 +1090,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) if ( p->pPars->fVerbose ) printf( "Candidate support: " ), - Vec_IntPrint( p->vDivVars ); + Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); - *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivVars, p->vDivValues, p->vLits ); + *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); clkSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) @@ -1103,7 +1126,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) if ( p->pPars->fVerbose ) { printf( "Node %d: UNSAT.\n", Pivot ); - Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivVars) ), printf( "\n" ); + Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); } RetValue = 1; break; @@ -1118,6 +1141,13 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) return RetValue; } +int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, + int nLuts, int nSels, int nVarsDivs[SBD_LUTS_MAX], + int pVarsDivs[SBD_LUTS_MAX][SBD_SIZE_MAX], word Truths[SBD_LUTS_MAX] ) +{ + return 0; +} + /**Function************************************************************* Synopsis [Computes delay-oriented k-feasible cut at the node.] @@ -1233,7 +1263,7 @@ int Sbd_ManMergeCuts( Sbd_Man_t * p, int Node ) Vec_IntWriteEntry( p->vLutLevs, Node, LevCur ); assert( pCutRes[0] <= p->pPars->nLutSize ); memcpy( Sbd_ObjCut(p, Node), pCutRes, sizeof(int) * (pCutRes[0] + 1) ); - //printf( "Setting node %d with delay %d.\n", Node, LevCur ); +//printf( "Setting node %d with delay %d.\n", Node, LevCur ); return LevCur == 1; // LevCur == Abc_MaxInt(Level0, Level1); } int Sbd_ManDelay( Sbd_Man_t * p ) @@ -1306,7 +1336,7 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) int iNewLev; // collect leaf literals Vec_IntClear( p->vLits ); - Vec_IntForEachEntry( p->vDivVars, Node, i ) + Vec_IntForEachEntry( p->vDivSet, Node, i ) { Node = Vec_IntEntry( p->vWinObjs, Node ); if ( Vec_IntEntry(p->vMirrors, Node) >= 0 ) @@ -1429,20 +1459,68 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { +// extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); + int RetValue; word Truth = 0; if ( Sbd_ManMergeCuts( p, Pivot ) ) return; - //if ( Pivot != 344 ) - // continue; + +// if ( Pivot != 13 ) +// return; + if ( p->pPars->fVerbose ) printf( "\nLooking at node %d\n", Pivot ); if ( Sbd_ManWindow( p, Pivot ) ) return; + +// Sbd_ManSolveSelect( p->pGia, p->vMirrors, Pivot, p->vDivVars, p->vDivValues, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); + RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) + { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); + //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); + } else if ( Sbd_ManExplore( p, Pivot, &Truth ) ) + { Sbd_ManImplement( p, Pivot, Truth ); + //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + } +/* + else + { + extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] + ); + + Sbd_Str_t Strs[2] = { + {1, 4, {0, 1, 2, 7}}, + {1, 4, {3, 4, 5, 6}} + }; + + word Truths[SBD_LUTS_MAX]; + + Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); + + int i, RetValue; + + for ( i = 0; i < 7; i++ ) + Vec_IntPush( vDivSet, i+1 ); + + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + vDivSet, 2, Strs, Truths ); + if ( RetValue ) + { + printf( "Solving succeded.\n" ); + //Sbd_ManImplement2( p, Pivot, Truth, nLuts, nSels, nVarsDivs, pVarsDivs, Truths ); + } + Vec_IntFree( vDivSet ); + } +*/ } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { @@ -1488,8 +1566,10 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) else { Gia_ManForEachAndId( pGia, Pivot ) + { if ( Pivot < nNodesOld ) Sbd_NtkPerformOne( p, Pivot ); + } } printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 4c553fb45..3646c6b96 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -52,10 +52,21 @@ ABC_NAMESPACE_HEADER_START #define SBD_SAT_UNDEC 0x1234567812345678 #define SBD_SAT_SAT 0x8765432187654321 +#define SBD_LUTS_MAX 2 +#define SBD_SIZE_MAX 4 +#define SBD_DIV_MAX 7 + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Sbd_Str_t_ Sbd_Str_t; +struct Sbd_Str_t_ +{ + int fLut; // LUT or SEL + int nVarIns; // input count + int VarIns[SBD_DIV_MAX]; // input vars +}; //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c new file mode 100644 index 000000000..42bb09555 --- /dev/null +++ b/src/opt/sbd/sbdLut.c @@ -0,0 +1,255 @@ +/**CFile**************************************************************** + + FileName [sbdLut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [CNF computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// count the number of parameter variables in the structure +int Sbd_ProblemCountParams( int nStrs, Sbd_Str_t * pStr0 ) +{ + Sbd_Str_t * pStr; int nPars = 0; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + nPars += (pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns); + return nPars; +} +// add clauses for the structure +void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +{ + // variable order: inputs, structure outputs, parameters + Sbd_Str_t * pStr; + int VarOut = nVars; + int VarPar = nVars + nStrs; + int m, k, n, status, pLits[SBD_SIZE_MAX+2]; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarOut++ ) + { + if ( pStr->fLut ) + { + int nMints = 1 << pStr->nVarIns; + assert( pStr->nVarIns <= 6 ); + for ( m = 0; m < nMints; m++, VarPar++ ) + { + for ( k = 0; k < pStr->nVarIns; k++ ) + pLits[k] = Abc_Var2Lit( pVars[pStr->VarIns[k]], (m >> k) & 1 ); + for ( n = 0; n < 2; n++ ) + { + pLits[pStr->nVarIns] = Abc_Var2Lit( pVars[VarPar], n ); + pLits[pStr->nVarIns+1] = Abc_Var2Lit( pVars[VarOut], !n ); + status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns + 2 ); + assert( status ); + } + } + } + else + { + for ( k = 0; k < pStr->nVarIns; k++, VarPar++ ) + { + for ( n = 0; n < 2; n++ ) + { + pLits[0] = Abc_Var2Lit( pVars[VarPar], 1 ); + pLits[1] = Abc_Var2Lit( pVars[VarOut], n ); + pLits[2] = Abc_Var2Lit( pVars[pStr->VarIns[k]], !n ); + status = sat_solver_addclause( pSat, pLits, pLits + 3 ); + assert( status ); + } + } + } + } +} +void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +{ + Sbd_Str_t * pStr; + int VarPar = nVars + nStrs; + int m, m2, pLits[2], status; + // make sure selector parameters are mutually exclusive + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarPar = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns ) + { + if ( pStr->fLut ) + continue; + for ( m = 0; m < pStr->nVarIns; m++ ) + for ( m2 = m+1; m2 < pStr->nVarIns; m2++ ) + { + pLits[0] = Abc_Var2Lit( pVars[VarPar + m], 1 ); + pLits[1] = Abc_Var2Lit( pVars[VarPar + m2], 1 ); + status = sat_solver_addclause( pSat, pLits, pLits + 2 ); + assert( status ); + } + } +} +void Sbd_ProblemPrintSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) +{ + Sbd_Str_t * pStr; + int m, nIters, iLit = 0; + printf( "Solution found:\n" ); + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + { + nIters = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; + printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", pStr-pStr0 ); + for ( m = 0; m < nIters; m++ ) + printf( "%d", Abc_LitIsCompl(Vec_IntEntry(vLits, iLit++)) ); + printf( "\n" ); + } + assert( iLit == Vec_IntSize(vLits) ); +} +void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits, word Truths[SBD_LUTS_MAX] ) +{ +} + +/**Function************************************************************* + + Synopsis [Solves QBF problem for the given window.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] ) // divisors, structures +{ + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); + sat_solver * pSatQbf = sat_solver_new(); + + int nVars = Vec_IntSize( vDivSet ); + int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); + + int VarCecOut = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); + int VarCecPar = VarCecOut + 1; + int VarCecFree = VarCecPar + nPars; + + int VarQbfPar = 0; + int VarQbfFree = nPars; + + int pVarsCec[256]; + int pVarsQbf[256]; + int i, iVar, iLit; + int RetValue = 0; + + assert( Vec_IntSize(vDivSet) <= SBD_SIZE_MAX ); + assert( nVars + nStrs + nPars <= 256 ); + + // collect CEC variables + Vec_IntForEachEntry( vDivSet, iVar, i ) + pVarsCec[i] = iVar; + pVarsCec[nVars] = VarCecOut; + for ( i = 1; i < nStrs; i++ ) + pVarsCec[nVars + i] = VarCecFree++; + for ( i = 0; i < nPars; i++ ) + pVarsCec[nVars + nStrs + i] = VarCecPar + i; + + // collect QBF variables + for ( i = 0; i < nVars + nStrs; i++ ) + pVarsQbf[i] = -1; + for ( i = 0; i < nPars; i++ ) + pVarsQbf[nVars + nStrs + i] = VarQbfPar + i; + + // add clauses to the CEC problem + Sbd_ProblemAddClauses( pSatCec, nVars, nStrs, pVarsCec, pStr0 ); + + // create QBF solver + sat_solver_setnvars( pSatQbf, 1000 ); + Sbd_ProblemAddClausesInit( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + + // assume all parameter variables are 0 + Vec_IntClear( vLits ); + for ( i = 0; i < nPars; i++ ) + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, 1) ); + while ( 1 ) + { + // check if these parameters solve the problem + int status = sat_solver_solve( pSatCec, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 ); + if ( status == l_False ) // solution found + break; + assert( status == l_True ); + Vec_IntClear( vLits ); + // create new QBF variables + for ( i = 0; i < nVars + nStrs; i++ ) + pVarsQbf[i] = VarQbfFree++; + // set their values + Vec_IntForEachEntry( vDivSet, iVar, i ) + { + iLit = Abc_Var2Lit( pVarsQbf[i], sat_solver_var_value(pSatCec, iVar) ); + status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); + assert( status ); + } + iLit = Abc_Var2Lit( pVarsQbf[nVars], sat_solver_var_value(pSatCec, VarCecOut) ); + status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); + assert( status ); + // add clauses to the QBF problem + Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + // check if solution still exists + status = sat_solver_solve( pSatQbf, NULL, NULL, 0, 0, 0, 0 ); + if ( status == l_False ) // solution does not exist + break; + assert( status == l_True ); + // find the new values of parameters + assert( Vec_IntSize(vLits) == 0 ); + for ( i = 0; i < nPars; i++ ) + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); + } + if ( Vec_IntSize(vLits) > 0 ) + { + Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); + Sbd_ProblemCollectSolution( nStrs, pStr0, vLits, Truths ); + RetValue = 1; + } + else + printf( "Solution does not exist.\n" ); + + sat_solver_delete( pSatCec ); + sat_solver_delete( pSatQbf ); + Vec_IntFree( vLits ); + return RetValue; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/sbd/sbdSat.c b/src/opt/sbd/sbdSat.c index ae8656278..f0de4dbf0 100644 --- a/src/opt/sbd/sbdSat.c +++ b/src/opt/sbd/sbdSat.c @@ -37,10 +37,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -#define SBD_LUTS_MAX 2 -#define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 16 - // new AIG manager typedef struct Sbd_Pro_t_ Sbd_Pro_t; struct Sbd_Pro_t_ diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index d722f4568..fc79caa71 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -39,19 +39,26 @@ ABC_NAMESPACE_IMPL_START a DFS ordered array of objects (vWinObjs) whose indexed in the array (which will be used as SAT variables) are given in array vObj2Var. The TFO nodes are listed as the last ones in vWinObjs. The root nodes - are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.] + are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots. + If fQbf is 1, returns the instance meant for QBF solving. It is using + the last variable (LastVar) as the placeholder for the second copy + of the pivot node.] SideEffects [] SeeAlso [] ***********************************************************************/ -sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) +sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ) { Gia_Obj_t * pObj; + int nAddVars = 64; int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue; int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo); int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int LastVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); //Vec_IntPrint( vWinObjs ); //Vec_IntPrint( vTfo ); //Vec_IntPrint( vRoots ); @@ -60,7 +67,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi pSat = sat_solver_new(); else sat_solver_restart( pSat ); - sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + 32 ); + sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + nAddVars ); // create constant 0 clause sat_solver_addclause( pSat, &iLit, &iLit + 1 ); // add clauses for all nodes @@ -100,8 +107,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Fan1 = Vec_IntEntry( vObj2Var, Fan1 ); Fan0 = Fan0 < TfoStart ? Fan0 : Fan0 + Vec_IntSize(vTfo); Fan1 = Fan1 < TfoStart ? Fan1 : Fan1 + Vec_IntSize(vTfo); - fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); - fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); + if ( fQbf ) + { + Fan0 = Fan0 == PivotVar ? LastVar : Fan0; + Fan1 = Fan1 == PivotVar ? LastVar : Fan1; + } + fCompl0 = Gia_ObjFaninC0(pObj) ^ (!fQbf && Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); + fCompl1 = Gia_ObjFaninC1(pObj) ^ (!fQbf && Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); if ( Gia_ObjIsXor(pObj) ) sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 ); else @@ -127,7 +139,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi sat_solver_delete( pSat ); return NULL; } - assert( sat_solver_nvars(pSat) == nVars + 32 ); + assert( sat_solver_nvars(pSat) == nVars + nAddVars ); } // finalize RetValue = sat_solver_simplify( pSat ); @@ -143,7 +155,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Synopsis [Solves one SAT problem.] - Description [Computes node function for PivotVar with fanins in vDivVars + Description [Computes node function for PivotVar with fanins in vDivSet using don't-care represented in the SAT solver. Uses array vValues to return the values of the first Vec_IntSize(vValues) SAT variables in case the implementation of the node with the given fanins does not exist.] @@ -153,12 +165,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi SeeAlso [] ***********************************************************************/ -word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp ) +word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ) { int nBTLimit = 0; word uCube, uTruth = 0; int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0; assert( FreeVar < sat_solver_nvars(pSat) ); + assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) ); pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1 pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit while ( 1 ) @@ -171,12 +184,12 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi return uTruth; assert( status == l_True ); // remember variable values - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) ); + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntWriteEntry( vDivValues, i, 2*sat_solver_var_value(pSat, iVar) ); // collect divisor literals Vec_IntClear( vTemp ); Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0 - Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntForEachEntry( vDivSet, iVar, i ) Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) ); // check against offset status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 ); @@ -195,7 +208,7 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi if ( pFinal[i] == pLits[0] ) continue; Vec_IntPush( vTemp, pFinal[i] ); - iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); + iVar = Vec_IntFind( vDivSet, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar]; } uTruth |= uCube; @@ -205,11 +218,11 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi } assert( status == l_True ); // store the counter-example - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) ); + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntAddToEntry( vDivValues, i, sat_solver_var_value(pSat, iVar) ); - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntAddToEntry( vValues, i, 0xC ); + for ( i = 0; i < Vec_IntSize(vDivValues); i++ ) + Vec_IntAddToEntry( vDivValues, i, 0xC ); /* // reduce the counter example for ( n = 0; n < 2; n++ ) @@ -230,6 +243,138 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi return SBD_SAT_SAT; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManSolve2( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp, Vec_Int_t * vSop ) +{ + int nBTLimit = 0; + int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0; + assert( FreeVar < sat_solver_nvars(pSat) ); + assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) ); + pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1 + pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit + Vec_IntClear( vSop ); + while ( 1 ) + { + // find onset minterm + status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return 0; + if ( status == l_False ) + return 1; + assert( status == l_True ); + // remember variable values + //for ( i = 0; i < Vec_IntSize(vValues); i++ ) + // Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) ); + // collect divisor literals + Vec_IntClear( vTemp ); + Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0 + //Vec_IntForEachEntry( vDivSet, iVar, i ) + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) ); + // check against offset + status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return 0; + if ( status == l_True ) + break; + assert( status == l_False ); + // compute cube and add clause + nFinal = sat_solver_final( pSat, &pFinal ); + Vec_IntClear( vTemp ); + Vec_IntPush( vTemp, Abc_LitNot(pLits[1]) ); // NOT(iNewLit) + for ( i = 0; i < nFinal; i++ ) + { + if ( pFinal[i] == pLits[0] ) + continue; + Vec_IntPush( vTemp, pFinal[i] ); + iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); + //uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar]; + Vec_IntPush( vSop, Abc_Var2Lit( iVar, !Abc_LitIsCompl(pFinal[i]) ) ); + } + //uTruth |= uCube; + Vec_IntPush( vSop, -1 ); + status = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp) ); + assert( status ); + nIter++; + } + assert( status == l_True ); + // store the counter-example + //for ( i = 0; i < Vec_IntSize(vValues); i++ ) + // Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) ); + return 0; +} + +word Sbd_ManSolverSupp( Vec_Int_t * vSop, int * pInds, int * pnVars ) +{ + word Supp = 0; + int i, Entry, nVars = 0; + Vec_IntForEachEntry( vSop, Entry, i ) + { + if ( Entry == -1 ) + continue; + assert( Abc_Lit2Var(Entry) < 64 ); + if ( (Supp >> Abc_Lit2Var(Entry)) & 1 ) + continue; + pInds[Abc_Lit2Var(Entry)] = nVars++; + Supp |= (word)1 << Abc_Lit2Var(Entry); + } + *pnVars = nVars; + return Supp; +} +void Sbd_ManSolverPrint( Vec_Int_t * vSop ) +{ + int v, i, Entry, nVars, pInds[64]; + word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); + char Cube[65] = {'\0'}; + assert( Cube[nVars] == '\0' ); + for ( v = 0; v < nVars; v++ ) + Cube[v] = '-'; + Vec_IntForEachEntry( vSop, Entry, i ) + { + if ( Entry == -1 ) + { + printf( "%s\n", Cube ); + for ( v = 0; v < nVars; v++ ) + Cube[v] = '-'; + continue; + } + Cube[pInds[Abc_Lit2Var(Entry)]] = '1' - (char)Abc_LitIsCompl(Entry); + } +} +void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) +{ + Vec_Int_t * vSop = Vec_IntAlloc( 100 ); + Vec_Int_t * vTemp = Vec_IntAlloc( 100 ); + sat_solver * pSat = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 0 ); + int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int FreeVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); + int Status = Sbd_ManSolve2( pSat, PivotVar, FreeVar, vDivVars, vDivValues, vTemp, vSop ); + printf( "Pivot = %4d. Divs = %4d. ", Pivot, Vec_IntSize(vDivVars) ); + if ( Status == 0 ) + printf( "UNSAT.\n" ); + else + { + int nVars, pInds[64]; + word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); + //Sbd_ManSolverPrint( vSop ); + printf( "SAT with %d vars and %d cubes.\n", nVars, Vec_IntCountEntry(vSop, -1) ); + } + Vec_IntFree( vTemp ); + Vec_IntFree( vSop ); + sat_solver_delete( pSat ); +} + + /**Function************************************************************* Synopsis [Returns a bunch of positive/negative random care minterms.] From 398c4ec92c4e25fa588a6b3bcbd016df91e57771 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 18:08:39 +0700 Subject: [PATCH 06/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 158 +++++++++++++++++++++++++++++++++++------- src/opt/sbd/sbdInt.h | 1 + src/opt/sbd/sbdLut.c | 108 ++++++++++++++++++++++------- src/opt/sbd/sbdWin.c | 35 ++++++++++ 4 files changed, 254 insertions(+), 48 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 563e6e98b..5c5fe35ab 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -777,15 +777,15 @@ void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ) } } -void Sbd_ManMatrPrint( word Cover[64], int nCol, int nRows ) +void Sbd_ManMatrPrint( Sbd_Man_t * p, word Cover[], int nCol, int nRows ) { int i, k; for ( i = 0; i <= nCol; i++ ) { printf( "%2d : ", i ); + printf( "%d ", i == nCol ? Vec_IntEntry(p->vLutLevs, p->Pivot) : Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Vec_IntEntry(p->vDivVars, i))) ); for ( k = 0; k < nRows; k++ ) - for ( k = 0; k < nRows; k++ ) - printf( "%d", (int)((Cover[i] >> k) & 1) ); + printf( "%d", (int)((Cover[i] >> k) & 1) ); printf( "\n"); } printf( "\n"); @@ -801,18 +801,18 @@ static inline void Sbd_ManCoverReverseOrder( word Cover[64] ) } } -static inline int Sbd_ManAddCube1( word Cover[64], int nRows, word Cube ) +static inline int Sbd_ManAddCube1( int nRowLimit, word Cover[], int nRows, word Cube ) { int n, m; if ( 0 ) { printf( "Adding cube: " ); - for ( n = 0; n < 64; n++ ) + for ( n = 0; n < nRowLimit; n++ ) printf( "%d", (int)((Cube >> n) & 1) ); printf( "\n" ); } // do not add contained Cube - assert( nRows <= 64 ); + assert( nRows <= nRowLimit ); for ( n = 0; n < nRows; n++ ) if ( (Cover[n] & Cube) == Cover[n] ) // Cube is contained return nRows; @@ -820,7 +820,7 @@ static inline int Sbd_ManAddCube1( word Cover[64], int nRows, word Cube ) for ( n = m = 0; n < nRows; n++ ) if ( (Cover[n] & Cube) != Cube ) // Cover[n] is not contained Cover[m++] = Cover[n]; - if ( m < 64 ) + if ( m < nRowLimit ) Cover[m++] = Cube; for ( n = m; n < nRows; n++ ) Cover[n] = 0; @@ -855,7 +855,7 @@ static inline int Sbd_ManAddCube2( word Cover[2][64], int nRows, word Cube[2] ) return nRows; } -static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDivs ) +static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[], int nDivs ) { int c0, c1, c2, c3; word Target = Cover[nDivs]; @@ -1052,7 +1052,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { Cube = (Cubes[0][1][i] & Cubes[1][0][k]) | (Cubes[0][0][i] & Cubes[1][1][k]); assert( Cube ); - nRows = Sbd_ManAddCube1( Cover, nRows, Cube ); + nRows = Sbd_ManAddCube1( 64, Cover, nRows, Cube ); } Sbd_ManCoverReverseOrder( Cover ); @@ -1072,7 +1072,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) { if ( p->pPars->fVerbose ) - Sbd_ManMatrPrint( Cover, nDivs, nRows ); + Sbd_ManMatrPrint( p, Cover, nDivs, nRows ); clk = Abc_Clock(); if ( !Sbd_ManFindCands( p, Cover, nDivs ) ) @@ -1141,10 +1141,123 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) return RetValue; } -int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, - int nLuts, int nSels, int nVarsDivs[SBD_LUTS_MAX], - int pVarsDivs[SBD_LUTS_MAX][SBD_SIZE_MAX], word Truths[SBD_LUTS_MAX] ) +int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); + abctime clk = Abc_Clock(); + word Onset[64] = {0}, Offset[64] = {0}, Cube; + word CoverRows[256] = {0}, CoverCols[64] = {{0}}; + int nIters, nItersMax = 32; + int i, k, nRows = 0; + + int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int nDivs = Vec_IntSize( p->vDivVars ); + int nConsts = 4; + int RetValue; + + if ( p->pSat ) + sat_solver_delete( p->pSat ); + p->pSat = NULL; + + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + + assert( nConsts <= 8 ); + RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); + if ( RetValue >= 0 ) + { + if ( p->pPars->fVerbose ) + printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); + p->nConsts++; + return RetValue; + } + + // create rows of the table + nRows = 0; + for ( i = 0; i < nConsts; i++ ) + for ( k = 0; k < nConsts; k++ ) + { + Cube = Onset[i] ^ Offset[k]; + assert( Cube ); + nRows = Sbd_ManAddCube1( 256, CoverRows, nRows, Cube ); + } + assert( nRows <= 64 ); + + // create columns of the table + for ( i = 0; i < nRows; i++ ) + for ( k = 0; k <= nDivs; k++ ) + if ( (CoverRows[i] >> k) & 1 ) + Abc_TtXorBit(&CoverCols[k], i); + + // solve the covering problem + for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) + { + if ( p->pPars->fVerbose ) + Sbd_ManMatrPrint( p, CoverCols, nDivs, nRows ); + + clk = Abc_Clock(); + if ( !Sbd_ManFindCands( p, CoverCols, nDivs ) ) + { + if ( p->pPars->fVerbose ) + printf( "Cannot find a feasible cover.\n" ); + //clkEnu += Abc_Clock() - clk; + //clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + //p->timeSat += clkSat; + //p->timeCov += clkAll; + //p->timeEnu += clkEnu; + return 0; + } + //clkEnu += Abc_Clock() - clk; + + if ( p->pPars->fVerbose ) + printf( "Candidate support: " ), + Vec_IntPrint( p->vDivSet ); + + clk = Abc_Clock(); + *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + //clkSat += Abc_Clock() - clk; + + if ( *pTruth == SBD_SAT_UNDEC ) + printf( "Node %d: Undecided.\n", Pivot ); + else if ( *pTruth == SBD_SAT_SAT ) + { + if ( p->pPars->fVerbose ) + { + int i; + printf( "Node %d: SAT.\n", Pivot ); + for ( i = 0; i < nDivs; i++ ) + printf( "%d", Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Vec_IntEntry(p->vDivVars, i))) ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%d", i % 10 ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%c", (Vec_IntEntry(p->vDivValues, i) & 0x4) ? '0' + (Vec_IntEntry(p->vDivValues, i) & 1) : 'x' ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%c", (Vec_IntEntry(p->vDivValues, i) & 0x8) ? '0' + ((Vec_IntEntry(p->vDivValues, i) >> 1) & 1) : 'x' ); + printf( "\n" ); + } + // add row to the covering table + for ( i = 0; i < nDivs; i++ ) + if ( Vec_IntEntry(p->vDivValues, i) == 0xE || Vec_IntEntry(p->vDivValues, i) == 0xD ) + CoverCols[i] |= ((word)1 << nRows); + CoverCols[nDivs] |= ((word)1 << nRows); + nRows++; + } + else + { + if ( p->pPars->fVerbose ) + { + printf( "Node %d: UNSAT. ", Pivot ); + Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); + } + return 1; + } + } return 0; } @@ -1465,7 +1578,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) if ( Sbd_ManMergeCuts( p, Pivot ) ) return; -// if ( Pivot != 13 ) +// if ( Pivot != 70 ) // return; if ( p->pPars->fVerbose ) @@ -1481,7 +1594,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); } - else if ( Sbd_ManExplore( p, Pivot, &Truth ) ) + else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) { Sbd_ManImplement( p, Pivot, Truth ); //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); @@ -1493,26 +1606,23 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 ); - Sbd_Str_t Strs[2] = { - {1, 4, {0, 1, 2, 7}}, - {1, 4, {3, 4, 5, 6}} - }; - - word Truths[SBD_LUTS_MAX]; +// Sbd_Str_t Strs[2] = { {1, 4, {0, 1, 2, 8}}, {1, 4, {3, 4, 5, 6}} }; +// Sbd_Str_t Strs[2] = { {1, 4, {1, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}} }; + Sbd_Str_t Strs[3] = { {1, 4, {8, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}}, {0, 4, {0, 1, 2, 3}} }; Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); int i, RetValue; - for ( i = 0; i < 7; i++ ) + for ( i = 0; i < 6; i++ ) Vec_IntPush( vDivSet, i+1 ); RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - vDivSet, 2, Strs, Truths ); + vDivSet, 3, Strs ); if ( RetValue ) { printf( "Solving succeded.\n" ); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 3646c6b96..5395e148e 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -66,6 +66,7 @@ struct Sbd_Str_t_ int fLut; // LUT or SEL int nVarIns; // input count int VarIns[SBD_DIV_MAX]; // input vars + word Res; // result of solving }; //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index 42bb09555..b68ecc26f 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "sbdInt.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -46,17 +47,18 @@ int Sbd_ProblemCountParams( int nStrs, Sbd_Str_t * pStr0 ) { Sbd_Str_t * pStr; int nPars = 0; for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) - nPars += (pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns); + nPars += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; return nPars; } // add clauses for the structure -void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +int Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) { // variable order: inputs, structure outputs, parameters Sbd_Str_t * pStr; int VarOut = nVars; int VarPar = nVars + nStrs; int m, k, n, status, pLits[SBD_SIZE_MAX+2]; +//printf( "Start par = %d. ", VarPar ); for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarOut++ ) { if ( pStr->fLut ) @@ -72,12 +74,14 @@ void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars pLits[pStr->nVarIns] = Abc_Var2Lit( pVars[VarPar], n ); pLits[pStr->nVarIns+1] = Abc_Var2Lit( pVars[VarOut], !n ); status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns + 2 ); - assert( status ); + if ( !status ) + return 0; } } } else { + assert( pStr->nVarIns <= SBD_DIV_MAX ); for ( k = 0; k < pStr->nVarIns; k++, VarPar++ ) { for ( n = 0; n < 2; n++ ) @@ -86,22 +90,32 @@ void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars pLits[1] = Abc_Var2Lit( pVars[VarOut], n ); pLits[2] = Abc_Var2Lit( pVars[pStr->VarIns[k]], !n ); status = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( status ); + if ( !status ) + return 0; } } } } +//printf( "Stop par = %d.\n", VarPar ); + return 1; } void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) { Sbd_Str_t * pStr; int VarPar = nVars + nStrs; - int m, m2, pLits[2], status; + int m, m2, status, pLits[SBD_DIV_MAX]; // make sure selector parameters are mutually exclusive - for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarPar = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns ) + for ( pStr = pStr0; pStr < pStr0 + nStrs; VarPar += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns, pStr++ ) { if ( pStr->fLut ) continue; + // one variable should be selected + assert( pStr->nVarIns <= SBD_DIV_MAX ); + for ( m = 0; m < pStr->nVarIns; m++ ) + pLits[m] = Abc_Var2Lit( pVars[VarPar + m], 0 ); + status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns ); + assert( status ); + // two variables cannot be selected for ( m = 0; m < pStr->nVarIns; m++ ) for ( m2 = m+1; m2 < pStr->nVarIns; m2++ ) { @@ -120,15 +134,44 @@ void Sbd_ProblemPrintSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) { nIters = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; - printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", pStr-pStr0 ); - for ( m = 0; m < nIters; m++ ) - printf( "%d", Abc_LitIsCompl(Vec_IntEntry(vLits, iLit++)) ); - printf( "\n" ); + printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", (int)(pStr-pStr0) ); + for ( m = 0; m < nIters; m++, iLit++ ) + printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ); + printf( " {" ); + for ( m = 0; m < pStr->nVarIns; m++ ) + printf( " %d", pStr->VarIns[m] ); + printf( " }\n" ); } assert( iLit == Vec_IntSize(vLits) ); } -void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits, word Truths[SBD_LUTS_MAX] ) +void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) { + Sbd_Str_t * pStr; + int m, nIters, iLit = 0; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + { + pStr->Res = 0; + if ( pStr->fLut ) + { + nIters = 1 << pStr->nVarIns; + for ( m = 0; m < nIters; m++, iLit++ ) + if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) + Abc_TtSetBit( &pStr->Res, m ); + Abc_TtStretch6( &pStr->Res, pStr->nVarIns, 6 ); + } + else + { + nIters = 0; + for ( m = 0; m < pStr->nVarIns; m++, iLit++ ) + if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) + { + pStr->Res = pStr->VarIns[m]; + nIters++; + } + assert( nIters == 1 ); + } + } + assert( iLit == Vec_IntSize(vLits) ); } /**Function************************************************************* @@ -145,38 +188,39 @@ void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] ) // divisors, structures + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 ) // divisors, structures { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + int fVerbose = 1; Vec_Int_t * vLits = Vec_IntAlloc( 100 ); sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); + int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); int VarCecOut = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); - int VarCecPar = VarCecOut + 1; - int VarCecFree = VarCecPar + nPars; + int VarCecPar = VarCecOut + nStrs; int VarQbfPar = 0; int VarQbfFree = nPars; int pVarsCec[256]; int pVarsQbf[256]; - int i, iVar, iLit; + int i, iVar, iLit, nIters; int RetValue = 0; - assert( Vec_IntSize(vDivSet) <= SBD_SIZE_MAX ); + assert( Vec_IntSize(vDivSet) <= SBD_DIV_MAX ); assert( nVars + nStrs + nPars <= 256 ); // collect CEC variables Vec_IntForEachEntry( vDivSet, iVar, i ) pVarsCec[i] = iVar; - pVarsCec[nVars] = VarCecOut; - for ( i = 1; i < nStrs; i++ ) - pVarsCec[nVars + i] = VarCecFree++; + for ( i = 0; i < nStrs; i++ ) + pVarsCec[nVars + i] = VarCecOut + i; for ( i = 0; i < nPars; i++ ) pVarsCec[nVars + nStrs + i] = VarCecPar + i; @@ -197,13 +241,24 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_IntClear( vLits ); for ( i = 0; i < nPars; i++ ) Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, 1) ); - while ( 1 ) + for ( nIters = 0; nIters < (1 << nVars); nIters++ ) { // check if these parameters solve the problem int status = sat_solver_solve( pSatCec, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 ); if ( status == l_False ) // solution found break; assert( status == l_True ); +// Vec_IntForEachEntry( vWinObjs, iVar, i ) +// printf( "Node = %4d. SatVar = %4d. Value = %d.\n", iVar, i, sat_solver_var_value(pSatCec, i) ); + + if ( fVerbose ) + { + printf( "Iter %3d : ", nIters ); + for ( i = 0; i < nPars; i++ ) + printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, i)) ); + printf( " " ); + } + Vec_IntClear( vLits ); // create new QBF variables for ( i = 0; i < nVars + nStrs; i++ ) @@ -211,15 +266,20 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, // set their values Vec_IntForEachEntry( vDivSet, iVar, i ) { - iLit = Abc_Var2Lit( pVarsQbf[i], sat_solver_var_value(pSatCec, iVar) ); + iLit = Abc_Var2Lit( pVarsQbf[i], !sat_solver_var_value(pSatCec, iVar) ); status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); assert( status ); + if ( fVerbose ) + printf( "%d", sat_solver_var_value(pSatCec, iVar) ); } iLit = Abc_Var2Lit( pVarsQbf[nVars], sat_solver_var_value(pSatCec, VarCecOut) ); status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); assert( status ); + if ( fVerbose ) + printf( " %d\n", !sat_solver_var_value(pSatCec, VarCecOut) ); // add clauses to the QBF problem - Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + if ( !Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ) ) + break; // solution does not exist // check if solution still exists status = sat_solver_solve( pSatQbf, NULL, NULL, 0, 0, 0, 0 ); if ( status == l_False ) // solution does not exist @@ -228,12 +288,12 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, // find the new values of parameters assert( Vec_IntSize(vLits) == 0 ); for ( i = 0; i < nPars; i++ ) - Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, !sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); } if ( Vec_IntSize(vLits) > 0 ) { Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); - Sbd_ProblemCollectSolution( nStrs, pStr0, vLits, Truths ); + Sbd_ProblemCollectSolution( nStrs, pStr0, vLits ); RetValue = 1; } else diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index fc79caa71..d5b7dd9d6 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -141,6 +141,17 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi } assert( sat_solver_nvars(pSat) == nVars + nAddVars ); } + else if ( fQbf ) + { + int n, pLits[2]; + for ( n = 0; n < 2; n++ ) + { + pLits[0] = Abc_Var2Lit( PivotVar, n ); + pLits[1] = Abc_Var2Lit( LastVar, n ); + RetValue = sat_solver_addclause( pSat, pLits, pLits + 2 ); + assert( RetValue ); + } + } // finalize RetValue = sat_solver_simplify( pSat ); if ( RetValue == 0 ) @@ -418,6 +429,30 @@ int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, return -1; } +int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ) +{ + int nBTLimit = 0; + int n, i, k, status, iLit, iVar; + word * pPats[2] = {pOnset, pOffset}; + assert( Vec_IntSize(vDivVars) < 64 ); + for ( n = 0; n < 2; n++ ) + for ( i = 0; i < nConsts; i++ ) + { + sat_solver_random_polarity( pSat ); + iLit = Abc_Var2Lit( PivotVar, n ); + status = sat_solver_solve( pSat, &iLit, &iLit + 1, nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return -2; + if ( status == l_False ) + return n; + pPats[n][i] = ((word)!n) << Vec_IntSize(vDivVars); + Vec_IntForEachEntry( vDivVars, iVar, k ) + if ( sat_solver_var_value(pSat, iVar) ) + Abc_TtXorBit(&pPats[n][i], k); + } + return -1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// From fcd3133a9f2817893aa60d1ec2d1b94a1f5a7b5a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 18:15:05 +0700 Subject: [PATCH 07/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 5 +++-- src/opt/sbd/sbdLut.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 5c5fe35ab..15874dc67 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -75,6 +75,8 @@ static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( static inline word * Sbd_ObjSim2( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[2], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim3( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[3], p->pPars->nWords * i ); } +extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -975,7 +977,6 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) int fVerbose = 0; abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); int nIters, nItersMax = 32; - extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; int i, k, n, Node, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; @@ -1147,7 +1148,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); word Onset[64] = {0}, Offset[64] = {0}, Cube; - word CoverRows[256] = {0}, CoverCols[64] = {{0}}; + word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; int i, k, nRows = 0; diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index b68ecc26f..b924a33b3 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -197,7 +197,7 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); - int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + //int PivotVar = Vec_IntEntry(vObj2Var, Pivot); int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); From 3581c94fec6e3fabe36591cd57a732d3f58a29ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 21:08:52 +0700 Subject: [PATCH 08/61] Updates to delay optimization project. --- abclib.dsp | 4 + src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCut.c | 617 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 622 insertions(+) create mode 100644 src/opt/sbd/sbdCut.c diff --git a/abclib.dsp b/abclib.dsp index e5583ddfa..1833f013b 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2759,6 +2759,10 @@ SOURCE=.\src\opt\sbd\sbdCore.c # End Source File # Begin Source File +SOURCE=.\src\opt\sbd\sbdCut.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\sbd\sbdInt.h # End Source File # Begin Source File diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index 0320d3818..3bdc20b37 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -1,6 +1,7 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ + src/opt/sbd/sbdCut.c \ src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c new file mode 100644 index 000000000..cabc301c5 --- /dev/null +++ b/src/opt/sbd/sbdCut.c @@ -0,0 +1,617 @@ +/**CFile**************************************************************** + + FileName [sbdCut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SBD_MAX_CUTSIZE 8 +#define SBD_MAX_CUTNUM 64 +#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) + +#define SBD_CUT_NO_LEAF 255 + +typedef struct Sbd_Cut_t_ Sbd_Cut_t; +struct Sbd_Cut_t_ +{ + word Sign; // signature + int iFunc; // functionality + unsigned Cost : 24; // misc cut cost + unsigned nLeaves : 8; // the number of leaves + int pLeaves[SBD_MAX_CUTSIZE]; // leaves +}; + +typedef struct Sbd_Sto_t_ Sbd_Sto_t; +struct Sbd_Sto_t_ +{ + int nLutSize; + int nCutNum; + int fCutMin; + int fVerbose; + Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vDelays; // delays for each node + Vec_Wec_t * vCuts; // cuts for each node + Vec_Mem_t * vTtMem; // truth tables + Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts + Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers + abctime clkStart; // starting time + double CutCount[4]; // cut counters +}; + +static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } + +#define Sbd_ForEachCut( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 2 ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, int nLutSize, int nCutNum, int fCutMin, int fVerbose ) +{ + Sbd_Sto_t * p; + assert( nLutSize > 1 && nLutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Sto_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutNum = nCutNum; + p->fCutMin = fCutMin; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); + p->vTtMem = fCutMin ? Vec_MemAllocForTT( nLutSize, 0 ) : NULL; + return p; +} +void Sbd_StoFree( Sbd_Sto_t * p ) +{ + Vec_IntFree( p->vDelays ); + Vec_WecFree( p->vCuts ); + if ( p->fCutMin ) + Vec_MemHashFree( p->vTtMem ); + if ( p->fCutMin ) + Vec_MemFree( p->vTtMem ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Check correctness of cuts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Sbd_CutGetSign( Sbd_Cut_t * pCut ) +{ + word Sign = 0; int i; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Sign |= ((word)1) << (pCut->pLeaves[i] & 0x3F); + return Sign; +} +static inline int Sbd_CutCheck( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase +{ + int nSizeB = pBase->nLeaves; + int nSizeC = pCut->nLeaves; + int i, * pB = pBase->pLeaves; + int k, * pC = pCut->pLeaves; + for ( i = 0; i < nSizeC; i++ ) + { + for ( k = 0; k < nSizeB; k++ ) + if ( pC[i] == pB[k] ) + break; + if ( k == nSizeB ) + return 0; + } + return 1; +} +static inline int Sbd_CutSetCheckArray( Sbd_Cut_t ** ppCuts, int nCuts ) +{ + Sbd_Cut_t * pCut0, * pCut1; + int i, k, m, n, Value; + assert( nCuts > 0 ); + for ( i = 0; i < nCuts; i++ ) + { + pCut0 = ppCuts[i]; + assert( pCut0->nLeaves <= SBD_MAX_CUTSIZE ); + assert( pCut0->Sign == Sbd_CutGetSign(pCut0) ); + // check duplicates + for ( m = 0; m < (int)pCut0->nLeaves; m++ ) + for ( n = m + 1; n < (int)pCut0->nLeaves; n++ ) + assert( pCut0->pLeaves[m] < pCut0->pLeaves[n] ); + // check pairs + for ( k = 0; k < nCuts; k++ ) + { + pCut1 = ppCuts[k]; + if ( pCut0 == pCut1 ) + continue; + // check containments + Value = Sbd_CutCheck( pCut0, pCut1 ); + assert( Value == 0 ); + } + } + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +{ + int nSize0 = pCut0->nLeaves; + int nSize1 = pCut1->nLeaves; + int i, * pC0 = pCut0->pLeaves; + int k, * pC1 = pCut1->pLeaves; + int c, * pC = pCut->pLeaves; + // the case of the largest cut sizes + if ( nSize0 == nLutSize && nSize1 == nLutSize ) + { + for ( i = 0; i < nSize0; i++ ) + { + if ( pC0[i] != pC1[i] ) return 0; + pC[i] = pC0[i]; + } + pCut->nLeaves = nLutSize; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; + } + // compare two cuts with different numbers + i = k = c = 0; + if ( nSize0 == 0 ) goto FlushCut1; + if ( nSize1 == 0 ) goto FlushCut0; + while ( 1 ) + { + if ( c == nLutSize ) return 0; + if ( pC0[i] < pC1[k] ) + { + pC[c++] = pC0[i++]; + if ( i >= nSize0 ) goto FlushCut1; + } + else if ( pC0[i] > pC1[k] ) + { + pC[c++] = pC1[k++]; + if ( k >= nSize1 ) goto FlushCut0; + } + else + { + pC[c++] = pC0[i++]; k++; + if ( i >= nSize0 ) goto FlushCut1; + if ( k >= nSize1 ) goto FlushCut0; + } + } + +FlushCut0: + if ( c + nSize0 > nLutSize + i ) return 0; + while ( i < nSize0 ) + pC[c++] = pC0[i++]; + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; + +FlushCut1: + if ( c + nSize1 > nLutSize + k ) return 0; + while ( k < nSize1 ) + pC[c++] = pC1[k++]; + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; +} +static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +{ + int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves; + int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves; + int xMin, c = 0, * pC = pCut->pLeaves; + while ( 1 ) + { + x0 = (i0 == nSize0) ? ABC_INFINITY : pC0[i0]; + x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1]; + xMin = Abc_MinInt(x0, x1); + if ( xMin == ABC_INFINITY ) break; + if ( c == nLutSize ) return 0; + pC[c++] = xMin; + if (x0 == xMin) i0++; + if (x1 == xMin) i1++; + } + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; +} +static inline int Sbd_CutSetCutIsContainedOrder( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase +{ + int i, nSizeB = pBase->nLeaves; + int k, nSizeC = pCut->nLeaves; + if ( nSizeB == nSizeC ) + { + for ( i = 0; i < nSizeB; i++ ) + if ( pBase->pLeaves[i] != pCut->pLeaves[i] ) + return 0; + return 1; + } + assert( nSizeB > nSizeC ); + if ( nSizeC == 0 ) + return 1; + for ( i = k = 0; i < nSizeB; i++ ) + { + if ( pBase->pLeaves[i] > pCut->pLeaves[k] ) + return 0; + if ( pBase->pLeaves[i] == pCut->pLeaves[k] ) + { + if ( ++k == nSizeC ) + return 1; + } + } + return 0; +} +static inline int Sbd_CutSetLastCutIsContained( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = 0; i < nCuts; i++ ) + if ( pCuts[i]->nLeaves <= pCuts[nCuts]->nLeaves && (pCuts[i]->Sign & pCuts[nCuts]->Sign) == pCuts[i]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[nCuts], pCuts[i]) ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) +{ + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + return 0; +} +static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, k, fChanges = 0; + for ( i = 0; i < nCuts; i++ ) + if ( pCuts[nCuts]->nLeaves < pCuts[i]->nLeaves && (pCuts[nCuts]->Sign & pCuts[i]->Sign) == pCuts[nCuts]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[i], pCuts[nCuts]) ) + pCuts[i]->nLeaves = SBD_CUT_NO_LEAF, fChanges = 1; + if ( !fChanges ) + return nCuts; + for ( i = k = 0; i <= nCuts; i++ ) + { + if ( pCuts[i]->nLeaves == SBD_CUT_NO_LEAF ) + continue; + if ( k < i ) + ABC_SWAP( Sbd_Cut_t *, pCuts[k], pCuts[i] ); + k++; + } + return k - 1; +} +static inline void Sbd_CutSetSortByCost( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = nCuts; i > 0; i-- ) + { + if ( Sbd_CutCompare(pCuts[i - 1], pCuts[i]) < 0 )//!= 1 ) + return; + ABC_SWAP( Sbd_Cut_t *, pCuts[i - 1], pCuts[i] ); + } +} +static inline int Sbd_CutSetAddCut( Sbd_Cut_t ** pCuts, int nCuts, int nCutNum ) +{ + if ( nCuts == 0 ) + return 1; + nCuts = Sbd_CutSetLastCutContains(pCuts, nCuts); + assert( nCuts >= 0 ); + Sbd_CutSetSortByCost( pCuts, nCuts ); + // add new cut if there is room + return Abc_MinInt( nCuts + 1, nCutNum - 1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutComputeTruth6( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) +{ + int nOldSupp = pCutR->nLeaves, truthId, fCompl; word t; + word t0 = *Sbd_CutTruth(p, pCut0); + word t1 = *Sbd_CutTruth(p, pCut1); + if ( Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ) t0 = ~t0; + if ( Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ) t1 = ~t1; + t0 = Abc_Tt6Expand( t0, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + t1 = Abc_Tt6Expand( t1, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + t = fIsXor ? t0 ^ t1 : t0 & t1; + if ( (fCompl = (int)(t & 1)) ) t = ~t; + pCutR->nLeaves = Abc_Tt6MinBase( &t, pCutR->pLeaves, pCutR->nLeaves ); + assert( (int)(t & 1) == 0 ); + truthId = Vec_MemHashInsert(p->vTtMem, &t); + pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); + assert( (int)pCutR->nLeaves <= nOldSupp ); + return (int)pCutR->nLeaves < nOldSupp; +} +static inline int Sbd_CutComputeTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) +{ + if ( p->nLutSize <= 6 ) + return Sbd_CutComputeTruth6( p, pCut0, pCut1, fCompl0, fCompl1, pCutR, fIsXor ); + { + word uTruth[SBD_MAX_TT_WORDS], uTruth0[SBD_MAX_TT_WORDS], uTruth1[SBD_MAX_TT_WORDS]; + int nOldSupp = pCutR->nLeaves, truthId; + int nLutSize = p->nLutSize, fCompl; + int nWords = Abc_Truth6WordNum(nLutSize); + word * pTruth0 = Sbd_CutTruth(p, pCut0); + word * pTruth1 = Sbd_CutTruth(p, pCut1); + Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ); + Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ); + Abc_TtExpand( uTruth0, nLutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth1, nLutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + if ( fIsXor ) + Abc_TtXor( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] ^ uTruth1[0]) & 1)) ); + else + Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] & uTruth1[0]) & 1)) ); + pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nLutSize ); + assert( (uTruth[0] & 1) == 0 ); +//Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" ); + truthId = Vec_MemHashInsert(p->vTtMem, uTruth); + pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); + assert( (int)pCutR->nLeaves <= nOldSupp ); + return (int)pCutR->nLeaves < nOldSupp; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutCountBits( word i ) +{ + i = i - ((i >> 1) & 0x5555555555555555); + i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333); + i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); + return (i*(0x0101010101010101))>>56; +} +static inline void Sbd_CutPrint( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); + printf( "%d {", pCut->nLeaves ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( " %*d", nDigits, pCut->pLeaves[i] ); + for ( ; i < (int)p->nLutSize; i++ ) + printf( " %*s", nDigits, " " ); + printf( " } Cost = %4d\n", pCut->Cost ); +} +static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vDelays, pCut->pLeaves[i] ); + return Cost; +} +static inline void Sbd_CutAddUnitCut( Sbd_Sto_t * p, int iObj ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + if ( Vec_IntSize(vThis) == 0 ) + Vec_IntPush( vThis, 1 ); + else + Vec_IntAddToEntry( vThis, 0, 1 ); + Vec_IntPush( vThis, 1 ); + Vec_IntPush( vThis, iObj ); + Vec_IntPush( vThis, 2 ); +} +static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + int i, v, * pCut, * pList = Vec_IntArray( vThis ); + Sbd_ForEachCut( pList, pCut, i ) + { + Sbd_Cut_t * pCutTemp = &p->pCuts[Index][i]; + pCutTemp->nLeaves = pCut[0]; + for ( v = 1; v <= pCut[0]; v++ ) + pCutTemp->pLeaves[v-1] = pCut[v]; + pCutTemp->iFunc = pCut[pCut[0]+1]; + pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); + pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); + } + return pList[0]; +} +static inline void Sbd_StoInitResult( Sbd_Sto_t * p ) +{ + int i; + for ( i = 0; i < SBD_MAX_CUTNUM; i++ ) + p->ppCuts[i] = &p->pCuts[2][i]; +} +static inline void Sbd_StoStoreResult( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, v; + Vec_Int_t * vList = Vec_WecEntry( p->vCuts, iObj ); + Vec_IntPush( vList, nCuts ); + for ( i = 0; i < nCuts; i++ ) + { + Vec_IntPush( vList, pCuts[i]->nLeaves ); + for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) + Vec_IntPush( vList, pCuts[i]->pLeaves[v] ); + Vec_IntPush( vList, pCuts[i]->iFunc ); + } +} +static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, v, Delay, DelayMin = ABC_INFINITY; + assert( nCuts > 0 ); + for ( i = 0; i < nCuts; i++ ) + { + if ( (int)pCuts[i]->nLeaves > p->nLutSize ) + continue; + Delay = 0; + for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) + Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vDelays, pCuts[i]->pLeaves[v]) ); + DelayMin = Abc_MinInt( DelayMin, Delay ); + } + assert( DelayMin < ABC_INFINITY ); + Vec_IntWriteEntry( p->vDelays, iObj, (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin ); +} +void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + int fIsXor = Gia_ObjIsXor(pObj); + int nLutSize = p->nLutSize; + int nCutNum = p->nCutNum; + int fComp0 = Gia_ObjFaninC0(pObj); + int fComp1 = Gia_ObjFaninC1(pObj); + int nCuts0 = Sbd_StoPrepareSet( p, Gia_ObjFaninId0(pObj, iObj), 0 ); + int nCuts1 = Sbd_StoPrepareSet( p, Gia_ObjFaninId1(pObj, iObj), 1 ); + int i, k, nCutsR = 0; + Sbd_Cut_t * pCut0, * pCut1, ** pCutsR = p->ppCuts; + assert( !Gia_ObjIsBuf(pObj) ); + assert( !Gia_ObjIsMux(p->pGia, pObj) ); + Sbd_StoInitResult( p ); + p->CutCount[0] += nCuts0 * nCuts1; + for ( i = 0, pCut0 = p->pCuts[0]; i < nCuts0; i++, pCut0++ ) + for ( k = 0, pCut1 = p->pCuts[1]; k < nCuts1; k++, pCut1++ ) + { + if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nLutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nLutSize ) + continue; + p->CutCount[1]++; + if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nLutSize) ) + continue; + if ( Sbd_CutSetLastCutIsContained(pCutsR, nCutsR) ) + continue; + p->CutCount[2]++; + if ( p->fCutMin && Sbd_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) ) + pCutsR[nCutsR]->Sign = Sbd_CutGetSign(pCutsR[nCutsR]); + pCutsR[nCutsR]->Cost = Sbd_CutCost( p, pCutsR[nCutsR] ); + nCutsR = Sbd_CutSetAddCut( pCutsR, nCutsR, nCutNum ); + } + Sbd_StoComputeDelay( p, iObj, pCutsR, nCutsR ); + p->CutCount[3] += nCutsR; + // debug printout + if ( 0 ) + { + printf( "*** Obj = %d Delay = %d\n", iObj, Vec_IntEntry(p->vDelays, iObj) ); + for ( i = 0; i < nCutsR; i++ ) + Sbd_CutPrint( p, pCutsR[i] ); + printf( "\n" ); + } + // verify + assert( nCutsR > 0 && nCutsR < nCutNum ); + assert( Sbd_CutSetCheckArray(pCutsR, nCutsR) ); + // store the cutset + Sbd_StoStoreResult( p, iObj, pCutsR, nCutsR ); + if ( nCutsR > 1 || pCutsR[0]->nLeaves > 1 ) + Sbd_CutAddUnitCut( p, iObj ); +} +int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) +{ + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, 0 ); + Vec_WecPushLevel( p->vCuts ); + Sbd_StoMergeCuts( p, iObj ); + return Vec_IntEntry( p->vDelays, iObj ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbd_StoComputeCuts( Sbd_Sto_t * p ) +{ + Gia_Obj_t * pObj; + int i, iObj; + Gia_ManForEachCiId( p->pGia, iObj, i ) + Sbd_CutAddUnitCut( p, iObj ); + Gia_ManForEachAnd( p->pGia, pObj, iObj ) + Sbd_StoMergeCuts( p, iObj ); + if ( !p->fVerbose ) + return; + printf( "CutPair = %.0f ", p->CutCount[0] ); + printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); + printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); + printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); + printf( "\n" ); +} +void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) +{ + Sbd_Sto_t * p = Sbd_StoAlloc( pGia, 8, 32, 1, 1 ); + Sbd_StoComputeCuts( p ); + Sbd_StoFree( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + From 1f45cca621ef5b76c5a7e8b3415530dc8182cdca Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 28 Dec 2016 09:43:28 +0700 Subject: [PATCH 09/61] C++ compatibility fix. --- src/proof/acec/acecSt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proof/acec/acecSt.c b/src/proof/acec/acecSt.c index 63aa81311..d97dadc9e 100644 --- a/src/proof/acec/acecSt.c +++ b/src/proof/acec/acecSt.c @@ -21,6 +21,8 @@ #include "acecInt.h" #include "misc/vec/vecWec.h" #include "misc/extra/extra.h" +#include "aig/aig/aig.h" +#include "opt/dar/dar.h" ABC_NAMESPACE_IMPL_START From fdd8404bfc47ae385b7a3684113e8a76806eba79 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 28 Dec 2016 12:34:53 +0700 Subject: [PATCH 10/61] Updates to delay optimization project. --- src/opt/sbd/sbdCut.c | 335 +++++++++++++++++++++++++++++-------------- src/opt/sbd/sbdInt.h | 11 +- 2 files changed, 239 insertions(+), 107 deletions(-) diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index cabc301c5..154df9145 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -28,36 +28,45 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// #define SBD_MAX_CUTSIZE 8 -#define SBD_MAX_CUTNUM 64 +#define SBD_MAX_CUTNUM 1001 #define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) -#define SBD_CUT_NO_LEAF 255 +#define SBD_CUT_NO_LEAF 0xF typedef struct Sbd_Cut_t_ Sbd_Cut_t; struct Sbd_Cut_t_ { word Sign; // signature int iFunc; // functionality - unsigned Cost : 24; // misc cut cost - unsigned nLeaves : 8; // the number of leaves + int Cost; // cut cost + int CostLev; // cut cost + unsigned fSpec : 1; // special cut + unsigned nTreeLeaves : 27; // cut cost + unsigned nLeaves : 4; // the number of leaves int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; -typedef struct Sbd_Sto_t_ Sbd_Sto_t; struct Sbd_Sto_t_ { int nLutSize; + int nCutSize; int nCutNum; int fCutMin; int fVerbose; Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vMirrors; // mirrors for each node Vec_Int_t * vDelays; // delays for each node + Vec_Int_t * vLevels; // levels for each node + Vec_Int_t * vRefs; // refs for each node Vec_Wec_t * vCuts; // cuts for each node Vec_Mem_t * vTtMem; // truth tables Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers abctime clkStart; // starting time double CutCount[4]; // cut counters + int nCutsSpec; // special cuts + int nCutsOver; // overflow cuts + int DelayMin; // minimum delay }; static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } @@ -68,45 +77,6 @@ static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Ve /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, int nLutSize, int nCutNum, int fCutMin, int fVerbose ) -{ - Sbd_Sto_t * p; - assert( nLutSize > 1 && nLutSize <= SBD_MAX_CUTSIZE ); - assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); - p = ABC_CALLOC( Sbd_Sto_t, 1 ); - p->clkStart = Abc_Clock(); - p->nLutSize = nLutSize; - p->nCutNum = nCutNum; - p->fCutMin = fCutMin; - p->fVerbose = fVerbose; - p->pGia = pGia; - p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); - p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); - p->vTtMem = fCutMin ? Vec_MemAllocForTT( nLutSize, 0 ) : NULL; - return p; -} -void Sbd_StoFree( Sbd_Sto_t * p ) -{ - Vec_IntFree( p->vDelays ); - Vec_WecFree( p->vCuts ); - if ( p->fCutMin ) - Vec_MemHashFree( p->vTtMem ); - if ( p->fCutMin ) - Vec_MemFree( p->vTtMem ); - ABC_FREE( p ); -} - /**Function************************************************************* Synopsis [Check correctness of cuts.] @@ -181,7 +151,7 @@ static inline int Sbd_CutSetCheckArray( Sbd_Cut_t ** ppCuts, int nCuts ) SeeAlso [] ***********************************************************************/ -static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize ) { int nSize0 = pCut0->nLeaves; int nSize1 = pCut1->nLeaves; @@ -189,14 +159,14 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C int k, * pC1 = pCut1->pLeaves; int c, * pC = pCut->pLeaves; // the case of the largest cut sizes - if ( nSize0 == nLutSize && nSize1 == nLutSize ) + if ( nSize0 == nCutSize && nSize1 == nCutSize ) { for ( i = 0; i < nSize0; i++ ) { if ( pC0[i] != pC1[i] ) return 0; pC[i] = pC0[i]; } - pCut->nLeaves = nLutSize; + pCut->nLeaves = nCutSize; pCut->iFunc = -1; pCut->Sign = pCut0->Sign | pCut1->Sign; return 1; @@ -207,7 +177,7 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C if ( nSize1 == 0 ) goto FlushCut0; while ( 1 ) { - if ( c == nLutSize ) return 0; + if ( c == nCutSize ) return 0; if ( pC0[i] < pC1[k] ) { pC[c++] = pC0[i++]; @@ -227,7 +197,7 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C } FlushCut0: - if ( c + nSize0 > nLutSize + i ) return 0; + if ( c + nSize0 > nCutSize + i ) return 0; while ( i < nSize0 ) pC[c++] = pC0[i++]; pCut->nLeaves = c; @@ -236,7 +206,7 @@ FlushCut0: return 1; FlushCut1: - if ( c + nSize1 > nLutSize + k ) return 0; + if ( c + nSize1 > nCutSize + k ) return 0; while ( k < nSize1 ) pC[c++] = pC1[k++]; pCut->nLeaves = c; @@ -244,7 +214,7 @@ FlushCut1: pCut->Sign = pCut0->Sign | pCut1->Sign; return 1; } -static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize ) { int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves; int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves; @@ -255,7 +225,7 @@ static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_ x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1]; xMin = Abc_MinInt(x0, x1); if ( xMin == ABC_INFINITY ) break; - if ( c == nLutSize ) return 0; + if ( c == nCutSize ) return 0; pC[c++] = xMin; if (x0 == xMin) i0++; if (x1 == xMin) i1++; @@ -313,10 +283,30 @@ static inline int Sbd_CutSetLastCutIsContained( Sbd_Cut_t ** pCuts, int nCuts ) ***********************************************************************/ static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) { - if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; - if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; - if ( pCut0->Cost < pCut1->Cost ) return -1; - if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->nLeaves <= 4 && pCut1->nLeaves <= 4 ) + { + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + } + else if ( pCut0->nLeaves <= 4 ) + return -1; + else if ( pCut1->nLeaves <= 4 ) + return 1; + else + { + if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1; + if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + } return 0; } static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) @@ -389,24 +379,24 @@ static inline int Sbd_CutComputeTruth6( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cu } static inline int Sbd_CutComputeTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) { - if ( p->nLutSize <= 6 ) + if ( p->nCutSize <= 6 ) return Sbd_CutComputeTruth6( p, pCut0, pCut1, fCompl0, fCompl1, pCutR, fIsXor ); { word uTruth[SBD_MAX_TT_WORDS], uTruth0[SBD_MAX_TT_WORDS], uTruth1[SBD_MAX_TT_WORDS]; int nOldSupp = pCutR->nLeaves, truthId; - int nLutSize = p->nLutSize, fCompl; - int nWords = Abc_Truth6WordNum(nLutSize); + int nCutSize = p->nCutSize, fCompl; + int nWords = Abc_Truth6WordNum(nCutSize); word * pTruth0 = Sbd_CutTruth(p, pCut0); word * pTruth1 = Sbd_CutTruth(p, pCut1); Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ); Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ); - Abc_TtExpand( uTruth0, nLutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); - Abc_TtExpand( uTruth1, nLutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth0, nCutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth1, nCutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); if ( fIsXor ) Abc_TtXor( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] ^ uTruth1[0]) & 1)) ); else Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] & uTruth1[0]) & 1)) ); - pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nLutSize ); + pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nCutSize ); assert( (uTruth[0] & 1) == 0 ); //Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" ); truthId = Vec_MemHashInsert(p->vTtMem, uTruth); @@ -434,15 +424,12 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline void Sbd_CutPrint( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +static inline int Sbd_CutIsSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { - int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); - printf( "%d {", pCut->nLeaves ); + int i, Delay = Vec_IntEntry(p->vDelays, iObj), DelayMax = -ABC_INFINITY; for ( i = 0; i < (int)pCut->nLeaves; i++ ) - printf( " %*d", nDigits, pCut->pLeaves[i] ); - for ( ; i < (int)p->nLutSize; i++ ) - printf( " %*s", nDigits, " " ); - printf( " } Cost = %4d\n", pCut->Cost ); + DelayMax = Abc_MaxInt( DelayMax, Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); + return DelayMax < -1; } static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { @@ -451,7 +438,21 @@ static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) Cost += Vec_IntEntry( p->vDelays, pCut->pLeaves[i] ); return Cost; } -static inline void Sbd_CutAddUnitCut( Sbd_Sto_t * p, int iObj ) +static inline int Sbd_CutCostLev( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vLevels, pCut->pLeaves[i] ); + return Cost; +} +static inline int Sbd_CutTreeLeaves( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1; + return Cost; +} +static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); if ( Vec_IntSize(vThis) == 0 ) @@ -474,7 +475,10 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->pLeaves[v-1] = pCut[v]; pCutTemp->iFunc = pCut[pCut[0]+1]; pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); + pCutTemp->fSpec = Sbd_CutIsSpec( p, iObj, pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); + pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); + pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); } return pList[0]; } @@ -511,18 +515,48 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC DelayMin = Abc_MinInt( DelayMin, Delay ); } assert( DelayMin < ABC_INFINITY ); - Vec_IntWriteEntry( p->vDelays, iObj, (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin ); + DelayMin = (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin; + Vec_IntWriteEntry( p->vDelays, iObj, DelayMin ); + p->DelayMin = Abc_MaxInt( p->DelayMin, DelayMin ); +} +static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = 0; i < nCuts; i++ ) + { + pCuts[i]->fSpec = Sbd_CutIsSpec( p, iObj, pCuts[i] ); + p->nCutsSpec += pCuts[i]->fSpec; + } +} +static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); + int Delay = Vec_IntEntry(p->vDelays, iObj); + printf( "%d {", pCut->nLeaves ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( " %*d", nDigits, pCut->pLeaves[i] ); + for ( ; i < (int)p->nCutSize; i++ ) + printf( " %*s", nDigits, " " ); + printf( " } Cost = %4d CostLev = %4d Tree = %2d ", pCut->Cost, pCut->CostLev, pCut->nTreeLeaves ); + printf( "%c ", pCut->fSpec ? '*' : ' ' ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); + printf( "\n" ); } void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) { Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); int fIsXor = Gia_ObjIsXor(pObj); - int nLutSize = p->nLutSize; + int nCutSize = p->nCutSize; int nCutNum = p->nCutNum; - int fComp0 = Gia_ObjFaninC0(pObj); - int fComp1 = Gia_ObjFaninC1(pObj); - int nCuts0 = Sbd_StoPrepareSet( p, Gia_ObjFaninId0(pObj, iObj), 0 ); - int nCuts1 = Sbd_StoPrepareSet( p, Gia_ObjFaninId1(pObj, iObj), 1 ); + int Lit0m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ) : -1; + int Lit1m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ) : -1; + int fComp0 = Gia_ObjFaninC0(pObj) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); + int fComp1 = Gia_ObjFaninC1(pObj) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); + int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + int nCuts0 = Sbd_StoPrepareSet( p, Fan0, 0 ); + int nCuts1 = Sbd_StoPrepareSet( p, Fan1, 1 ); int i, k, nCutsR = 0; Sbd_Cut_t * pCut0, * pCut1, ** pCutsR = p->ppCuts; assert( !Gia_ObjIsBuf(pObj) ); @@ -532,10 +566,10 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) for ( i = 0, pCut0 = p->pCuts[0]; i < nCuts0; i++, pCut0++ ) for ( k = 0, pCut1 = p->pCuts[1]; k < nCuts1; k++, pCut1++ ) { - if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nLutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nLutSize ) + if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nCutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nCutSize ) continue; p->CutCount[1]++; - if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nLutSize) ) + if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nCutSize) ) continue; if ( Sbd_CutSetLastCutIsContained(pCutsR, nCutsR) ) continue; @@ -543,16 +577,21 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) if ( p->fCutMin && Sbd_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) ) pCutsR[nCutsR]->Sign = Sbd_CutGetSign(pCutsR[nCutsR]); pCutsR[nCutsR]->Cost = Sbd_CutCost( p, pCutsR[nCutsR] ); + pCutsR[nCutsR]->CostLev = Sbd_CutCostLev( p, pCutsR[nCutsR] ); + pCutsR[nCutsR]->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutsR[nCutsR] ); nCutsR = Sbd_CutSetAddCut( pCutsR, nCutsR, nCutNum ); } Sbd_StoComputeDelay( p, iObj, pCutsR, nCutsR ); + Sbd_StoComputeSpec( p, iObj, pCutsR, nCutsR ); p->CutCount[3] += nCutsR; + p->nCutsOver += nCutsR == nCutNum-1; // debug printout if ( 0 ) { - printf( "*** Obj = %d Delay = %d\n", iObj, Vec_IntEntry(p->vDelays, iObj) ); + printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) - Sbd_CutPrint( p, pCutsR[i] ); + if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->fSpec ) + Sbd_CutPrint( p, iObj, pCutsR[i] ); printf( "\n" ); } // verify @@ -561,21 +600,12 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) // store the cutset Sbd_StoStoreResult( p, iObj, pCutsR, nCutsR ); if ( nCutsR > 1 || pCutsR[0]->nLeaves > 1 ) - Sbd_CutAddUnitCut( p, iObj ); -} -int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) -{ - assert( iObj == Vec_IntSize(p->vDelays) ); - assert( iObj == Vec_WecSize(p->vCuts) ); - Vec_IntPush( p->vDelays, 0 ); - Vec_WecPushLevel( p->vCuts ); - Sbd_StoMergeCuts( p, iObj ); - return Vec_IntEntry( p->vDelays, iObj ); + Sbd_CutAddUnit( p, iObj ); } /**Function************************************************************* - Synopsis [] + Synopsis [Incremental cut computation.] Description [] @@ -584,30 +614,123 @@ int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) SeeAlso [] ***********************************************************************/ -void Sbd_StoComputeCuts( Sbd_Sto_t * p ) +Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ) { - Gia_Obj_t * pObj; - int i, iObj; - Gia_ManForEachCiId( p->pGia, iObj, i ) - Sbd_CutAddUnitCut( p, iObj ); - Gia_ManForEachAnd( p->pGia, pObj, iObj ) - Sbd_StoMergeCuts( p, iObj ); - if ( !p->fVerbose ) + Sbd_Sto_t * p; + assert( nLutSize <= nCutSize ); + assert( nCutSize < SBD_CUT_NO_LEAF ); + assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Sto_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutSize = nCutSize; + p->nCutNum = nCutNum; + p->fCutMin = fCutMin; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vMirrors = vMirrors; + p->vDelays = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vLevels = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vRefs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecAlloc( Gia_ManObjNum(pGia) ); + p->vTtMem = fCutMin ? Vec_MemAllocForTT( nCutSize, 0 ) : NULL; + return p; +} +void Sbd_StoFree( Sbd_Sto_t * p ) +{ + Vec_IntFree( p->vDelays ); + Vec_IntFree( p->vLevels ); + Vec_IntFree( p->vRefs ); + Vec_WecFree( p->vCuts ); + if ( p->fCutMin ) + Vec_MemHashFree( p->vTtMem ); + if ( p->fCutMin ) + Vec_MemFree( p->vTtMem ); + ABC_FREE( p ); +} +void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) +{ + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_IntSize(p->vLevels) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, Delay ); + Vec_IntPush( p->vLevels, Level ); + Vec_WecPushLevel( p->vCuts ); +} +void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) +{ + Sbd_StoComputeCutsObj( p, iObj, Delay, Level ); + Sbd_CutAddUnit( p, iObj ); +} +int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + int Lev0 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId0(pObj, iObj) ); + int Lev1 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId1(pObj, iObj) ); + Sbd_StoComputeCutsObj( p, iObj, -1, 1 + Abc_MaxInt(Lev0, Lev1) ); + Sbd_StoMergeCuts( p, iObj ); + return Vec_IntEntry( p->vDelays, iObj ); +} +void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + assert( iObj == Vec_IntSize(p->vRefs) ); + assert( iMirror < iObj ); + Vec_IntPush( p->vRefs, iMirror > 0 ? Vec_IntEntry(p->vRefs, iMirror) : 0 ); + if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId1(pObj, iObj), 1 ); + } + else if ( Gia_ObjIsCo(pObj) ) + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); +} +void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + Vec_IntAddToEntry( p->vRefs, iObj, -1 ); + if ( Vec_IntEntry( p->vRefs, iObj ) > 0 ) return; - printf( "CutPair = %.0f ", p->CutCount[0] ); - printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); - printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); - printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); - printf( "\n" ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); + Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); } void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) { - Sbd_Sto_t * p = Sbd_StoAlloc( pGia, 8, 32, 1, 1 ); - Sbd_StoComputeCuts( p ); + Sbd_Sto_t * p = Sbd_StoAlloc( pGia, NULL, 4, 8, 100, 1, 1 ); + Gia_Obj_t * pObj; + int i, iObj; + // prepare references + Gia_ManForEachObj( p->pGia, pObj, iObj ) + Sbd_StoRefObj( p, iObj, -1 ); + // compute cuts + Sbd_StoComputeCutsObj( p, 0, 0, 0 ); + Gia_ManForEachCiId( p->pGia, iObj, i ) + Sbd_StoComputeCutsCi( p, iObj, 0, 0 ); + Gia_ManForEachAnd( p->pGia, pObj, iObj ) + Sbd_StoComputeCutsNode( p, iObj ); + if ( p->fVerbose ) + { + printf( "Running cut computation with LutSize = %d CutSize = %d CutNum = %d:\n", p->nLutSize, p->nCutSize, p->nCutNum ); + printf( "CutPair = %.0f ", p->CutCount[0] ); + printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); + printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); + printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); + printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) ); + printf( "\n" ); + printf( "Spec = %4d ", p->nCutsSpec ); + printf( "Over = %4d ", p->nCutsOver ); + printf( "Lev = %4d ", p->DelayMin ); + Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart ); + } Sbd_StoFree( p ); } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 5395e148e..54174f768 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -60,6 +60,8 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Sbd_Sto_t_ Sbd_Sto_t; + typedef struct Sbd_Str_t_ Sbd_Str_t; struct Sbd_Str_t_ { @@ -78,7 +80,14 @@ struct Sbd_Str_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== sbdCnf.c ==========================================================*/ +/*=== sbdCut.c ==========================================================*/ +extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); +extern void Sbd_StoFree( Sbd_Sto_t * p ); +extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); +extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); ABC_NAMESPACE_HEADER_END From 4488ab83d0c36f65a349122f58c44b55025ff856 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 29 Dec 2016 14:45:16 +0700 Subject: [PATCH 11/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 270 +++++++++++++++++++++++++++++++++++++-- src/opt/sbd/sbdCut.c | 92 +++++++++---- src/opt/sbd/sbdInt.h | 4 +- src/sat/bsat/satSolver.h | 7 +- 4 files changed, 333 insertions(+), 40 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 15874dc67..daefb9aff 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -43,6 +43,7 @@ struct Sbd_Man_t_ Vec_Wrd_t * vSims[4]; // simulation information (main, backup, controlability) Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary + Vec_Int_t * vLits2; // temporary int nConsts; // constants int nChanges; // changes abctime timeWin; @@ -52,6 +53,7 @@ struct Sbd_Man_t_ abctime timeEnu; abctime timeOther; abctime timeTotal; + Sbd_Sto_t * pSto; // target node int Pivot; // target node int DivCutoff; // the place where D-2 divisors begin @@ -201,6 +203,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) // target node p->vCover = Vec_IntAlloc( 100 ); p->vLits = Vec_IntAlloc( 100 ); + p->vLits2 = Vec_IntAlloc( 100 ); p->vRoots = Vec_IntAlloc( 100 ); p->vWinObjs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); p->vObj2Var = Vec_IntStart( Gia_ManObjNum(pGia) ); @@ -223,6 +226,8 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Gia_ManForEachCiId( pGia, Id, i ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); + // cut enumeration + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, 2*pPars->nLutSize-1, 64, 1, 1 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -236,6 +241,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_WrdFree( p->vSims[i] ); Vec_IntFree( p->vCover ); Vec_IntFree( p->vLits ); + Vec_IntFree( p->vLits2 ); Vec_IntFree( p->vRoots ); Vec_IntFree( p->vWinObjs ); Vec_IntFree( p->vObj2Var ); @@ -246,7 +252,8 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vCounts[0] ); Vec_IntFree( p->vCounts[1] ); Vec_WrdFree( p->vMatrix ); - if ( p->pSat ) sat_solver_delete( p->pSat ); + sat_solver_delete_p( &p->pSat ); + Sbd_StoFree( p->pSto ); ABC_FREE( p ); } @@ -1158,10 +1165,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) int nConsts = 4; int RetValue; - if ( p->pSat ) - sat_solver_delete( p->pSat ); - p->pSat = NULL; - + sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; @@ -1262,6 +1266,125 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) return 0; } +int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +{ + extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 + ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); + abctime clk = Abc_Clock(); + + int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int nDivs = Vec_IntSize( p->vDivVars ); + int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); + int i, k, iObj, nIters; + + int nLeaves, pLeaves[SBD_DIV_MAX]; + + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodeRefs[SBD_DIV_MAX]; + int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; + + sat_solver_delete_p( &p->pSat ); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + + // extract one cut + nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); + + // solve the covering problem + for ( nIters = 0; nIters < nLeaves; nIters++ ) + { + word Truth; + // try to remove one variable from divisors + Vec_IntClear( p->vDivSet ); + for ( i = 0; i < nLeaves; i++ ) + if ( i != nIters && pLeaves[i] != -1 ) + Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); + assert( Vec_IntSize(p->vDivSet) < nLeaves ); + + Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + if ( Truth == SBD_SAT_UNDEC ) + printf( "Node %d: Undecided.\n", Pivot ); + else if ( Truth == SBD_SAT_SAT ) + continue; + else + pLeaves[nIters] = -1; + } + + Vec_IntClear( p->vDivSet ); + for ( i = 0; i < nLeaves; i++ ) + if ( pLeaves[i] != -1 ) + Vec_IntPush( p->vDivSet, pLeaves[i] ); + printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); + + //Delay++; + + // count number of nodes on each level + nNodesTop = 0, nNodesBot = 0; + Vec_IntForEachEntry( p->vDivSet, iObj, i ) + { + int DelayDiff = Vec_IntEntry(p->vLutLevs, iObj) - Delay; + if ( DelayDiff > -2 ) + break; + if ( DelayDiff == -2 ) + pNodesTop[nNodesTop++] = i; + else // if ( DelayDiff < -2 ) + pNodesBot[nNodesBot++] = i; + Vec_IntWriteEntry( p->vDivSet, iObj, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); + pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); + } + if ( i < Vec_IntSize(p->vDivSet) ) + return 0; + if ( nNodesTop > p->pPars->nLutSize-1 ) + return 0; + if ( nNodesBot > p->pPars->nLutSize ) + { + // move left-over to the top + while ( nNodesBot > p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot]; + assert( nNodesBot == p->pPars->nLutSize ); + assert( nNodesTop <= p->pPars->nLutSize-1 ); + } + nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; + + // number of structures + *pnStrs = 2 + nNodesDiff; + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; + + Strs[1].fLut = 1; + Strs[1].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[2+k].fLut = 0; + Strs[2+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[2+k].VarIns[i] = pNodesBot[i]; + Strs[2+k].Res = 0; + } + + return Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + p->vDivSet, *pnStrs, Strs ); +} + + /**Function************************************************************* Synopsis [Computes delay-oriented k-feasible cut at the node.] @@ -1503,6 +1626,87 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) return 0; } +int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) +{ + int i, k, w, iLit, Node; + int iObjLast = Gia_ManObjNum(p->pGia); + int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); + int iNewLev; + // collect leaf literals + Vec_IntClear( p->vLits ); + Vec_IntForEachEntry( p->vDivSet, Node, i ) + { + Node = Vec_IntEntry( p->vWinObjs, Node ); + if ( Vec_IntEntry(p->vMirrors, Node) >= 0 ) + Vec_IntPush( p->vLits, Vec_IntEntry(p->vMirrors, Node) ); + else + Vec_IntPush( p->vLits, Abc_Var2Lit(Node, 0) ); + } + // collect structure nodes + for ( i = 0; i < nStrs; i++ ) + Vec_IntPush( p->vLits, -1 ); + // implement structures + for ( i = nStrs-1; i >= 0; i-- ) + { + if ( pStrs[i].fLut ) + { + // collect local literals + Vec_IntClear( p->vLits2 ); + for ( k = 0; k < (int)pStrs[i].nVarIns; k++ ) + Vec_IntPush( p->vLits2, Vec_IntEntry(p->vLits, pStrs[i].VarIns[k]) ); + // pretend to have MUXes + // assert( p->pGia->pMuxes == NULL ); + if ( p->pGia->nXors && p->pGia->pMuxes == NULL ) + p->pGia->pMuxes = (unsigned *)p; + // derive new function of the node + iLit = Dsm_ManTruthToGia( p->pGia, &pStrs[i].Res, p->vLits2, p->vCover ); + if ( p->pGia->pMuxes == (unsigned *)p ) + p->pGia->pMuxes = NULL; + } + else + { + iLit = Vec_IntEntry( p->vLits, (int)pStrs[i].Res ); + assert( iLit > 0 ); + } + // update literal + assert( Vec_IntEntry(p->vLits, Vec_IntSize(p->vLits)-nStrs+i) == -1 ); + Vec_IntWriteEntry( p->vLits, Vec_IntSize(p->vLits)-nStrs+i, iLit ); + } + iLit = Vec_IntEntry( p->vLits, Vec_IntSize(p->vDivSet) ); + assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); + // remember this function + assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); + Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); + if ( p->pPars->fVerbose ) + printf( "Replacing node %d by literal %d.\n", Pivot, iLit ); + + // extend data-structure to accommodate new nodes + assert( Vec_IntSize(p->vLutLevs) == iObjLast ); + for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); + assert( i == Vec_IntSize(p->vLutLevs) ); + Vec_IntPush( p->vLutLevs, Delay ); + Vec_IntPush( p->vObj2Var, 0 ); + Vec_IntPush( p->vMirrors, -1 ); + Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); + //Sbd_ManFindCut( p, i, p->vLits ); + for ( k = 0; k < 4; k++ ) + for ( w = 0; w < p->pPars->nWords; w++ ) + Vec_WrdPush( p->vSims[k], 0 ); + } + // make sure delay reduction is achieved + iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); + assert( iNewLev < iCurLev ); + // update delay of the initial node + assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + p->nChanges++; + return 0; +} + /**Function************************************************************* Synopsis [Derives new AIG after resynthesis.] @@ -1537,7 +1741,7 @@ void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * v } Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) { - Gia_Man_t * pNew; + Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i; Gia_ManFillValue( p ); @@ -1557,6 +1761,10 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Gia_ManTransferTiming( pNew, p ); + // remove dangling nodes + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManTransferTiming( pNew, pTemp ); + Gia_ManStop( pTemp ); return pNew; } @@ -1574,12 +1782,17 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { // extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); + Sbd_Str_t Strs[4]; + int nStrs = 0; int RetValue; word Truth = 0; - if ( Sbd_ManMergeCuts( p, Pivot ) ) - return; + if ( !p->pSto ) + { + if ( Sbd_ManMergeCuts( p, Pivot ) ) + return; + } -// if ( Pivot != 70 ) +// if ( Pivot != 15 ) // return; if ( p->pPars->fVerbose ) @@ -1595,11 +1808,28 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); } - else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) + else if ( Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { - Sbd_ManImplement( p, Pivot, Truth ); + //Sbd_ManImplement( p, Pivot, Truth ); + Sbd_ManImplement2( p, Pivot, nStrs, Strs ); //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); } +/* + else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) + { + int i; + Sbd_Str_t Strs; + Strs.fLut = 1; + Strs.nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs.nVarIns; i++ ) + Strs.VarIns[i] = i; + Strs.Res = Truth; + //Sbd_ManImplement( p, Pivot, Truth ); + Sbd_ManImplement2( p, Pivot, 1, &Strs ); + //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + } +*/ + /* else { @@ -1642,6 +1872,9 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) int k, Pivot; assert( pPars->nLutSize <= 6 ); //Sbd_ManMergeTest( p ); + // prepare references + Gia_ManForEachObj( p->pGia, pObj, Pivot ) + Sbd_StoRefObj( p->pSto, Pivot, -1 ); //return NULL; if ( pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)pGia->pManTime) ) { @@ -1676,10 +1909,19 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) } else { - Gia_ManForEachAndId( pGia, Pivot ) + Gia_ManForEachObj( pGia, pObj, Pivot ) { - if ( Pivot < nNodesOld ) - Sbd_NtkPerformOne( p, Pivot ); + if ( Pivot == nNodesOld ) + break; + if ( Gia_ObjIsAnd(pObj) ) + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); + if ( Delay > 1 ) + Sbd_NtkPerformOne( p, Pivot ); + } + else if ( !Gia_ObjIsCo(pObj) ) + Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); } } printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 154df9145..d4c085a1e 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -40,9 +40,9 @@ struct Sbd_Cut_t_ int iFunc; // functionality int Cost; // cut cost int CostLev; // cut cost - unsigned fSpec : 1; // special cut - unsigned nTreeLeaves : 27; // cut cost - unsigned nLeaves : 4; // the number of leaves + unsigned nSlowLeaves : 14; // slow leaves + unsigned nTreeLeaves : 14; // tree leaves + unsigned nLeaves : 4; // leaf count int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; @@ -62,11 +62,13 @@ struct Sbd_Sto_t_ Vec_Mem_t * vTtMem; // truth tables Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers - abctime clkStart; // starting time + int nCutsR; // the number of cuts + int Pivot; // current object double CutCount[4]; // cut counters int nCutsSpec; // special cuts int nCutsOver; // overflow cuts int DelayMin; // minimum delay + abctime clkStart; // starting time }; static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } @@ -309,6 +311,22 @@ static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) } return 0; } +static inline int Sbd_CutCompare2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) +{ + assert( pCut0->nLeaves > 4 && pCut1->nLeaves > 4 ); + if ( pCut0->nSlowLeaves < pCut1->nSlowLeaves ) return -1; + if ( pCut0->nSlowLeaves > pCut1->nSlowLeaves ) return 1; + if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1; + if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + return 0; +} + static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) { int i, k, fChanges = 0; @@ -424,12 +442,12 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline int Sbd_CutIsSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { - int i, Delay = Vec_IntEntry(p->vDelays, iObj), DelayMax = -ABC_INFINITY; + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); for ( i = 0; i < (int)pCut->nLeaves; i++ ) - DelayMax = Abc_MaxInt( DelayMax, Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); - return DelayMax < -1; + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); + return Count; } static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { @@ -475,9 +493,9 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->pLeaves[v-1] = pCut[v]; pCutTemp->iFunc = pCut[pCut[0]+1]; pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); - pCutTemp->fSpec = Sbd_CutIsSpec( p, iObj, pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); + pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); } return pList[0]; @@ -524,8 +542,8 @@ static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCu int i; for ( i = 0; i < nCuts; i++ ) { - pCuts[i]->fSpec = Sbd_CutIsSpec( p, iObj, pCuts[i] ); - p->nCutsSpec += pCuts[i]->fSpec; + pCuts[i]->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCuts[i] ); + p->nCutsSpec += (pCuts[i]->nSlowLeaves == 0); } } static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) @@ -537,8 +555,9 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) printf( " %*d", nDigits, pCut->pLeaves[i] ); for ( ; i < (int)p->nCutSize; i++ ) printf( " %*s", nDigits, " " ); - printf( " } Cost = %4d CostLev = %4d Tree = %2d ", pCut->Cost, pCut->CostLev, pCut->nTreeLeaves ); - printf( "%c ", pCut->fSpec ? '*' : ' ' ); + printf( " } Cost = %3d CostL = %3d Slow = %d Tree = %d ", + pCut->Cost, pCut->CostLev, pCut->nSlowLeaves, pCut->nTreeLeaves ); + printf( "%c ", pCut->nSlowLeaves == 0 ? '*' : ' ' ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); printf( "\n" ); @@ -585,12 +604,14 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) Sbd_StoComputeSpec( p, iObj, pCutsR, nCutsR ); p->CutCount[3] += nCutsR; p->nCutsOver += nCutsR == nCutNum-1; + p->nCutsR = nCutsR; + p->Pivot = iObj; // debug printout - if ( 0 ) + if ( 1 ) { printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) - if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->fSpec ) + if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->nSlowLeaves < 2 ) Sbd_CutPrint( p, iObj, pCutsR[i] ); printf( "\n" ); } @@ -630,10 +651,10 @@ Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, p->fVerbose = fVerbose; p->pGia = pGia; p->vMirrors = vMirrors; - p->vDelays = Vec_IntAlloc( Gia_ManObjNum(pGia) ); - p->vLevels = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vLevels = Vec_IntStart( Gia_ManObjNum(pGia) ); p->vRefs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); - p->vCuts = Vec_WecAlloc( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); p->vTtMem = fCutMin ? Vec_MemAllocForTT( nCutSize, 0 ) : NULL; return p; } @@ -651,12 +672,20 @@ void Sbd_StoFree( Sbd_Sto_t * p ) } void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { - assert( iObj == Vec_IntSize(p->vDelays) ); - assert( iObj == Vec_IntSize(p->vLevels) ); - assert( iObj == Vec_WecSize(p->vCuts) ); - Vec_IntPush( p->vDelays, Delay ); - Vec_IntPush( p->vLevels, Level ); - Vec_WecPushLevel( p->vCuts ); + if ( iObj < Vec_IntSize(p->vDelays) ) + { + Vec_IntWriteEntry( p->vDelays, iObj, Delay ); + Vec_IntWriteEntry( p->vLevels, iObj, Level ); + } + else + { + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_IntSize(p->vLevels) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, Delay ); + Vec_IntPush( p->vLevels, Level ); + Vec_WecPushLevel( p->vCuts ); + } } void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { @@ -698,6 +727,21 @@ void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); } +int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) +{ + Sbd_Cut_t * pCutBest = NULL; int i; + assert( p->Pivot == iObj ); + for ( i = 0; i < p->nCutsR; i++ ) + { + if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) + pCutBest = p->ppCuts[i]; + } +Sbd_CutPrint( p, iObj, pCutBest ); + assert( pCutBest->nLeaves <= SBD_DIV_MAX ); + for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) + pLeaves[i] = pCutBest->pLeaves[i]; + return pCutBest->nLeaves; +} void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) { Sbd_Sto_t * p = Sbd_StoAlloc( pGia, NULL, 4, 8, 100, 1, 1 ); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 54174f768..31d0ea06d 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -54,7 +54,7 @@ ABC_NAMESPACE_HEADER_START #define SBD_LUTS_MAX 2 #define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 7 +#define SBD_DIV_MAX 8 //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -88,6 +88,8 @@ extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ); + ABC_NAMESPACE_HEADER_END diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 7ef2c9e8c..162b91e52 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -229,7 +229,12 @@ static void sat_solver_compress(sat_solver* s) (void) RetValue; } } - +static void sat_solver_delete_p( sat_solver ** ps ) +{ + if ( *ps ) + sat_solver_delete( *ps ); + *ps = NULL; +} static void sat_solver_clean_polarity(sat_solver* s, int * pVars, int nVars ) { int i; From 54b4692d4bb2a6c5e59b5f54aaff95e2c4966e77 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 29 Dec 2016 21:26:02 +0700 Subject: [PATCH 12/61] Updates to delay optimization project. --- src/base/abci/abc.c | 16 ++- src/opt/dau/dauGia.c | 2 +- src/opt/sbd/sbd.h | 1 + src/opt/sbd/sbdCore.c | 288 +++++++++++++++++++++--------------------- src/opt/sbd/sbdCut.c | 62 ++++++--- src/opt/sbd/sbdInt.h | 3 +- src/opt/sbd/sbdLut.c | 17 +-- 7 files changed, 216 insertions(+), 173 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7866b22d7..f9717aa8f 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSWFMCacvwh" ) ) != EOF ) { switch ( c ) { @@ -41025,6 +41025,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutSize < 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->nLutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLutNum < 0 ) + goto usage; + break; case 'W': if ( globalUtilOptind >= argc ) { @@ -41107,9 +41118,10 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSWFMC ] [-acvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); + Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); Abc_Print( -2, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels ); Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 5e74ad217..683750398 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -241,7 +241,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd ) if ( pGia->pHTable == NULL ) { if ( fAnd ) - iFan = Gia_ManAppendAnd( pGia, iFan0, iFan1 ); + iFan = Gia_ManAppendAnd2( pGia, iFan0, iFan1 ); else if ( pGia->pMuxes ) { int fCompl = Abc_LitIsCompl(iFan0) ^ Abc_LitIsCompl(iFan1); diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 89d29958b..6cdfafe48 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -39,6 +39,7 @@ typedef struct Sbd_Par_t_ Sbd_Par_t; struct Sbd_Par_t_ { int nLutSize; // target LUT size + int nLutNum; // target LUT count int nTfoLevels; // the number of TFO levels (windowing) int nTfoFanMax; // the max number of fanouts (windowing) int nWinSizeMax; // maximum window size (windowing) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index daefb9aff..0b399b8ab 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1,12 +1,12 @@ /**CFile**************************************************************** - FileName [sbd.c] + FileName [sbdCore.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [SAT-based optimization using internal don't-cares.] - Synopsis [] + Synopsis [Core procedures.] Author [Alan Mishchenko] @@ -14,7 +14,7 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: sbd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: sbdCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -30,7 +30,6 @@ ABC_NAMESPACE_IMPL_START #define SBD_MAX_LUTSIZE 6 - typedef struct Sbd_Man_t_ Sbd_Man_t; struct Sbd_Man_t_ { @@ -44,13 +43,13 @@ struct Sbd_Man_t_ Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary Vec_Int_t * vLits2; // temporary - int nConsts; // constants - int nChanges; // changes + int nLuts[3]; // 0=const, 1=1lut, 2=2lut abctime timeWin; abctime timeCnf; abctime timeSat; abctime timeCov; abctime timeEnu; + abctime timeQbf; abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; @@ -98,6 +97,7 @@ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) { memset( pPars, 0, sizeof(Sbd_Par_t) ); pPars->nLutSize = 4; // target LUT size + pPars->nLutNum = 2; // target LUT count pPars->nTfoLevels = 2; // the number of TFO levels (windowing) pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) pPars->nWinSizeMax = 0; // maximum window size (windowing) @@ -489,24 +489,26 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) ***********************************************************************/ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) { + extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ); + int nMintCount = 1; Vec_Ptr_t * vSims; word * pSims = Sbd_ObjSim0( p, Pivot ); word * pCtrl = Sbd_ObjSim2( p, Pivot ); int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); int RetValue, i, iObj, Ind, fFindOnset, nCares[2] = {0}; + abctime clk = Abc_Clock(); - extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; if ( p->pSat == NULL ) { - if ( p->pPars->fVerbose ) - printf( "Found stuck-at-%d node %d.\n", 0, Pivot ); + //if ( p->pPars->fVerbose ) + // printf( "Found stuck-at-%d node %d.\n", 0, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return 0; } //return -1; @@ -526,7 +528,7 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) nCares[0] = nCares[0] < nMintCount ? nMintCount - nCares[0] : 0; nCares[1] = nCares[1] < nMintCount ? nMintCount - nCares[1] : 0; - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Computing %d offset and %d onset minterms for node %d.\n", nCares[0], nCares[1], Pivot ); if ( Vec_IntSize(p->vLits) >= nCares[0] + nCares[1] ) @@ -565,10 +567,10 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) Vec_PtrFree( vSims ); if ( RetValue >= 0 ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return RetValue; } // set controlability of these minterms @@ -1153,7 +1155,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); - abctime clk = Abc_Clock(); + abctime clk, clkSat = 0, clkEnu = 0, clkAll; word Onset[64] = {0}, Offset[64] = {0}, Cube; word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; @@ -1165,20 +1167,25 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) int nConsts = 4; int RetValue; - sat_solver_delete_p( &p->pSat ); + clk = Abc_Clock(); + //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; + clkAll = Abc_Clock(); assert( nConsts <= 8 ); + clk = Abc_Clock(); RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); + clkSat += Abc_Clock() - clk; if ( RetValue >= 0 ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return RetValue; } + RetValue = 0; // create rows of the table nRows = 0; @@ -1200,36 +1207,35 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) // solve the covering problem for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) Sbd_ManMatrPrint( p, CoverCols, nDivs, nRows ); clk = Abc_Clock(); if ( !Sbd_ManFindCands( p, CoverCols, nDivs ) ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Cannot find a feasible cover.\n" ); - //clkEnu += Abc_Clock() - clk; - //clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - //p->timeSat += clkSat; - //p->timeCov += clkAll; - //p->timeEnu += clkEnu; + clkEnu += Abc_Clock() - clk; + clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + p->timeSat += clkSat; + p->timeCov += clkAll; + p->timeEnu += clkEnu; return 0; } - //clkEnu += Abc_Clock() - clk; - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Candidate support: " ), Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - //clkSat += Abc_Clock() - clk; + clkSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( *pTruth == SBD_SAT_SAT ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) { int i; printf( "Node %d: SAT.\n", Pivot ); @@ -1255,15 +1261,21 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) } else { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) { printf( "Node %d: UNSAT. ", Pivot ); Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); } - return 1; + p->nLuts[1]++; + RetValue = 1; + break; } } - return 0; + clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + p->timeSat += clkSat; + p->timeCov += clkAll; + p->timeEnu += clkEnu; + return RetValue; } int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) @@ -1277,37 +1289,41 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); + word Truth; int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); - int nDivs = Vec_IntSize( p->vDivVars ); + //int nDivs = Vec_IntSize( p->vDivVars ); int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); - int i, k, iObj, nIters; + int i, k, iObj, nIters, RetValue; int nLeaves, pLeaves[SBD_DIV_MAX]; - int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodeRefs[SBD_DIV_MAX]; + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX];//, pNodeRefs[SBD_DIV_MAX]; int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; - sat_solver_delete_p( &p->pSat ); + //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; // extract one cut nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); + if ( nLeaves == -1 ) + return 0; // solve the covering problem for ( nIters = 0; nIters < nLeaves; nIters++ ) { - word Truth; // try to remove one variable from divisors Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) if ( i != nIters && pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); assert( Vec_IntSize(p->vDivSet) < nLeaves ); - + // compute truth table + clk = Abc_Clock(); Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + p->timeSat += Abc_Clock() - clk; if ( Truth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( Truth == SBD_SAT_SAT ) @@ -1315,16 +1331,34 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) else pLeaves[nIters] = -1; } - Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) if ( pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, pLeaves[i] ); - printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + //printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + if ( Vec_IntSize(p->vDivSet) <= p->pPars->nLutSize ) + { + *pnStrs = 1; + // remap divisors + Vec_IntForEachEntry( p->vDivSet, iObj, i ) + Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); + // compute truth table + clk = Abc_Clock(); + Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + p->timeSat += Abc_Clock() - clk; + assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); + // create structure + Strs->fLut = 1; + Strs->nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs->nVarIns; i++ ) + Strs->VarIns[i] = i; + Strs->Res = Truth; + p->nLuts[1]++; + //Extra_PrintBinary( stdout, (unsigned *)&Truth, 1 << Strs->nVarIns ), printf( "\n" ); + return 1; + } assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); - //Delay++; - // count number of nodes on each level nNodesTop = 0, nNodesBot = 0; Vec_IntForEachEntry( p->vDivSet, iObj, i ) @@ -1336,8 +1370,8 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) pNodesTop[nNodesTop++] = i; else // if ( DelayDiff < -2 ) pNodesBot[nNodesBot++] = i; - Vec_IntWriteEntry( p->vDivSet, iObj, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); - pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); + Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); + //pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); } if ( i < Vec_IntSize(p->vDivSet) ) return 0; @@ -1379,9 +1413,15 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) Strs[2+k].Res = 0; } - return Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - p->vDivSet, *pnStrs, Strs ); + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + + if ( RetValue ) + p->nLuts[2]++; + return RetValue; } @@ -1622,7 +1662,6 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); - p->nChanges++; return 0; } @@ -1677,13 +1716,14 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // remember this function assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Replacing node %d by literal %d.\n", Pivot, iLit ); // extend data-structure to accommodate new nodes assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); @@ -1703,7 +1743,6 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); - p->nChanges++; return 0; } @@ -1781,11 +1820,10 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { -// extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); Sbd_Str_t Strs[4]; - int nStrs = 0; + int i, RetValue, nStrs = 0; + word Truth = 0; - int RetValue; word Truth = 0; if ( !p->pSto ) { if ( Sbd_ManMergeCuts( p, Pivot ) ) @@ -1795,83 +1833,39 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) // if ( Pivot != 15 ) // return; - if ( p->pPars->fVerbose ) - printf( "\nLooking at node %d\n", Pivot ); if ( Sbd_ManWindow( p, Pivot ) ) return; -// Sbd_ManSolveSelect( p->pGia, p->vMirrors, Pivot, p->vDivVars, p->vDivValues, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); - RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); - //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } - else if ( Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) + else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) + { + Strs->fLut = 1; + Strs->nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs->nVarIns; i++ ) + Strs->VarIns[i] = i; + Strs->Res = Truth; + Sbd_ManImplement2( p, Pivot, 1, Strs ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); + } + else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { - //Sbd_ManImplement( p, Pivot, Truth ); Sbd_ManImplement2( p, Pivot, nStrs, Strs ); - //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); } -/* - else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) - { - int i; - Sbd_Str_t Strs; - Strs.fLut = 1; - Strs.nVarIns = Vec_IntSize( p->vDivSet ); - for ( i = 0; i < Strs.nVarIns; i++ ) - Strs.VarIns[i] = i; - Strs.Res = Truth; - //Sbd_ManImplement( p, Pivot, Truth ); - Sbd_ManImplement2( p, Pivot, 1, &Strs ); - //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); - } -*/ - -/* - else - { - extern int Sbd_ProblemSolve( - Gia_Man_t * p, Vec_Int_t * vMirrors, - int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, - Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 - ); - -// Sbd_Str_t Strs[2] = { {1, 4, {0, 1, 2, 8}}, {1, 4, {3, 4, 5, 6}} }; -// Sbd_Str_t Strs[2] = { {1, 4, {1, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}} }; - Sbd_Str_t Strs[3] = { {1, 4, {8, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}}, {0, 4, {0, 1, 2, 3}} }; - - Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); - - int i, RetValue; - - for ( i = 0; i < 6; i++ ) - Vec_IntPush( vDivSet, i+1 ); - - RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - vDivSet, 3, Strs ); - if ( RetValue ) - { - printf( "Solving succeded.\n" ); - //Sbd_ManImplement2( p, Pivot, Truth, nLuts, nSels, nVarsDivs, pVarsDivs, Truths ); - } - Vec_IntFree( vDivSet ); - } -*/ } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; Sbd_Man_t * p = Sbd_ManStart( pGia, pPars ); - int nNodesOld = Gia_ManObjNum(pGia);//, Count = 0; + int nNodesOld = Gia_ManObjNum(pGia); int k, Pivot; assert( pPars->nLutSize <= 6 ); - //Sbd_ManMergeTest( p ); // prepare references Gia_ManForEachObj( p->pGia, pObj, Pivot ) Sbd_StoRefObj( p->pSto, Pivot, -1 ); @@ -1886,32 +1880,6 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Pivot = Gia_ObjId( pGia, pObj ); if ( Pivot >= nNodesOld ) - continue; - if ( Gia_ObjIsAnd(pObj) ) - Sbd_NtkPerformOne( p, Pivot ); - else if ( Gia_ObjIsCi(pObj) ) - { - int arrTime = Tim_ManGetCiArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj) ); - Vec_IntWriteEntry( p->vLutLevs, Pivot, arrTime ); - } - else if ( Gia_ObjIsCo(pObj) ) - { - int arrTime = Vec_IntEntry( p->vLutLevs, Gia_ObjFaninId0(pObj, Pivot) ); - Tim_ManSetCoArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj), arrTime ); - } - else if ( !Gia_ObjIsConst0(pObj) ) - assert( 0 ); - } - //Tim_ManPrint( pGia->pManTime ); - Tim_ManStop( (Tim_Man_t *)pGia->pManTime ); - pGia->pManTime = pTimOld; - Vec_IntFree( vNodes ); - } - else - { - Gia_ManForEachObj( pGia, pObj, Pivot ) - { - if ( Pivot == nNodesOld ) break; if ( Gia_ObjIsAnd(pObj) ) { @@ -1920,23 +1888,61 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) if ( Delay > 1 ) Sbd_NtkPerformOne( p, Pivot ); } - else if ( !Gia_ObjIsCo(pObj) ) + else if ( Gia_ObjIsCi(pObj) ) + { + int arrTime = Tim_ManGetCiArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj) ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, arrTime ); + Sbd_StoComputeCutsCi( p->pSto, Pivot, arrTime, arrTime ); + } + else if ( Gia_ObjIsCo(pObj) ) + { + int arrTime = Vec_IntEntry( p->vLutLevs, Gia_ObjFaninId0(pObj, Pivot) ); + Tim_ManSetCoArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj), arrTime ); + } + else if ( Gia_ObjIsConst0(pObj) ) + Sbd_StoComputeCutsConst0( p->pSto, 0 ); + else assert( 0 ); + } + //Tim_ManPrint( pGia->pManTime ); + Tim_ManStop( (Tim_Man_t *)pGia->pManTime ); + pGia->pManTime = pTimOld; + Vec_IntFree( vNodes ); + } + else + { + Sbd_StoComputeCutsConst0( p->pSto, 0 ); + Gia_ManForEachObj( pGia, pObj, Pivot ) + { + if ( Pivot >= nNodesOld ) + break; + if ( Gia_ObjIsCi(pObj) ) Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); + else if ( Gia_ObjIsAnd(pObj) ) + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); + if ( Delay > 1 ) + Sbd_NtkPerformOne( p, Pivot ); + } + //if ( nNodesOld != Gia_ManObjNum(pGia) ) + // break; } } - printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); + printf( "Found %d constants, %d one-LUT and %d two-LUT replacements with delay %d. ", + p->nLuts[0], p->nLuts[1], p->nLuts[2], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); pNew = Sbd_ManDerive( pGia, p->vMirrors ); // print runtime statistics - p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu; - if ( 0 ) + p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu - p->timeQbf; + if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); ABC_PRTP( "Cnf", p->timeCnf , p->timeTotal ); ABC_PRTP( "Sat", p->timeSat , p->timeTotal ); ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); ABC_PRTP( "Enu", p->timeEnu , p->timeTotal ); + ABC_PRTP( "Qbf", p->timeQbf , p->timeTotal ); ABC_PRTP( "Oth", p->timeOther, p->timeTotal ); ABC_PRTP( "ALL", p->timeTotal, p->timeTotal ); } diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index d4c085a1e..9c54c74ae 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -40,8 +40,9 @@ struct Sbd_Cut_t_ int iFunc; // functionality int Cost; // cut cost int CostLev; // cut cost - unsigned nSlowLeaves : 14; // slow leaves - unsigned nTreeLeaves : 14; // tree leaves + unsigned nTreeLeaves : 9; // tree leaves + unsigned nSlowLeaves : 9; // slow leaves + unsigned nTopLeaves : 10; // top leaves unsigned nLeaves : 4; // leaf count int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; @@ -442,13 +443,6 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) -{ - int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); - return Count; -} static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { int i, Cost = 0; @@ -470,6 +464,20 @@ static inline int Sbd_CutTreeLeaves( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1; return Cost; } +static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); + return Count; +} +static inline int Sbd_CutTopLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay == -2); + return Count; +} static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); @@ -481,6 +489,14 @@ static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) Vec_IntPush( vThis, iObj ); Vec_IntPush( vThis, 2 ); } +static inline void Sbd_CutAddZero( Sbd_Sto_t * p, int iObj ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + assert( Vec_IntSize(vThis) == 0 ); + Vec_IntPush( vThis, 1 ); + Vec_IntPush( vThis, 0 ); + Vec_IntPush( vThis, 0 ); +} static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); @@ -495,8 +511,9 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); - pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); + pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); + pCutTemp->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCutTemp ); } return pList[0]; } @@ -542,6 +559,7 @@ static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCu int i; for ( i = 0; i < nCuts; i++ ) { + pCuts[i]->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCuts[i] ); pCuts[i]->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCuts[i] ); p->nCutsSpec += (pCuts[i]->nSlowLeaves == 0); } @@ -555,8 +573,8 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) printf( " %*d", nDigits, pCut->pLeaves[i] ); for ( ; i < (int)p->nCutSize; i++ ) printf( " %*s", nDigits, " " ); - printf( " } Cost = %3d CostL = %3d Slow = %d Tree = %d ", - pCut->Cost, pCut->CostLev, pCut->nSlowLeaves, pCut->nTreeLeaves ); + printf( " } Cost = %3d CostL = %3d Tree = %d Slow = %d Top = %d ", + pCut->Cost, pCut->CostLev, pCut->nTreeLeaves, pCut->nSlowLeaves, pCut->nTopLeaves ); printf( "%c ", pCut->nSlowLeaves == 0 ? '*' : ' ' ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); @@ -607,7 +625,7 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) p->nCutsR = nCutsR; p->Pivot = iObj; // debug printout - if ( 1 ) + if ( 0 ) { printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) @@ -687,6 +705,11 @@ void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) Vec_WecPushLevel( p->vCuts ); } } +void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ) +{ + Sbd_StoComputeCutsObj( p, iObj, 0, 0 ); + Sbd_CutAddZero( p, iObj ); +} void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { Sbd_StoComputeCutsObj( p, iObj, Delay, Level ); @@ -732,11 +755,14 @@ int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) Sbd_Cut_t * pCutBest = NULL; int i; assert( p->Pivot == iObj ); for ( i = 0; i < p->nCutsR; i++ ) - { - if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) + if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && + (int)p->ppCuts[i]->nSlowLeaves == 0 && + (int)p->ppCuts[i]->nTopLeaves <= p->nLutSize-1 && + (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) pCutBest = p->ppCuts[i]; - } -Sbd_CutPrint( p, iObj, pCutBest ); + if ( pCutBest == NULL ) + return -1; +//Sbd_CutPrint( p, iObj, pCutBest ); assert( pCutBest->nLeaves <= SBD_DIV_MAX ); for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) pLeaves[i] = pCutBest->pLeaves[i]; @@ -751,7 +777,7 @@ void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) Gia_ManForEachObj( p->pGia, pObj, iObj ) Sbd_StoRefObj( p, iObj, -1 ); // compute cuts - Sbd_StoComputeCutsObj( p, 0, 0, 0 ); + Sbd_StoComputeCutsConst0( p, 0 ); Gia_ManForEachCiId( p->pGia, iObj, i ) Sbd_StoComputeCutsCi( p, iObj, 0, 0 ); Gia_ManForEachAnd( p->pGia, pObj, iObj ) diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 31d0ea06d..d54285f8f 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -84,7 +84,8 @@ struct Sbd_Str_t_ extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); extern void Sbd_StoFree( Sbd_Sto_t * p ); extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); -extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index b924a33b3..e8aee7900 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -157,7 +157,7 @@ void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits for ( m = 0; m < nIters; m++, iLit++ ) if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) Abc_TtSetBit( &pStr->Res, m ); - Abc_TtStretch6( &pStr->Res, pStr->nVarIns, 6 ); + pStr->Res = Abc_Tt6Stretch( pStr->Res, pStr->nVarIns ); } else { @@ -192,13 +192,12 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - int fVerbose = 1; + int fVerbose = 0; + abctime clk = Abc_Clock(); Vec_Int_t * vLits = Vec_IntAlloc( 100 ); sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); - //int PivotVar = Vec_IntEntry(vObj2Var, Pivot); - int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); @@ -248,8 +247,6 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, if ( status == l_False ) // solution found break; assert( status == l_True ); -// Vec_IntForEachEntry( vWinObjs, iVar, i ) -// printf( "Node = %4d. SatVar = %4d. Value = %d.\n", iVar, i, sat_solver_var_value(pSatCec, i) ); if ( fVerbose ) { @@ -292,16 +289,16 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, } if ( Vec_IntSize(vLits) > 0 ) { - Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); + //Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); Sbd_ProblemCollectSolution( nStrs, pStr0, vLits ); RetValue = 1; } - else - printf( "Solution does not exist.\n" ); - sat_solver_delete( pSatCec ); sat_solver_delete( pSatQbf ); Vec_IntFree( vLits ); + + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return RetValue; } From 01924ca118cad9bc8bf84de0525e54f5c4a832ec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 20:21:46 +0700 Subject: [PATCH 13/61] Updates to delay optimization project. --- src/aig/gia/gia.h | 53 +++-- src/base/abci/abc.c | 28 ++- src/opt/dau/dauGia.c | 2 +- src/opt/sbd/sbd.h | 2 + src/opt/sbd/sbdCore.c | 442 ++++++++++++++++++++++++++++-------------- src/opt/sbd/sbdCut.c | 68 +++++-- src/opt/sbd/sbdInt.h | 39 ++-- src/opt/sbd/sbdLut.c | 1 - src/opt/sbd/sbdWin.c | 5 +- 9 files changed, 444 insertions(+), 196 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index ac40f9754..d9b1716a3 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -665,21 +665,6 @@ static inline int Gia_ManAppendAnd( Gia_Man_t * p, int iLit0, int iLit1 ) } return Gia_ObjId( p, pObj ) << 1; } -static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 ) -{ - if ( !p->fGiaSimple ) - { - if ( iLit0 < 2 ) - return iLit0 ? iLit1 : 0; - if ( iLit1 < 2 ) - return iLit1 ? iLit0 : 0; - if ( iLit0 == iLit1 ) - return iLit1; - if ( iLit0 == Abc_LitNot(iLit1) ) - return 0; - } - return Gia_ManAppendAnd( p, iLit0, iLit1 ); -} static inline int Gia_ManAppendXorReal( Gia_Man_t * p, int iLit0, int iLit1 ) { Gia_Obj_t * pObj = Gia_ManAppendObj( p ); @@ -780,6 +765,44 @@ static inline int Gia_ManAppendXor( Gia_Man_t * p, int iLit0, int iLit1 ) { return Gia_ManAppendMux( p, iLit0, Abc_LitNot(iLit1), iLit1 ); } + +static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + if ( !p->fGiaSimple ) + { + if ( iLit0 < 2 ) + return iLit0 ? iLit1 : 0; + if ( iLit1 < 2 ) + return iLit1 ? iLit0 : 0; + if ( iLit0 == iLit1 ) + return iLit1; + if ( iLit0 == Abc_LitNot(iLit1) ) + return 0; + } + return Gia_ManAppendAnd( p, iLit0, iLit1 ); +} +static inline int Gia_ManAppendOr2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + return Abc_LitNot(Gia_ManAppendAnd2( p, Abc_LitNot(iLit0), Abc_LitNot(iLit1) )); +} +static inline int Gia_ManAppendMux2( Gia_Man_t * p, int iCtrl, int iData1, int iData0 ) +{ + int iTemp0 = Gia_ManAppendAnd2( p, Abc_LitNot(iCtrl), iData0 ); + int iTemp1 = Gia_ManAppendAnd2( p, iCtrl, iData1 ); + return Abc_LitNotCond( Gia_ManAppendAnd2( p, Abc_LitNot(iTemp0), Abc_LitNot(iTemp1) ), 1 ); +} +static inline int Gia_ManAppendMaj2( Gia_Man_t * p, int iData0, int iData1, int iData2 ) +{ + int iTemp0 = Gia_ManAppendOr2( p, iData1, iData2 ); + int iTemp1 = Gia_ManAppendAnd2( p, iData0, iTemp0 ); + int iTemp2 = Gia_ManAppendAnd2( p, iData1, iData2 ); + return Gia_ManAppendOr2( p, iTemp1, iTemp2 ); +} +static inline int Gia_ManAppendXor2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + return Gia_ManAppendMux2( p, iLit0, Abc_LitNot(iLit1), iLit1 ); +} + static inline void Gia_ManPatchCoDriver( Gia_Man_t * p, int iCoIndex, int iLit0 ) { Gia_Obj_t * pObjCo = Gia_ManCo( p, iCoIndex ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f9717aa8f..fccd4f635 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KSWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCacvwh" ) ) != EOF ) { switch ( c ) { @@ -41036,6 +41036,28 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutNum < 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; + } + pPars->nCutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutSize < 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->nCutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutNum < 0 ) + goto usage; + break; case 'W': if ( globalUtilOptind >= argc ) { @@ -41118,10 +41140,12 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KSWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-acvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); + Abc_Print( -2, "\t-N : the cut size considered for optimization (2 <= num <= 10) [default = %d]\n", pPars->nCutSize ); + Abc_Print( -2, "\t-P : the number of cuts computed at a node (1 <= num <= 500) [default = %d]\n", pPars->nCutNum ); Abc_Print( -2, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels ); Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 683750398..8b0a76c3e 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -249,7 +249,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd ) iFan = Abc_LitNotCond( iFan, fCompl ); } else - iFan = Gia_ManAppendXor( pGia, iFan0, iFan1 ); + iFan = Gia_ManAppendXor2( pGia, iFan0, iFan1 ); } else { diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 6cdfafe48..6e0f6b3b0 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -40,6 +40,8 @@ struct Sbd_Par_t_ { int nLutSize; // target LUT size int nLutNum; // target LUT count + int nCutSize; // target cut size + int nCutNum; // target cut count int nTfoLevels; // the number of TFO levels (windowing) int nTfoFanMax; // the max number of fanouts (windowing) int nWinSizeMax; // maximum window size (windowing) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 0b399b8ab..a48e6489f 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -43,12 +43,14 @@ struct Sbd_Man_t_ Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary Vec_Int_t * vLits2; // temporary - int nLuts[3]; // 0=const, 1=1lut, 2=2lut + int nLuts[6]; // 0=const, 1=1lut, 2=2lut, 3=3lut + int nTried; + int nUsed; abctime timeWin; + abctime timeCut; + abctime timeCov; abctime timeCnf; abctime timeSat; - abctime timeCov; - abctime timeEnu; abctime timeQbf; abctime timeOther; abctime timeTotal; @@ -76,8 +78,6 @@ static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( static inline word * Sbd_ObjSim2( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[2], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim3( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[3], p->pPars->nWords * i ); } -extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -96,17 +96,19 @@ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) { memset( pPars, 0, sizeof(Sbd_Par_t) ); - pPars->nLutSize = 4; // target LUT size - pPars->nLutNum = 2; // target LUT count - pPars->nTfoLevels = 2; // the number of TFO levels (windowing) - pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) - pPars->nWinSizeMax = 0; // maximum window size (windowing) - pPars->nBTLimit = 0; // maximum number of SAT conflicts - pPars->nWords = 1; // simulation word count - pPars->fArea = 0; // area-oriented optimization - pPars->fCover = 0; // use complete cover procedure - pPars->fVerbose = 0; // verbose flag - pPars->fVeryVerbose = 0; // verbose flag + pPars->nLutSize = 4; // target LUT size + pPars->nLutNum = 3; // target LUT count + pPars->nCutSize = (pPars->nLutSize - 1) * pPars->nLutNum + 1; // target cut size + pPars->nCutNum = 128; // target cut count + pPars->nTfoLevels = 5; // the number of TFO levels (windowing) + pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) + pPars->nWinSizeMax = 2000; // maximum window size (windowing) + pPars->nBTLimit = 0; // maximum number of SAT conflicts + pPars->nWords = 1; // simulation word count + pPars->fArea = 0; // area-oriented optimization + pPars->fCover = 0; // use complete cover procedure + pPars->fVerbose = 0; // verbose flag + pPars->fVeryVerbose = 0; // verbose flag } /**Function************************************************************* @@ -227,7 +229,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, 2*pPars->nLutSize-1, 64, 1, 1 ); + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 1, 1 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -437,6 +439,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ManIncrementTravId( p->pGia ); Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); + if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + return 0; Sbd_ManUpdateOrder( p, Pivot ); assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); @@ -461,6 +465,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vObj2Var, Abc_Lit2Var(Node), Vec_IntSize(p->vWinObjs) ); Vec_IntPush( p->vWinObjs, Abc_Lit2Var(Node) ); } + if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + return 0; // compute controlability for node if ( Vec_IntSize(p->vTfo) == 0 ) Abc_TtFill( Sbd_ObjSim2(p, Pivot), p->pPars->nWords ); @@ -473,7 +479,7 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) // propagate controlability to fanins for the TFI nodes starting from the pivot Sbd_ManPropagateControl( p, Pivot ); assert( Vec_IntSize(p->vDivValues) <= 64 ); - return (int)(Vec_IntSize(p->vDivValues) > 64); + return (int)(Vec_IntSize(p->vDivValues) <= 64); } /**Function************************************************************* @@ -489,10 +495,6 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) ***********************************************************************/ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) { - extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ); - int nMintCount = 1; Vec_Ptr_t * vSims; word * pSims = Sbd_ObjSim0( p, Pivot ); @@ -984,7 +986,7 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { int fVerbose = 0; - abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); + abctime clk; int nIters, nItersMax = 32; word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; @@ -1089,14 +1091,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { if ( p->pPars->fVerbose ) printf( "Cannot find a feasible cover.\n" ); - clkEnu += Abc_Clock() - clk; - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; + p->timeCov += Abc_Clock() - clk; return RetValue; } - clkEnu += Abc_Clock() - clk; + p->timeCov += Abc_Clock() - clk; if ( p->pPars->fVerbose ) printf( "Candidate support: " ), @@ -1104,7 +1102,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); @@ -1143,19 +1141,12 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) } //break; } - //printf( "Node %4d : Iter = %4d Start table = %4d Final table = %4d\n", Pivot, nIters, nRowsOld, nRows ); - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; return RetValue; } int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); - abctime clk, clkSat = 0, clkEnu = 0, clkAll; + abctime clk; word Onset[64] = {0}, Offset[64] = {0}, Cube; word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; @@ -1171,12 +1162,11 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; - clkAll = Abc_Clock(); assert( nConsts <= 8 ); clk = Abc_Clock(); RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( RetValue >= 0 ) { if ( p->pPars->fVeryVerbose ) @@ -1215,21 +1205,18 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { if ( p->pPars->fVeryVerbose ) printf( "Cannot find a feasible cover.\n" ); - clkEnu += Abc_Clock() - clk; - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; + p->timeCov += Abc_Clock() - clk; return 0; } - + p->timeCov += Abc_Clock() - clk; + if ( p->pPars->fVeryVerbose ) printf( "Candidate support: " ), Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); @@ -1271,65 +1258,42 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) break; } } - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; return RetValue; } -int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +int Sbd_ManExploreCut( Sbd_Man_t * p, int Pivot, int nLeaves, int * pLeaves, int * pnStrs, Sbd_Str_t * Strs, int * pFreeVar ) { - extern int Sbd_ProblemSolve( - Gia_Man_t * p, Vec_Int_t * vMirrors, - int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, - Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 - ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); - word Truth; - int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); - int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); - //int nDivs = Vec_IntSize( p->vDivVars ); int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); - int i, k, iObj, nIters, RetValue; + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodesBot1[SBD_DIV_MAX], pNodesBot2[SBD_DIV_MAX]; + int nNodesTop = 0, nNodesBot = 0, nNodesBot1 = 0, nNodesBot2 = 0, nNodesDiff = 0, nNodesDiff1 = 0, nNodesDiff2 = 0; + int i, k, iObj, nIters, RetValue = 0; - int nLeaves, pLeaves[SBD_DIV_MAX]; - - int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX];//, pNodeRefs[SBD_DIV_MAX]; - int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; - - //sat_solver_delete_p( &p->pSat ); - p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); - p->timeCnf += Abc_Clock() - clk; - - // extract one cut - nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); - if ( nLeaves == -1 ) - return 0; - - // solve the covering problem + // try to remove fanins for ( nIters = 0; nIters < nLeaves; nIters++ ) { + word Truth; // try to remove one variable from divisors Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) - if ( i != nIters && pLeaves[i] != -1 ) + if ( i != nLeaves-1-nIters && pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); assert( Vec_IntSize(p->vDivSet) < nLeaves ); // compute truth table clk = Abc_Clock(); - Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; if ( Truth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( Truth == SBD_SAT_SAT ) - continue; + { + int DelayDiff = Vec_IntEntry(p->vLutLevs, pLeaves[nLeaves-1-nIters]) - Delay; + if ( DelayDiff > -2 ) + return 0; + } else - pLeaves[nIters] = -1; + pLeaves[nLeaves-1-nIters] = -1; } Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) @@ -1338,13 +1302,14 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) //printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); if ( Vec_IntSize(p->vDivSet) <= p->pPars->nLutSize ) { + word Truth; *pnStrs = 1; // remap divisors Vec_IntForEachEntry( p->vDivSet, iObj, i ) Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); // compute truth table clk = Abc_Clock(); - Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); // create structure @@ -1360,7 +1325,7 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); // count number of nodes on each level - nNodesTop = 0, nNodesBot = 0; + nNodesTop = nNodesBot = nNodesBot1 = nNodesBot2 = 0; Vec_IntForEachEntry( p->vDivSet, iObj, i ) { int DelayDiff = Vec_IntEntry(p->vLutLevs, iObj) - Delay; @@ -1369,60 +1334,227 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) if ( DelayDiff == -2 ) pNodesTop[nNodesTop++] = i; else // if ( DelayDiff < -2 ) + { pNodesBot[nNodesBot++] = i; + if ( DelayDiff == -3 ) + pNodesBot1[nNodesBot1++] = i; + else // if ( DelayDiff < -3 ) + pNodesBot2[nNodesBot2++] = i; + } Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); - //pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); } + assert( nNodesBot == nNodesBot1 + nNodesBot2 ); if ( i < Vec_IntSize(p->vDivSet) ) return 0; if ( nNodesTop > p->pPars->nLutSize-1 ) return 0; - if ( nNodesBot > p->pPars->nLutSize ) + + // try 44 + if ( Vec_IntSize(p->vDivSet) <= 2*p->pPars->nLutSize-1 ) { - // move left-over to the top - while ( nNodesBot > p->pPars->nLutSize ) - pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot]; - assert( nNodesBot == p->pPars->nLutSize ); + int nMoved = 0; + if ( nNodesBot > p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot > p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot], nMoved++; + assert( nNodesBot == p->pPars->nLutSize ); + } + assert( nNodesBot <= p->pPars->nLutSize ); assert( nNodesTop <= p->pPars->nLutSize-1 ); - } - nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; - - // number of structures - *pnStrs = 2 + nNodesDiff; - Strs[0].fLut = 1; - Strs[0].nVarIns = p->pPars->nLutSize; - for ( i = 0; i < nNodesTop; i++ ) - Strs[0].VarIns[i] = pNodesTop[i]; - for ( ; i < p->pPars->nLutSize; i++ ) - Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; - Strs[0].Res = 0; + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; - Strs[1].fLut = 1; - Strs[1].nVarIns = nNodesBot; - for ( i = 0; i < nNodesBot; i++ ) - Strs[1].VarIns[i] = pNodesBot[i]; - Strs[1].Res = 0; - - for ( k = 0; k < nNodesDiff; k++ ) - { - Strs[2+k].fLut = 0; - Strs[2+k].nVarIns = nNodesBot; + Strs[1].fLut = 1; + Strs[1].nVarIns = nNodesBot; for ( i = 0; i < nNodesBot; i++ ) - Strs[2+k].VarIns[i] = pNodesBot[i]; - Strs[2+k].Res = 0; + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; + assert( nNodesDiff >= 0 && nNodesDiff <= 3 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[2+k].fLut = 0; + Strs[2+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[2+k].VarIns[i] = pNodesBot[i]; + Strs[2+k].Res = 0; + } + + *pnStrs = 2 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[2]++; + + while ( nMoved-- ) + pNodesBot[nNodesBot++] = pNodesTop[--nNodesTop]; } - clk = Abc_Clock(); - RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - p->vDivSet, *pnStrs, Strs ); - p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + return RetValue; + if ( p->pPars->nLutNum < 3 ) + return 0; + if ( Vec_IntSize(p->vDivSet) < 2*p->pPars->nLutSize-1 ) + return 0; - if ( RetValue ) - p->nLuts[2]++; + // try 444 -- LUT(LUT, LUT) + if ( nNodesTop <= p->pPars->nLutSize-2 ) + { + int nMoved = 0; + if ( nNodesBot > 2*p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot > 2*p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot], nMoved++; + assert( nNodesBot == 2*p->pPars->nLutSize ); + } + assert( nNodesBot > p->pPars->nLutSize ); + assert( nNodesBot <= 2*p->pPars->nLutSize ); + assert( nNodesTop <= p->pPars->nLutSize-2 ); + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; + + Strs[1].fLut = 1; + Strs[1].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < Strs[1].nVarIns; i++ ) + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + Strs[2].fLut = 1; + Strs[2].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < Strs[2].nVarIns; i++ ) + Strs[2].VarIns[i] = pNodesBot[nNodesBot-p->pPars->nLutSize+i]; + Strs[2].Res = 0; + + nNodesDiff = p->pPars->nLutSize-2 - nNodesTop; + assert( nNodesDiff >= 0 && nNodesDiff <= 2 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[3+k].fLut = 0; + Strs[3+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[3+k].VarIns[i] = pNodesBot[i]; + Strs[3+k].Res = 0; + } + + *pnStrs = 3 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[3]++; + + while ( nMoved-- ) + pNodesBot[nNodesBot++] = pNodesTop[--nNodesTop]; + } + if ( RetValue ) + return RetValue; + + // try 444 -- LUT(LUT(LUT)) + if ( nNodesBot1 + nNodesTop <= 2*p->pPars->nLutSize-2 ) + { + if ( nNodesBot2 > p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot2 > p->pPars->nLutSize ) + pNodesBot1[nNodesBot1++] = pNodesBot2[--nNodesBot2]; + assert( nNodesBot2 == p->pPars->nLutSize ); + } + if ( nNodesBot1 > p->pPars->nLutSize-1 ) // need to move bottom left-over to the top + { + while ( nNodesBot1 > p->pPars->nLutSize-1 ) + pNodesTop[nNodesTop++] = pNodesBot1[--nNodesBot1]; + assert( nNodesBot1 == p->pPars->nLutSize-1 ); + } + assert( nNodesBot2 <= p->pPars->nLutSize ); + assert( nNodesBot1 <= p->pPars->nLutSize-1 ); + assert( nNodesTop <= p->pPars->nLutSize-1 ); + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + Strs[0].VarIns[i++] = Vec_IntSize(p->vDivSet)+1; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+2 + i-nNodesTop; + Strs[0].Res = 0; + nNodesDiff1 = p->pPars->nLutSize-1 - nNodesTop; + + Strs[1].fLut = 1; + Strs[1].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesBot1; i++ ) + Strs[1].VarIns[i] = pNodesBot1[i]; + Strs[1].VarIns[i++] = Vec_IntSize(p->vDivSet)+2; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[1].VarIns[i] = Vec_IntSize(p->vDivSet)+2+nNodesDiff1 + i-nNodesBot1; + Strs[1].Res = 0; + nNodesDiff2 = p->pPars->nLutSize-1 - nNodesBot1; + + Strs[2].fLut = 1; + Strs[2].nVarIns = nNodesBot2; + for ( i = 0; i < Strs[2].nVarIns; i++ ) + Strs[2].VarIns[i] = pNodesBot2[i]; + Strs[2].Res = 0; + + nNodesDiff = nNodesDiff1 + nNodesDiff2; + assert( nNodesDiff >= 0 && nNodesDiff <= 3 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[3+k].fLut = 0; + Strs[3+k].nVarIns = nNodesBot2; + for ( i = 0; i < nNodesBot2; i++ ) + Strs[3+k].VarIns[i] = pNodesBot2[i]; + Strs[3+k].Res = 0; + if ( k >= nNodesDiff1 ) + continue; + Strs[3+k].nVarIns += nNodesBot1; + for ( i = 0; i < nNodesBot1; i++ ) + Strs[3+k].VarIns[nNodesBot2 + i] = pNodesBot1[i]; + } + + *pnStrs = 3 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[4]++; + } return RetValue; } +int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +{ + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int FreeVarStart = FreeVar; + int nSize, nLeaves, pLeaves[SBD_DIV_MAX]; + //sat_solver_delete_p( &p->pSat ); + abctime clk = Abc_Clock(); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + // extract one cut + for ( nSize = p->pPars->nLutSize + 1; nSize <= p->pPars->nCutSize; nSize++ ) + { + nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, nSize, pLeaves ); + if ( nLeaves == -1 ) + continue; + assert( nLeaves == nSize ); + if ( Sbd_ManExploreCut( p, Pivot, nLeaves, pLeaves, pnStrs, Strs, &FreeVar ) ) + return 1; + } + assert( FreeVar - FreeVarStart <= SBD_FVAR_MAX ); + return 0; +} /**Function************************************************************* @@ -1722,7 +1854,10 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // extend data-structure to accommodate new nodes assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + { + Vec_IntPush( p->vMirrors, -1 ); Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + } Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { @@ -1730,7 +1865,6 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); Vec_IntPush( p->vObj2Var, 0 ); - Vec_IntPush( p->vMirrors, -1 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); //Sbd_ManFindCut( p, i, p->vLits ); for ( k = 0; k < 4; k++ ) @@ -1820,22 +1954,16 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[4]; - int i, RetValue, nStrs = 0; - word Truth = 0; - - if ( !p->pSto ) - { - if ( Sbd_ManMergeCuts( p, Pivot ) ) - return; - } - -// if ( Pivot != 15 ) -// return; - - if ( Sbd_ManWindow( p, Pivot ) ) + Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; + int RetValue, nStrs = 0; + if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; - + if ( !Sbd_ManWindow( p, Pivot ) ) + return; + //if ( Vec_IntSize(p->vWinObjs) > 100 ) + // printf( "Obj %d : Win = %d TFO = %d. Roots = %d.\n", Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vTfo), Vec_IntSize(p->vRoots) ); + p->nTried++; + p->nUsed++; RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) { @@ -1844,6 +1972,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) } else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { + int i; Strs->fLut = 1; Strs->nVarIns = Vec_IntSize( p->vDivSet ); for ( i = 0; i < Strs->nVarIns; i++ ) @@ -1855,8 +1984,17 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + if ( !p->pPars->fVerbose ) + return; + if ( Vec_IntSize(p->vDivSet) <= 4 ) + printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); + else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) + printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + else + printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); } + else + p->nUsed--; } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { @@ -1875,6 +2013,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( pGia ); Tim_Man_t * pTimOld = (Tim_Man_t *)pGia->pManTime; pGia->pManTime = Tim_ManDup( pTimOld, 1 ); + //Tim_ManPrint( pGia->pManTime ); Tim_ManIncrementTravId( (Tim_Man_t *)pGia->pManTime ); Gia_ManForEachObjVec( vNodes, pGia, pObj, k ) { @@ -1883,9 +2022,11 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) break; if ( Gia_ObjIsAnd(pObj) ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 ) + if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) Sbd_NtkPerformOne( p, Pivot ); } else if ( Gia_ObjIsCi(pObj) ) @@ -1903,7 +2044,6 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Sbd_StoComputeCutsConst0( p->pSto, 0 ); else assert( 0 ); } - //Tim_ManPrint( pGia->pManTime ); Tim_ManStop( (Tim_Man_t *)pGia->pManTime ); pGia->pManTime = pTimOld; Vec_IntFree( vNodes ); @@ -1919,29 +2059,33 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); else if ( Gia_ObjIsAnd(pObj) ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 ) + if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) Sbd_NtkPerformOne( p, Pivot ); } //if ( nNodesOld != Gia_ManObjNum(pGia) ) // break; } } - printf( "Found %d constants, %d one-LUT and %d two-LUT replacements with delay %d. ", - p->nLuts[0], p->nLuts[1], p->nLuts[2], Sbd_ManDelay(p) ); + printf( "K = %d. S = %d. N = %d. P = %d. ", + p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); + printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", + p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); pNew = Sbd_ManDerive( pGia, p->vMirrors ); // print runtime statistics - p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu - p->timeQbf; - if ( p->pPars->fVerbose ) + p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; + //if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); + ABC_PRTP( "Cut", p->timeCut , p->timeTotal ); + ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); ABC_PRTP( "Cnf", p->timeCnf , p->timeTotal ); ABC_PRTP( "Sat", p->timeSat , p->timeTotal ); - ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); - ABC_PRTP( "Enu", p->timeEnu , p->timeTotal ); ABC_PRTP( "Qbf", p->timeQbf , p->timeTotal ); ABC_PRTP( "Oth", p->timeOther, p->timeTotal ); ABC_PRTP( "ALL", p->timeTotal, p->timeTotal ); diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 9c54c74ae..7bcf2189f 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -27,9 +27,9 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define SBD_MAX_CUTSIZE 8 -#define SBD_MAX_CUTNUM 1001 -#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) +#define SBD_MAX_CUTSIZE 10 +#define SBD_MAX_CUTNUM 501 +#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) #define SBD_CUT_NO_LEAF 0xF @@ -568,6 +568,7 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); int Delay = Vec_IntEntry(p->vDelays, iObj); + if ( pCut == NULL ) { printf( "No cut.\n" ); return; } printf( "%d {", pCut->nLeaves ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( " %*d", nDigits, pCut->pLeaves[i] ); @@ -724,45 +725,88 @@ int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) Sbd_StoMergeCuts( p, iObj ); return Vec_IntEntry( p->vDelays, iObj ); } +int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ) +{ + return Vec_IntEntry(p->vRefs, iObj); +} void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ) { Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); assert( iObj == Vec_IntSize(p->vRefs) ); assert( iMirror < iObj ); - Vec_IntPush( p->vRefs, iMirror > 0 ? Vec_IntEntry(p->vRefs, iMirror) : 0 ); + Vec_IntPush( p->vRefs, 0 ); +//printf( "Ref %d\n", iObj ); + if ( iMirror > 0 ) + { + Vec_IntWriteEntry( p->vRefs, iObj, Vec_IntEntry(p->vRefs, iMirror) ); + Vec_IntWriteEntry( p->vRefs, iMirror, 1 ); + } if ( Gia_ObjIsAnd(pObj) ) { - Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); - Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId1(pObj, iObj), 1 ); + int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + int Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + Vec_IntAddToEntry( p->vRefs, Fan0, 1 ); + Vec_IntAddToEntry( p->vRefs, Fan1, 1 ); } else if ( Gia_ObjIsCo(pObj) ) + { + int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + assert( Lit0m == -1 ); Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); + } } void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) { - Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + Gia_Obj_t * pObj; + int Lit0m, Lit1m, Fan0, Fan1; + return; + + pObj = Gia_ManObj(p->pGia, iObj); + if ( Vec_IntEntry(p->vRefs, iObj) == 0 ) + printf( "Ref count mismatch at node %d\n", iObj ); + assert( Vec_IntEntry(p->vRefs, iObj) > 0 ); Vec_IntAddToEntry( p->vRefs, iObj, -1 ); if ( Vec_IntEntry( p->vRefs, iObj ) > 0 ) return; if ( Gia_ObjIsCi(pObj) ) return; +//printf( "Deref %d\n", iObj ); assert( Gia_ObjIsAnd(pObj) ); - Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); - Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); + Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + if ( Fan0 ) Sbd_StoDerefObj( p, Fan0 ); + if ( Fan1 ) Sbd_StoDerefObj( p, Fan1 ); } -int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) +int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ) { + int fVerbose = 0; Sbd_Cut_t * pCutBest = NULL; int i; assert( p->Pivot == iObj ); + if ( fVerbose && iObj % 1000 == 0 ) + printf( "Node %6d : \n", iObj ); for ( i = 0; i < p->nCutsR; i++ ) + { + if ( fVerbose && iObj % 1000 == 0 ) + Sbd_CutPrint( p, iObj, p->ppCuts[i] ); + if ( nSize && (int)p->ppCuts[i]->nLeaves != nSize ) + continue; if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && - (int)p->ppCuts[i]->nSlowLeaves == 0 && + (int)p->ppCuts[i]->nSlowLeaves <= 1 && (int)p->ppCuts[i]->nTopLeaves <= p->nLutSize-1 && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) pCutBest = p->ppCuts[i]; + } + if ( fVerbose && iObj % 1000 == 0 ) + { + printf( "Best cut of size %d:\n", nSize ); + Sbd_CutPrint( p, iObj, pCutBest ); + } if ( pCutBest == NULL ) return -1; -//Sbd_CutPrint( p, iObj, pCutBest ); assert( pCutBest->nLeaves <= SBD_DIV_MAX ); for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) pLeaves[i] = pCutBest->pLeaves[i]; diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index d54285f8f..668c12315 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -52,9 +52,10 @@ ABC_NAMESPACE_HEADER_START #define SBD_SAT_UNDEC 0x1234567812345678 #define SBD_SAT_SAT 0x8765432187654321 -#define SBD_LUTS_MAX 2 -#define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 8 +#define SBD_LUTS_MAX 2 +#define SBD_SIZE_MAX 4 +#define SBD_DIV_MAX 10 +#define SBD_FVAR_MAX 100 //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -81,16 +82,28 @@ struct Sbd_Str_t_ //////////////////////////////////////////////////////////////////////// /*=== sbdCut.c ==========================================================*/ -extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); -extern void Sbd_StoFree( Sbd_Sto_t * p ); -extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); -extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); -extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); -extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); -extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); -extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); -extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ); - +extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); +extern void Sbd_StoFree( Sbd_Sto_t * p ); +extern int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); +extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); +/*=== sbdWin.c ==========================================================*/ +extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); +extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); +extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); +extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); +/*=== sbdQbf.c ==========================================================*/ +extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 + ); ABC_NAMESPACE_HEADER_END diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index e8aee7900..ffcb71f84 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -96,7 +96,6 @@ int Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, } } } -//printf( "Stop par = %d.\n", VarPar ); return 1; } void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index d5b7dd9d6..b62332d15 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -54,7 +54,6 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ) { Gia_Obj_t * pObj; - int nAddVars = 64; int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue; int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo); int PivotVar = Vec_IntEntry(vObj2Var, Pivot); @@ -67,7 +66,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi pSat = sat_solver_new(); else sat_solver_restart( pSat ); - sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + nAddVars ); + sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + SBD_FVAR_MAX ); // create constant 0 clause sat_solver_addclause( pSat, &iLit, &iLit + 1 ); // add clauses for all nodes @@ -139,7 +138,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi sat_solver_delete( pSat ); return NULL; } - assert( sat_solver_nvars(pSat) == nVars + nAddVars ); + assert( sat_solver_nvars(pSat) == nVars + SBD_FVAR_MAX ); } else if ( fQbf ) { From 8eb5d1896a82ef9d1d5e0f25bb6f23e29e9e2ada Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 21:46:25 +0700 Subject: [PATCH 14/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 10 ++++++++++ src/opt/sbd/sbdWin.c | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a48e6489f..251a4deb7 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -52,6 +52,7 @@ struct Sbd_Man_t_ abctime timeCnf; abctime timeSat; abctime timeQbf; + abctime timeNew; abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; @@ -440,7 +441,10 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + { + p->timeWin += Abc_Clock() - clk; return 0; + } Sbd_ManUpdateOrder( p, Pivot ); assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); @@ -466,7 +470,10 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Vec_IntPush( p->vWinObjs, Abc_Lit2Var(Node) ); } if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + { + p->timeWin += Abc_Clock() - clk; return 0; + } // compute controlability for node if ( Vec_IntSize(p->vTfo) == 0 ) Abc_TtFill( Sbd_ObjSim2(p, Pivot), p->pPars->nWords ); @@ -1855,13 +1862,16 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + assert( i == Vec_IntSize(p->vMirrors) ); Vec_IntPush( p->vMirrors, -1 ); Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); } Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); + p->timeCut += Abc_Clock() - clk; assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); Vec_IntPush( p->vObj2Var, 0 ); diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index b62332d15..069a4125e 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -360,6 +360,7 @@ void Sbd_ManSolverPrint( Vec_Int_t * vSop ) } Cube[pInds[Abc_Lit2Var(Entry)]] = '1' - (char)Abc_LitIsCompl(Entry); } + Supp = 0; } void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) { @@ -378,6 +379,7 @@ void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); //Sbd_ManSolverPrint( vSop ); printf( "SAT with %d vars and %d cubes.\n", nVars, Vec_IntCountEntry(vSop, -1) ); + Supp = 0; } Vec_IntFree( vTemp ); Vec_IntFree( vSop ); From 3f2899d6ea1a141f40d7fdfe4556bb349d53c250 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 22:00:26 +0700 Subject: [PATCH 15/61] Compiler warnings. --- src/base/main/mainReal.c | 4 ++-- src/map/scl/sclLiberty.c | 6 +++--- src/misc/util/utilTruth.h | 6 +++--- src/misc/vec/vecPtr.h | 2 +- src/opt/lpk/lpkCore.c | 6 +++--- src/opt/lpk/lpkCut.c | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/base/main/mainReal.c b/src/base/main/mainReal.c index ee43d38d0..31bfef754 100644 --- a/src/base/main/mainReal.c +++ b/src/base/main/mainReal.c @@ -196,7 +196,7 @@ int Abc_RealMain( int argc, char * argv[] ) case 't': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { - if ( !strcmp(globalUtilOptarg, "none") == 0 ) + if ( (!strcmp(globalUtilOptarg, "none")) == 0 ) { fInitRead = 1; sprintf( sReadCmd, "read_%s", globalUtilOptarg ); @@ -211,7 +211,7 @@ int Abc_RealMain( int argc, char * argv[] ) case 'T': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { - if (!strcmp(globalUtilOptarg, "none") == 0) + if ( (!strcmp(globalUtilOptarg, "none")) == 0) { fFinalWrite = 1; sprintf( sWriteCmd, "write_%s", globalUtilOptarg); diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 50e69d08b..5ecf76bbc 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -509,7 +509,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents ) { FILE * pFile = fopen( pFileName, "rb" ); char * pContents = ABC_ALLOC( char, nContents+1 ); - int RetValue; + int RetValue = 0; RetValue = fread( pContents, nContents, 1, pFile ); fclose( pFile ); pContents[nContents] = 0; @@ -518,7 +518,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents ) void Scl_LibertyStringDump( char * pFileName, Vec_Str_t * vStr ) { FILE * pFile = fopen( pFileName, "wb" ); - int RetValue; + int RetValue = 0; if ( pFile == NULL ) { printf( "Scl_LibertyStringDump(): The output file is unavailable.\n" ); @@ -583,7 +583,7 @@ Scl_Tree_t * Scl_LibertyParse( char * pFileName, int fVerbose ) return NULL; pPos = p->pContents; Scl_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents ); - if ( !Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 ) + if ( (!Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents )) == 0 ) { if ( p->pError ) printf( "%s", p->pError ); printf( "Parsing failed. " ); diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index b8a34da79..d77ed64d6 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -2612,7 +2612,7 @@ static inline int Abc_TtProcessBiDec( word * pTruth, int nVars, int nSuppLim ) static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLim ) { word This, That, pTemp[64]; - int Res, resThis, resThat, nThis, nThat; + int Res, resThis, resThat;//, nThis, nThat; int nWords = Abc_TtWordNum(nVars); Abc_TtCopy( pTemp, pTruth, nWords, 0 ); Res = Abc_TtProcessBiDec( pTemp, nVars, nSuppLim ); @@ -2634,8 +2634,8 @@ static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLi // Dau_DsdPrintFromTruth( pTemp, nVars ); - nThis = Abc_TtBitCount16(resThis); - nThat = Abc_TtBitCount16(resThat); + //nThis = Abc_TtBitCount16(resThis); + //nThat = Abc_TtBitCount16(resThat); printf( "Variable sets: " ); Abc_TtPrintVarSet( resThis, nVars ); diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h index 5b40665f6..015aa1be6 100644 --- a/src/misc/vec/vecPtr.h +++ b/src/misc/vec/vecPtr.h @@ -65,7 +65,7 @@ struct Vec_Ptr_t_ #define Vec_PtrForEachEntryTwo( Type1, vVec1, Type2, vVec2, pEntry1, pEntry2, i ) \ for ( i = 0; (i < Vec_PtrSize(vVec1)) && (((pEntry1) = (Type1)Vec_PtrEntry(vVec1, i)), 1) && (((pEntry2) = (Type2)Vec_PtrEntry(vVec2, i)), 1); i++ ) #define Vec_PtrForEachEntryDouble( Type1, Type2, vVec, Entry1, Entry2, i ) \ - for ( i = 0; (i+1 < Vec_IntSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 ) + for ( i = 0; (i+1 < Vec_PtrSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// diff --git a/src/opt/lpk/lpkCore.c b/src/opt/lpk/lpkCore.c index a9088d106..6595b3654 100644 --- a/src/opt/lpk/lpkCore.c +++ b/src/opt/lpk/lpkCore.c @@ -96,12 +96,12 @@ void Lpk_IfManStart( Lpk_Man_t * p ) int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode ) { Vec_Ptr_t * vNodes; - Abc_Obj_t * pTemp; + Abc_Obj_t * pTemp, * pTemp2; int i; vNodes = Vec_VecEntry( p->vVisited, iNode ); if ( Vec_PtrSize(vNodes) == 0 ) return 1; - Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pTemp, i ) + Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pTemp, pTemp2, i ) { // check if the node has changed pTemp = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pTemp ); @@ -110,7 +110,7 @@ int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode ) // check if the number of fanouts has changed // if ( Abc_ObjFanoutNum(pTemp) != (int)Vec_PtrEntry(vNodes, i+1) ) // return 1; - i++; +// i++; } return 0; } diff --git a/src/opt/lpk/lpkCut.c b/src/opt/lpk/lpkCut.c index 73711f2b6..208facf29 100644 --- a/src/opt/lpk/lpkCut.c +++ b/src/opt/lpk/lpkCut.c @@ -234,7 +234,7 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p ) { Lpk_Cut_t * pCut; Vec_Ptr_t * vNodes = Vec_VecEntry( p->vVisited, p->pObj->Id ); - Abc_Obj_t * pNode; + Abc_Obj_t * pNode, * pNode2; int i, k; // collect the nodes that impact the given node Vec_PtrClear( vNodes ); @@ -252,11 +252,11 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p ) } } // clear the marks - Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i ) + Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pNode, pNode2, i ) { pNode = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pNode ); pNode->fMarkC = 0; - i++; +// i++; } //printf( "%d ", Vec_PtrSize(vNodes) ); } From 290c70f73e023434bee208eb4d8161541096bebe Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 22:56:30 +0700 Subject: [PATCH 16/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 251a4deb7..a36b4bd20 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1883,7 +1883,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) } // make sure delay reduction is achieved iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); - assert( iNewLev < iCurLev ); + assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); From ab8db51f37581f247991c16f3ec11ef2674f1934 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 23:10:16 +0700 Subject: [PATCH 17/61] Updates to delay optimization project. --- src/opt/dau/dauGia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 8b0a76c3e..fa757e628 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -361,7 +361,7 @@ int Dau_DsdToGia_rec( Gia_Man_t * pGia, char * pStr, char ** p, int * pMatches, if ( pGia->pMuxes ) Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] ); else - Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] ); + Res = Gia_ManAppendMux2( pGia, Temp[0], Temp[1], Temp[2] ); } else { From 39f32259957884645450ba345426f7f030f14713 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 00:32:19 +0700 Subject: [PATCH 18/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a36b4bd20..a6ae8bbb7 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1851,7 +1851,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Vec_IntWriteEntry( p->vLits, Vec_IntSize(p->vLits)-nStrs+i, iLit ); } iLit = Vec_IntEntry( p->vLits, Vec_IntSize(p->vDivSet) ); - assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); + //assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); // remember this function assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); From 278c00242f7c3ca46858ece6682749cca06a5deb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 00:33:06 +0700 Subject: [PATCH 19/61] Compiler warnings. --- src/misc/zlib/inflate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/zlib/inflate.c b/src/misc/zlib/inflate.c index 449779a97..9fae70457 100644 --- a/src/misc/zlib/inflate.c +++ b/src/misc/zlib/inflate.c @@ -1445,7 +1445,7 @@ long ZEXPORT inflateMark(z_streamp strm) { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + if (strm == Z_NULL || strm->state == Z_NULL) return -(1L << 16); state = (struct inflate_state FAR *)strm->state; return ((long)(state->back) << 16) + (state->mode == COPY ? state->length : From 1fef441a0dfde7887c18d218749c0f8d2d75f5ee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 11:01:47 +0700 Subject: [PATCH 20/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a6ae8bbb7..fa4cbc82f 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -360,12 +360,14 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) if ( p->DivCutoff == -1 ) p->DivCutoff = 0; // verify +/* assert( Vec_IntSize(p->vDivVars) < 64 ); Vec_IntForEachEntryStart( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); +*/ //printf( "%d ", Vec_IntSize(p->vDivVars) ); // printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", // Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); From 4b20003e0cdec5d4d88ecf360c806e786272ab39 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 11:04:28 +0700 Subject: [PATCH 21/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index fa4cbc82f..f8af9a4a0 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -366,8 +366,8 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); - Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); */ + Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); //printf( "%d ", Vec_IntSize(p->vDivVars) ); // printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", // Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); From 385cb73d32de7e7d18da68fffe6fd089cb7930b2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 19:47:30 +0700 Subject: [PATCH 22/61] Updates to delay optimization project. --- abclib.dsp | 4 + src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCore.c | 29 ++- src/opt/sbd/sbdCut2.c | 432 ++++++++++++++++++++++++++++++++++++++++ src/opt/sbd/sbdInt.h | 7 + 5 files changed, 472 insertions(+), 1 deletion(-) create mode 100644 src/opt/sbd/sbdCut2.c diff --git a/abclib.dsp b/abclib.dsp index 1833f013b..6cc945749 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2763,6 +2763,10 @@ SOURCE=.\src\opt\sbd\sbdCut.c # End Source File # Begin Source File +SOURCE=.\src\opt\sbd\sbdCut2.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\sbd\sbdInt.h # End Source File # Begin Source File diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index 3bdc20b37..a9a6c3be4 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -2,6 +2,7 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ src/opt/sbd/sbdCut.c \ + src/opt/sbd/sbdCut2.c \ src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index f8af9a4a0..c9e92d730 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -56,6 +56,7 @@ struct Sbd_Man_t_ abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; + Sbd_Srv_t * pSrv; // target node int Pivot; // target node int DivCutoff; // the place where D-2 divisors begin @@ -230,7 +231,8 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 1, 1 ); + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, 1, 1 ); + p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -257,6 +259,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_WrdFree( p->vMatrix ); sat_solver_delete_p( &p->pSat ); Sbd_StoFree( p->pSto ); + Sbd_ManCutServerStop( p->pSrv ); ABC_FREE( p ); } @@ -1320,6 +1323,11 @@ int Sbd_ManExploreCut( Sbd_Man_t * p, int Pivot, int nLeaves, int * pLeaves, int clk = Abc_Clock(); Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; + if ( Truth == SBD_SAT_SAT ) + { + printf( "The cut at node %d is not topological.\n", p->Pivot ); + return 0; + } assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); // create structure Strs->fLut = 1; @@ -1552,6 +1560,17 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; // extract one cut + if ( p->pSrv ) + { + nLeaves = Sbd_ManCutServerFirst( p->pSrv, Pivot, pLeaves ); + if ( nLeaves == -1 ) + return 0; + assert( nLeaves <= p->pPars->nCutSize ); + if ( Sbd_ManExploreCut( p, Pivot, nLeaves, pLeaves, pnStrs, Strs, &FreeVar ) ) + return 1; + return 0; + } + // extract one cut for ( nSize = p->pPars->nLutSize + 1; nSize <= p->pPars->nCutSize; nSize++ ) { nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, nSize, pLeaves ); @@ -1679,6 +1698,7 @@ int Sbd_ManMergeCuts( Sbd_Man_t * p, int Node ) assert( iFan0 != iFan1 ); assert( Vec_IntEntry(p->vLutLevs, Node) == 0 ); Vec_IntWriteEntry( p->vLutLevs, Node, LevCur ); + //Vec_IntWriteEntry( p->vLevs, Node, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, iFan0), Vec_IntEntry(p->vLevs, iFan1)) ); assert( pCutRes[0] <= p->pPars->nLutSize ); memcpy( Sbd_ObjCut(p, Node), pCutRes, sizeof(int) * (pCutRes[0] + 1) ); //printf( "Setting node %d with delay %d.\n", Node, LevCur ); @@ -1742,6 +1762,7 @@ void Sbd_ManFindCut( Sbd_Man_t * p, int Node, Vec_Int_t * vCutLits ) // create cut assert( Vec_IntEntry(p->vLutLevs, Node) == 0 ); Vec_IntWriteEntry( p->vLutLevs, Node, LevelMax+1 ); + //Vec_IntWriteEntry( p->vLevs, Node, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Node)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Node))) ); memcpy( Sbd_ObjCut(p, Node), pCut, sizeof(int) * (pCut[0] + 1) ); } @@ -1803,11 +1824,13 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + //Vec_IntWriteEntry( p->vLevs, Pivot, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) ); return 0; } int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) { + Gia_Obj_t * pObj = NULL; int i, k, w, iLit, Node; int iObjLast = Gia_ManObjNum(p->pGia); int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); @@ -1871,11 +1894,13 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); p->timeCut += Abc_Clock() - clk; assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); + //Vec_IntPush( p->vLevs, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObjI, i)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObjI, i))) ); Vec_IntPush( p->vObj2Var, 0 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); //Sbd_ManFindCut( p, i, p->vLits ); @@ -1887,8 +1912,10 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node + pObj = Gia_ManObj( p->pGia, Pivot ); assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + //Vec_IntWriteEntry( p->vLevs, Pivot, Pivot ? 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) : 0 ); return 0; } diff --git a/src/opt/sbd/sbdCut2.c b/src/opt/sbd/sbdCut2.c new file mode 100644 index 000000000..9422e439b --- /dev/null +++ b/src/opt/sbd/sbdCut2.c @@ -0,0 +1,432 @@ +/**CFile**************************************************************** + + FileName [sbdCut2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdCut2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SBD_MAX_CUTSIZE 10 +#define SBD_MAX_CUTNUM 501 + +#define SBD_CUT_NO_LEAF 0xF + +typedef struct Sbd_Cut_t_ Sbd_Cut_t; +struct Sbd_Cut_t_ +{ + word Sign; // signature + int iFunc; // functionality + int Cost; // cut cost + int CostLev; // cut cost + unsigned nTreeLeaves : 9; // tree leaves + unsigned nSlowLeaves : 9; // slow leaves + unsigned nTopLeaves : 10; // top leaves + unsigned nLeaves : 4; // leaf count + int pLeaves[SBD_MAX_CUTSIZE]; // leaves +}; + +struct Sbd_Srv_t_ +{ + int nLutSize; + int nCutSize; + int nCutNum; + int fVerbose; + Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vMirrors; // mirrors for each node + Vec_Int_t * vLutLevs; // delays for each node + Vec_Int_t * vLevs; // levels for each node + Vec_Int_t * vRefs; // refs for each node + Sbd_Cut_t pCuts[SBD_MAX_CUTNUM]; // temporary cuts + Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers + abctime clkStart; // starting time + Vec_Int_t * vCut0; // current cut + Vec_Int_t * vCut; // current cut + Vec_Int_t * vCutTop; // current cut + Vec_Int_t * vCutBot; // current cut +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, + Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs, + int nLutSize, int nCutSize, int nCutNum, int fVerbose ) +{ + Sbd_Srv_t * p; + assert( nLutSize <= nCutSize ); + assert( nCutSize < SBD_CUT_NO_LEAF ); + assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Srv_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutSize = nCutSize; + p->nCutNum = nCutNum; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vMirrors = vMirrors; + p->vLutLevs = vLutLevs; + p->vLevs = vLevs; + p->vRefs = vRefs; + p->vCut0 = Vec_IntAlloc( 100 ); + p->vCut = Vec_IntAlloc( 100 ); + p->vCutTop = Vec_IntAlloc( 100 ); + p->vCutBot = Vec_IntAlloc( 100 ); + return p; +} +void Sbd_ManCutServerStop( Sbd_Srv_t * p ) +{ + Vec_IntFree( p->vCut0 ); + Vec_IntFree( p->vCut ); + Vec_IntFree( p->vCutTop ); + Vec_IntFree( p->vCutBot ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutIsTopo_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj ) +{ + Gia_Obj_t * pObj; + int Ret0, Ret1; + if ( Vec_IntEntry(vMirrors, iObj) >= 0 ) + iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj)); + if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 1; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Ret0 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Ret1 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + return Ret0 && Ret1; +} +int Sbd_ManCutIsTopo( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vCut, int iObj ) +{ + int i, Entry, RetValue; + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vCut, Entry, i ) + Gia_ObjSetTravIdCurrentId( p, Entry ); + RetValue = Sbd_ManCutIsTopo_rec( p, vMirrors, iObj ); + if ( RetValue == 0 ) + printf( "Cut of node %d is not tological\n", iObj ); + assert( RetValue ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_ManCutExpandOne( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, int iThis, int iObj ) +{ + int Lit0m, Lit1m, Fan0, Fan1, iPlace0, iPlace1; + int LutLev = Vec_IntEntry( vLutLevs, iObj ); + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + iPlace0 = Vec_IntFind( vCut, Fan0 ); + iPlace1 = Vec_IntFind( vCut, Fan1 ); + if ( iPlace0 == -1 && iPlace1 == -1 ) + return 0; + if ( Vec_IntEntry(vLutLevs, Fan0) > LutLev || Vec_IntEntry(vLutLevs, Fan1) > LutLev ) + return 0; + Vec_IntDrop( vCut, iThis ); + if ( iPlace0 == -1 && Fan0 ) + Vec_IntPushOrder( vCut, Fan0 ); + if ( iPlace1 == -1 && Fan1 ) + Vec_IntPushOrder( vCut, Fan1 ); + return 1; +} +void Vec_IntIsOrdered( Vec_Int_t * vCut ) +{ + int i, Prev, Entry; + Prev = Vec_IntEntry( vCut, 0 ); + Vec_IntForEachEntryStart( vCut, Entry, i, 1 ) + { + assert( Prev < Entry ); + Prev = Entry; + } +} +void Sbd_ManCutExpand( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut ) +{ + int i, Entry; + do + { + Vec_IntForEachEntry( vCut, Entry, i ) + if ( Sbd_ManCutExpandOne( p, vMirrors, vLutLevs, vCut, i, Entry ) ) + break; + } + while ( i < Vec_IntSize(vCut) ); +} +void Sbd_ManCutReload( Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, int LevStop, Vec_Int_t * vCut, Vec_Int_t * vCutTop, Vec_Int_t * vCutBot ) +{ + int i, Entry; + Vec_IntClear( vCutTop ); + Vec_IntClear( vCutBot ); + Vec_IntForEachEntry( vCut, Entry, i ) + { + assert( Entry ); + assert( Vec_IntEntry(vMirrors, Entry) == -1 ); + assert( Vec_IntEntry(vLutLevs, Entry) <= LevStop ); + if ( Vec_IntEntry(vLutLevs, Entry) == LevStop ) + Vec_IntPush( vCutTop, Entry ); + else + Vec_IntPush( vCutBot, Entry ); + } + Vec_IntIsOrdered( vCut ); +} +int Sbd_ManCutCollect_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, int LevStop, Vec_Int_t * vLutLevs, Vec_Int_t * vCut ) +{ + Gia_Obj_t * pObj; + int Ret0, Ret1; + if ( Vec_IntEntry(vMirrors, iObj) >= 0 ) + iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj)); + if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 1; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) || Vec_IntEntry(vLutLevs, iObj) <= LevStop ) + { + Vec_IntPush( vCut, iObj ); + return Vec_IntEntry(vLutLevs, iObj) <= LevStop; + } + assert( Gia_ObjIsAnd(pObj) ); + Ret0 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj), LevStop, vLutLevs, vCut ); + Ret1 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj), LevStop, vLutLevs, vCut ); + return Ret0 && Ret1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutReduceTop( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, Vec_Int_t * vCutTop, int nCutSize ) +{ + int i, Entry, Lit0m, Lit1m, Fan0, Fan1; + int LevStop = Vec_IntEntry(vLutLevs, iObj) - 2; + Vec_IntIsOrdered( vCut ); + Vec_IntForEachEntryReverse( vCutTop, Entry, i ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Entry ); + if ( Gia_ObjIsCi(pObj) ) + continue; + assert( Gia_ObjIsAnd(pObj) ); + assert( Vec_IntEntry(vLutLevs, Entry) == LevStop ); + Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, Entry) ); + Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, Entry) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, Entry); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, Entry); + if ( Vec_IntEntry(vLutLevs, Fan0) > LevStop || Vec_IntEntry(vLutLevs, Fan1) > LevStop ) + continue; + assert( Vec_IntEntry(vLutLevs, Fan0) <= LevStop ); + assert( Vec_IntEntry(vLutLevs, Fan1) <= LevStop ); + if ( Vec_IntEntry(vLutLevs, Fan0) == LevStop && Vec_IntEntry(vLutLevs, Fan1) == LevStop ) + continue; + Vec_IntRemove( vCut, Entry ); + if ( Fan0 ) Vec_IntPushUniqueOrder( vCut, Fan0 ); + if ( Fan1 ) Vec_IntPushUniqueOrder( vCut, Fan1 ); + //Sbd_ManCutIsTopo( p, vMirrors, vCut, iObj ); + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) +{ + int RetValue, LevStop = Vec_IntEntry(p->vLutLevs, iObj) - 2; + + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "1=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + +#if 0 + // recompute the cut + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +#endif + + // try to reduce the topmost + Vec_IntClear( p->vCut0 ); + Vec_IntAppend( p->vCut0, p->vCut ); + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "* %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "*** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + } + } + } + } + return -1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 668c12315..9b4898549 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -62,6 +62,7 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// typedef struct Sbd_Sto_t_ Sbd_Sto_t; +typedef struct Sbd_Srv_t_ Sbd_Srv_t; typedef struct Sbd_Str_t_ Sbd_Str_t; struct Sbd_Str_t_ @@ -92,6 +93,12 @@ extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, i extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); +/*=== sbdCut2.c ==========================================================*/ +extern Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, + Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs, + int nLutSize, int nCutSize, int nCutNum, int fVerbose ); +extern void Sbd_ManCutServerStop( Sbd_Srv_t * p ); +extern int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ); /*=== sbdWin.c ==========================================================*/ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); From 26eb3f3684e4478d6839d7d0a92ac67003c06b20 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 19:48:46 +0700 Subject: [PATCH 23/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index c9e92d730..7df97d3bf 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1894,7 +1894,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { - Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); + //Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); p->timeCut += Abc_Clock() - clk; From d948f7259a61a8eec0fdc94882b530e2d7f0ba12 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 20:48:21 +0700 Subject: [PATCH 24/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 ++ src/opt/sbd/sbdCut2.c | 59 +++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 7df97d3bf..ed3b620ed 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -2009,6 +2009,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } +/* else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { int i; @@ -2020,6 +2021,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Sbd_ManImplement2( p, Pivot, 1, Strs ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } +*/ else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); diff --git a/src/opt/sbd/sbdCut2.c b/src/opt/sbd/sbdCut2.c index 9422e439b..b4a8be74d 100644 --- a/src/opt/sbd/sbdCut2.c +++ b/src/opt/sbd/sbdCut2.c @@ -336,36 +336,6 @@ int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) return Vec_IntSize(p->vCut); } -#if 0 - // recompute the cut - Vec_IntClear( p->vCut ); - Gia_ManIncrementTravId( p->pGia ); - RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); - if ( RetValue == 0 ) // cannot build delay-improving cut - return -1; - // check if the current cut is good - Vec_IntSort( p->vCut, 0 ); -/* - Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); - if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) - { - //printf( "%d ", Vec_IntSize(p->vCut) ); - memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); - return Vec_IntSize(p->vCut); - } -*/ - // try to expand the cut - Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); - Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); - if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) - { - //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); - //printf( "%d ", Vec_IntSize(p->vCut) ); - memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); - return Vec_IntSize(p->vCut); - } -#endif - // try to reduce the topmost Vec_IntClear( p->vCut0 ); Vec_IntAppend( p->vCut0, p->vCut ); @@ -420,6 +390,35 @@ int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) } } } + + // recompute the cut + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + return -1; } From 6e1df46cd346ace1ed118da70c5b301915fcf453 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 20:49:36 +0700 Subject: [PATCH 25/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index ed3b620ed..988ad3dba 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1993,7 +1993,7 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; + Sbd_Str_t Strs[SBD_DIV_MAX]; //word Truth = 0; int RetValue, nStrs = 0; if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; From 74c8d35f330f80e6e489f6829288093e798fbfc2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 16:29:10 +0700 Subject: [PATCH 26/61] Updates to delay optimization project. --- abclib.dsp | 4 ++ src/base/abci/abc.c | 31 +++++----- src/opt/sbd/module.make | 1 + src/opt/sbd/sbd.h | 4 ++ src/opt/sbd/sbdCore.c | 113 +++++++++++++++++++++++++++++++----- src/opt/sbd/sbdCut.c | 22 ++++++- src/opt/sbd/sbdInt.h | 3 + src/opt/sbd/sbdPath.c | 124 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 272 insertions(+), 30 deletions(-) create mode 100644 src/opt/sbd/sbdPath.c diff --git a/abclib.dsp b/abclib.dsp index 6cc945749..4ec50a1f3 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -2775,6 +2775,10 @@ SOURCE=.\src\opt\sbd\sbdLut.c # End Source File # Begin Source File +SOURCE=.\src\opt\sbd\sbdPath.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\sbd\sbdSat.c # End Source File # Begin Source File diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fccd4f635..2be65ed0f 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCmcdpvwh" ) ) != EOF ) { switch ( c ) { @@ -41102,11 +41102,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBTLimit < 0 ) goto usage; break; - case 'a': - pPars->fArea ^= 1; + case 'm': + pPars->fMapping ^= 1; break; case 'c': - pPars->fCover ^= 1; + pPars->fMoreCuts ^= 1; + break; + case 'd': + pPars->fFindDivs ^= 1; + break; + case 'p': + pPars->fUsePath ^= 1; break; case 'v': pPars->fVerbose ^= 1; @@ -41122,25 +41128,22 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pGia == NULL ) { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): There is no AIG.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Mfsd(): There is no AIG.\n" ); return 0; } if ( Gia_ManBufNum(pAbc->pGia) ) { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): This command does not work with barrier buffers.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Mfsd(): This command does not work with barrier buffers.\n" ); return 1; } if ( Gia_ManHasMapping(pAbc->pGia) ) - { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has mapping (run &st to unmap).\n" ); - return 0; - } + Abc_Print( 1, "The current AIG has mapping, which can be used to determine critical path if \"-p\" is selected.\n" ); pTemp = Sbd_NtkPerform( pAbc->pGia, pPars ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-mcdpvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); @@ -41150,8 +41153,10 @@ usage: Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); Abc_Print( -2, "\t-C : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit ); - Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" ); - Abc_Print( -2, "\t-c : toggle using complete slow covering procedure [default = %s]\n", pPars->fCover? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "area": "area+edges" ); + Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index a9a6c3be4..fc176715d 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -4,5 +4,6 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCut.c \ src/opt/sbd/sbdCut2.c \ src/opt/sbd/sbdLut.c \ + src/opt/sbd/sbdPath.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 6e0f6b3b0..9c419b164 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -47,6 +47,10 @@ struct Sbd_Par_t_ int nWinSizeMax; // maximum window size (windowing) int nBTLimit; // maximum number of SAT conflicts int nWords; // simulation word count + int fMapping; // generate mapping + int fMoreCuts; // use several cuts + int fFindDivs; // perform divisor search + int fUsePath; // optimize only critical path int fArea; // area-oriented optimization int fCover; // use complete cover procedure int fVerbose; // verbose flag diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 988ad3dba..275d866fc 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -38,6 +38,7 @@ struct Sbd_Man_t_ Vec_Wec_t * vTfos; // TFO for each node (roots are marked) (windowing) Vec_Int_t * vLutLevs; // LUT level for each node after resynthesis Vec_Int_t * vLutCuts; // LUT cut for each nodes after resynthesis + Vec_Int_t * vLutCuts2; // LUT cut for each nodes after resynthesis Vec_Int_t * vMirrors; // alternative node Vec_Wrd_t * vSims[4]; // simulation information (main, backup, controlability) Vec_Int_t * vCover; // temporary @@ -73,7 +74,8 @@ struct Sbd_Man_t_ sat_solver * pSat; // SAT solver }; -static inline int * Sbd_ObjCut( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts, (p->pPars->nLutSize + 1) * i ); } +static inline int * Sbd_ObjCut( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts, (p->pPars->nLutSize + 1) * i ); } +static inline int * Sbd_ObjCut2( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts2, (p->pPars->nLutSize + 1) * i ); } static inline word * Sbd_ObjSim0( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[0], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[1], p->pPars->nWords * i ); } @@ -107,6 +109,10 @@ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) pPars->nWinSizeMax = 2000; // maximum window size (windowing) pPars->nBTLimit = 0; // maximum number of SAT conflicts pPars->nWords = 1; // simulation word count + pPars->fMapping = 1; // generate mapping + pPars->fMoreCuts = 0; // use several cuts + pPars->fFindDivs = 0; // perform divisor search + pPars->fUsePath = 0; // optimize only critical path pPars->fArea = 0; // area-oriented optimization pPars->fCover = 0; // use complete cover procedure pPars->fVerbose = 0; // verbose flag @@ -231,8 +237,13 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, 1, 1 ); - p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); + if ( pPars->fMoreCuts ) + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, !pPars->fMapping, 1 ); + else + { + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, !pPars->fMapping, 1 ); + p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); + } return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -258,8 +269,8 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vCounts[1] ); Vec_WrdFree( p->vMatrix ); sat_solver_delete_p( &p->pSat ); - Sbd_StoFree( p->pSto ); - Sbd_ManCutServerStop( p->pSrv ); + if ( p->pSto ) Sbd_StoFree( p->pSto ); + if ( p->pSrv ) Sbd_ManCutServerStop( p->pSrv ); ABC_FREE( p ); } @@ -1830,7 +1841,7 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) { - Gia_Obj_t * pObj = NULL; + //Gia_Obj_t * pObj = NULL; int i, k, w, iLit, Node; int iObjLast = Gia_ManObjNum(p->pGia); int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); @@ -1903,6 +1914,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) //Vec_IntPush( p->vLevs, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObjI, i)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObjI, i))) ); Vec_IntPush( p->vObj2Var, 0 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); + Sbd_StoSaveBestDelayCut( p->pSto, i, Sbd_ObjCut(p, i) ); //Sbd_ManFindCut( p, i, p->vLits ); for ( k = 0; k < 4; k++ ) for ( w = 0; w < p->pPars->nWords; w++ ) @@ -1912,7 +1924,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node - pObj = Gia_ManObj( p->pGia, Pivot ); + //pObj = Gia_ManObj( p->pGia, Pivot ); assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); //Vec_IntWriteEntry( p->vLevs, Pivot, Pivot ? 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) : 0 ); @@ -1930,6 +1942,70 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) SeeAlso [] ***********************************************************************/ +void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) +{ + Gia_Obj_t * pObj; int k, * pCut; + if ( Gia_ObjIsTravIdCurrentId(pNew, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(pNew, iObj); + pObj = Gia_ManObj( pNew, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + pCut = Sbd_ObjCut2( p, iObj ); + for ( k = 1; k <= pCut[0]; k++ ) + Sbd_ManDeriveMapping_rec( p, pNew, pCut[k] ); + // add mapping + Vec_IntWriteEntry( pNew->vMapping, iObj, Vec_IntSize(pNew->vMapping) ); + for ( k = 0; k <= pCut[0]; k++ ) + Vec_IntPush( pNew->vMapping, pCut[k] ); + Vec_IntPush( pNew->vMapping, iObj ); +} +void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) +{ + Gia_Obj_t * pObj, * pFan; + int i, k, iFan, iObjNew, * pCut, * pCutNew; + Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); + // derive cuts for the new manager + p->vLutCuts2 = Vec_IntStart( Gia_ManObjNum(pNew) * (p->pPars->nLutSize + 1) ); + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + if ( Vec_IntEntry(p->vMirrors, i) >= 0 ) + continue; + if ( pObj->Value == ~0 ) + continue; + iObjNew = Abc_Lit2Var( pObj->Value ); + if ( !Gia_ObjIsAnd(Gia_ManObj(pNew, iObjNew)) ) + continue; + pCutNew = Sbd_ObjCut2( p, iObjNew ); + pCut = Sbd_ObjCut( p, i ); + Vec_IntClear( vLeaves ); + for ( k = 1; k <= pCut[0]; k++ ) + { + iFan = Vec_IntEntry(p->vMirrors, pCut[k]) >= 0 ? Abc_Lit2Var(Vec_IntEntry(p->vMirrors, pCut[k])) : pCut[k]; + pFan = Gia_ManObj( p->pGia, iFan ); + if ( pFan->Value == ~0 ) + continue; + iObjNew = Abc_Lit2Var( pFan->Value ); + if ( iObjNew == 0 ) + continue; + Vec_IntPushUniqueOrder( vLeaves, iObjNew ); + } + assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); + assert( Vec_IntSize(vLeaves) > 1 ); + pCutNew[0] = Vec_IntSize(vLeaves); + memcpy( pCutNew+1, Vec_IntArray(vLeaves), sizeof(int) * Vec_IntSize(vLeaves) ); + } + Vec_IntFree( vLeaves ); + // create new mapping + Vec_IntFreeP( &pNew->vMapping ); + pNew->vMapping = Vec_IntAlloc( (p->pPars->nLutSize + 2) * Gia_ManObjNum(pNew) ); + Vec_IntFill( pNew->vMapping, Gia_ManObjNum(pNew), 0 ); + Gia_ManIncrementTravId( pNew ); + Gia_ManForEachCo( pNew, pObj, i ) + Sbd_ManDeriveMapping_rec( p, pNew, Gia_ObjFaninId0p(pNew, pObj) ); + Vec_IntFreeP( &p->vLutCuts2 ); +} void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors ) { Gia_Obj_t * pObj; @@ -1951,7 +2027,7 @@ void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * v if ( Obj != Node ) Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) ); } -Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) +Gia_Man_t * Sbd_ManDerive( Sbd_Man_t * pMan, Gia_Man_t * p, Vec_Int_t * vMirrors ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; @@ -1973,9 +2049,12 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Gia_ManTransferTiming( pNew, p ); + if ( pMan->pPars->fMapping ) + Sbd_ManDeriveMapping( pMan, pNew ); // remove dangling nodes pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManTransferTiming( pNew, pTemp ); + Gia_ManTransferMapping( pNew, pTemp ); Gia_ManStop( pTemp ); return pNew; } @@ -1993,7 +2072,7 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[SBD_DIV_MAX]; //word Truth = 0; + Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; int RetValue, nStrs = 0; if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; @@ -2009,8 +2088,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } -/* - else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) + else if ( p->pPars->fFindDivs && p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { int i; Strs->fLut = 1; @@ -2021,7 +2099,6 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Sbd_ManImplement2( p, Pivot, 1, Strs ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } -*/ else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); @@ -2041,6 +2118,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; + Vec_Bit_t * vPath; Sbd_Man_t * p = Sbd_ManStart( pGia, pPars ); int nNodesOld = Gia_ManObjNum(pGia); int k, Pivot; @@ -2049,6 +2127,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Gia_ManForEachObj( p->pGia, pObj, Pivot ) Sbd_StoRefObj( p->pSto, Pivot, -1 ); //return NULL; + vPath = (pPars->fUsePath && Gia_ManHasMapping(pGia)) ? Sbc_ManCriticalPath(pGia) : NULL; if ( pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)pGia->pManTime) ) { Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( pGia ); @@ -2065,9 +2144,10 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Sbd_StoSaveBestDelayCut( p->pSto, Pivot, Sbd_ObjCut(p, Pivot) ); p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) + if ( Delay > 1 && (!vPath || Vec_BitEntry(vPath, Pivot)) ) Sbd_NtkPerformOne( p, Pivot ); } else if ( Gia_ObjIsCi(pObj) ) @@ -2102,22 +2182,25 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Sbd_StoSaveBestDelayCut( p->pSto, Pivot, Sbd_ObjCut(p, Pivot) ); p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) + if ( Delay > 1 && (!vPath || Vec_BitEntry(vPath, Pivot)) ) Sbd_NtkPerformOne( p, Pivot ); } //if ( nNodesOld != Gia_ManObjNum(pGia) ) // break; } } + Vec_BitFreeP( &vPath ); printf( "K = %d. S = %d. N = %d. P = %d. ", p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); - pNew = Sbd_ManDerive( pGia, p->vMirrors ); + //Sbd_ManDeriveMapping2( p ); + pNew = Sbd_ManDerive( p, pGia, p->vMirrors ); // print runtime statistics p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; //if ( p->pPars->fVerbose ) diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 7bcf2189f..59505c98e 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -65,10 +65,11 @@ struct Sbd_Sto_t_ Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers int nCutsR; // the number of cuts int Pivot; // current object - double CutCount[4]; // cut counters + int iCutBest; // best-delay cut int nCutsSpec; // special cuts int nCutsOver; // overflow cuts int DelayMin; // minimum delay + double CutCount[4]; // cut counters abctime clkStart; // starting time }; @@ -540,6 +541,7 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC { int i, v, Delay, DelayMin = ABC_INFINITY; assert( nCuts > 0 ); + p->iCutBest = -1; for ( i = 0; i < nCuts; i++ ) { if ( (int)pCuts[i]->nLeaves > p->nLutSize ) @@ -547,8 +549,16 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC Delay = 0; for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vDelays, pCuts[i]->pLeaves[v]) ); - DelayMin = Abc_MinInt( DelayMin, Delay ); + //DelayMin = Abc_MinInt( DelayMin, Delay ); + if ( DelayMin > Delay ) + { + DelayMin = Delay; + p->iCutBest = i; + } + else if ( DelayMin == Delay && p->iCutBest >= 0 && pCuts[p->iCutBest]->nLeaves > pCuts[i]->nLeaves ) + p->iCutBest = i; } + assert( p->iCutBest >= 0 ); assert( DelayMin < ABC_INFINITY ); DelayMin = (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin; Vec_IntWriteEntry( p->vDelays, iObj, DelayMin ); @@ -725,6 +735,14 @@ int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) Sbd_StoMergeCuts( p, iObj ); return Vec_IntEntry( p->vDelays, iObj ); } +void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut ) +{ + Sbd_Cut_t * pCutBest = p->ppCuts[p->iCutBest]; int i; + assert( iObj == p->Pivot ); + pCut[0] = pCutBest->nLeaves; + for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) + pCut[i+1] = pCutBest->pLeaves[i]; +} int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ) { return Vec_IntEntry(p->vRefs, iObj); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 9b4898549..eabe5355f 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -92,6 +92,7 @@ extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut ); extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); /*=== sbdCut2.c ==========================================================*/ extern Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, @@ -104,6 +105,8 @@ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); +/*=== sbdPath.c ==========================================================*/ +extern Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ); /*=== sbdQbf.c ==========================================================*/ extern int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c new file mode 100644 index 000000000..417cb4078 --- /dev/null +++ b/src/opt/sbd/sbdPath.c @@ -0,0 +1,124 @@ +/**CFile**************************************************************** + + FileName [sbdPath.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Critical path.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdPath.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) +{ + Gia_Obj_t * pObj; + int k, iFan, Value = 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return Vec_BitEntry(vPath, iObj); + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + Value |= Sbc_ManAddInternalToPath_rec( p, iFan, vPath ); + if ( Value ) + Vec_BitWriteEntry( vPath, iObj, 1 ); + return Value; +} +void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) +{ + int iObj; + Gia_ManForEachLut( p, iObj ) + { + if ( !Vec_BitEntry(vPath, iObj) ) + continue; + Gia_ManIncrementTravId( p ); + Sbc_ManAddInternalToPath_rec( p, iObj, vPath ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath ) +{ + Gia_Obj_t * pObj; int k, iFan; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Vec_BitWriteEntry( vPath, iObj, 1 ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + if ( pLevels[iFan] == LevelFan ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, LevelFan-1, vPath ); +} +Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) +{ + int * pLevels = NULL, k, iDriver; + int nLevels = p->pManTime ? Gia_ManLutLevelWithBoxes(p) : Gia_ManLutLevel(p, &pLevels); + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + if ( p->pManTime ) + pLevels = Vec_IntArray( p->vLevels ); + Gia_ManIncrementTravId( p ); + Gia_ManForEachCoDriverId( p, iDriver, k ) + if ( pLevels[iDriver] == nLevels && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); + if ( !p->pManTime ) + ABC_FREE( pLevels ); + Sbc_ManAddInternalToPath( p, vPath ); + return vPath; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + From daf310cd4a98a941df164fc1deca6803723389c8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 17:15:00 +0700 Subject: [PATCH 27/61] Updates to delay optimization project. --- src/opt/sbd/sbdPath.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 417cb4078..3a040e1ea 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -61,12 +61,14 @@ int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) } void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) { - int iObj; + int k, iFan, iObj; Gia_ManForEachLut( p, iObj ) { if ( !Vec_BitEntry(vPath, iObj) ) continue; Gia_ManIncrementTravId( p ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + Gia_ObjSetTravIdCurrentId(p, iFan); Sbc_ManAddInternalToPath_rec( p, iObj, vPath ); } } @@ -106,7 +108,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) pLevels = Vec_IntArray( p->vLevels ); Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) - if ( pLevels[iDriver] == nLevels && iDriver ) + if ( (pLevels[iDriver] == nLevels) && iDriver ) Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); if ( !p->pManTime ) ABC_FREE( pLevels ); From 8b898f85e6daae51e1fa4fdedeab84a23f6655bb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 17:18:08 +0700 Subject: [PATCH 28/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 275d866fc..63dc51abc 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1945,7 +1945,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) { Gia_Obj_t * pObj; int k, * pCut; - if ( Gia_ObjIsTravIdCurrentId(pNew, iObj) ) + if ( !iObj || Gia_ObjIsTravIdCurrentId(pNew, iObj) ) return; Gia_ObjSetTravIdCurrentId(pNew, iObj); pObj = Gia_ManObj( pNew, iObj ); From 9be69dca362453a9e2f631b81e3130180eb57a97 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 18:03:33 +0700 Subject: [PATCH 29/61] Updates to delay optimization project. --- src/aig/gia/giaIf.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 26f549d05..ac748f8c7 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -539,22 +539,14 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) { sprintf( FileNameOld, "%s", p->pName ); fprintf( pTable, "\n" ); - fprintf( pTable, "%s ", p->pName ); -// fprintf( pTable, "%d ", Gia_ManCiNum(p) ); -// fprintf( pTable, "%d ", Gia_ManCoNum(p) ); -// fprintf( pTable, "%d ", Gia_ManAndNum(p) ); -// fprintf( pTable, "%d ", Gia_ManPiNum(p) - Gia_ManBoxCiNum(p) - Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManPoNum(p) - Gia_ManBoxCoNum(p) - Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManClockDomainNum(p) ); - + fprintf( pTable, "%s ", p->pName ); fprintf( pTable, " " ); - fprintf( pTable, "%d ", p->MappedDelay ); - fprintf( pTable, "%d ", p->MappedArea ); - fprintf( pTable, "%d ", nFanins ); - fprintf( pTable, "%d ", LevelMax ); + fprintf( pTable, "%d ", Gia_ManAndNum(p) ); fprintf( pTable, "%d ", nLuts ); -// fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); + fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } else @@ -2014,7 +2006,7 @@ void Gia_ManMappingVerify( Gia_Man_t * p ) void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia ) { Gia_Obj_t * pObj; - int i, k, iFan; + int i, k, iFan, iPlace; if ( !Gia_ManHasMapping(pGia) ) return; Gia_ManMappingVerify( pGia ); @@ -2023,12 +2015,20 @@ void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia ) Vec_IntFill( p->vMapping, Gia_ManObjNum(p), 0 ); Gia_ManForEachLut( pGia, i ) { + if ( Gia_ObjValue(Gia_ManObj(pGia, i)) == ~0 ) // handle dangling LUT + continue; assert( !Abc_LitIsCompl(Gia_ObjValue(Gia_ManObj(pGia, i))) ); pObj = Gia_ManObj( p, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, i))) ); Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) ); + iPlace = Vec_IntSize( p->vMapping ); Vec_IntPush( p->vMapping, Gia_ObjLutSize(pGia, i) ); Gia_LutForEachFanin( pGia, i, iFan, k ) - Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) ); + { + if ( Gia_ObjValue(Gia_ManObj(pGia, iFan)) == ~0 ) // handle dangling LUT fanin + Vec_IntAddToEntry( p->vMapping, iPlace, -1 ); + else + Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) ); + } iFan = Abc_Lit2Var( Gia_ObjValue(Gia_ManObj(pGia, Abc_AbsInt(Gia_ObjLutMuxId(pGia, i)))) ); Vec_IntPush( p->vMapping, Gia_ObjLutIsMux(pGia, i) ? -iFan : iFan ); } From 51e3a7c2776e671738b5e6a679214df46fe205ee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 18:43:41 +0700 Subject: [PATCH 30/61] Updates to delay optimization project. --- src/opt/sbd/sbdPath.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 3a040e1ea..7392516dc 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "sbdInt.h" +#include "misc/tim/tim.h" ABC_NAMESPACE_IMPL_START @@ -92,12 +93,28 @@ void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelF Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); if ( Gia_ObjIsCi(pObj) ) + { + Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; + int iBox = pManTime ? Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) ) : -1; + if ( iBox >= 0 ) + { + int curCo = Tim_ManBoxInputFirst( pManTime, iBox ); + int nBoxInputs = Tim_ManBoxInputNum( pManTime, iBox ); + for ( k = 0; k < nBoxInputs; k++ ) + { + Gia_Obj_t * pCo = Gia_ManCo( p, curCo + k ); + int iDriver = Gia_ObjFaninId0p( p, pCo ); + if ( (pLevels[iDriver] >= LevelFan-1) && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + } + } return; + } assert( Gia_ObjIsAnd(pObj) ); Vec_BitWriteEntry( vPath, iObj, 1 ); Gia_LutForEachFanin( p, iObj, iFan, k ) - if ( pLevels[iFan] == LevelFan ) - Sbc_ManCriticalPath_rec( p, pLevels, iFan, LevelFan-1, vPath ); + if ( pLevels[iFan] >= LevelFan-1 ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath ); } Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) { @@ -109,7 +126,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) if ( (pLevels[iDriver] == nLevels) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); if ( !p->pManTime ) ABC_FREE( pLevels ); Sbc_ManAddInternalToPath( p, vPath ); From 378bb416462a0ce10ecb1964d8d9b424e762d7b5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 19:18:55 +0700 Subject: [PATCH 31/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- src/opt/sbd/sbdPath.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 63dc51abc..8b1de4aae 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1992,7 +1992,7 @@ void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) Vec_IntPushUniqueOrder( vLeaves, iObjNew ); } assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); - assert( Vec_IntSize(vLeaves) > 1 ); + //assert( Vec_IntSize(vLeaves) > 1 ); pCutNew[0] = Vec_IntSize(vLeaves); memcpy( pCutNew+1, Vec_IntArray(vLeaves), sizeof(int) * Vec_IntSize(vLeaves) ); } diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 7392516dc..a2b1a9b00 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -52,7 +52,7 @@ int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); if ( Gia_ObjIsCi(pObj) ) - return 0; + return Vec_BitEntry(vPath, iObj); assert( Gia_ObjIsAnd(pObj) ); Gia_LutForEachFanin( p, iObj, iFan, k ) Value |= Sbc_ManAddInternalToPath_rec( p, iFan, vPath ); @@ -85,13 +85,14 @@ void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) SeeAlso [] ***********************************************************************/ -void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath ) +void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath, int Slack ) { Gia_Obj_t * pObj; int k, iFan; if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) return; Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); + Vec_BitWriteEntry( vPath, iObj, 1 ); if ( Gia_ObjIsCi(pObj) ) { Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; @@ -104,21 +105,20 @@ void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelF { Gia_Obj_t * pCo = Gia_ManCo( p, curCo + k ); int iDriver = Gia_ObjFaninId0p( p, pCo ); - if ( (pLevels[iDriver] >= LevelFan-1) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + if ( (pLevels[iDriver]+Slack >= LevelFan-1) && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Abc_MaxInt(0, pLevels[iDriver]+Slack-(LevelFan-1)) ); } } return; } assert( Gia_ObjIsAnd(pObj) ); - Vec_BitWriteEntry( vPath, iObj, 1 ); Gia_LutForEachFanin( p, iObj, iFan, k ) - if ( pLevels[iFan] >= LevelFan-1 ) - Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath ); + if ( pLevels[iFan]+Slack >= LevelFan-1 ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath, Abc_MaxInt(0, pLevels[iFan]+Slack-(LevelFan-1)) ); } Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) { - int * pLevels = NULL, k, iDriver; + int * pLevels = NULL, k, iDriver, Slack = 1; int nLevels = p->pManTime ? Gia_ManLutLevelWithBoxes(p) : Gia_ManLutLevel(p, &pLevels); Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); if ( p->pManTime ) @@ -126,7 +126,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) if ( (pLevels[iDriver] == nLevels) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Slack ); if ( !p->pManTime ) ABC_FREE( pLevels ); Sbc_ManAddInternalToPath( p, vPath ); From 58622ed032570bc7437762ff55058281677f5ee1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 5 Jan 2017 12:53:15 +0700 Subject: [PATCH 32/61] Adding two external APIs. --- src/aig/miniaig/abcapis.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/aig/miniaig/abcapis.h b/src/aig/miniaig/abcapis.h index f412f5aef..eb8586fef 100644 --- a/src/aig/miniaig/abcapis.h +++ b/src/aig/miniaig/abcapis.h @@ -52,6 +52,8 @@ extern int Cmd_CommandExecute( void * pAbc, char * pCommandLine ); // procedures to input/output 'mini AIG' extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig ); extern void * Abc_NtkOutputMiniAig( void * pAbc ); +extern void Abc_FrameGiaInputMiniAig( void * pAbc, void * p ); +extern void * Abc_FrameGiaOutputMiniAig( void * pAbc ); extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops ); // procedures to input/output 'mini LUT' From e9a7ad68c4c2f2b95695875996e713f7ae708912 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 5 Jan 2017 13:23:27 +0700 Subject: [PATCH 33/61] Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 8b1de4aae..179977fba 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -2086,7 +2086,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) if ( RetValue >= 0 ) { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); + //if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } else if ( p->pPars->fFindDivs && p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { @@ -2097,19 +2097,19 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Strs->VarIns[i] = i; Strs->Res = Truth; Sbd_ManImplement2( p, Pivot, 1, Strs ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); + //if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); if ( !p->pPars->fVerbose ) return; - if ( Vec_IntSize(p->vDivSet) <= 4 ) - printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); - else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) - printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); - else - printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); + //if ( Vec_IntSize(p->vDivSet) <= 4 ) + // printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); + //else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) + // printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + //else + // printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); } else p->nUsed--; @@ -2193,17 +2193,19 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) } } Vec_BitFreeP( &vPath ); - printf( "K = %d. S = %d. N = %d. P = %d. ", - p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); - printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", - p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; - Abc_PrintTime( 1, "Time", p->timeTotal ); - //Sbd_ManDeriveMapping2( p ); + if ( p->pPars->fVerbose ) + { + printf( "K = %d. S = %d. N = %d. P = %d. ", + p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); + printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", + p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); + Abc_PrintTime( 1, "Time", p->timeTotal ); + } pNew = Sbd_ManDerive( p, pGia, p->vMirrors ); // print runtime statistics p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; - //if ( p->pPars->fVerbose ) + if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); ABC_PRTP( "Cut", p->timeCut , p->timeTotal ); From a2fcd0710d22d79ef238e1cb9ef328ce94fa5000 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 6 Jan 2017 11:52:00 +0700 Subject: [PATCH 34/61] Creating file name from design name for PDR invariant. --- src/proof/pdr/pdrCore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index c020c56af..66cae36e8 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -922,10 +922,11 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) } if ( p->pPars->fDumpInv ) { + char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); Abc_FrameSetStr( Pdr_ManDumpString(p) ); Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) ); - Pdr_ManDumpClauses( p, (char *)"inv.pla", RetValue==1 ); + Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); } p->tTotal += Abc_Clock() - clk; Pdr_ManStop( p ); From 5c9983d089c9cac4eb71bb5ce38838cd47b29d62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 6 Jan 2017 12:47:57 +0700 Subject: [PATCH 35/61] Dealing wit COs driven by inverters in MiniLUT. --- src/aig/gia/giaMini.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index a886311f1..4ee92cdda 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -21,6 +21,7 @@ #include "gia.h" #include "opt/dau/dau.h" #include "base/main/main.h" +#include "misc/util/utilTruth.h" #include "aig/miniaig/miniaig.h" #include "aig/miniaig/minilut.h" @@ -245,6 +246,34 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p ) return pGia; } +/**Function************************************************************* + + Synopsis [Marks LUTs that should be complemented.] + + Description [These are LUTs whose all PO fanouts require them + in negative polarity. Other fanouts may require them in + positive polarity.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Gia_ManFindComplLuts( Gia_Man_t * pGia ) +{ + Gia_Obj_t * pObj; int i; + // mark objects pointed by COs in negative polarity + Vec_Bit_t * vMarks = Vec_BitStart( Gia_ManObjNum(pGia) ); + Gia_ManForEachCo( pGia, pObj, i ) + if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Gia_ObjFaninC0(pObj) ) + Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 1 ); + // unmark objects pointed by COs in positive polarity + Gia_ManForEachCo( pGia, pObj, i ) + if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) ) + Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 0 ); + return vMarks; +} + /**Function************************************************************* Synopsis [Converts GIA into MiniLUT.] @@ -260,8 +289,9 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) { Mini_Lut_t * p; Vec_Wrd_t * vTruths; + Vec_Bit_t * vMarks; Gia_Obj_t * pObj, * pFanin; - int i, k, LutSize, pVars[16]; + int i, k, iFanin, LutSize, pVars[16]; word Truth; assert( Gia_ManHasMapping(pGia) ); LutSize = Gia_ManLutSizeMax( pGia ); @@ -274,12 +304,17 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) pObj->Value = Mini_LutCreatePi(p); // create internal nodes vTruths = Vec_WrdStart( Gia_ManObjNum(pGia) ); + vMarks = Gia_ManFindComplLuts( pGia ); Gia_ManForEachLut( pGia, i ) { pObj = Gia_ManObj( pGia, i ); Gia_LutForEachFaninObj( pGia, i, pFanin, k ) pVars[k] = pFanin->Value; Truth = Gia_LutComputeTruth6( pGia, i, vTruths ); + Truth = Vec_BitEntry(vMarks, i) ? ~Truth : Truth; + Gia_LutForEachFanin( pGia, i, iFanin, k ) + if ( Vec_BitEntry(vMarks, iFanin) ) + Truth = Abc_Tt6Flip( Truth, k ); pObj->Value = Mini_LutCreateNode( p, Gia_ObjLutSize(pGia, i), pVars, (unsigned *)&Truth ); } Vec_WrdFree( vTruths ); @@ -288,7 +323,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) { if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(pGia) ) pObj->Value = Mini_LutCreatePo( p, Gia_ObjFaninC0(pObj) ); - else if ( !Gia_ObjFaninC0(pObj) ) + else if ( Gia_ObjFaninC0(pObj) == Vec_BitEntry(vMarks, Gia_ObjFaninId0p(pGia, pObj)) ) pObj->Value = Mini_LutCreatePo( p, Gia_ObjFanin0(pObj)->Value ); else // add inverter LUT { @@ -298,6 +333,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) pObj->Value = Mini_LutCreatePo( p, LutInv ); } } + Vec_BitFree( vMarks ); // set registers Mini_LutSetRegNum( p, Gia_ManRegNum(pGia) ); //Mini_LutPrintStats( p ); From 460167ec747aed778bfc13f2040dd8a205169fa2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 08:57:08 +0700 Subject: [PATCH 36/61] Compiler warnings. --- src/aig/gia/giaJf.c | 16 ++++++++-------- src/aig/gia/giaKf.c | 14 +++++++------- src/aig/gia/giaLf.c | 10 +++++----- src/aig/gia/giaMf.c | 8 ++++---- src/base/abci/abcExact.c | 2 +- src/map/if/ifDec16.c | 2 +- src/map/scl/sclLiberty.c | 8 ++++---- src/proof/acec/acecCo.c | 2 +- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/aig/gia/giaJf.c b/src/aig/gia/giaJf.c index 93dac301b..2d75581d0 100644 --- a/src/aig/gia/giaJf.c +++ b/src/aig/gia/giaJf.c @@ -1256,10 +1256,10 @@ void Jf_ManComputeCuts( Jf_Man_t * p, int fEdge ) } if ( p->pPars->fVerbose ) { - printf( "CutPair = %lu ", p->CutCount[0] ); - printf( "Merge = %lu ", p->CutCount[1] ); - printf( "Eval = %lu ", p->CutCount[2] ); - printf( "Cut = %lu ", p->CutCount[3] ); + printf( "CutPair = %lu ", (long)p->CutCount[0] ); + printf( "Merge = %lu ", (long)p->CutCount[1] ); + printf( "Eval = %lu ", (long)p->CutCount[2] ); + printf( "Cut = %lu ", (long)p->CutCount[3] ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); printf( "Memory: " ); printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) ); @@ -1702,11 +1702,11 @@ void Jf_ManPrintStats( Jf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); if ( p->pPars->fGenCnf ) - printf( "Cnf =%9lu ", p->pPars->Clause ); + printf( "Cnf =%9lu ", (long)p->pPars->Clause ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/aig/gia/giaKf.c b/src/aig/gia/giaKf.c index caa88bfcf..a823f7262 100644 --- a/src/aig/gia/giaKf.c +++ b/src/aig/gia/giaKf.c @@ -1125,9 +1125,9 @@ void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } @@ -1173,10 +1173,10 @@ void Kf_ManComputeMapping( Kf_Man_t * p ) Kf_ManComputeRefs( p ); if ( p->pPars->fVerbose ) { - printf( "CutPair = %lu ", p->pSett->CutCount[0] ); - printf( "Merge = %lu ", p->pSett->CutCount[1] ); - printf( "Eval = %lu ", p->pSett->CutCount[2] ); - printf( "Cut = %lu ", p->pSett->CutCount[3] ); + printf( "CutPair = %lu ", (long)p->pSett->CutCount[0] ); + printf( "Merge = %lu ", (long)p->pSett->CutCount[1] ); + printf( "Eval = %lu ", (long)p->pSett->CutCount[2] ); + printf( "Cut = %lu ", (long)p->pSett->CutCount[3] ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); printf( "Memory: " ); printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) ); diff --git a/src/aig/gia/giaLf.c b/src/aig/gia/giaLf.c index 082b19286..7973966a3 100644 --- a/src/aig/gia/giaLf.c +++ b/src/aig/gia/giaLf.c @@ -2012,14 +2012,14 @@ void Lf_ManPrintStats( Lf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); - printf( "LUT =%9lu ", p->pPars->Area+p->nInverters ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); + printf( "LUT =%9lu ", (long)p->pPars->Area+p->nInverters ); if ( Vec_FltSize(&p->vSwitches) ) printf( "Swt =%8.1f ", p->Switches ); if ( p->pPars->fUseMux7 ) - printf( "Mux7 =%7lu ", p->pPars->Mux7 ); + printf( "Mux7 =%7lu ", (long)p->pPars->Mux7 ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 591f5bc5e..2ded34bd0 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -1415,11 +1415,11 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); if ( p->pPars->fGenCnf ) - printf( "CNF =%9lu ", p->pPars->Clause ); + printf( "CNF =%9lu ", (long)p->pPars->Clause ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c index 757034cd0..adb64d791 100644 --- a/src/base/abci/abcExact.c +++ b/src/base/abci/abcExact.c @@ -873,7 +873,7 @@ static void Ses_StoreRead( Ses_Store_t * pStore, const char * pFilename, int fSy fclose( pFile ); - printf( "read %lu entries from file\n", nEntries ); + printf( "read %lu entries from file\n", (long)nEntries ); } // computes top decomposition of variables wrt. to AND and OR diff --git a/src/map/if/ifDec16.c b/src/map/if/ifDec16.c index 22de91baf..4b555bf86 100644 --- a/src/map/if/ifDec16.c +++ b/src/map/if/ifDec16.c @@ -902,7 +902,7 @@ void If_CluReverseOrder_old( word * pF, int nVars, int * V2P, int * P2V, int iVa // return the number of cofactors w.r.t. the topmost vars (nBSsize) int If_CluCountCofs( word * pF, int nVars, int nBSsize, int iShift, word pCofs[3][CLU_WRD_MAX/4] ) { - word iCofs[128], iCof, Result = 0; + word iCofs[128] = {0}, iCof, Result = 0; word * pCofA, * pCofB; int nMints = (1 << nBSsize); int i, c, w, nCofs; diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 5ecf76bbc..b48cfbe16 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -765,10 +765,10 @@ Vec_Str_t * Scl_LibertyParseGenlibStr( char * pFileName, int fVerbose ) ***********************************************************************/ //#define SCL_DEBUG #ifdef SCL_DEBUG -static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); } -static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", Val ); Vec_StrPutW( vOut, Val ); } -static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); } -static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); } +static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); } +static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", (long)Val ); Vec_StrPutW( vOut, Val ); } +static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); } +static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); } static inline void Vec_StrPut_( Vec_Str_t * vOut ) { printf( "\n" ); } #else static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { Vec_StrPutI( vOut, Val ); } diff --git a/src/proof/acec/acecCo.c b/src/proof/acec/acecCo.c index 1e8ed7bb6..a997eb034 100644 --- a/src/proof/acec/acecCo.c +++ b/src/proof/acec/acecCo.c @@ -109,7 +109,7 @@ Vec_Int_t * Gia_PolynCoreOrder_int( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Wec { Vec_Int_t * vOrder = Vec_IntAlloc( 1000 ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(pGia) ); - int i, k, Index, Driver, Entry1, Entry2 = -1; + int i, k, Index = -1, Driver, Entry1, Entry2 = -1; // mark roots Vec_IntForEachEntry( vRoots, Driver, i ) Vec_BitWriteEntry( vIsRoot, Driver, 1 ); From 3dd2325aa8572bbe0689a537101f138a0c7b8c87 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 09:51:38 +0700 Subject: [PATCH 37/61] Adding an option to not add buffers to decouple COs driven by the same internal node. --- src/base/abc/abcUtil.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index f01ef07ab..dd3a75b7c 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -1077,6 +1077,7 @@ void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate ) ***********************************************************************/ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate ) { + int fAddBuffers = 1; Vec_Ptr_t * vDrivers, * vCoTerms; Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin; int i, k, LevelMax, nTotal = 0; @@ -1191,6 +1192,12 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate ) // collect COs that needs fixing by adding buffers or duplicating vCoTerms = Vec_PtrAlloc( 100 ); Abc_NtkIncrementTravId( pNtk ); + + // The following cases should be addressed only if the network is written + // into a BLIF file. Otherwise, it is possible to skip them: + // (1) if a CO points to a CI with a different name + // (2) if an internal node drives more than one CO + if ( fAddBuffers ) Abc_NtkForEachCo( pNtk, pNode, i ) { // if the driver is a CI and has different name, this is an error From a2813847318bf22e0c36c7141047eaa82657f60d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 14:42:47 +0700 Subject: [PATCH 38/61] Bug fix in delay-opt framework. --- src/opt/sbd/sbdCore.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 179977fba..4f560a0a7 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1964,7 +1964,7 @@ void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) { Gia_Obj_t * pObj, * pFan; - int i, k, iFan, iObjNew, * pCut, * pCutNew; + int i, k, iFan, iObjNew, iFanNew, * pCut, * pCutNew; Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); // derive cuts for the new manager p->vLutCuts2 = Vec_IntStart( Gia_ManObjNum(pNew) * (p->pPars->nLutSize + 1) ); @@ -1986,10 +1986,10 @@ void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) pFan = Gia_ManObj( p->pGia, iFan ); if ( pFan->Value == ~0 ) continue; - iObjNew = Abc_Lit2Var( pFan->Value ); - if ( iObjNew == 0 ) + iFanNew = Abc_Lit2Var( pFan->Value ); + if ( iFanNew == 0 || iFanNew == iObjNew ) continue; - Vec_IntPushUniqueOrder( vLeaves, iObjNew ); + Vec_IntPushUniqueOrder( vLeaves, iFanNew ); } assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); //assert( Vec_IntSize(vLeaves) > 1 ); From 8ad3d6bec8ff89c8d742869cff05735d6f023fc8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 8 Jan 2017 03:10:42 +0700 Subject: [PATCH 39/61] Bug fixes by Clifford Wolf. --- src/map/if/ifLibLut.c | 4 ++++ src/opt/sbd/sbdCnf.c | 4 ++-- src/opt/sfm/sfmCnf.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/map/if/ifLibLut.c b/src/map/if/ifLibLut.c index 26fa137ba..1033cc1f3 100644 --- a/src/map/if/ifLibLut.c +++ b/src/map/if/ifLibLut.c @@ -75,6 +75,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) Abc_Print( 1, "Error in the LUT library file \"%s\".\n", FileName ); ABC_FREE( p->pName ); ABC_FREE( p ); + fclose( pFile ); return NULL; } @@ -93,6 +94,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) ABC_FREE( p->pName ); ABC_FREE( p ); Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i ); + fclose( pFile ); return NULL; } @@ -105,6 +107,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) ABC_FREE( p->pName ); ABC_FREE( p ); Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i ); + fclose( pFile ); return NULL; } i++; @@ -136,6 +139,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) } } + fclose( pFile ); return p; } diff --git a/src/opt/sbd/sbdCnf.c b/src/opt/sbd/sbdCnf.c index 6291baedc..8705858e6 100644 --- a/src/opt/sbd/sbdCnf.c +++ b/src/opt/sbd/sbdCnf.c @@ -44,7 +44,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ void Sbd_PrintCnf( Vec_Str_t * vCnf ) { - char Entry; + signed char Entry; int i, Lit; Vec_StrForEachEntry( vCnf, Entry, i ) { @@ -121,7 +121,7 @@ int Sbd_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf void Sbd_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar ) { Vec_Int_t * vClause; - char Entry; + signed char Entry; int i, Lit; Vec_WecClear( vRes ); vClause = Vec_WecPushLevel( vRes ); diff --git a/src/opt/sfm/sfmCnf.c b/src/opt/sfm/sfmCnf.c index 0ab92258b..b4dd11f89 100644 --- a/src/opt/sfm/sfmCnf.c +++ b/src/opt/sfm/sfmCnf.c @@ -45,7 +45,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ void Sfm_PrintCnf( Vec_Str_t * vCnf ) { - char Entry; + signed char Entry; int i, Lit; Vec_StrForEachEntry( vCnf, Entry, i ) { @@ -153,7 +153,7 @@ Vec_Wec_t * Sfm_CreateCnf( Sfm_Ntk_t * p ) void Sfm_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar ) { Vec_Int_t * vClause; - char Entry; + signed char Entry; int i, Lit; Vec_WecClear( vRes ); vClause = Vec_WecPushLevel( vRes ); From feb57982a999b6c6faf58b0e279d9b8949802962 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 10:46:29 +0700 Subject: [PATCH 40/61] Change suggested by Udi Finkelstein. --- src/base/cmd/cmd.c | 21 +-------------------- src/base/cmd/cmdLoad.c | 21 +-------------------- 2 files changed, 2 insertions(+), 40 deletions(-) diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index 0b7c17887..ab037139a 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -1147,26 +1147,7 @@ usage: #if defined(WIN32) && !defined(__cplusplus) #include - -// these structures are defined in but are for some reason invisible -typedef unsigned long _fsize_t; // Could be 64 bits for Win32 - -struct _finddata_t { - unsigned attrib; - time_t time_create; // -1 for FAT file systems - time_t time_access; // -1 for FAT file systems - time_t time_write; - _fsize_t size; - char name[260]; -}; - -extern long _findfirst( char *filespec, struct _finddata_t *fileinfo ); -extern int _findnext( long handle, struct _finddata_t *fileinfo ); -extern int _findclose( long handle ); - -//extern char * _getcwd( char * buffer, int maxlen ); -//extern int _chdir( const char *dirname ); - +#include /**Function************************************************************* diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c index 7f7c1b60d..accd9440f 100644 --- a/src/base/cmd/cmdLoad.c +++ b/src/base/cmd/cmdLoad.c @@ -97,26 +97,7 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv ) #if defined(WIN32) && !defined(__cplusplus) #include - - -// these structures are defined in but are for some reason invisible -typedef unsigned long _fsize_t; // Could be 64 bits for Win32 - -struct _finddata_t { - unsigned attrib; - time_t time_create; // -1 for FAT file systems - time_t time_access; // -1 for FAT file systems - time_t time_write; - _fsize_t size; - char name[260]; -}; - -extern long _findfirst( char *filespec, struct _finddata_t *fileinfo ); -extern int _findnext( long handle, struct _finddata_t *fileinfo ); -extern int _findclose( long handle ); - -//extern char * _getcwd( char * buffer, int maxlen ); -//extern int _chdir( const char *dirname ); +#include /**Function************************************************************* From 9514c327e3d8703775d138fe029b247adbf06099 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:04:48 +0700 Subject: [PATCH 41/61] Bug fix in delay-opt framework. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 2be65ed0f..a69737ead 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41153,7 +41153,7 @@ usage: Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); Abc_Print( -2, "\t-C : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit ); - Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "area": "area+edges" ); + Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" ); Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" ); Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" ); From 902377a45d9fe9ab7939f31d848b48f40a612480 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:16:28 +0700 Subject: [PATCH 42/61] Delay-oriented performance improvement in &dch. --- src/aig/gia/giaAig.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index 3cf01c70b..cbfe86a47 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -22,6 +22,7 @@ #include "proof/fra/fra.h" #include "proof/dch/dch.h" #include "opt/dar/dar.h" +#include "opt/dau/dau.h" ABC_NAMESPACE_IMPL_START @@ -576,11 +577,16 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) ***********************************************************************/ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) { - Gia_Man_t * pGia; + Gia_Man_t * pGia, * pGia1; Aig_Man_t * pNew; if ( p->pManTime && p->vLevels == NULL ) Gia_ManLevelWithBoxes( p ); - pNew = Gia_ManToAig( p, 0 ); + if ( Gia_ManHasMapping(p) ) + pGia1 = (Gia_Man_t *)Dsm_ManDeriveGia( p, 0 ); + else + pGia1 = Gia_ManDup( p ); + pNew = Gia_ManToAig( pGia1, 0 ); + Gia_ManStop( pGia1 ); pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars ); // pGia = Gia_ManFromAig( pNew ); pGia = Gia_ManFromAigChoices( pNew ); From ab6a87a4db2b2d9b188c09d9142b96503261e9ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:35:13 +0700 Subject: [PATCH 43/61] Delay-oriented performance improvement in &dch (make it conditional). --- src/aig/gia/giaAig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index cbfe86a47..dfd4a467b 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -577,11 +577,12 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) ***********************************************************************/ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) { + int fUseMapping = 0; Gia_Man_t * pGia, * pGia1; Aig_Man_t * pNew; if ( p->pManTime && p->vLevels == NULL ) Gia_ManLevelWithBoxes( p ); - if ( Gia_ManHasMapping(p) ) + if ( fUseMapping && Gia_ManHasMapping(p) ) pGia1 = (Gia_Man_t *)Dsm_ManDeriveGia( p, 0 ); else pGia1 = Gia_ManDup( p ); From fbdf28e4c937067737d84db37ff6e1a65348df5f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 19:50:05 +0700 Subject: [PATCH 44/61] Updated to arithmetic verification. --- src/aig/gia/giaDup.c | 16 +- src/base/abci/abc.c | 146 ++++++++++----- src/proof/acec/acec.h | 18 +- src/proof/acec/acecCore.c | 383 +++++++++++++++++++++++++++++++++++++- src/proof/acec/acecInt.h | 13 +- src/proof/acec/acecPa.c | 16 ++ 6 files changed, 527 insertions(+), 65 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index c58596b2f..cdb6a2085 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3879,12 +3879,20 @@ Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) int i, iObj, iObj2, fFlip, Count1 = 0; Vec_Int_t * vXors, * vPart[2], * vOrder; Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0); - assert( Gia_ManCoNum(p) == 1 ); vXors = Vec_IntAlloc( 100 ); - if ( Gia_ObjFaninC0(pObj) ) - Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors ); + if ( Gia_ManCoNum(p) == 1 ) + { + if ( Gia_ObjFaninC0(pObj) ) + Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors ); + else + Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); + } else - Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); + { + Gia_ManForEachCo( p, pObj, i ) + if ( Gia_ObjFaninId0p(p, pObj) > 0 ) + Vec_IntPush( vXors, Gia_ObjFaninId0p(p, pObj) ); + } // order by support size Gia_ManDupDemiterOrderXors( p, vXors ); //Vec_IntPrint( vXors ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index a69737ead..dd157afda 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40532,14 +40532,12 @@ usage: int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pFile; - Cec_ParCec_t ParsCec, * pPars = &ParsCec; - Gia_Man_t * pSecond; - char * FileName, * pTemp; + Acec_ParCec_t ParsCec, * pPars = &ParsCec; char ** pArgvNew; - int c, nArgcNew, fMiter = 0, fDualOutput = 0, fTwoOutput = 0; - Cec_ManCecSetDefaultParams( pPars ); + int c, nArgcNew; + Acec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdtvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtvh" ) ) != EOF ) { switch ( c ) { @@ -40565,17 +40563,14 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->TimeLimit < 0 ) goto usage; break; - case 'n': - pPars->fNaive ^= 1; - break; case 'm': - fMiter ^= 1; + pPars->fMiter ^= 1; break; case 'd': - fDualOutput ^= 1; + pPars->fDualOutput ^= 1; break; case 't': - fTwoOutput ^= 1; + pPars->fTwoOutput ^= 1; break; case 'v': pPars->fVerbose ^= 1; @@ -40586,15 +40581,20 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( fMiter ) + if ( pPars->fMiter ) { Gia_Man_t * pGia0, * pGia1, * pDual; + if ( argc != globalUtilOptind ) + { + Abc_Print( -1, "Abc_CommandAbc9Acec(): If the input is a miter, it cannot be given on the command line.\n" ); + return 1; + } if ( pAbc->pGia == NULL ) { Abc_Print( -1, "Abc_CommandAbc9Acec(): There is no AIG.\n" ); return 1; } - if ( fDualOutput ) + if ( pPars->fDualOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) { @@ -40604,28 +40604,28 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( !pPars->fSilent ) Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); Gia_ManDemiterDual( pAbc->pGia, &pGia0, &pGia1 ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } - else if ( fTwoOutput ) + else if ( pPars->fTwoOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) { - Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" ); + Abc_Print( -1, "The two-output miter should have an even number of outputs.\n" ); return 1; } if ( !pPars->fSilent ) Abc_Print( 1, "Assuming the current network is a two-word miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); Gia_ManDemiterTwoWords( pAbc->pGia, &pGia0, &pGia1 ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } - else + else // regular single- or multi-output miter { if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a regular single- or multi-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); pDual = Gia_ManDemiterToDual( pAbc->pGia ); Gia_ManDemiterDual( pDual, &pGia0, &pGia1 ); Gia_ManStop( pDual ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb ); Gia_ManStop( pGia0 ); @@ -40635,52 +40635,96 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 1 ) + if ( nArgcNew == 0 || nArgcNew == 1 ) { - if ( pAbc->pGia->pSpec == NULL ) + Gia_Man_t * pSecond; + char * pTemp, * FileName = NULL; + if ( nArgcNew == 0 ) { - Abc_Print( -1, "File name is not given on the command line.\n" ); - return 1; + FileName = pAbc->pGia->pSpec; + if ( FileName == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } } - FileName = pAbc->pGia->pSpec; + else // if ( nArgcNew == 1 ) + { + FileName = pArgvNew[0]; + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + } + pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pSecond == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + pAbc->Status = Acec_Solve( pAbc->pGia, pSecond, pPars ); + Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Gia_ManStop( pSecond ); + } + else if ( nArgcNew == 2 ) + { + Gia_Man_t * pGias[2] = {NULL}; int i; + char * pTemp, * FileName[2] = { pArgvNew[0], pArgvNew[1] }; + for ( i = 0; i < 2; i++ ) + { + // fix the wrong symbol + for ( pTemp = FileName[i]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName[i], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName[i] ); + if ( (FileName[i] = Extra_FileGetSimilarName( FileName[i], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName[i] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[i] = Gia_AigerRead( FileName[i], 0, 0, 0 ); + if ( pGias[i] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + } + pAbc->Status = Acec_Solve( pGias[0], pGias[1], pPars ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); } else - FileName = pArgvNew[0]; - // fix the wrong symbol - for ( pTemp = FileName; *pTemp; pTemp++ ) - if ( *pTemp == '>' ) - *pTemp = '\\'; - if ( (pFile = fopen( FileName, "r" )) == NULL ) { - Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); - if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", FileName ); - Abc_Print( 1, "\n" ); + Abc_Print( -1, "Too many command-line arguments.\n" ); return 1; } - fclose( pFile ); - pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); - if ( pSecond == NULL ) - { - Abc_Print( -1, "Reading AIGER has failed.\n" ); - return 0; - } - pAbc->Status = Gia_PolynCec( pAbc->pGia, pSecond, pPars ); - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); - Gia_ManStop( pSecond ); return 0; usage: - Abc_Print( -2, "usage: &acec [-CT num] [-nmdtvh]\n" ); + Abc_Print( -2, "usage: &acec [-CT num] [-mdtvh] \n" ); Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); - Abc_Print( -2, "\t-n : toggle using naive SAT-based checking [default = %s]\n", pPars->fNaive? "yes":"no"); - Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits"); - Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no"); - Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", fTwoOutput? "yes":"no"); + Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits"); + Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no"); + Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n"); + Abc_Print( -2, "\tfile2 : (optional) the file with the second network\n"); return 1; } diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index c61b4485a..058e0f56d 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -38,6 +38,21 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +// combinational equivalence checking parameters +typedef struct Acec_ParCec_t_ Acec_ParCec_t; +struct Acec_ParCec_t_ +{ + int nBTLimit; // conflict limit at a node + int TimeLimit; // the runtime limit in seconds + int fMiter; // input circuit is a miter + int fDualOutput; // dual-output miter + int fTwoOutput; // two-output miter + int fSilent; // print no messages + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats + int iOutFail; // the number of failed output +}; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -51,7 +66,8 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /*=== acecCore.c ========================================================*/ -extern int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars ); +extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ); +extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ); /*=== acecFadds.c ========================================================*/ extern Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose, Vec_Int_t ** vCutsXor2 ); extern Vec_Int_t * Gia_ManDetectHalfAdders( Gia_Man_t * p, int fVerbose ); diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index ac7ee67b1..09ccb5326 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "acecInt.h" +#include "proof/cec/cec.h" ABC_NAMESPACE_IMPL_START @@ -31,6 +32,31 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) +{ + memset( p, 0, sizeof(Acec_ParCec_t) ); + p->nBTLimit = 1000; // conflict limit at a node + p->TimeLimit = 0; // the runtime limit in seconds + p->fMiter = 0; // input circuit is a miter + p->fDualOutput = 0; // dual-output miter + p->fTwoOutput = 0; // two-output miter + p->fSilent = 0; // print no messages + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats + p->iOutFail = -1; // the number of failed output +} + /**Function************************************************************* Synopsis [] @@ -42,15 +68,356 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars ) +void Acec_BoxFree( Acec_Box_t * pBox ) { - Vec_Int_t * vOrder0 = Gia_PolynReorder( pGia0, pPars->fVerbose, pPars->fVeryVerbose ); - Vec_Int_t * vOrder1 = Gia_PolynReorder( pGia1, pPars->fVerbose, pPars->fVeryVerbose ); - Gia_PolynBuild( pGia0, vOrder0, 0, pPars->fVerbose, pPars->fVeryVerbose ); - Gia_PolynBuild( pGia1, vOrder1, 0, pPars->fVerbose, pPars->fVeryVerbose ); - Vec_IntFree( vOrder0 ); - Vec_IntFree( vOrder1 ); - return 1; + Vec_WecFree( pBox->vUnique ); + Vec_WecFree( pBox->vShared ); + Vec_WecFree( pBox->vLeafLits ); + Vec_WecFree( pBox->vRootLits ); + ABC_FREE( pBox ); +} +void Acec_BoxFreeP( Acec_Box_t ** ppBox ) +{ + if ( *ppBox ) + Acec_BoxFree( *ppBox ); + *ppBox = NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) +{ + int And, Or; + Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); + And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); + Or = Gia_ManAppendOr2( pNew, Out[1], And ); + Out[0] = Abc_LitNot( Or ); +} +void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) +{ + int In2[2], Out1[2], Out2[2]; + Acec_InsertHadd( pNew, In, Out1 ); + In2[0] = Out1[0]; + In2[1] = In[2]; + Acec_InsertHadd( pNew, In2, Out2 ); + Out[0] = Out2[0]; + Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); +} +Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) +{ + Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); + Vec_Int_t * vLevel; + int i, In[3], Out[2]; + Vec_WecForEachLevel( vLeafMap, vLevel, i ) + { + if ( Vec_IntSize(vLevel) == 0 ) + { + Vec_IntPush( vRootRanks, 0 ); + continue; + } + while ( Vec_IntSize(vLevel) > 1 ) + { + if ( Vec_IntSize(vLevel) == 2 ) + Vec_IntPush( vLevel, 0 ); + In[0] = Vec_IntPop( vLevel ); + In[1] = Vec_IntPop( vLevel ); + In[2] = Vec_IntPop( vLevel ); + Acec_InsertFadd( pNew, In, Out ); + Vec_IntPush( vLevel, Out[0] ); + if ( i-1 < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i+1); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, Out[1] ); + } + assert( Vec_IntSize(vLevel) == 1 ); + Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); + } + return vRootRanks; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( pAdd ); + Gia_ManConst0(pAdd)->Value = 0; + if ( pBase == NULL ) + { + pBase = Gia_ManStart( Gia_ManObjNum(pAdd) ); + pBase->pName = Abc_UtilStrsav( pAdd->pName ); + pBase->pSpec = Abc_UtilStrsav( pAdd->pSpec ); + Gia_ManForEachCi( pAdd, pObj, i ) + pObj->Value = Gia_ManAppendCi(pBase); + Gia_ManHashAlloc( pBase ); + } + else + { + assert( Gia_ManCiNum(pBase) == Gia_ManCiNum(pAdd) ); + Gia_ManForEachCi( pAdd, pObj, i ) + pObj->Value = Gia_Obj2Lit( pBase, Gia_ManCi(pBase, i) ); + } + Gia_ManForEachAnd( pAdd, pObj, i ) + pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + return pBase; +} +Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd ) +{ + Gia_Obj_t * pObj; int i; + Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) ); + Gia_ManForEachCand( pAdd, pObj, i ) + Vec_IntWriteEntry( vMapNew, i, Abc_Lit2Var(pObj->Value) ); + return vMapNew; +} +void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) +{ + Gia_Man_t * pBase; + pBase = Acec_FindEquivs( NULL, pOne ); + pBase = Acec_FindEquivs( pBase, pTwo ); + *pvMap1 = Acec_CountRemap( pOne ); + *pvMap2 = Acec_CountRemap( pTwo ); + Gia_ManStop( pBase ); +} +static inline void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCosts ) +{ + int i, j, best_i; + for ( i = 0; i < nSize-1; i++ ) + { + best_i = i; + for ( j = i+1; j < nSize; j++ ) + if ( pCosts[Abc_Lit2Var(pArray[j])] > pCosts[Abc_Lit2Var(pArray[best_i])] ) + best_i = j; + ABC_SWAP( int, pArray[i], pArray[best_i] ); + } +} +int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) +{ + Vec_Int_t * vMap0, * vMap1, * vLevel; + int i, nSize, nTotal; + Acec_ComputeEquivClasses( pBox0->pGia, pBox1->pGia, &vMap0, &vMap1 ); + // sort nodes in the classes by their equivalences + Vec_WecForEachLevel( pBox0->vLeafLits, vLevel, i ) + Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); + Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) + Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); + // reorder nodes to have the same order + assert( pBox0->vShared == NULL ); + assert( pBox1->vShared == NULL ); + pBox0->vShared = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) ); + pBox1->vShared = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) ); + pBox0->vUnique = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) ); + pBox1->vUnique = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) ); + nSize = Abc_MinInt( Vec_WecSize(pBox0->vLeafLits), Vec_WecSize(pBox1->vLeafLits) ); + Vec_WecForEachLevelStart( pBox0->vLeafLits, vLevel, i, nSize ) + Vec_IntAppend( Vec_WecEntry(pBox0->vUnique, i), vLevel ); + Vec_WecForEachLevelStart( pBox1->vLeafLits, vLevel, i, nSize ) + Vec_IntAppend( Vec_WecEntry(pBox1->vUnique, i), vLevel ); + for ( i = 0; i < nSize; i++ ) + { + Vec_Int_t * vShared0 = Vec_WecEntry( pBox0->vShared, i ); + Vec_Int_t * vShared1 = Vec_WecEntry( pBox1->vShared, i ); + Vec_Int_t * vUnique0 = Vec_WecEntry( pBox0->vUnique, i ); + Vec_Int_t * vUnique1 = Vec_WecEntry( pBox1->vUnique, i ); + + Vec_Int_t * vLevel0 = Vec_WecEntry( pBox0->vLeafLits, i ); + Vec_Int_t * vLevel1 = Vec_WecEntry( pBox1->vLeafLits, i ); + int * pBeg0 = Vec_IntArray(vLevel0); + int * pBeg1 = Vec_IntArray(vLevel1); + int * pEnd0 = Vec_IntLimit(vLevel0); + int * pEnd1 = Vec_IntLimit(vLevel1); + while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) + { + if ( *pBeg0 == *pBeg1 ) + { + Vec_IntPush( vShared0, *pBeg0++ ); + Vec_IntPush( vShared1, *pBeg1++ ); + } + else if ( *pBeg0 > *pBeg1 ) + Vec_IntPush( vUnique0, *pBeg0++ ); + else + Vec_IntPush( vUnique1, *pBeg1++ ); + } + while ( pBeg0 < pEnd0 ) + Vec_IntPush( vUnique0, *pBeg0++ ); + while ( pBeg1 < pEnd1 ) + Vec_IntPush( vUnique1, *pBeg1++ ); + assert( Vec_IntSize(vShared0) == Vec_IntSize(vShared1) ); + assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); + assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); + } + nTotal = Vec_WecSizeSize(pBox0->vShared); + printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); + printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + return nTotal; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); +} +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +{ + Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); + Vec_Int_t * vLevel, * vRootRanks; + int i, k, iLit, iLitNew; + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); + iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + Vec_WecPush( vLeafMap, i, iLitNew ); + } + // construct map of root literals + vRootRanks = Acec_InsertTree( pNew, vLeafMap ); + Vec_WecFree( vLeafMap ); + return vRootRanks; +} + +Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) +{ + Gia_Man_t * p = pBox->pGia; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vRootRanks, * vLevel; + int i, k, iLit, iLitNew; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + // implement tree + if ( fAll ) + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + else + { + Vec_Wec_t * vLeafLits; + assert( pBox->vShared != NULL ); + assert( pBox->vUnique != NULL ); + vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); + // add these roots to the unique ones + vLeafLits = Vec_WecDup( pBox->vUnique ); + Vec_IntForEachEntry( vRootRanks, iLit, i ) + { + if ( i < Vec_WecSize(vLeafLits) ) + vLevel = Vec_WecEntry(vLeafLits, i); + else + vLevel = Vec_WecPushLevel(vLeafLits); + Vec_IntPush( vLevel, iLit ); + } + Vec_IntFree( vRootRanks ); + vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); + Vec_WecFree( vLeafLits ); + } + // update polarity of literals + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, k ); + pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + } + Vec_IntFree( vRootRanks ); + // construct the outputs + Gia_ManForEachCo( p, pObj, i ) + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) +{ + int status = -1; + Gia_Man_t * pMiter; + Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; + Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0 ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1 ); + if ( pBox0 == NULL || pBox1 == NULL ) // cannot match + printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); + else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching + printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" ); + else + { + pGia0n = Acec_InsertBox( pBox0, 1 ); + pGia1n = Acec_InsertBox( pBox1, 1 ); + printf( "Found, matched, and normalized arithmetic boxes in LHS and RHS. Solving resulting CEC.\n" ); + } + // solve regular CEC problem + Cec_ManCecSetDefaultParams( pCecPars ); + pCecPars->nBTLimit = pPars->nBTLimit; + pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose ); + if ( pMiter ) + { + int fDumpMiter = 1; + if ( fDumpMiter ) + { + Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" ); + Gia_AigerWrite( pMiter, "acec_miter.aig", 0, 0 ); + } + status = Cec_ManVerify( pMiter, pCecPars ); + ABC_SWAP( Abc_Cex_t *, pGia0->pCexComb, pMiter->pCexComb ); + Gia_ManStop( pMiter ); + } + else + printf( "Miter computation has failed.\n" ); + if ( pGia0n != pGia0 ) + Gia_ManStop( pGia0n ); + if ( pGia1n != pGia1 ) + Gia_ManStop( pGia1n ); + Acec_BoxFreeP( &pBox0 ); + Acec_BoxFreeP( &pBox1 ); + return status; } //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index e761e56e0..d53b61c75 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////////////////// #include "aig/gia/gia.h" -#include "proof/cec/cec.h" #include "acec.h" //////////////////////////////////////////////////////////////////////// @@ -38,6 +37,16 @@ ABC_NAMESPACE_HEADER_START +typedef struct Acec_Box_t_ Acec_Box_t; +struct Acec_Box_t_ +{ + Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vLeafLits; // leaf literals by rank + Vec_Wec_t * vRootLits; // root literals by rank + Vec_Wec_t * vShared; // shared leaves + Vec_Wec_t * vUnique; // unique leaves +}; + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// @@ -54,6 +63,8 @@ ABC_NAMESPACE_HEADER_START /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== acecPa.c ========================================================*/ +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecPa.c b/src/proof/acec/acecPa.c index ecaf20472..b59cdbeff 100644 --- a/src/proof/acec/acecPa.c +++ b/src/proof/acec/acecPa.c @@ -273,6 +273,22 @@ void Pas_ManComputeCutsTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +{ + return NULL; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 5fbc0cd7f09a382241266404d78c18c5443d2b9d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 10 Jan 2017 16:58:24 +0700 Subject: [PATCH 45/61] Updates to arithmetic verification. --- abclib.dsp | 4 +++ src/aig/gia/giaShow.c | 6 ---- src/proof/acec/acec.h | 4 +++ src/proof/acec/acecCl.c | 8 ------ src/proof/acec/acecInt.h | 7 ++++- src/proof/acec/acecPa.c | 21 -------------- src/proof/acec/acecPool.c | 17 ------------ src/proof/acec/acecRe.c | 4 +++ src/proof/acec/acecTree.c | 56 ++++++++++++++++++++++++++++++++++++++ src/proof/acec/module.make | 1 + 10 files changed, 75 insertions(+), 53 deletions(-) create mode 100644 src/proof/acec/acecTree.c diff --git a/abclib.dsp b/abclib.dsp index 4ec50a1f3..a84bef073 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5535,6 +5535,10 @@ SOURCE=.\src\proof\acec\acecSt.c # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecTree.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecUtil.c # End Source File # End Group diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index afd36fff2..986d5624d 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -814,18 +814,12 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In } void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Abc_ShowFile( char * FileNameDot ); static int Counter = 0; char FileNameDot[200]; FILE * pFile; Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); - Ree_ManRemoveTrivial( pMan, vAdds ); - Ree_ManRemoveContained( pMan, vAdds ); // create the file name // Gia_ShowGetFileName( pMan->pName, FileNameDot ); diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 058e0f56d..918119f84 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -76,6 +76,10 @@ extern Vec_Int_t * Gia_PolynReorder( Gia_Man_t * pGia, int fVerbose, int fVery extern Vec_Int_t * Gia_PolynFindOrder( Gia_Man_t * pGia, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int fVerbose, int fVeryVerbose ); /*=== acecPolyn.c ========================================================*/ extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fSigned, int fVerbose, int fVeryVerbose ); +/*=== acecRe.c ========================================================*/ +extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); +extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); +extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 63483d57d..145f2e0b2 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -306,18 +306,10 @@ Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) ***********************************************************************/ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - abctime clk = Abc_Clock(); Gia_Man_t * pNew; Vec_Int_t * vRootXorSet; // Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); -// Ree_ManRemoveTrivial( p, vAdds ); -// Ree_ManRemoveContained( p, vAdds ); //Ree_ManPrintAdders( vAdds, 1 ); // printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index d53b61c75..065f6300c 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -63,12 +63,17 @@ struct Acec_Box_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== acecPa.c ========================================================*/ +/*=== acecCo.c ========================================================*/ +extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); +extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecTree.c ========================================================*/ extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); + + ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecPa.c b/src/proof/acec/acecPa.c index b59cdbeff..6b382d91c 100644 --- a/src/proof/acec/acecPa.c +++ b/src/proof/acec/acecPa.c @@ -248,11 +248,6 @@ int Pas_ManComputeCuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vOrder, Ve ***********************************************************************/ void Pas_ManComputeCutsTest( Gia_Man_t * p ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); - - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); abctime clk = Abc_Clock(); Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); Vec_Int_t * vIns, * vOuts; @@ -273,22 +268,6 @@ void Pas_ManComputeCutsTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) -{ - return NULL; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecPool.c b/src/proof/acec/acecPool.c index 08ee37f26..0868545eb 100644 --- a/src/proof/acec/acecPool.c +++ b/src/proof/acec/acecPool.c @@ -303,17 +303,9 @@ void Acec_ManPrintRanks( Vec_Int_t * vPairs ) ***********************************************************************/ void Acec_ManProfile( Gia_Man_t * p, int fVerbose ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - abctime clk = Abc_Clock(); Vec_Wec_t * vBoxes; int i; Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, fVerbose ); - Ree_ManRemoveTrivial( p, vAdds ); - Ree_ManRemoveContained( p, vAdds ); //Ree_ManPrintAdders( vAdds, 1 ); printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); @@ -396,13 +388,6 @@ Vec_Int_t * Acec_ManPoolTopMost( Gia_Man_t * p, Vec_Int_t * vAdds ) } void Acec_ManPool( Gia_Man_t * p ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); - - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); Vec_Int_t * vTops, * vTree; Vec_Wec_t * vTrees; @@ -413,8 +398,6 @@ void Acec_ManPool( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - Ree_ManRemoveTrivial( p, vAdds ); - Ree_ManRemoveContained( p, vAdds ); nFadds = Ree_ManCountFadds( vAdds ); printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 26faad006..60b894c8d 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -392,6 +392,8 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos } Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ) { + extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); Gia_Obj_t * pObj; int * pList0, * pList1, i, nCuts = 0; Hash_IntMan_t * pHash = Hash_IntManStart( 1000 ); @@ -430,6 +432,8 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) ); Vec_IntFree( vData ); Hash_IntManStop( pHash ); + Ree_ManRemoveTrivial( p, vAdds ); + Ree_ManRemoveContained( p, vAdds ); return vAdds; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c new file mode 100644 index 000000000..c2d89a1c7 --- /dev/null +++ b/src/proof/acec/acecTree.c @@ -0,0 +1,56 @@ +/**CFile**************************************************************** + + FileName [acecTree.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Adder tree construction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecTree.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +{ + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 4003695e5..4db695c51 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -11,4 +11,5 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ src/proof/acec/acecSt.c \ + src/proof/acec/acecTree.c \ src/proof/acec/acecUtil.c From 4bfb97d3e1b313f4b72ee0fa7adfa8949236db85 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 10 Jan 2017 19:19:02 +0700 Subject: [PATCH 46/61] Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 10 +- src/proof/acec/acecInt.h | 2 + src/proof/acec/acecTree.c | 275 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+), 4 deletions(-) diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 09ccb5326..a8123a5ef 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -70,10 +70,12 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) ***********************************************************************/ void Acec_BoxFree( Acec_Box_t * pBox ) { - Vec_WecFree( pBox->vUnique ); - Vec_WecFree( pBox->vShared ); - Vec_WecFree( pBox->vLeafLits ); - Vec_WecFree( pBox->vRootLits ); + Vec_WecFreeP( &pBox->vLeafs ); + Vec_WecFreeP( &pBox->vRoots ); + Vec_WecFreeP( &pBox->vLeafLits ); + Vec_WecFreeP( &pBox->vRootLits ); + Vec_WecFreeP( &pBox->vUnique ); + Vec_WecFreeP( &pBox->vShared ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 065f6300c..08f163e0b 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -41,6 +41,8 @@ typedef struct Acec_Box_t_ Acec_Box_t; struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vLeafs; // leaf literals by rank + Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index c2d89a1c7..08122584d 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -31,6 +31,281 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Find internal cut points with exactly one adder fanin/fanout.] + + Description [Returns a map of point into its input/output adder.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut ) +{ + int * pPlace = Vec_IntEntryP( vMap, Abc_Var2Lit(iObj, fOut) ); + if ( *pPlace == -1 ) + *pPlace = iAdd; + else if ( *pPlace >= 0 ) + *pPlace = -2; +} +Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) ); + int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+3), i, 1 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+4), i, 1 ); + } + return vMap; +} + +/**Function************************************************************* + + Synopsis [Find adder trees as groups of adders connected vis cut-points.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeWhichPoint( Vec_Int_t * vAdds, int iAdd, int iObj ) +{ + int k; + for ( k = 0; k < 5; k++ ) + if ( Vec_IntEntry(vAdds, 6*iAdd+k) == iObj ) + return k; + assert( 0 ); + return -1; +} +void Acec_TreeFindTrees2_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iAdd, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ) +{ + extern void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ); + int k; + if ( Vec_BitEntry(vFound, iAdd) ) + return; + Vec_BitWriteEntry( vFound, iAdd, 1 ); + Vec_IntPush( vTree, iAdd ); + Vec_IntPush( vTree, Rank ); + //printf( "Assigning rank %d to (%d:%d).\n", Rank, Vec_IntEntry(vAdds, 6*iAdd+3), Vec_IntEntry(vAdds, 6*iAdd+4) ); + for ( k = 0; k < 5; k++ ) + Acec_TreeFindTrees_rec( vAdds, vMap, Vec_IntEntry(vAdds, 6*iAdd+k), k == 4 ? Rank + 1 : Rank, vTree, vFound ); +} +void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ) +{ + int In = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 1) ); + int Out = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 0) ); + if ( In < 0 || Out < 0 ) + return; + Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); + Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); +} +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); + Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds ); + Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 ); + Vec_Int_t * vTree; + int i, k, In, Out, Box, Rank, MinRank; + // go through the cut-points + Vec_IntForEachEntryDouble( vMap, In, Out, i ) + { + if ( In < 0 || Out < 0 ) + continue; + assert( Vec_BitEntry(vFound, In) == Vec_BitEntry(vFound, Out) ); + if ( Vec_BitEntry(vFound, In) ) + continue; + vTree = Vec_WecPushLevel( vTrees ); + Acec_TreeFindTrees_rec( vAdds, vMap, i/2, 0, vTree, vFound ); + // normalize rank + MinRank = ABC_INFINITY; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MinRank = Abc_MinInt( MinRank, Rank ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + Vec_IntWriteEntry( vTree, k+1, Rank - MinRank ); + } + Vec_BitFree( vFound ); + Vec_IntFree( vMap ); + // sort by size + Vec_WecSort( vTrees, 1 ); + return vTrees; +} +void Acec_TreeFindTreesTest( Gia_Man_t * p ) +{ + Vec_Wec_t * vTrees; + + abctime clk = Abc_Clock(); + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); + int nFadds = Ree_ManCountFadds( vAdds ); + printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + clk = Abc_Clock(); + vTrees = Acec_TreeFindTrees( p, vAdds ); + printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Vec_WecPrint( vTrees, 0 ); + + Vec_WecFree( vTrees ); + Vec_IntFree( vAdds ); +} + + +/**Function************************************************************* + + Synopsis [Creates leaves and roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_PrintRootLits( Vec_Wec_t * vRoots ) +{ + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevel( vRoots, vLevel, i ) + { + printf( "Rank %d : ", i ); + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); + } + printf( "\n" ); + } +} +int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) +{ + int k, Box, Rank, MaxRank = 0; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MaxRank = Abc_MaxInt( MaxRank, Rank ); + return MaxRank; +} +void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) +{ + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box, Rank; + Vec_BitWriteEntry( vIsLeaf, 0, 1 ); + Vec_BitWriteEntry( vIsRoot, 0, 1 ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + for ( k = 0; k < 3; k++ ) + { + if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + continue; + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k), 1 ); + Vec_WecPush( vLeaves, Rank, Vec_IntEntry(vAdds, 6*Box+k) ); + } + for ( k = 3; k < 5; k++ ) + { + if ( Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + continue; + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k), 1 ); + Vec_WecPush( vRoots, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), k==4), Vec_IntEntry(vAdds, 6*Box+2)!=0) ); + } + } + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vIsRoot ); + // sort each level + Vec_WecForEachLevel( vLeaves, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + Vec_WecForEachLevel( vRoots, vLevel, i ) + Vec_IntSort( vLevel, 0 ); +} + +/**Function************************************************************* + + Synopsis [Creates polarity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ +} + +/**Function************************************************************* + + Synopsis [Derives one adder tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); + pBox->pGia = p; + + pBox->vLeafs = Vec_WecStart( Acec_CreateBoxMaxRank(vTree) + 1 ); + pBox->vRoots = Vec_WecStart( Vec_WecSize(pBox->vLeafs) + 1 ); + + Acec_BoxInsOuts( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots ); + + pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); + pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); + + Acec_BoxPhases( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits ); + + return pBox; +} +void Acec_CreateBoxTest( Gia_Man_t * p ) +{ + extern void Acec_BoxFree( Acec_Box_t * pBox ); + Acec_Box_t * pBox; + Vec_Wec_t * vTrees; + + abctime clk = Abc_Clock(); + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); + int nFadds = Ree_ManCountFadds( vAdds ); + printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + clk = Abc_Clock(); + vTrees = Acec_TreeFindTrees( p, vAdds ); + printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Vec_WecPrint( vTrees, 0 ); + + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + Vec_WecPrint( pBox->vLeafs, 0 ); + Vec_WecPrint( pBox->vRoots, 0 ); + Acec_PrintRootLits( pBox->vRoots ); + Acec_BoxFree( pBox ); + + Vec_WecFree( vTrees ); + Vec_IntFree( vAdds ); +} + /**Function************************************************************* Synopsis [] From 89d08cfd06ecb1653ef0613049447c91bc114f46 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 13:36:54 +0700 Subject: [PATCH 47/61] Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 2 + src/proof/acec/acecInt.h | 2 + src/proof/acec/acecRe.c | 11 +- src/proof/acec/acecTree.c | 273 +++++++++++++++++++++++++++++++++----- 4 files changed, 257 insertions(+), 31 deletions(-) diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index a8123a5ef..444e08949 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -70,12 +70,14 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) ***********************************************************************/ void Acec_BoxFree( Acec_Box_t * pBox ) { + Vec_WecFreeP( &pBox->vAdds ); Vec_WecFreeP( &pBox->vLeafs ); Vec_WecFreeP( &pBox->vRoots ); Vec_WecFreeP( &pBox->vLeafLits ); Vec_WecFreeP( &pBox->vRootLits ); Vec_WecFreeP( &pBox->vUnique ); Vec_WecFreeP( &pBox->vShared ); + Vec_BitFreeP( &pBox->vInvHadds ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 08f163e0b..3f10c6aa4 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -41,12 +41,14 @@ typedef struct Acec_Box_t_ Acec_Box_t; struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vAdds; // adders by rank Vec_Wec_t * vLeafs; // leaf literals by rank Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves Vec_Wec_t * vUnique; // unique leaves + Vec_Bit_t * vInvHadds; // complemented half adders }; //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 60b894c8d..161b6fbb5 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -370,7 +370,7 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos Vec_IntForEachEntryDouble( vXorOne, iObj, Truth, j ) Vec_IntForEachEntryDouble( vMajOne, iObj2, Truth2, k ) { - int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0xEE, 0xDD, 0xBB, 0x77}; + int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0x77, 0xBB, 0xDD, 0xEE}; int SignMaj[8] = {0xE8, 0xD4, 0xB2, 0x71, 0x8E, 0x4D, 0x2B, 0x17}; int n, SignXor = (Truth == 0x99 || Truth == 0x69) << 3; for ( n = 0; n < 8; n++ ) @@ -390,6 +390,14 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos Vec_WecFree( vMajMap ); return vAdds; } +int Ree_ManCompare( int * pCut0, int * pCut1 ) +{ + if ( pCut0[3] < pCut1[3] ) return -1; + if ( pCut0[3] > pCut1[3] ) return 1; + if ( pCut0[4] < pCut1[4] ) return -1; + if ( pCut0[4] > pCut1[4] ) return 1; + return 0; +} Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ) { extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); @@ -427,6 +435,7 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Vec_IntFree( vTemp ); Vec_IntFree( vCuts ); vAdds = Ree_ManDeriveAdds( pHash, vData, fVerbose ); + qsort( Vec_IntArray(vAdds), Vec_IntSize(vAdds)/6, 24, (int (*)(const void *, const void *))Ree_ManCompare ); if ( fVerbose ) printf( "Adders = %d. Total cuts = %d. Hashed cuts = %d. Hashed/Adders = %.2f.\n", Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 08122584d..ba08deb5f 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -169,23 +169,6 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Acec_PrintRootLits( Vec_Wec_t * vRoots ) -{ - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevel( vRoots, vLevel, i ) - { - printf( "Rank %d : ", i ); - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); - } - printf( "\n" ); - } -} int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) { int k, Box, Rank, MaxRank = 0; @@ -193,7 +176,7 @@ int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) MaxRank = Abc_MaxInt( MaxRank, Rank ); return MaxRank; } -void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) +void Acec_TreeInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vBoxes, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) { Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); @@ -211,6 +194,7 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W } Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { + Vec_WecPush( vBoxes, Rank, Box ); for ( k = 0; k < 3; k++ ) { if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) @@ -229,12 +213,91 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W Vec_BitFree( vIsLeaf ); Vec_BitFree( vIsRoot ); // sort each level + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( vLeaves, vLevel, i ) Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( vRoots, vLevel, i ) Vec_IntSort( vLevel, 0 ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + int Truth0, Truth1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return pObj->Value; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + assert( !Gia_ObjIsXor(pObj) ); + Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); + Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); + Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; + Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; + return (pObj->Value = Truth0 & Truth1); +} +void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bit_t * vPhase ) +{ + Gia_Obj_t * pObj; + unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; + int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; + + //if ( !fFadd ) + // return; + + Gia_ManIncrementTravId( p ); + for ( k = 0; k < 3; k++ ) + { + iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + pObj = Gia_ManObj( p, iObj ); + pObj->Value = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~Truths[k] : Truths[k]; + Gia_ObjSetTravIdCurrent( p, pObj ); + } + + iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); + TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthXor = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthXor : TruthXor; + + iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); + TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthMaj = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthMaj : TruthMaj; + + if ( fFadd ) // FADD + { + if ( TruthXor != 0x96 ) + printf( "Fadd %d sum is wrong.\n", iBox ); + if ( TruthMaj != 0xE8 ) + printf( "Fadd %d carry is wrong.\n", iBox ); + } + else + { + if ( TruthXor != 0x66 ) + printf( "Hadd %d sum is wrong.\n", iBox ); + if ( TruthMaj != 0x88 ) + printf( "Hadd %d carry is wrong.\n", iBox ); + } +} +void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) +{ + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Acec_TreeVerifyPhaseOne( p, vAdds, Box, vPhase ); +} + /**Function************************************************************* Synopsis [Creates polarity.] @@ -246,8 +309,96 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W SeeAlso [] ***********************************************************************/ -void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) { + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); + return vMap; +} +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, + Vec_Bit_t * vPhase, Vec_Bit_t * vInvHadds, Vec_Bit_t * vVisit ) +{ + int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + assert( Node != 0 ); + if ( Vec_BitEntry(vVisit, Node) ) + { + assert( Vec_BitEntry(vPhase, Node) == fPhase ); + return; + } + Vec_BitWriteEntry( vVisit, Node, 1 ); + if ( fPhase ) + Vec_BitWriteEntry( vPhase, Node, fPhase ); + iBox = Vec_IntEntry( vMap, Node ); + if ( iBox == -1 ) + return; + assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); + Sign = Vec_IntEntry( vAdds, 6*iBox+5 ); + fXorPhase = ((Sign >> 3) & 1); + if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) + { + fPhase ^= ((Sign >> 2) & 1); + // remember complemented HADD + if ( fPhase ) + Vec_BitWriteEntry( vInvHadds, iBox, 1 ); + } + for ( k = 0; k < 3; k++ ) + { + int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fXorPhase ^= fPhaseThis; + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); + } + if ( Vec_BitEntry(vVisit, iXor) ) + assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + if ( fXorPhase ) + Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); +} +void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, + Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, + Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits, Vec_Bit_t * vInvHadds ) +{ + Vec_Int_t * vMap = Acec_TreeCarryMap( p, vAdds, vBoxes ); + Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vVisit = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevelReverse( vRoots, vLevel, i ) + { + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + if ( !fCout ) + continue; + Acec_TreePhases_rec( p, vAdds, vMap, Node, fFadd, vPhase, vInvHadds, vVisit ); + } + } + Vec_IntFree( vMap ); + Vec_BitFree( vVisit ); + Acec_TreeVerifyPhases( p, vAdds, vBoxes, vPhase ); + // create leaves + Vec_WecForEachLevel( vLeaves, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + Vec_WecPush( vLeafLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); + // add constants + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + if ( Vec_BitEntry(vInvHadds, iObj) ) + Vec_WecPush( vLeafLits, i, 1 ); + // create roots + Vec_WecForEachLevel( vRoots, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + iObj >>= 2, Vec_WecPush( vRootLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); + // cleanup + Vec_BitFree( vPhase ); } /**Function************************************************************* @@ -261,20 +412,77 @@ void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_We SeeAlso [] ***********************************************************************/ +void Acec_PrintRootLits( Vec_Wec_t * vRoots ) +{ + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevel( vRoots, vLevel, i ) + { + printf( "Rank %d : ", i ); + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); + } + printf( "\n" ); + } +} +void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vLevel; + int i, k, iBox; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vLevel, iBox, k ) + printf( " (%d,%d)", Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); + printf( " }\n" ); + } +} +void Vec_WecPrintLits( Vec_Wec_t * p ) +{ + Vec_Int_t * vVec; + int i, k, Entry; + Vec_WecForEachLevel( p, vVec, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vVec, Entry, k ) + printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); + printf( " }\n" ); + } +} +void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) +{ + printf( "Adders:\n" ); + Acec_PrintAdders( pBox->vAdds, vAdds ); + printf( "Inputs:\n" ); + Vec_WecPrintLits( pBox->vLeafLits ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox->vRootLits ); + //printf( "Raw outputs:\n" ); + //Acec_PrintRootLits( pBox->vRoots ); +} + Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { + int MaxRank = Acec_CreateBoxMaxRank(vTree); + Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; - pBox->vLeafs = Vec_WecStart( Acec_CreateBoxMaxRank(vTree) + 1 ); - pBox->vRoots = Vec_WecStart( Vec_WecSize(pBox->vLeafs) + 1 ); + pBox->vAdds = Vec_WecStart( MaxRank + 1 ); + pBox->vLeafs = Vec_WecStart( MaxRank + 1 ); + pBox->vRoots = Vec_WecStart( MaxRank + 2 ); - Acec_BoxInsOuts( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots ); + Acec_TreeInsOuts( p, vAdds, vTree, pBox->vAdds, pBox->vLeafs, pBox->vRoots ); pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); + pBox->vInvHadds = Vec_BitStart( Vec_IntSize(vAdds)/6 ); - Acec_BoxPhases( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits ); + Acec_TreePhases( p, vAdds, pBox->vAdds, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits, pBox->vInvHadds ); return pBox; } @@ -283,10 +491,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) extern void Acec_BoxFree( Acec_Box_t * pBox ); Acec_Box_t * pBox; Vec_Wec_t * vTrees; + Vec_Int_t * vTree; abctime clk = Abc_Clock(); Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); - int nFadds = Ree_ManCountFadds( vAdds ); + int i, nFadds = Ree_ManCountFadds( vAdds ); printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); @@ -294,13 +503,17 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) vTrees = Acec_TreeFindTrees( p, vAdds ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); - Vec_WecPrint( vTrees, 0 ); + //Vec_WecPrint( vTrees, 0 ); - pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); - Vec_WecPrint( pBox->vLeafs, 0 ); - Vec_WecPrint( pBox->vRoots, 0 ); - Acec_PrintRootLits( pBox->vRoots ); - Acec_BoxFree( pBox ); + Vec_WecForEachLevel( vTrees, vTree, i ) + { + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, i) ); + printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", + i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), + Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); + //Acec_PrintBox( pBox ); + Acec_BoxFree( pBox ); + } Vec_WecFree( vTrees ); Vec_IntFree( vAdds ); From 8b8b410af2d9cc75de758516f8c7dcf7a6098edc Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 13:44:27 +0700 Subject: [PATCH 48/61] Changing file naming in 'show' and '&show'. --- src/aig/aig/aigShow.c | 5 ++--- src/aig/gia/giaShow.c | 8 ++------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/aig/aig/aigShow.c b/src/aig/aig/aigShow.c index eac2a510a..d983602a6 100644 --- a/src/aig/aig/aigShow.c +++ b/src/aig/aig/aigShow.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "aig.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -340,12 +341,10 @@ void Aig_WriteDotAig( Aig_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold ) { extern void Abc_ShowFile( char * FileNameDot ); - static int Counter = 0; char FileNameDot[200]; FILE * pFile; // create the file name -// Aig_ShowGetFileName( pMan->pName, FileNameDot ); - sprintf( FileNameDot, "temp%02d.dot", Counter++ ); + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) { diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 986d5624d..5589d3841 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -21,6 +21,7 @@ #include "gia.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -815,15 +816,10 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { extern void Abc_ShowFile( char * FileNameDot ); - static int Counter = 0; char FileNameDot[200]; FILE * pFile; - Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); - - // create the file name -// Gia_ShowGetFileName( pMan->pName, FileNameDot ); - sprintf( FileNameDot, "temp%02d.dot", Counter++ ); + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) { From 55b6b4bdab816b34bfa81a58eb4e9fefe0c1cba4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 16:08:23 +0700 Subject: [PATCH 49/61] Updates to arithmetic verification. --- abclib.dsp | 4 + src/base/abci/abc.c | 48 +++++++++ src/base/wlc/wlcBlast.c | 2 +- src/proof/acec/acec.h | 2 + src/proof/acec/acecCore.c | 199 ++-------------------------------- src/proof/acec/acecInt.h | 5 +- src/proof/acec/acecNorm.c | 215 +++++++++++++++++++++++++++++++++++++ src/proof/acec/acecTree.c | 101 ++++++++++++----- src/proof/acec/module.make | 1 + 9 files changed, 356 insertions(+), 221 deletions(-) create mode 100644 src/proof/acec/acecNorm.c diff --git a/abclib.dsp b/abclib.dsp index a84bef073..e2ff005ed 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5507,6 +5507,10 @@ SOURCE=.\src\proof\acec\acecInt.h # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecNorm.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecOrder.c # End Source File # Begin Source File diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dd157afda..20d44227e 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -481,6 +481,7 @@ static int Abc_CommandAbc9Fadds ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1124,6 +1125,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&atree", Abc_CommandAbc9ATree, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 ); @@ -40728,6 +40730,52 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" ); + return 0; + } + pTemp = Acec_Normalize( pAbc->pGia, fVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &anorm [-vh]\n" ); + Abc_Print( -2, "\t normalize adder trees in the current AIG\n" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index ec3b040d5..5e6a1a471 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1509,7 +1509,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) ); } - pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName ); + //pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName ); // dump the miter parts if ( 0 ) { diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 918119f84..7ad5baf95 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -80,6 +80,8 @@ extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int f extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); +/*=== acecTree.c ========================================================*/ +extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 444e08949..3e31fa360 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -57,98 +57,6 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) p->iOutFail = -1; // the number of failed output } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Acec_BoxFree( Acec_Box_t * pBox ) -{ - Vec_WecFreeP( &pBox->vAdds ); - Vec_WecFreeP( &pBox->vLeafs ); - Vec_WecFreeP( &pBox->vRoots ); - Vec_WecFreeP( &pBox->vLeafLits ); - Vec_WecFreeP( &pBox->vRootLits ); - Vec_WecFreeP( &pBox->vUnique ); - Vec_WecFreeP( &pBox->vShared ); - Vec_BitFreeP( &pBox->vInvHadds ); - ABC_FREE( pBox ); -} -void Acec_BoxFreeP( Acec_Box_t ** ppBox ) -{ - if ( *ppBox ) - Acec_BoxFree( *ppBox ); - *ppBox = NULL; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) -{ - int And, Or; - Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); - And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); - Or = Gia_ManAppendOr2( pNew, Out[1], And ); - Out[0] = Abc_LitNot( Or ); -} -void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) -{ - int In2[2], Out1[2], Out2[2]; - Acec_InsertHadd( pNew, In, Out1 ); - In2[0] = Out1[0]; - In2[1] = In[2]; - Acec_InsertHadd( pNew, In2, Out2 ); - Out[0] = Out2[0]; - Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); -} -Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) -{ - Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); - Vec_Int_t * vLevel; - int i, In[3], Out[2]; - Vec_WecForEachLevel( vLeafMap, vLevel, i ) - { - if ( Vec_IntSize(vLevel) == 0 ) - { - Vec_IntPush( vRootRanks, 0 ); - continue; - } - while ( Vec_IntSize(vLevel) > 1 ) - { - if ( Vec_IntSize(vLevel) == 2 ) - Vec_IntPush( vLevel, 0 ); - In[0] = Vec_IntPop( vLevel ); - In[1] = Vec_IntPop( vLevel ); - In[2] = Vec_IntPop( vLevel ); - Acec_InsertFadd( pNew, In, Out ); - Vec_IntPush( vLevel, Out[0] ); - if ( i-1 < Vec_WecSize(vLeafMap) ) - vLevel = Vec_WecEntry(vLeafMap, i+1); - else - vLevel = Vec_WecPushLevel(vLeafMap); - Vec_IntPush( vLevel, Out[1] ); - } - assert( Vec_IntSize(vLevel) == 1 ); - Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); - } - return vRootRanks; -} - /**Function************************************************************* Synopsis [] @@ -251,12 +159,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int * pEnd1 = Vec_IntLimit(vLevel1); while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) { - if ( *pBeg0 == *pBeg1 ) + int Entry0 = Abc_Lit2LitV( Vec_IntArray(vMap0), *pBeg0 ); + int Entry1 = Abc_Lit2LitV( Vec_IntArray(vMap1), *pBeg1 ); + if ( Entry0 == Entry1 ) { Vec_IntPush( vShared0, *pBeg0++ ); Vec_IntPush( vShared1, *pBeg1++ ); } - else if ( *pBeg0 > *pBeg1 ) + else if ( Entry0 > Entry1 ) Vec_IntPush( vUnique0, *pBeg0++ ); else Vec_IntPush( vUnique1, *pBeg1++ ); @@ -269,105 +179,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); } + Vec_IntFree( vMap0 ); + Vec_IntFree( vMap1 ); nTotal = Vec_WecSizeSize(pBox0->vShared); printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); return nTotal; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) -{ - if ( ~pObj->Value ) - return pObj->Value; - assert( Gia_ObjIsAnd(pObj) ); - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); - return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); -} -Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) -{ - Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); - Vec_Int_t * vLevel, * vRootRanks; - int i, k, iLit, iLitNew; - Vec_WecForEachLevel( vLeafLits, vLevel, i ) - Vec_IntForEachEntry( vLevel, iLit, k ) - { - Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); - iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); - iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); - Vec_WecPush( vLeafMap, i, iLitNew ); - } - // construct map of root literals - vRootRanks = Acec_InsertTree( pNew, vLeafMap ); - Vec_WecFree( vLeafMap ); - return vRootRanks; -} - -Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) -{ - Gia_Man_t * p = pBox->pGia; - Gia_Man_t * pNew; - Gia_Obj_t * pObj; - Vec_Int_t * vRootRanks, * vLevel; - int i, k, iLit, iLitNew; - pNew = Gia_ManStart( Gia_ManObjNum(p) ); - pNew->pName = Abc_UtilStrsav( p->pName ); - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Gia_ManConst0(p)->Value = 0; - Gia_ManForEachCi( p, pObj, i ) - pObj->Value = Gia_ManAppendCi( pNew ); - // implement tree - if ( fAll ) - vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); - else - { - Vec_Wec_t * vLeafLits; - assert( pBox->vShared != NULL ); - assert( pBox->vUnique != NULL ); - vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); - // add these roots to the unique ones - vLeafLits = Vec_WecDup( pBox->vUnique ); - Vec_IntForEachEntry( vRootRanks, iLit, i ) - { - if ( i < Vec_WecSize(vLeafLits) ) - vLevel = Vec_WecEntry(vLeafLits, i); - else - vLevel = Vec_WecPushLevel(vLeafLits); - Vec_IntPush( vLevel, iLit ); - } - Vec_IntFree( vRootRanks ); - vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); - Vec_WecFree( vLeafLits ); - } - // update polarity of literals - Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) - Vec_IntForEachEntry( vLevel, iLit, k ) - { - pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); - iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, k ); - pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); - } - Vec_IntFree( vRootRanks ); - // construct the outputs - Gia_ManForEachCo( p, pObj, i ) - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); - Gia_ManForEachCo( p, pObj, i ) - pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); - return pNew; -} - /**Function************************************************************* Synopsis [] @@ -385,8 +204,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) Gia_Man_t * pMiter; Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0 ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1 ); + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, pPars->fVerbose ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching @@ -403,7 +222,7 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose ); if ( pMiter ) { - int fDumpMiter = 1; + int fDumpMiter = 0; if ( fDumpMiter ) { Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 3f10c6aa4..c0d899e17 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -70,8 +70,11 @@ struct Acec_Box_t_ /*=== acecCo.c ========================================================*/ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecNorm.c ========================================================*/ +extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ); +extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c new file mode 100644 index 000000000..9faf7acfd --- /dev/null +++ b/src/proof/acec/acecNorm.c @@ -0,0 +1,215 @@ +/**CFile**************************************************************** + + FileName [acecNorm.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Adder tree normalization.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecNorm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) +{ + int And, Or; + Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); + And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); + Or = Gia_ManAppendOr2( pNew, Out[1], And ); + Out[0] = Abc_LitNot( Or ); +} +void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) +{ + int In2[2], Out1[2], Out2[2]; + Acec_InsertHadd( pNew, In, Out1 ); + In2[0] = Out1[0]; + In2[1] = In[2]; + Acec_InsertHadd( pNew, In2, Out2 ); + Out[0] = Out2[0]; + Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); +} +Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) +{ + Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); + Vec_Int_t * vLevel; + int i, In[3], Out[2]; + Vec_WecForEachLevel( vLeafMap, vLevel, i ) + { + if ( Vec_IntSize(vLevel) == 0 ) + { + Vec_IntPush( vRootRanks, 0 ); + continue; + } + while ( Vec_IntSize(vLevel) > 1 ) + { + if ( Vec_IntSize(vLevel) == 2 ) + Vec_IntPush( vLevel, 0 ); + In[2] = Vec_IntPop( vLevel ); + In[1] = Vec_IntPop( vLevel ); + In[0] = Vec_IntPop( vLevel ); + Acec_InsertFadd( pNew, In, Out ); + Vec_IntPush( vLevel, Out[0] ); + if ( i+1 < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i+1); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, Out[1] ); + vLevel = Vec_WecEntry(vLeafMap, i); + } + assert( Vec_IntSize(vLevel) == 1 ); + Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); + } + return vRootRanks; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); +} +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +{ + Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); + Vec_Int_t * vLevel, * vRootRanks; + int i, k, iLit, iLitNew; + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); + iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + Vec_WecPush( vLeafMap, i, iLitNew ); + } + // construct map of root literals + vRootRanks = Acec_InsertTree( pNew, vLeafMap ); + Vec_WecFree( vLeafMap ); + return vRootRanks; +} +Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) +{ + Gia_Man_t * p = pBox->pGia; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vRootRanks, * vLevel; + int i, k, iLit, iLitNew; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + // implement tree + if ( fAll ) + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + else + { + Vec_Wec_t * vLeafLits; + assert( pBox->vShared != NULL ); + assert( pBox->vUnique != NULL ); + vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); + // add these roots to the unique ones + vLeafLits = Vec_WecDup( pBox->vUnique ); + Vec_IntForEachEntry( vRootRanks, iLit, i ) + { + if ( i < Vec_WecSize(vLeafLits) ) + vLevel = Vec_WecEntry(vLeafLits, i); + else + vLevel = Vec_WecPushLevel(vLeafLits); + Vec_IntPush( vLevel, iLit ); + } + Vec_IntFree( vRootRanks ); + vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); + Vec_WecFree( vLeafLits ); + } + // update polarity of literals + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, i ); + pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + } + Vec_IntFree( vRootRanks ); + // construct the outputs + Gia_ManForEachCo( p, pObj, i ) + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ) +{ + Acec_Box_t * pBox = Acec_DeriveBox( pGia, fVerbose ); + Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); + Acec_BoxFreeP( &pBox ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index ba08deb5f..1c0af00a5 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -31,6 +31,36 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_BoxFree( Acec_Box_t * pBox ) +{ + Vec_WecFreeP( &pBox->vAdds ); + Vec_WecFreeP( &pBox->vLeafs ); + Vec_WecFreeP( &pBox->vRoots ); + Vec_WecFreeP( &pBox->vLeafLits ); + Vec_WecFreeP( &pBox->vRootLits ); + Vec_WecFreeP( &pBox->vUnique ); + Vec_WecFreeP( &pBox->vShared ); + Vec_BitFreeP( &pBox->vInvHadds ); + ABC_FREE( pBox ); +} +void Acec_BoxFreeP( Acec_Box_t ** ppBox ) +{ + if ( *ppBox ) + Acec_BoxFree( *ppBox ); + *ppBox = NULL; +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -412,6 +442,31 @@ void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, SeeAlso [] ***********************************************************************/ +void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vLevel; + int i, k, iBox; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vLevel, iBox, k ) + printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, + Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); + printf( " }\n" ); + } +} +void Vec_WecPrintLits( Vec_Wec_t * p ) +{ + Vec_Int_t * vVec; + int i, k, Entry; + Vec_WecForEachLevel( p, vVec, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vVec, Entry, k ) + printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); + printf( " }\n" ); + } +} void Acec_PrintRootLits( Vec_Wec_t * vRoots ) { Vec_Int_t * vLevel; @@ -429,30 +484,6 @@ void Acec_PrintRootLits( Vec_Wec_t * vRoots ) printf( "\n" ); } } -void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) -{ - Vec_Int_t * vLevel; - int i, k, iBox; - Vec_WecForEachLevel( vBoxes, vLevel, i ) - { - printf( " %4d : {", i ); - Vec_IntForEachEntry( vLevel, iBox, k ) - printf( " (%d,%d)", Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); - printf( " }\n" ); - } -} -void Vec_WecPrintLits( Vec_Wec_t * p ) -{ - Vec_Int_t * vVec; - int i, k, Entry; - Vec_WecForEachLevel( p, vVec, i ) - { - printf( " %4d : {", i ); - Vec_IntForEachEntry( vVec, Entry, k ) - printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); - printf( " }\n" ); - } -} void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) { printf( "Adders:\n" ); @@ -488,7 +519,6 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree } void Acec_CreateBoxTest( Gia_Man_t * p ) { - extern void Acec_BoxFree( Acec_Box_t * pBox ); Acec_Box_t * pBox; Vec_Wec_t * vTrees; Vec_Int_t * vTree; @@ -511,8 +541,8 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); - //Acec_PrintBox( pBox ); - Acec_BoxFree( pBox ); + Acec_PrintBox( pBox, vAdds ); + Acec_BoxFreeP( &pBox ); } Vec_WecFree( vTrees ); @@ -530,9 +560,22 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) { - return NULL; + Acec_Box_t * pBox = NULL; + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds ); + if ( vTrees && Vec_WecSize(vTrees) > 0 ) + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + if ( pBox )//&& fVerbose ) + printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", + 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), + Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); + if ( pBox && fVerbose ) + Acec_PrintBox( pBox, vAdds ); + Vec_WecFreeP( &vTrees ); + Vec_IntFree( vAdds ); + return pBox; } //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 4db695c51..25fa25484 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -8,6 +8,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecPool.c \ src/proof/acec/acecCover.c \ src/proof/acec/acecFadds.c \ + src/proof/acec/acecNorm.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ src/proof/acec/acecSt.c \ From d52dafa6c2365837543f15be7abd274f8654ba14 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 12 Jan 2017 16:12:48 +0700 Subject: [PATCH 50/61] Updates to arithmetic verification. --- abclib.dsp | 4 + src/aig/gia/gia.h | 1 + src/aig/gia/giaTruth.c | 51 +++++ src/base/wlc/wlcBlast.c | 26 +++ src/proof/acec/acecInt.h | 2 + src/proof/acec/acecMult.c | 432 +++++++++++++++++++++++++++++++++++++ src/proof/acec/acecTree.c | 26 ++- src/proof/acec/module.make | 1 + 8 files changed, 534 insertions(+), 9 deletions(-) create mode 100644 src/proof/acec/acecMult.c diff --git a/abclib.dsp b/abclib.dsp index e2ff005ed..170633e49 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5507,6 +5507,10 @@ SOURCE=.\src\proof\acec\acecInt.h # End Source File # Begin Source File +SOURCE=.\src\proof\acec\acecMult.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\acec\acecNorm.c # End Source File # Begin Source File diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index d9b1716a3..7cf1feff3 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1514,6 +1514,7 @@ extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimi extern word Gia_LutComputeTruth6( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTruths ); extern word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp ); extern word Gia_ObjComputeTruthTable6( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTruths ); +extern word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ); extern void Gia_ObjCollectInternal( Gia_Man_t * p, Gia_Obj_t * pObj ); extern word * Gia_ObjComputeTruthTable( Gia_Man_t * p, Gia_Obj_t * pObj ); extern void Gia_ObjComputeTruthTableStart( Gia_Man_t * p, int nVarsMax ); diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c index ce06fa0b9..f636a573c 100644 --- a/src/aig/gia/giaTruth.c +++ b/src/aig/gia/giaTruth.c @@ -137,6 +137,57 @@ word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp ) return Vec_WrdEntry( vTemp, iObj ); } +/**Function************************************************************* + + Synopsis [Computes truth table up to 6 inputs in terms of CIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Gia_ObjComputeTruth6( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ) +{ + int i, Fanin; + assert( Vec_WrdSize(vTemp) == Gia_ManObjNum(p) ); + assert( Vec_IntSize(vSupp) <= 6 ); + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vSupp, Fanin, i ) + { + Gia_ObjSetTravIdCurrentId( p, Fanin ); + Vec_WrdWriteEntry( vTemp, Fanin, s_Truth6[i] ); + } + Gia_ObjComputeTruthTable6Lut_rec( p, iObj, vTemp ); + return Vec_WrdEntry( vTemp, iObj ); +} +void Gia_ObjComputeTruth6CisSupport_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp ) +{ + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPushOrder( vSupp, iObj ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId0p(p, pObj), vSupp ); + Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId1p(p, pObj), vSupp ); +} +word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ) +{ + int iObj = Abc_Lit2Var(iLit); + Vec_IntClear( vSupp ); + if ( !iObj ) return Abc_LitIsCompl(iLit) ? ~(word)0 : (word)0; + Gia_ManIncrementTravId( p ); + Gia_ObjComputeTruth6CisSupport_rec( p, iObj, vSupp ); + Gia_ObjComputeTruth6( p, iObj, vSupp, vTemp ); + return Abc_LitIsCompl(iLit) ? ~Vec_WrdEntry(vTemp, iObj) : Vec_WrdEntry(vTemp, iObj); +} + /**Function************************************************************* Synopsis [Computes truth table up to 6 inputs.] diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 5e6a1a471..b22ac6cdc 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -643,6 +643,31 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) Vec_IntInsert( vProd, i + 1, Node ); Vec_IntInsert( vLevel, i + 1, Level ); } +void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) +{ + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; word Truth; + int i, k, iLit; + Vec_WecForEachLevel( vProds, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + printf( "Obj = %4d : ", Abc_Lit2Var(iLit) ); + printf( "Compl = %d ", Abc_LitIsCompl(iLit) ); + printf( "Rank = %2d ", i ); + Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + if ( k == Vec_IntSize(vLevel)-1 ) + printf( "\n" ); + } + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); +} void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes ) { Vec_Int_t * vLevel, * vProd; @@ -812,6 +837,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int Vec_WecPush( vLevels, k, 0 ); } //Vec_WecPrint( vProds, 0 ); + //Wlc_BlastPrintMatrix( pNew, vProds ); //printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) ); Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index c0d899e17..0dc3f7060 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -70,6 +70,8 @@ struct Acec_Box_t_ /*=== acecCo.c ========================================================*/ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecMult.c ========================================================*/ +extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); /*=== acecNorm.c ========================================================*/ extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c new file mode 100644 index 000000000..397f6d571 --- /dev/null +++ b/src/proof/acec/acecMult.c @@ -0,0 +1,432 @@ +/**CFile**************************************************************** + + FileName [acecMult.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Multiplier.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecMult.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +unsigned s_Classes4a[96] = { + 0xD728, 0xB748, 0x9F60, 0xD278, 0xB478, 0x96F0, 0xC66C, 0x96CC, 0x9C6C, 0x96AA, 0xA66A, 0x9A6A, + 0x28D7, 0x48B7, 0x609F, 0x2D87, 0x4B87, 0x690F, 0x3993, 0x6933, 0x6393, 0x6955, 0x5995, 0x6595, + 0xEB14, 0xED12, 0xF906, 0xE1B4, 0xE1D2, 0xF096, 0xC99C, 0xCC96, 0xC9C6, 0xAA96, 0xA99A, 0xA9A6, + 0x14EB, 0x12ED, 0x06F9, 0x1E4B, 0x1E2D, 0x0F69, 0x3663, 0x3369, 0x3639, 0x5569, 0x5665, 0x5659, + 0x7D82, 0x7B84, 0x6F90, 0x78D2, 0x78B4, 0x69F0, 0x6CC6, 0x69CC, 0x6C9C, 0x69AA, 0x6AA6, 0x6A9A, + 0x827D, 0x847B, 0x906F, 0x872D, 0x874B, 0x960F, 0x9339, 0x9633, 0x9363, 0x9655, 0x9559, 0x9565, + 0xBE41, 0xDE21, 0xF609, 0xB4E1, 0xD2E1, 0xF069, 0x9CC9, 0xCC69, 0xC6C9, 0xAA69, 0x9AA9, 0xA6A9, + 0x41BE, 0x21DE, 0x09F6, 0x4B1E, 0x2D1E, 0x0F96, 0x6336, 0x3396, 0x3936, 0x5596, 0x6556, 0x5956 +}; + +unsigned s_Classes4b[384] = { + 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0, + 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22, + 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0, + 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88, + 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A, + 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522, + 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A, + 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588, + 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570, + 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A, + 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0, + 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A, + 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025, + 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5, + 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085, + 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5, + 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B, + 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511, + 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E, + 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544, + 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1, + 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11, + 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4, + 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44, + 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207, + 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5, + 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D, + 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5, + 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752, + 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A, + 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58, + 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A +}; + +unsigned s_Classes4c[768] = { + 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0, + 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22, + 0xCA3F, 0xAC5F, 0xE23F, 0xB877, 0xD877, 0xE45F, 0xC3AF, 0xA5CF, 0xE32F, 0xB787, 0xD787, 0xE54F, + 0xCB3B, 0x9F93, 0xC3BB, 0x99F3, 0xD973, 0xD793, 0x9F95, 0xAD5D, 0xB795, 0xB975, 0x99F5, 0xA5DD, + 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0, + 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88, + 0xC53F, 0xA35F, 0xD13F, 0x8B77, 0x8D77, 0xB15F, 0xC35F, 0xA53F, 0xD31F, 0x87B7, 0x87D7, 0xB51F, + 0xC737, 0x939F, 0xC377, 0x993F, 0x9D37, 0x93D7, 0x959F, 0xA757, 0x95B7, 0x9B57, 0x995F, 0xA577, + 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A, + 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522, + 0x3ACF, 0x5CAF, 0x2EF3, 0x74BB, 0x72DD, 0x4EF5, 0x3CAF, 0x5ACF, 0x2FE3, 0x7B4B, 0x7D2D, 0x4FE5, + 0x3BCB, 0x6F63, 0x3CBB, 0x66F3, 0x73D9, 0x7D39, 0x6F65, 0x5DAD, 0x7B59, 0x75B9, 0x66F5, 0x5ADD, + 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A, + 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588, + 0x35CF, 0x53AF, 0x1DF3, 0x47BB, 0x27DD, 0x1BF5, 0x3C5F, 0x5A3F, 0x1FD3, 0x4B7B, 0x2D7D, 0x1FB5, + 0x37C7, 0x636F, 0x3C77, 0x663F, 0x379D, 0x397D, 0x656F, 0x57A7, 0x597B, 0x579B, 0x665F, 0x5A77, + 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570, + 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A, + 0xACF3, 0xCAF5, 0xB8CF, 0xE2DD, 0xE4BB, 0xD8AF, 0xAFC3, 0xCFA5, 0xBC8F, 0xED2D, 0xEB4B, 0xDA8F, + 0xBCB3, 0xF939, 0xBBC3, 0xF399, 0xE6B3, 0xEB63, 0xF959, 0xDAD5, 0xED65, 0xE6D5, 0xF599, 0xDDA5, + 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0, + 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A, + 0x5CF3, 0x3AF5, 0x74CF, 0x2EDD, 0x4EBB, 0x72AF, 0x5FC3, 0x3FA5, 0x7C4F, 0x2DED, 0x4BEB, 0x7A2F, + 0x7C73, 0x39F9, 0x77C3, 0x3F99, 0x6E3B, 0x63EB, 0x59F9, 0x7A75, 0x65ED, 0x6E5D, 0x5F99, 0x77A5, + 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025, + 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5, + 0xA3FC, 0xC5FA, 0x8BFC, 0xD1EE, 0xB1EE, 0x8DFA, 0xAF3C, 0xCF5A, 0x8FBC, 0xDE1E, 0xBE1E, 0x8FDA, + 0xB3BC, 0xF636, 0xBB3C, 0xF366, 0xB3E6, 0xBE36, 0xF656, 0xD5DA, 0xDE56, 0xD5E6, 0xF566, 0xDD5A, + 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085, + 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5, + 0x53FC, 0x35FA, 0x47FC, 0x1DEE, 0x1BEE, 0x27FA, 0x5F3C, 0x3F5A, 0x4F7C, 0x1EDE, 0x1EBE, 0x2F7A, + 0x737C, 0x36F6, 0x773C, 0x3F66, 0x3B6E, 0x36BE, 0x56F6, 0x757A, 0x56DE, 0x5D6E, 0x5F66, 0x775A, + 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B, + 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511, + 0x3FCA, 0x5FAC, 0x3FE2, 0x77B8, 0x77D8, 0x5FE4, 0x3CFA, 0x5AFC, 0x3EF2, 0x7B78, 0x7D78, 0x5EF4, + 0x3ECE, 0x6F6C, 0x3CEE, 0x66FC, 0x76DC, 0x7D6C, 0x6F6A, 0x5EAE, 0x7B6A, 0x76BA, 0x66FA, 0x5AEE, + 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E, + 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544, + 0x3FC5, 0x5FA3, 0x3FD1, 0x778B, 0x778D, 0x5FB1, 0x3CF5, 0x5AF3, 0x3DF1, 0x787B, 0x787D, 0x5BF1, + 0x3DCD, 0x6C6F, 0x3CDD, 0x66CF, 0x67CD, 0x6C7D, 0x6A6F, 0x5BAB, 0x6A7B, 0x67AB, 0x66AF, 0x5ABB, + 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1, + 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11, + 0xCF3A, 0xAF5C, 0xF32E, 0xBB74, 0xDD72, 0xF54E, 0xC3FA, 0xA5FC, 0xF23E, 0xB7B4, 0xD7D2, 0xF45E, + 0xCE3E, 0x9F9C, 0xC3EE, 0x99FC, 0xDC76, 0xD7C6, 0x9F9A, 0xAE5E, 0xB7A6, 0xBA76, 0x99FA, 0xA5EE, + 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4, + 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44, + 0xCF35, 0xAF53, 0xF31D, 0xBB47, 0xDD27, 0xF51B, 0xC3F5, 0xA5F3, 0xF13D, 0xB4B7, 0xD2D7, 0xF15B, + 0xCD3D, 0x9C9F, 0xC3DD, 0x99CF, 0xCD67, 0xC6D7, 0x9A9F, 0xAB5B, 0xA6B7, 0xAB67, 0x99AF, 0xA5BB, + 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207, + 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5, + 0xF3AC, 0xF5CA, 0xCFB8, 0xDDE2, 0xBBE4, 0xAFD8, 0xFA3C, 0xFC5A, 0xCBF8, 0xDED2, 0xBEB4, 0xADF8, + 0xE3EC, 0xF6C6, 0xEE3C, 0xFC66, 0xB9EC, 0xBE9C, 0xF6A6, 0xE5EA, 0xDE9A, 0xD9EA, 0xFA66, 0xEE5A, + 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D, + 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5, + 0xF35C, 0xF53A, 0xCF74, 0xDD2E, 0xBB4E, 0xAF72, 0xF53C, 0xF35A, 0xC7F4, 0xD2DE, 0xB4BE, 0xA7F2, + 0xD3DC, 0xC6F6, 0xDD3C, 0xCF66, 0x9BCE, 0x9CBE, 0xA6F6, 0xB5BA, 0x9ADE, 0x9DAE, 0xAF66, 0xBB5A, + 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752, + 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A, + 0xFCA3, 0xFAC5, 0xFC8B, 0xEED1, 0xEEB1, 0xFA8D, 0xFAC3, 0xFCA5, 0xF8CB, 0xEDE1, 0xEBE1, 0xF8AD, + 0xECE3, 0xF9C9, 0xEEC3, 0xFC99, 0xECB9, 0xEBC9, 0xF9A9, 0xEAE5, 0xEDA9, 0xEAD9, 0xFA99, 0xEEA5, + 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58, + 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A, + 0xFC53, 0xFA35, 0xFC47, 0xEE1D, 0xEE1B, 0xFA27, 0xF5C3, 0xF3A5, 0xF4C7, 0xE1ED, 0xE1EB, 0xF2A7, + 0xDCD3, 0xC9F9, 0xDDC3, 0xCF99, 0xCE9B, 0xC9EB, 0xA9F9, 0xBAB5, 0xA9ED, 0xAE9D, 0xAF99, 0xBBA5 +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Computes NPN-canonical form using brute-force methods.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Extra_TruthCanonNPN2( unsigned uTruth, int nVars, Vec_Int_t * vRes ) +{ + static int nVarsOld, nPerms; + static char ** pPerms = NULL; + + unsigned uTruthMin, uTruthC, uPhase, uPerm; + int nMints, k, i; + + if ( pPerms == NULL ) + { + nPerms = Extra_Factorial( nVars ); + pPerms = Extra_Permutations( nVars ); + nVarsOld = nVars; + } + else if ( nVarsOld != nVars ) + { + ABC_FREE( pPerms ); + nPerms = Extra_Factorial( nVars ); + pPerms = Extra_Permutations( nVars ); + nVarsOld = nVars; + } + + nMints = (1 << nVars); + uTruthC = (unsigned)( (~uTruth) & ((~((unsigned)0)) >> (32-nMints)) ); + uTruthMin = 0xFFFFFFFF; + for ( i = 0; i < nMints; i++ ) + { + uPhase = Extra_TruthPolarize( uTruth, i, nVars ); + for ( k = 0; k < nPerms; k++ ) + { + uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 ); + Vec_IntPushUnique( vRes, uPerm ); + if ( uTruthMin > uPerm ) + uTruthMin = uPerm; + } + uPhase = Extra_TruthPolarize( uTruthC, i, nVars ); + for ( k = 0; k < nPerms; k++ ) + { + uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 ); + Vec_IntPushUnique( vRes, uPerm ); + if ( uTruthMin > uPerm ) + uTruthMin = uPerm; + } + } + return uTruthMin; +} + +void Acec_MultFuncTest5() +{ + Vec_Int_t * vRes = Vec_IntAlloc( 1000 ); + int i, Entry; + + unsigned Truth = 0xF335ACC0; + unsigned Canon = Extra_TruthCanonNPN2( Truth, 5, vRes ); + + Extra_PrintHex( stdout, (unsigned*)&Truth, 5 ); printf( "\n" ); + Extra_PrintHex( stdout, (unsigned*)&Canon, 5 ); printf( "\n" ); + + printf( "Members = %d.\n", Vec_IntSize(vRes) ); + Vec_IntForEachEntry( vRes, Entry, i ) + { + Extra_PrintHex( stdout, (unsigned*)&Entry, 5 ); + printf( ", " ); + if ( i % 8 == 7 ) + printf( "\n" ); + } + + Vec_IntFree( vRes ); +} + +void Acec_MultFuncTest4() +{ + Vec_Int_t * vRes = Vec_IntAlloc( 1000 ); + int i, Entry; + + unsigned Truth = 0x35C0; + //unsigned Truth = 0xD728; + unsigned Canon = Extra_TruthCanonNPN2( Truth, 4, vRes ); + + Extra_PrintHex( stdout, (unsigned*)&Truth, 4 ); printf( "\n" ); + Extra_PrintHex( stdout, (unsigned*)&Canon, 4 ); printf( "\n" ); + + printf( "Members = %d.\n", Vec_IntSize(vRes) ); + Vec_IntForEachEntry( vRes, Entry, i ) + { + Extra_PrintHex( stdout, (unsigned*)&Entry, 4 ); + printf( ", " ); + if ( i % 12 == 11 ) + printf( "\n" ); + } + + Vec_IntFree( vRes ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_MultCollectInputs( Vec_Int_t * vPairs, Vec_Int_t * vRanks, int iObj ) +{ + Vec_Int_t * vItems = Vec_IntAlloc( 100 ); + int k, iObj1, iObj2; + // collect all those appearing with this one + Vec_IntForEachEntryDouble( vPairs, iObj1, iObj2, k ) + if ( iObj == iObj1 ) + Vec_IntPushUnique( vItems, iObj2 ); + else if ( iObj == iObj2 ) + Vec_IntPushUnique( vItems, iObj1 ); + // sort items by rank cost + Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks ); + return vItems; +} +Vec_Int_t * Acec_MultDetectInputs1( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ + Vec_Int_t * vInputs = Vec_IntAlloc( 100 ); + Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vPairs = Vec_IntAlloc( 100 ); + Vec_Int_t * vItems = Vec_IntAlloc( 100 ); + Vec_Int_t * vItems0; + Vec_Int_t * vItems1; + Vec_Int_t * vLevel; + int i, k, iLit, iObj, Count; + // count how many times each input appears + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + iObj = Abc_Lit2Var(iLit); + Vec_IntAddToEntry( vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), 1 ); + Vec_IntAddToEntry( vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), 1 ); +/* + printf( "Rank %2d : Leaf = %4d : (%2d, %2d)\n", i, iObj, + Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) ); + if ( k == Vec_IntSize(vLevel) - 1 ) + printf( "\n" ); +*/ + } + // count ranks for each one + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + iObj = Abc_Lit2Var(iLit); + if ( Vec_IntEntry(vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj)) < 2 ) + { + printf( "Skipping %d.\n", iObj ); + continue; + } + if ( Vec_IntEntry(vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj)) < 2 ) + { + printf( "Skipping %d.\n", iObj ); + continue; + } + Vec_IntAddToEntry( vRanks, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), i ); + Vec_IntAddToEntry( vRanks, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), i ); + + Vec_IntPushTwo( vPairs, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) ); + } + + // print statistics + Vec_IntForEachEntry( vCounts, Count, i ) + { + if ( !Count ) + continue; + if ( !Vec_IntEntry(vRanks, i) ) + continue; + Vec_IntPush( vItems, i ); + printf( "Obj = %3d Occurs = %3d Ranks = %3d\n", i, Count, Vec_IntEntry(vRanks, i) ); + } + // sort items by rank cost + Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks ); + // collect all those appearing with the last one + vItems0 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems) ); + Vec_IntAppend( vInputs, vItems0 ); + // collect all those appearing with the last one + vItems1 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems0) ); + Vec_IntAppend( vInputs, vItems1 ); + + Vec_IntPrint( vItems0 ); + Vec_IntPrint( vItems1 ); + + Vec_IntFree( vCounts ); + Vec_IntFree( vRanks ); + Vec_IntFree( vPairs ); + Vec_IntFree( vItems ); + Vec_IntFree( vItems0 ); + Vec_IntFree( vItems1 ); + return vInputs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ + Vec_Int_t * vInputs = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, iLit, iObj, j, Entry; + + ABC_FREE( p->pRefs ); + Gia_ManCreateRefs( p ); + Gia_ManForEachCiId( p, iObj, i ) + printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) ); + printf( "\n" ); + Gia_ManForEachAndId( p, iObj ) + if ( Gia_ObjRefNumId(p, iObj) >= 4 ) + printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) ); + printf( "\n" ); + + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); + if ( Vec_IntSize(vSupp) >= 4 ) + { + printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) ); + printf( "Rank = %2d ", i ); + printf( "Supp = %2d ", Vec_IntSize(vSupp) ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + // support rank counts + Vec_IntForEachEntry( vSupp, Entry, j ) + { + Vec_IntAddToEntry( vRanks, Entry, i ); + Vec_IntAddToEntry( vCounts, Entry, 1 ); + } + if ( k == Vec_IntSize(vLevel)-1 ) + printf( "\n" ); + } + + Vec_IntForEachEntry( vCounts, Entry, j ) + if ( Entry ) + printf( "%d=%d(%.2f) ", j, Entry, 1.0*Vec_IntEntry(vRanks, j)/Entry ); + printf( "\n" ); + + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + Vec_IntFree( vRanks ); + Vec_IntFree( vCounts ); + return vInputs; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 1c0af00a5..53e1cb60f 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -307,16 +307,16 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bi if ( fFadd ) // FADD { if ( TruthXor != 0x96 ) - printf( "Fadd %d sum is wrong.\n", iBox ); + printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0xE8 ) - printf( "Fadd %d carry is wrong.\n", iBox ); + printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); } else { if ( TruthXor != 0x66 ) - printf( "Hadd %d sum is wrong.\n", iBox ); + printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0x88 ) - printf( "Hadd %d carry is wrong.\n", iBox ); + printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); } } void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) @@ -356,7 +356,9 @@ void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, in assert( Node != 0 ); if ( Vec_BitEntry(vVisit, Node) ) { - assert( Vec_BitEntry(vPhase, Node) == fPhase ); + //assert( Vec_BitEntry(vPhase, Node) == fPhase ); + if ( Vec_BitEntry(vPhase, Node) != fPhase ) + printf( "Phase check failed for node %d.\n", Node ); return; } Vec_BitWriteEntry( vVisit, Node, 1 ); @@ -386,7 +388,12 @@ void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, in Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); } if ( Vec_BitEntry(vVisit, iXor) ) - assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + { + //assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + if ( Vec_BitEntry(vPhase, iXor) != fXorPhase ) + printf( "Phase check failed for XOR %d.\n", iXor ); + return; + } if ( fXorPhase ) Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); } @@ -448,7 +455,7 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) int i, k, iBox; Vec_WecForEachLevel( vBoxes, vLevel, i ) { - printf( " %4d : {", i ); + printf( " %4d : %2d {", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iBox, k ) printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); @@ -461,7 +468,7 @@ void Vec_WecPrintLits( Vec_Wec_t * p ) int i, k, Entry; Vec_WecForEachLevel( p, vVec, i ) { - printf( " %4d : {", i ); + printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); Vec_IntForEachEntry( vVec, Entry, k ) printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); printf( " }\n" ); @@ -473,7 +480,7 @@ void Acec_PrintRootLits( Vec_Wec_t * vRoots ) int i, k, iObj; Vec_WecForEachLevel( vRoots, vLevel, i ) { - printf( "Rank %d : ", i ); + printf( "Rank %d : %2d ", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iObj, k ) { int fFadd = Abc_LitIsCompl(iObj); @@ -573,6 +580,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); +// Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 25fa25484..dbf86ac2a 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -8,6 +8,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecPool.c \ src/proof/acec/acecCover.c \ src/proof/acec/acecFadds.c \ + src/proof/acec/acecMult.c \ src/proof/acec/acecNorm.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ From f5240276cb29e730be44b96da9013db046683a5f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 15:25:35 +0700 Subject: [PATCH 51/61] Updates to arithmetic verification. --- src/aig/gia/giaTruth.c | 2 ++ src/proof/acec/acecMult.c | 2 +- src/proof/acec/acecTree.c | 63 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c index f636a573c..ab5f569e9 100644 --- a/src/aig/gia/giaTruth.c +++ b/src/aig/gia/giaTruth.c @@ -184,6 +184,8 @@ word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wr if ( !iObj ) return Abc_LitIsCompl(iLit) ? ~(word)0 : (word)0; Gia_ManIncrementTravId( p ); Gia_ObjComputeTruth6CisSupport_rec( p, iObj, vSupp ); + if ( Vec_IntSize(vSupp) > 6 ) + return 0; Gia_ObjComputeTruth6( p, iObj, vSupp, vTemp ); return Abc_LitIsCompl(iLit) ? ~Vec_WrdEntry(vTemp, iObj) : Vec_WrdEntry(vTemp, iObj); } diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 397f6d571..33c321443 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -389,7 +389,7 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec Vec_IntForEachEntry( vLevel, iLit, k ) { word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); - if ( Vec_IntSize(vSupp) >= 4 ) + if ( Vec_IntSize(vSupp) >= 0 ) { printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) ); printf( "Rank = %2d ", i ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 53e1cb60f..8be8a3402 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -61,6 +61,65 @@ void Acec_BoxFreeP( Acec_Box_t ** ppBox ) *ppBox = NULL; } +/**Function************************************************************* + + Synopsis [Filters trees by removing TFO of roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ; + Gia_Obj_t * pObj; + int i, k = 0, Box, Rank; + // mark roots + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+0), 0 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+1), 0 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+2), 0 ); + } + // iterate through nodes to detect TFO of roots + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Vec_BitEntry(vIsRoot, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vIsRoot, Gia_ObjFaninId1(pObj,i)) || + Vec_BitEntry(vMarked, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vMarked, Gia_ObjFaninId1(pObj,i)) ) + Vec_BitWriteEntry( vMarked, i, 1 ); + } + // remove those that overlap with roots + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) + { + printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); + continue; + } + Vec_IntWriteEntry( vTree, k++, Box ); + Vec_IntWriteEntry( vTree, k++, Rank ); + } + Vec_IntShrink( vTree, k ); + Vec_BitFree( vIsRoot ); + Vec_BitFree( vMarked ); +} +void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees ) +{ + Vec_Int_t * vLevel; + int i; + Vec_WecForEachLevel( vTrees, vLevel, i ) + Acec_TreeFilterOne( p, vAdds, vLevel ); +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -163,6 +222,8 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) } Vec_BitFree( vFound ); Vec_IntFree( vMap ); + // filter trees + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -580,7 +641,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); -// Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; From 1a39fb39462d34e40e4ed9da4615d18a463471e0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 17:32:58 +0700 Subject: [PATCH 52/61] Adding print-out of critical path for mapped AIGs to &show. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaShow.c | 342 +++++++++++++++++++++++++++++++++++++++--- src/base/abci/abc.c | 15 +- src/opt/sbd/sbdPath.c | 54 +++++++ 4 files changed, 381 insertions(+), 32 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 7cf1feff3..680601191 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1426,7 +1426,7 @@ extern Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); /*=== giaShow.c ===========================================================*/ -extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ); +extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath ); /*=== giaShrink.c ===========================================================*/ extern Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose ); extern Gia_Man_t * Gia_ManMapShrink6( Gia_Man_t * p, int nFanoutMax, int fKeepLevel, int fVerbose ); diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 5589d3841..28e874bfd 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -46,40 +46,64 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) +void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) { FILE * pFile; - Gia_Obj_t * pNode;//, * pTemp, * pPrev; - int LevelMax, Prev, Level, i; - int fConstIsUsed = 0; + Gia_Obj_t * pNode; + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + int i, k, iFan, LevelMax, nLevels, * pLevels, Level, Prev; + int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + assert( Gia_ManHasMapping(p) ); - if ( Gia_ManAndNum(p) > 500 ) + // set critical CO drivers + nLevels = Gia_ManLutLevel( p, &pLevels ); + Gia_ManForEachCoDriverId( p, iFan, i ) + if ( pLevels[iFan] == nLevels ) + Vec_BitWriteEntry( vPath, iFan, 1 ); + + // set critical internal nodes + Gia_ManForEachLutReverse( p, i ) + { + nLuts++; + if ( !Vec_BitEntry(vPath, i) ) + continue; + nNodes++; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] +1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + Vec_BitWriteEntry( vPath, iFan, 1 ); + nEdges++; + //printf( "%d -> %d\n", i, iFan ); + } + } + + if ( nNodes > 500 ) { - fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); + fprintf( stdout, "Cannot visualize AIG with more than 500 critical nodes.\n" ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) { + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); return; } - // mark the nodes - if ( vBold ) - Gia_ManForEachObjVec( vBold, p, pNode, i ) - pNode->fMark0 = 1; - else if ( p->nXors || p->nMuxes ) - Gia_ManForEachObj( p, pNode, i ) - if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) ) - pNode->fMark0 = 1; + Vec_IntFreeP( &p->vLevels ); + p->vLevels = Vec_IntAllocArray( pLevels, Gia_ManObjNum(p) ); - // compute levels - LevelMax = 1 + Gia_ManLevelNum( p ); + // compute CO levels + LevelMax = 1 + nLevels; Gia_ManForEachCo( p, pNode, i ) Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); // write the DOT header - fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); fprintf( pFile, "\n" ); fprintf( pFile, "digraph AIG {\n" ); fprintf( pFile, "size = \"7.5,10\";\n" ); @@ -153,7 +177,271 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); + fprintf( pFile, "The critical path contains %d LUTs with %d critical edges and spans %d levels.", nNodes, nEdges, nLevels ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate the COs + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", LevelMax ); + // generate the CO nodes + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ); + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + fprintf( pFile, ", shape = %s", "invtriangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate nodes of each rank + for ( Level = LevelMax - 1; Level > 0; Level-- ) + { + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", Level ); + Gia_ManForEachObj( p, pNode, i ) + { + if ( (int)Gia_ObjLevel(p, pNode) != Level || !Vec_BitEntry(vPath, i) ) + continue; + fprintf( pFile, " Node%d [label = \"%d:%d\"", i, i, Gia_ObjIsAnd(pNode)? Gia_ObjLutSize(p, i) : 0 ); + fprintf( pFile, ", shape = ellipse" ); + if ( pNode->fMark0 ) + fprintf( pFile, ", style = filled" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + } + + // generate the CI nodes + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", 0 ); + // generate the CI nodes + Gia_ManForEachCi( p, pNode, i ) + { + if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) ) + continue; + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate invisible edges from the square down + fprintf( pFile, "title1 -> title2 [style = invis];\n" ); + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) ); + } + // generate invisible edges among the COs + Prev = -1; + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ); + if ( Prev >= 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Gia_ManForEachCi( p, pNode, i ) + { + if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) ) + continue; + if ( Prev >= 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + + // generate edges + Gia_ManForEachObj( p, pNode, i ) + { + if ( Gia_ObjIsCo(pNode) ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ) + { + // generate the edge from this node to the next + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ObjFaninId0p(p, pNode) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + continue; + } + if ( !Gia_ObjIsAnd(pNode) || !Vec_BitEntry(vPath, i) ) + continue; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] + 1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + // generate the edge from this node to the next + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", iFan ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + } + + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + + Vec_IntFreeP( &p->vLevels ); + Vec_BitFree( vPath ); +} + + +/**Function************************************************************* + + Synopsis [Writes the graph structure of AIG for DOT.] + + Description [Useful for graph visualization using tools such as GraphViz: + http://www.graphviz.org/] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) +{ + FILE * pFile; + Gia_Obj_t * pNode;//, * pTemp, * pPrev; + int LevelMax, Prev, Level, i; + int fConstIsUsed = 0; + + if ( Gia_ManAndNum(p) > 500 ) + { + fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); + return; + } + if ( (pFile = fopen( pFileName, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); + return; + } + + // mark the nodes + if ( vBold ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) + pNode->fMark0 = 1; + else if ( p->nXors || p->nMuxes ) + Gia_ManForEachObj( p, pNode, i ) + if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) ) + pNode->fMark0 = 1; + + // compute levels + LevelMax = 1 + Gia_ManLevelNum( p ); + Gia_ManForEachCo( p, pNode, i ) + Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); + + // write the DOT header + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "digraph AIG {\n" ); + fprintf( pFile, "size = \"7.5,10\";\n" ); +// fprintf( pFile, "ranksep = 0.5;\n" ); +// fprintf( pFile, "nodesep = 0.5;\n" ); + fprintf( pFile, "center = true;\n" ); +// fprintf( pFile, "orientation = landscape;\n" ); +// fprintf( pFile, "edge [fontsize = 10];\n" ); +// fprintf( pFile, "edge [dir = none];\n" ); + fprintf( pFile, "edge [dir = back];\n" ); + fprintf( pFile, "\n" ); + + // labels on the left of the picture + fprintf( pFile, "{\n" ); + fprintf( pFile, " node [shape = plaintext];\n" ); + fprintf( pFile, " edge [style = invis];\n" ); + fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); + fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); + // generate node names with labels + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + fprintf( pFile, " [label = " ); + // label name + fprintf( pFile, "\"" ); + fprintf( pFile, "\"" ); + fprintf( pFile, "];\n" ); + } + + // genetate the sequence of visible/invisible nodes to mark levels + fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + // the connector + if ( Level != 0 ) + fprintf( pFile, " ->" ); + else + fprintf( pFile, ";" ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate title box on top + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle1;\n" ); + fprintf( pFile, " title1 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=20,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "%s", "AIG structure visualized by ABC" ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" ); +// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate statistics box + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle2;\n" ); + fprintf( pFile, " title2 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=18,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "The AIG contains %d nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -388,6 +676,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Gia_Obj_t * pNode;//, * pTemp, * pPrev; int LevelMax, Prev, Level, i; int fConstIsUsed = 0; + int nFadds = Ree_ManCountFadds( vAdds ); if ( Gia_ManAndNum(p) > 1000 ) { @@ -406,7 +695,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); // write the DOT header - fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); fprintf( pFile, "\n" ); fprintf( pFile, "digraph AIG {\n" ); fprintf( pFile, "size = \"7.5,10\";\n" ); @@ -480,7 +769,8 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); + fprintf( pFile, "The AIG contains %d nodes, %d full-adders, and %d half-adders, and spans %d levels.", + Gia_ManAndNum(p), nFadds, Vec_IntSize(vAdds)/6-nFadds, LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -813,12 +1103,12 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); } -void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) +void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath ) { extern void Abc_ShowFile( char * FileNameDot ); char FileNameDot[200]; FILE * pFile; - Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); + Vec_Int_t * vXors = NULL, * vAdds = fAdders ? Ree_ManComputeCuts( pMan, &vXors, 0 ) : NULL; sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) @@ -828,15 +1118,17 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) } fclose( pFile ); // generate the file - if ( fAdders ) + if ( fPath ) + Gia_ShowPath( pMan, FileNameDot ); + else if ( fAdders ) Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file Abc_ShowFile( FileNameDot ); - Vec_IntFree( vAdds ); - Vec_IntFree( vXors ); + Vec_IntFreeP( &vAdds ); + Vec_IntFreeP( &vXors ); } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 20d44227e..910014c6d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -28594,9 +28594,9 @@ usage: int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) { Vec_Int_t * vBold = NULL; - int c, fAdders = 0, fFadds = 0; + int c, fAdders = 0, fFadds = 0, fPath = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "afh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "afph" ) ) != EOF ) { switch ( c ) { @@ -28606,6 +28606,9 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'f': fFadds ^= 1; break; + case 'p': + fPath ^= 1; + break; case 'h': goto usage; default: @@ -28628,15 +28631,16 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManForEachLut( pAbc->pGia, c ) Vec_IntPush( vBold, c ); } - Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds ); + Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds, fPath ); Vec_IntFreeP( &vBold ); return 0; usage: - Abc_Print( -2, "usage: &show [-afh]\n" ); + Abc_Print( -2, "usage: &show [-afph]\n" ); Abc_Print( -2, "\t shows the current GIA using GSView\n" ); Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle only showing full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle showing only full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle showing the critical path of a LUT mapping [default = %s]\n", fPath? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -42679,7 +42683,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); // Gia_PolynExplore( pAbc->pGia ); -// Gia_ManTestSatEnum( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index a2b1a9b00..270c81c8f 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -134,6 +134,60 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbc_ManDelayTrace( Gia_Man_t * p ) +{ + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + int i, k, iFan, nLevels, * pLevels; + int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + if ( !Gia_ManHasMapping(p) ) + { + printf( "No mapping is available.\n" ); + return; + } + assert( Gia_ManHasMapping(p) ); + // set critical CO drivers + nLevels = Gia_ManLutLevel( p, &pLevels ); + Gia_ManForEachCoDriverId( p, iFan, i ) + if ( pLevels[iFan] == nLevels ) + Vec_BitWriteEntry( vPath, iFan, 1 ); + // set critical internal nodes + Gia_ManForEachLutReverse( p, i ) + { + nLuts++; + if ( !Vec_BitEntry(vPath, i) ) + continue; + nNodes++; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] +1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + Vec_BitWriteEntry( vPath, iFan, 1 ); + nEdges++; + //printf( "%d -> %d\n", i, iFan ); + } + } + Gia_ManForEachLut( p, i ) + Gia_LutForEachFanin( p, i, iFan, k ) + nEdgesAll += (Vec_BitEntry(vPath, i) && Vec_BitEntry(vPath, iFan)); + + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); + printf( "AIG = %d. LUT = %d. Lev = %d. Path nodes = %d. Path edges = %d. (%d.)\n", + Gia_ManAndNum(p), nLuts, nLevels, nNodes, nEdges, nEdgesAll ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 6d606b51ab084c96d92848be789397700bb3591f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 21:17:00 +0700 Subject: [PATCH 53/61] Updates to arithmetic verification. --- src/aig/gia/giaShow.c | 28 ++- src/base/wlc/wlcBlast.c | 10 + src/proof/acec/acecInt.h | 3 - src/proof/acec/acecMult.c | 107 +++++++++ src/proof/acec/acecTree.c | 456 ++++++++++++++++---------------------- 5 files changed, 326 insertions(+), 278 deletions(-) diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 28e874bfd..cf89d942d 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -52,7 +52,7 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) Gia_Obj_t * pNode; Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); int i, k, iFan, LevelMax, nLevels, * pLevels, Level, Prev; - int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + int nLuts = 0, nNodes = 0, nEdges = 0; assert( Gia_ManHasMapping(p) ); // set critical CO drivers @@ -670,7 +670,7 @@ int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node ) return Vec_IntEntry( vAdds, 6*iBox+4 ); return Node; } -void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) +void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) { FILE * pFile; Gia_Obj_t * pNode;//, * pTemp, * pPrev; @@ -689,6 +689,11 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In return; } + // mark the nodes + if ( vBold ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) + pNode->fMark0 = 1; + // compute levels LevelMax = 1 + p->nLevels; Gia_ManForEachCo( p, pNode, i ) @@ -819,7 +824,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In else fprintf( pFile, ", shape = ellipse" ); */ - if ( Vec_IntEntry(vMapAdds, iNode) >= 0 ) + if ( !pNode->fMark0 && Vec_IntEntry(vMapAdds, iNode) >= 0 ) { int iBox = Vec_IntEntry(vMapAdds, iNode); fprintf( pFile, " Node%d [label = \"%d_%d\"", Gia_ShowAddOut(vAdds, vMapAdds, iNode), Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); @@ -848,8 +853,8 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); fprintf( pFile, ", shape = ellipse" ); } -// if ( pNode->fMark0 ) -// fprintf( pFile, ", style = filled" ); + if ( pNode->fMark0 ) + fprintf( pFile, ", style = filled" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); @@ -920,8 +925,6 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Gia_ManForEachObjVec( vOrder, p, pNode, i ) { int iNode = Gia_ObjId( p, pNode ); -// if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) ) -// continue; if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pNode)) >= 0 ) { int k, iBox = Vec_IntEntry(vMapAdds, iNode); @@ -990,6 +993,11 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, "\n" ); fclose( pFile ); + // unmark nodes + if ( vBold ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) + pNode->fMark0 = 0; + Vec_IntFreeP( &p->vLevels ); } @@ -1093,12 +1101,12 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v SeeAlso [] ***********************************************************************/ -void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) +void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); - Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Gia_WriteDotAig( p, pFileName, vBold, vAdds, vXors, vMapAdds, vMapXors, vOrder ); Vec_IntFree( vMapAdds ); Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); @@ -1121,7 +1129,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, if ( fPath ) Gia_ShowPath( pMan, FileNameDot ); else if ( fAdders ) - Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); + Gia_ShowProcess( pMan, FileNameDot, vBold, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index b22ac6cdc..b49c2dd7b 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -645,10 +645,20 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) } void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) { + int fVerbose = 0; Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel; word Truth; int i, k, iLit; + Vec_WecForEachLevel( vProds, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) ) + Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) ); + printf( "Booth partial products: %d pps, %d unique, %d nodes.\n", + Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) ); + Vec_IntPrint( vSupp ); + + if ( fVerbose ) Vec_WecForEachLevel( vProds, vLevel, i ) Vec_IntForEachEntry( vLevel, iLit, k ) { diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 0dc3f7060..125d923fa 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -42,13 +42,10 @@ struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager Vec_Wec_t * vAdds; // adders by rank - Vec_Wec_t * vLeafs; // leaf literals by rank - Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves Vec_Wec_t * vUnique; // unique leaves - Vec_Bit_t * vInvHadds; // complemented half adders }; //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 33c321443..8ccf966ef 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -20,6 +20,7 @@ #include "acecInt.h" #include "misc/extra/extra.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -400,6 +401,15 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); printf( " " ); Vec_IntPrint( vSupp ); + /* + if ( Truth == 0xF335ACC0F335ACC0 ) + { + int iObj = Abc_Lit2Var(iLit); + Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 ); + Gia_ManShow( pGia0, NULL, 0, 0, 0 ); + Gia_ManStop( pGia0 ); + } + */ } // support rank counts Vec_IntForEachEntry( vSupp, Entry, j ) @@ -423,6 +433,103 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec return vInputs; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_MultFindPPs_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vBold ) +{ + Gia_Obj_t * pObj; + pObj = Gia_ManObj( p, iObj ); + if ( pObj->fMark0 ) + return; + pObj->fMark0 = 1; + if ( !Gia_ObjIsAnd(pObj) ) + return; + Acec_MultFindPPs_rec( p, Gia_ObjFaninId0(pObj, iObj), vBold ); + Acec_MultFindPPs_rec( p, Gia_ObjFaninId1(pObj, iObj), vBold ); + Vec_IntPush( vBold, iObj ); +} +Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) +{ + word Saved[32] = { + ABC_CONST(0xF335ACC0F335ACC0), + ABC_CONST(0x35C035C035C035C0), + ABC_CONST(0xD728D728D728D728), + ABC_CONST(0xFD80FD80FD80FD80), + ABC_CONST(0xACC0ACC0ACC0ACC0), + ABC_CONST(0x7878787878787878), + ABC_CONST(0x2828282828282828), + ABC_CONST(0xD0D0D0D0D0D0D0D0), + ABC_CONST(0x8080808080808080), + ABC_CONST(0x8888888888888888), + ABC_CONST(0xAAAAAAAAAAAAAAAA), + ABC_CONST(0x5555555555555555), + + ABC_CONST(0xD5A8D5A8D5A8D5A8), + ABC_CONST(0x2A572A572A572A57), + ABC_CONST(0xF3C0F3C0F3C0F3C0), + ABC_CONST(0x5858585858585858), + ABC_CONST(0xA7A7A7A7A7A7A7A7), + ABC_CONST(0x2727272727272727), + ABC_CONST(0xD8D8D8D8D8D8D8D8) + }; + + Vec_Int_t * vBold = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + int i, iObj, nProds = 0; + Gia_ManCleanMark0(p); + Gia_ManForEachAndId( p, iObj ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp ); + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + continue; + for ( i = 0; i < 32; i++ ) + { + if ( Saved[i] == 0 ) + break; + if ( Truth == Saved[i] || Truth == ~Saved[i] ) + { + //Vec_IntPush( vBold, iObj ); + Acec_MultFindPPs_rec( p, iObj, vBold ); + printf( "%d ", iObj ); + nProds++; + break; + } + } +/* + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); +*/ + } + printf( "\n" ); + Gia_ManCleanMark0(p); + printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); + + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + return vBold; +} +void Acec_MultFindPPsTest( Gia_Man_t * p ) +{ + Vec_Int_t * vBold = Acec_MultFindPPs( p ); + Gia_ManShow( p, vBold, 1, 0, 0 ); + Vec_IntFree( vBold ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 8be8a3402..370e8eb65 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -45,13 +45,10 @@ ABC_NAMESPACE_IMPL_START void Acec_BoxFree( Acec_Box_t * pBox ) { Vec_WecFreeP( &pBox->vAdds ); - Vec_WecFreeP( &pBox->vLeafs ); - Vec_WecFreeP( &pBox->vRoots ); Vec_WecFreeP( &pBox->vLeafLits ); Vec_WecFreeP( &pBox->vRootLits ); Vec_WecFreeP( &pBox->vUnique ); Vec_WecFreeP( &pBox->vShared ); - Vec_BitFreeP( &pBox->vInvHadds ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) @@ -120,6 +117,141 @@ void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees Acec_TreeFilterOne( p, vAdds, vLevel ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + int Truth0, Truth1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return pObj->Value; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + assert( !Gia_ObjIsXor(pObj) ); + Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); + Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); + Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; + Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; + return (pObj->Value = Truth0 & Truth1); +} +void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) +{ + Gia_Obj_t * pObj; + unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; + int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; + + int Sign = Vec_IntEntry( vAdds, 6*iBox+5 ), Phase[5]; + for ( k = 0; k < 5; k++ ) + Phase[k] = (Sign >> (4+k)) & 1; + + Gia_ManIncrementTravId( p ); + for ( k = 0; k < 3; k++ ) + { + iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + pObj = Gia_ManObj( p, iObj ); + pObj->Value = Phase[k] ? 0xFF & ~Truths[k] : Truths[k]; + Gia_ObjSetTravIdCurrent( p, pObj ); + } + + iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); + TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthXor = Phase[3] ? 0xFF & ~TruthXor : TruthXor; + + iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); + TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthMaj = Phase[4] ? 0xFF & ~TruthMaj : TruthMaj; + + if ( fFadd ) // FADD + { + if ( TruthXor != 0x96 ) + printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); + if ( TruthMaj != 0xE8 ) + printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); + } + else + { + if ( TruthXor != 0x66 ) + printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); + if ( TruthMaj != 0x88 ) + printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); + } +} +void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Acec_TreeVerifyPhaseOne( p, vAdds, Box ); +} + +/**Function************************************************************* + + Synopsis [Creates polarity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); + return vMap; +} +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase ) +{ + int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + assert( Node != 0 ); + iBox = Vec_IntEntry( vMap, Node ); + if ( iBox == -1 ) + return; + assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); + Sign = Vec_IntEntry( vAdds, 6*iBox+5 ) & 0xFFFFFFF0; + fXorPhase = ((Sign >> 3) & 1); + if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) + { + fPhase ^= ((Sign >> 2) & 1); + if ( fPhase ) // complemented HADD + Sign |= (1 << 6); + } + for ( k = 0; k < 3; k++ ) + { + int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fXorPhase ^= fPhaseThis; + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis ); + if ( fPhaseThis ) + Sign |= (1 << (4+k)); + } + if ( fXorPhase ) + Sign |= (1 << 7); + if ( fPhase ) + Sign |= (1 << 8); + // save updated signature + Vec_IntWriteEntry( vAdds, 6*iBox+5, Sign ); +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -249,256 +381,6 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) } -/**Function************************************************************* - - Synopsis [Creates leaves and roots.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) -{ - int k, Box, Rank, MaxRank = 0; - Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) - MaxRank = Abc_MaxInt( MaxRank, Rank ); - return MaxRank; -} -void Acec_TreeInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vBoxes, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) -{ - Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, Box, Rank; - Vec_BitWriteEntry( vIsLeaf, 0, 1 ); - Vec_BitWriteEntry( vIsRoot, 0, 1 ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); - } - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - Vec_WecPush( vBoxes, Rank, Box ); - for ( k = 0; k < 3; k++ ) - { - if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) - continue; - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k), 1 ); - Vec_WecPush( vLeaves, Rank, Vec_IntEntry(vAdds, 6*Box+k) ); - } - for ( k = 3; k < 5; k++ ) - { - if ( Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) - continue; - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k), 1 ); - Vec_WecPush( vRoots, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), k==4), Vec_IntEntry(vAdds, 6*Box+2)!=0) ); - } - } - Vec_BitFree( vIsLeaf ); - Vec_BitFree( vIsRoot ); - // sort each level - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntSort( vLevel, 0 ); - Vec_WecForEachLevel( vLeaves, vLevel, i ) - Vec_IntSort( vLevel, 0 ); - Vec_WecForEachLevel( vRoots, vLevel, i ) - Vec_IntSort( vLevel, 0 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) -{ - int Truth0, Truth1; - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return pObj->Value; - Gia_ObjSetTravIdCurrent(p, pObj); - assert( Gia_ObjIsAnd(pObj) ); - assert( !Gia_ObjIsXor(pObj) ); - Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); - Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); - Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; - Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; - return (pObj->Value = Truth0 & Truth1); -} -void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bit_t * vPhase ) -{ - Gia_Obj_t * pObj; - unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; - int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; - - //if ( !fFadd ) - // return; - - Gia_ManIncrementTravId( p ); - for ( k = 0; k < 3; k++ ) - { - iObj = Vec_IntEntry( vAdds, 6*iBox+k ); - if ( iObj == 0 ) - continue; - pObj = Gia_ManObj( p, iObj ); - pObj->Value = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~Truths[k] : Truths[k]; - Gia_ObjSetTravIdCurrent( p, pObj ); - } - - iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); - TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthXor = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthXor : TruthXor; - - iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); - TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthMaj = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthMaj : TruthMaj; - - if ( fFadd ) // FADD - { - if ( TruthXor != 0x96 ) - printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); - if ( TruthMaj != 0xE8 ) - printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); - } - else - { - if ( TruthXor != 0x66 ) - printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); - if ( TruthMaj != 0x88 ) - printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); - } -} -void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) -{ - Vec_Int_t * vLevel; - int i, k, Box; - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, Box, k ) - Acec_TreeVerifyPhaseOne( p, vAdds, Box, vPhase ); -} - -/**Function************************************************************* - - Synopsis [Creates polarity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) -{ - Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, Box; - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, Box, k ) - Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); - return vMap; -} -void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, - Vec_Bit_t * vPhase, Vec_Bit_t * vInvHadds, Vec_Bit_t * vVisit ) -{ - int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; - assert( Node != 0 ); - if ( Vec_BitEntry(vVisit, Node) ) - { - //assert( Vec_BitEntry(vPhase, Node) == fPhase ); - if ( Vec_BitEntry(vPhase, Node) != fPhase ) - printf( "Phase check failed for node %d.\n", Node ); - return; - } - Vec_BitWriteEntry( vVisit, Node, 1 ); - if ( fPhase ) - Vec_BitWriteEntry( vPhase, Node, fPhase ); - iBox = Vec_IntEntry( vMap, Node ); - if ( iBox == -1 ) - return; - assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); - iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); - Sign = Vec_IntEntry( vAdds, 6*iBox+5 ); - fXorPhase = ((Sign >> 3) & 1); - if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) - { - fPhase ^= ((Sign >> 2) & 1); - // remember complemented HADD - if ( fPhase ) - Vec_BitWriteEntry( vInvHadds, iBox, 1 ); - } - for ( k = 0; k < 3; k++ ) - { - int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); - if ( iObj == 0 ) - continue; - fPhaseThis = ((Sign >> k) & 1) ^ fPhase; - fXorPhase ^= fPhaseThis; - Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); - } - if ( Vec_BitEntry(vVisit, iXor) ) - { - //assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); - if ( Vec_BitEntry(vPhase, iXor) != fXorPhase ) - printf( "Phase check failed for XOR %d.\n", iXor ); - return; - } - if ( fXorPhase ) - Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); -} -void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, - Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, - Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits, Vec_Bit_t * vInvHadds ) -{ - Vec_Int_t * vMap = Acec_TreeCarryMap( p, vAdds, vBoxes ); - Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Bit_t * vVisit = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevelReverse( vRoots, vLevel, i ) - { - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - if ( !fCout ) - continue; - Acec_TreePhases_rec( p, vAdds, vMap, Node, fFadd, vPhase, vInvHadds, vVisit ); - } - } - Vec_IntFree( vMap ); - Vec_BitFree( vVisit ); - Acec_TreeVerifyPhases( p, vAdds, vBoxes, vPhase ); - // create leaves - Vec_WecForEachLevel( vLeaves, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - Vec_WecPush( vLeafLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); - // add constants - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - if ( Vec_BitEntry(vInvHadds, iObj) ) - Vec_WecPush( vLeafLits, i, 1 ); - // create roots - Vec_WecForEachLevel( vRoots, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - iObj >>= 2, Vec_WecPush( vRootLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); - // cleanup - Vec_BitFree( vPhase ); -} - /**Function************************************************************* Synopsis [Derives one adder tree.] @@ -564,25 +446,69 @@ void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) //Acec_PrintRootLits( pBox->vRoots ); } +int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) +{ + int k, Box, Rank, MaxRank = 0; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MaxRank = Abc_MaxInt( MaxRank, Rank ); + return MaxRank; +} Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { int MaxRank = Acec_CreateBoxMaxRank(vTree); + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel, * vMap; + int i, k, Box, Rank; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); - pBox->pGia = p; + pBox->pGia = p; + pBox->vAdds = Vec_WecStart( MaxRank + 1 ); + pBox->vLeafLits = Vec_WecStart( MaxRank + 1 ); + pBox->vRootLits = Vec_WecStart( MaxRank + 2 ); - pBox->vAdds = Vec_WecStart( MaxRank + 1 ); - pBox->vLeafs = Vec_WecStart( MaxRank + 1 ); - pBox->vRoots = Vec_WecStart( MaxRank + 2 ); + // collect boxes; mark inputs/outputs + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_WecPush( pBox->vAdds, Rank, Box ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + // sort each level + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntSort( vLevel, 0 ); - Acec_TreeInsOuts( p, vAdds, vTree, pBox->vAdds, pBox->vLeafs, pBox->vRoots ); - - pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); - pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); - pBox->vInvHadds = Vec_BitStart( Vec_IntSize(vAdds)/6 ); - - Acec_TreePhases( p, vAdds, pBox->vAdds, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits, pBox->vInvHadds ); + // set phases + vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0 ); + Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); + Vec_IntFree( vMap ); + // collect inputs/outputs + Vec_BitWriteEntry( vIsLeaf, 0, 0 ); + Vec_BitWriteEntry( vIsRoot, 0, 0 ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + int Sign = Vec_IntEntry( vAdds, 6*Box+5 ); + for ( k = 0; k < 3; k++ ) + if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vLeafLits, Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (4+k)) & 1) ); + for ( k = 3; k < 5; k++ ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vRootLits, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (7+k)) & 1) ); + } + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vIsRoot ); + // sort each level + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntSort( vLevel, 0 ); return pBox; } void Acec_CreateBoxTest( Gia_Man_t * p ) @@ -641,7 +567,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); - //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; From 79701f8b4603596095d3d04a13018c8e9598f7a0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Jan 2017 16:11:59 +0700 Subject: [PATCH 54/61] Updates to arithmetic verification. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaEquiv.c | 27 ++++++- src/base/abci/abc.c | 20 +++-- src/base/abci/abcDress3.c | 30 +------ src/proof/acec/acec.h | 3 +- src/proof/acec/acecCore.c | 73 +++++++++++++---- src/proof/acec/acecInt.h | 3 +- src/proof/acec/acecMult.c | 19 +++-- src/proof/acec/acecNorm.c | 6 +- src/proof/acec/acecTree.c | 161 ++++++++++++++++++++++---------------- 10 files changed, 215 insertions(+), 128 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 680601191..dc6c679ad 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1270,6 +1270,7 @@ extern void Gia_ManOrigIdsInit( Gia_Man_t * p ); extern void Gia_ManOrigIdsStart( Gia_Man_t * p ); extern void Gia_ManOrigIdsRemap( Gia_Man_t * p, Gia_Man_t * pNew ); extern Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs ); +extern Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ); extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p ); extern int Gia_ManCheckTopoOrder( Gia_Man_t * p ); extern int * Gia_ManDeriveNexts( Gia_Man_t * p ); diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 584be4cd3..1b0bce07d 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -129,7 +129,7 @@ Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs ) } Gia_ManHashStop( pNew ); Gia_ManForEachCo( p, pObj, i ) - Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Vec_IntFree( vMap ); // compute equivalences assert( !p->pReprs && !p->pNexts ); @@ -169,6 +169,31 @@ Gia_Man_t * Gia_ManOrigIdsReduceTest( Gia_Man_t * p, Vec_Int_t * vPairs ) return pNew; } +/**Function************************************************************* + + Synopsis [Compute equivalence classes of nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ) +{ + Gia_Man_t * pTemp; + Cec_ParFra_t ParsFra, * pPars = &ParsFra; + Cec_ManFraSetDefaultParams( pPars ); + pPars->fUseOrigIds = 1; + pPars->fSatSweeping = 1; + pPars->nBTLimit = nConfs; + pPars->fVerbose = fVerbose; + pTemp = Cec_ManSatSweeping( pGia, pPars, 0 ); + Gia_ManStop( pTemp ); + return Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv ); +} + /**Function************************************************************* Synopsis [Returns 1 if AIG is not in the required topo order.] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 910014c6d..1e94f28fc 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40543,7 +40543,7 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) int c, nArgcNew; Acec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtbvh" ) ) != EOF ) { switch ( c ) { @@ -40578,6 +40578,9 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) case 't': pPars->fTwoOutput ^= 1; break; + case 'b': + pPars->fBooth ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -40720,13 +40723,14 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &acec [-CT num] [-mdtvh] \n" ); + Abc_Print( -2, "usage: &acec [-CT num] [-mdtbvh] \n" ); Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits"); Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no"); Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no"); + Abc_Print( -2, "\t-b : toggle working with Booth multipliers [default = %s]\n", pPars->fBooth? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n"); @@ -40748,12 +40752,15 @@ usage: int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; - int c, fVerbose = 0; + int c, fBooth = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) { switch ( c ) { + case 'b': + fBooth ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -40768,13 +40775,14 @@ int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" ); return 0; } - pTemp = Acec_Normalize( pAbc->pGia, fVerbose ); + pTemp = Acec_Normalize( pAbc->pGia, fBooth, fVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &anorm [-vh]\n" ); + Abc_Print( -2, "usage: &anorm [-bvh]\n" ); Abc_Print( -2, "\t normalize adder trees in the current AIG\n" ); + Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/abci/abcDress3.c b/src/base/abci/abcDress3.c index 33545f0a2..ce0cb7f55 100644 --- a/src/base/abci/abcDress3.c +++ b/src/base/abci/abcDress3.c @@ -33,32 +33,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [Compute equivalence classes of nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ) -{ - Gia_Man_t * pTemp; - Cec_ParFra_t ParsFra, * pPars = &ParsFra; - Cec_ManFraSetDefaultParams( pPars ); - pPars->fUseOrigIds = 1; - pPars->fSatSweeping = 1; - pPars->nBTLimit = nConfs; - pPars->fVerbose = fVerbose; - pTemp = Cec_ManSatSweeping( pGia, pPars, 0 ); - Gia_ManStop( pTemp ); - pTemp = Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv ); - Gia_ManStop( pTemp ); -} - /**Function************************************************************* Synopsis [Converts AIG from HOP to GIA.] @@ -315,13 +289,15 @@ void Abc_NtkDumpEquivFile( char * pFileName, Vec_Int_t * vClasses, Abc_Ntk_t * p void Abc_NtkDumpEquiv( Abc_Ntk_t * pNtks[2], char * pFileName, int nConfs, int fByName, int fVerbose ) { //abctime clk = Abc_Clock(); + Gia_Man_t * pTemp; Vec_Int_t * vClasses; // derive shared AIG for the two networks Gia_Man_t * pGia = Abc_NtkAigToGiaTwo( pNtks[0], pNtks[1], fByName ); if ( fVerbose ) printf( "Computing equivalences for networks \"%s\" and \"%s\" with conflict limit %d.\n", Abc_NtkName(pNtks[0]), Abc_NtkName(pNtks[1]), nConfs ); // compute equivalences in this AIG - Abc_NtkComputeGiaEquivs( pGia, nConfs, fVerbose ); + pTemp = Gia_ManComputeGiaEquivs( pGia, nConfs, fVerbose ); + Gia_ManStop( pTemp ); //if ( fVerbose ) // Abc_PrintTime( 1, "Equivalence computation time", Abc_Clock() - clk ); if ( fVerbose ) diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 7ad5baf95..5a24bec7d 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -47,6 +47,7 @@ struct Acec_ParCec_t_ int fMiter; // input circuit is a miter int fDualOutput; // dual-output miter int fTwoOutput; // two-output miter + int fBooth; // expecting Booth multiplier int fSilent; // print no messages int fVeryVerbose; // verbose stats int fVerbose; // verbose stats @@ -81,7 +82,7 @@ extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); /*=== acecTree.c ========================================================*/ -extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ); +extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 3e31fa360..4a91663f5 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -68,7 +68,7 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) +Gia_Man_t * Acec_CommonStart( Gia_Man_t * pBase, Gia_Man_t * pAdd ) { Gia_Obj_t * pObj; int i; @@ -93,35 +93,69 @@ Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); return pBase; } -Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd ) +void Acec_CommonFinish( Gia_Man_t * pBase ) +{ + int Id; + Gia_ManCreateRefs( pBase ); + Gia_ManForEachAndId( pBase, Id ) + if ( Gia_ObjRefNumId(pBase, Id) == 0 ) + Gia_ManAppendCo( pBase, Abc_Var2Lit(Id,0) ); +} +Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase ) { Gia_Obj_t * pObj; int i; Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) ); + Gia_ManSetPhase( pAdd ); + Vec_IntWriteEntry( vMapNew, 0, 0 ); Gia_ManForEachCand( pAdd, pObj, i ) - Vec_IntWriteEntry( vMapNew, i, Abc_Lit2Var(pObj->Value) ); + { + int iObjBase = Abc_Lit2Var(pObj->Value); + Gia_Obj_t * pObjBase = Gia_ManObj( pBase, iObjBase ); + int iObjRepr = Abc_Lit2Var(pObjBase->Value); + Vec_IntWriteEntry( vMapNew, i, Abc_Var2Lit(iObjRepr, Gia_ObjPhase(pObj)) ); + } return vMapNew; } void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) { - Gia_Man_t * pBase; - pBase = Acec_FindEquivs( NULL, pOne ); - pBase = Acec_FindEquivs( pBase, pTwo ); - *pvMap1 = Acec_CountRemap( pOne ); - *pvMap2 = Acec_CountRemap( pTwo ); + Gia_Man_t * pBase, * pRepr; + pBase = Acec_CommonStart( NULL, pOne ); + pBase = Acec_CommonStart( pBase, pTwo ); + Acec_CommonFinish( pBase ); + + //Gia_ManShow( pBase, NULL, 0, 0, 0 ); + + pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 ); + *pvMap1 = Acec_CountRemap( pOne, pBase ); + *pvMap2 = Acec_CountRemap( pTwo, pBase ); Gia_ManStop( pBase ); + Gia_ManStop( pRepr ); } -static inline void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCosts ) +void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) { int i, j, best_i; for ( i = 0; i < nSize-1; i++ ) { best_i = i; for ( j = i+1; j < nSize; j++ ) - if ( pCosts[Abc_Lit2Var(pArray[j])] > pCosts[Abc_Lit2Var(pArray[best_i])] ) + if ( Abc_Lit2LitL(pCostLits, pArray[j]) > Abc_Lit2LitL(pCostLits, pArray[best_i]) ) best_i = j; ABC_SWAP( int, pArray[i], pArray[best_i] ); } } +void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) +{ + Vec_Int_t * vLevel; + int i, k, Entry; + printf( "Leaf literals and their classes:\n" ); + Vec_WecForEachLevel( vLits, vLevel, i ) + { + printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) ); + Vec_IntForEachEntry( vLevel, Entry, k ) + printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); + printf( "\n" ); + } +} int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) { Vec_Int_t * vMap0, * vMap1, * vLevel; @@ -132,6 +166,8 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); + //Acec_MatchPrintEquivLits( pBox0->vLeafLits, Vec_IntArray(vMap0) ); + //Acec_MatchPrintEquivLits( pBox1->vLeafLits, Vec_IntArray(vMap1) ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); assert( pBox1->vShared == NULL ); @@ -159,8 +195,9 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int * pEnd1 = Vec_IntLimit(vLevel1); while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) { - int Entry0 = Abc_Lit2LitV( Vec_IntArray(vMap0), *pBeg0 ); - int Entry1 = Abc_Lit2LitV( Vec_IntArray(vMap1), *pBeg1 ); + int Entry0 = Abc_Lit2LitL( Vec_IntArray(vMap0), *pBeg0 ); + int Entry1 = Abc_Lit2LitL( Vec_IntArray(vMap1), *pBeg1 ); + assert( *pBeg0 && *pBeg1 ); if ( Entry0 == Entry1 ) { Vec_IntPush( vShared0, *pBeg0++ ); @@ -201,11 +238,16 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) { int status = -1; + abctime clk = Abc_Clock(); Gia_Man_t * pMiter; Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, pPars->fVerbose ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, pPars->fVerbose ); + Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; + Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, pPars->fVerbose ); + Vec_BitFreeP( &vIgnore0 ); + Vec_BitFreeP( &vIgnore1 ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching @@ -214,7 +256,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) { pGia0n = Acec_InsertBox( pBox0, 1 ); pGia1n = Acec_InsertBox( pBox1, 1 ); - printf( "Found, matched, and normalized arithmetic boxes in LHS and RHS. Solving resulting CEC.\n" ); + printf( "Matching of adder trees in LHS and RHS succeeded. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 125d923fa..cc5786bb8 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -69,10 +69,11 @@ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Ve extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); /*=== acecMult.c ========================================================*/ extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); +extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ); /*=== acecNorm.c ========================================================*/ extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 8ccf966ef..0733c00bf 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -490,18 +490,16 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Gia_ManForEachAndId( p, iObj ) { word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp ); + if ( Vec_IntSize(vSupp) > 6 ) + continue; vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); if ( Vec_IntSize(vSupp) > 5 ) continue; - for ( i = 0; i < 32; i++ ) + for ( i = 0; i < 32 && Saved[i]; i++ ) { - if ( Saved[i] == 0 ) - break; if ( Truth == Saved[i] || Truth == ~Saved[i] ) { - //Vec_IntPush( vBold, iObj ); Acec_MultFindPPs_rec( p, iObj, vBold ); - printf( "%d ", iObj ); nProds++; break; } @@ -515,7 +513,6 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Vec_IntPrint( vSupp ); */ } - printf( "\n" ); Gia_ManCleanMark0(p); printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); @@ -523,6 +520,16 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Vec_WrdFree( vTemp ); return vBold; } +Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ) +{ + Vec_Bit_t * vIgnore = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vMap = Acec_MultFindPPs( p ); + int i, Entry; + Vec_IntForEachEntry( vMap, Entry, i ) + Vec_BitWriteEntry( vIgnore, Entry, 1 ); + Vec_IntFree( vMap ); + return vIgnore; +} void Acec_MultFindPPsTest( Gia_Man_t * p ) { Vec_Int_t * vBold = Acec_MultFindPPs( p ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 9faf7acfd..4ed32e7b4 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -198,11 +198,13 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ) +Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ) { - Acec_Box_t * pBox = Acec_DeriveBox( pGia, fVerbose ); + Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL; + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); Acec_BoxFreeP( &pBox ); + Vec_BitFreeP( &vIgnore ); return pNew; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 370e8eb65..fef369238 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -27,6 +27,12 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; } +static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; } + +static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); } +static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -147,10 +153,7 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) Gia_Obj_t * pObj; unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; - - int Sign = Vec_IntEntry( vAdds, 6*iBox+5 ), Phase[5]; - for ( k = 0; k < 5; k++ ) - Phase[k] = (Sign >> (4+k)) & 1; + int fFlip = !fFadd && Acec_SignBit2(vAdds, iBox, 2); Gia_ManIncrementTravId( p ); for ( k = 0; k < 3; k++ ) @@ -159,17 +162,17 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) if ( iObj == 0 ) continue; pObj = Gia_ManObj( p, iObj ); - pObj->Value = Phase[k] ? 0xFF & ~Truths[k] : Truths[k]; + pObj->Value = (Acec_SignBit2(vAdds, iBox, k) ^ fFlip) ? 0xFF & ~Truths[k] : Truths[k]; Gia_ObjSetTravIdCurrent( p, pObj ); } iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthXor = Phase[3] ? 0xFF & ~TruthXor : TruthXor; + TruthXor = (Acec_SignBit2(vAdds, iBox, 3) ^ fFlip) ? 0xFF & ~TruthXor : TruthXor; iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthMaj = Phase[4] ? 0xFF & ~TruthMaj : TruthMaj; + TruthMaj = (Acec_SignBit2(vAdds, iBox, 4) ^ fFlip) ? 0xFF & ~TruthMaj : TruthMaj; if ( fFadd ) // FADD { @@ -180,6 +183,8 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) } else { + //printf( "Sign1 = %d%d%d %d\n", Acec_SignBit(vAdds, iBox, 0), Acec_SignBit(vAdds, iBox, 1), Acec_SignBit(vAdds, iBox, 2), Acec_SignBit(vAdds, iBox, 3) ); + //printf( "Sign2 = %d%d%d %d%d\n", Acec_SignBit2(vAdds, iBox, 0), Acec_SignBit2(vAdds, iBox, 1), Acec_SignBit2(vAdds, iBox, 2), Acec_SignBit2(vAdds, iBox, 3), Acec_SignBit2(vAdds, iBox, 4) ); if ( TruthXor != 0x66 ) printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0x88 ) @@ -194,6 +199,36 @@ void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes Vec_IntForEachEntry( vLevel, Box, k ) Acec_TreeVerifyPhaseOne( p, vAdds, Box ); } +void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vRoots = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, n, Box; + // mark all output points and their values + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + { + Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+3 ), 1 ); + Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+4 ), 1 ); + Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+3 ), Acec_SignBit2(vAdds, Box, 3) ); + Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+4 ), Acec_SignBit2(vAdds, Box, 4) ); + } + // compare with input points + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + for ( n = 0; n < 3; n++ ) + { + if ( !Vec_BitEntry(vRoots, Vec_IntEntry(vAdds, 6*Box+n)) ) + continue; + if ( Vec_BitEntry(vPhase, Vec_IntEntry(vAdds, 6*Box+n)) == Acec_SignBit2(vAdds, Box, n) ) + continue; + printf( "Phase of input %d=%d is mismatched in box %d=(%d,%d).\n", + n, Vec_IntEntry(vAdds, 6*Box+n), Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4) ); + } + Vec_BitFree( vPhase ); + Vec_BitFree( vRoots ); +} /**Function************************************************************* @@ -216,40 +251,40 @@ Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBo Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); return vMap; } -void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase ) +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit ) { - int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + int k, iBox, iXor, fXorPhase, fPhaseThis; assert( Node != 0 ); iBox = Vec_IntEntry( vMap, Node ); if ( iBox == -1 ) return; assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + if ( Vec_BitEntry(vVisit, iBox) ) + return; + Vec_BitWriteEntry( vVisit, iBox, 1 ); iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); - Sign = Vec_IntEntry( vAdds, 6*iBox+5 ) & 0xFFFFFFF0; - fXorPhase = ((Sign >> 3) & 1); + fXorPhase = Acec_SignBit(vAdds, iBox, 3); if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) { - fPhase ^= ((Sign >> 2) & 1); - if ( fPhase ) // complemented HADD - Sign |= (1 << 6); + //fPhaseThis = Acec_SignBit( vAdds, iBox, 2 ) ^ fPhase; + //fXorPhase ^= fPhaseThis; + //Acec_SignSetBit2( vAdds, iBox, 2, fPhaseThis ); // complemented HADD -- create const1 input + fPhase ^= Acec_SignBit( vAdds, iBox, 2 ); + fXorPhase ^= fPhase; + Acec_SignSetBit2( vAdds, iBox, 2, fPhase ); // complemented HADD -- create const1 input } for ( k = 0; k < 3; k++ ) { int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); if ( iObj == 0 ) continue; - fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fPhaseThis = Acec_SignBit(vAdds, iBox, k) ^ fPhase; fXorPhase ^= fPhaseThis; - Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis ); - if ( fPhaseThis ) - Sign |= (1 << (4+k)); + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vVisit ); + Acec_SignSetBit2( vAdds, iBox, k, fPhaseThis ); } - if ( fXorPhase ) - Sign |= (1 << 7); - if ( fPhase ) - Sign |= (1 << 8); - // save updated signature - Vec_IntWriteEntry( vAdds, 6*iBox+5, Sign ); + Acec_SignSetBit2( vAdds, iBox, 3, fXorPhase ); + Acec_SignSetBit2( vAdds, iBox, 4, fPhase ); } /**Function************************************************************* @@ -271,12 +306,14 @@ void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut ) else if ( *pPlace >= 0 ) *pPlace = -2; } -Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) { Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) ); int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 ); @@ -328,10 +365,10 @@ void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); } -Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) { Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); - Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds ); + Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore ); Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 ); Vec_Int_t * vTree; int i, k, In, Out, Box, Rank, MinRank; @@ -371,7 +408,7 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Vec_WecPrint( vTrees, 0 ); @@ -417,23 +454,6 @@ void Vec_WecPrintLits( Vec_Wec_t * p ) printf( " }\n" ); } } -void Acec_PrintRootLits( Vec_Wec_t * vRoots ) -{ - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevel( vRoots, vLevel, i ) - { - printf( "Rank %d : %2d ", i, Vec_IntSize(vLevel) ); - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); - } - printf( "\n" ); - } -} void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) { printf( "Adders:\n" ); @@ -442,8 +462,6 @@ void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) Vec_WecPrintLits( pBox->vLeafLits ); printf( "Outputs:\n" ); Vec_WecPrintLits( pBox->vRootLits ); - //printf( "Raw outputs:\n" ); - //Acec_PrintRootLits( pBox->vRoots ); } int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) @@ -456,10 +474,11 @@ int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { int MaxRank = Acec_CreateBoxMaxRank(vTree); + Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 ); Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, k, Box, Rank; + int i, j, k, Box, Rank; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -470,38 +489,42 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree // collect boxes; mark inputs/outputs Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { - Vec_WecPush( pBox->vAdds, Rank, Box ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + Vec_WecPush( pBox->vAdds, Rank, Box ); } // sort each level Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) Vec_IntSort( vLevel, 0 ); - // set phases + // set phases starting from roots vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) - Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0 ); + Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit ); Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); + Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds ); + Vec_BitFree( vVisit ); Vec_IntFree( vMap ); // collect inputs/outputs - Vec_BitWriteEntry( vIsLeaf, 0, 0 ); - Vec_BitWriteEntry( vIsRoot, 0, 0 ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - int Sign = Vec_IntEntry( vAdds, 6*Box+5 ); - for ( k = 0; k < 3; k++ ) - if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) - Vec_WecPush( pBox->vLeafLits, Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (4+k)) & 1) ); - for ( k = 3; k < 5; k++ ) - if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) - Vec_WecPush( pBox->vRootLits, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (7+k)) & 1) ); - } + Vec_BitWriteEntry( vIsRoot, 0, 1 ); + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, j ) + { + for ( k = 0; k < 3; k++ ) + if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + for ( k = 3; k < 5; k++ ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) ) + Vec_WecPush( pBox->vLeafLits, i, 1 ); + } Vec_BitFree( vIsLeaf ); Vec_BitFree( vIsRoot ); // sort each level @@ -524,7 +547,7 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); //Vec_WecPrint( vTrees, 0 ); @@ -554,11 +577,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) { Acec_Box_t * pBox = NULL; Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); - Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); if ( pBox )//&& fVerbose ) @@ -567,7 +590,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); - Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; From 1b86911c4fe0b193c3a281e823de7934664da798 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Jan 2017 20:28:26 +0700 Subject: [PATCH 55/61] Updates to arithmetic verification. --- src/aig/gia/giaShow.c | 14 ++--- src/base/abci/abc.c | 2 +- src/misc/vec/vecInt.h | 18 +++++++ src/misc/vec/vecWec.h | 17 ++++++ src/proof/acec/acecCore.c | 108 +++++++++++++++++++++++++++++++++++--- src/proof/acec/acecMult.c | 20 ++++--- src/proof/acec/acecNorm.c | 2 +- src/proof/acec/acecRe.c | 27 ++++++---- src/proof/acec/acecTree.c | 28 +++++++++- 9 files changed, 201 insertions(+), 35 deletions(-) diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index cf89d942d..4dd85aab6 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define NODE_MAX 2000 + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -79,11 +81,11 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) } } - if ( nNodes > 500 ) + if ( nNodes > NODE_MAX ) { ABC_FREE( pLevels ); Vec_BitFree( vPath ); - fprintf( stdout, "Cannot visualize AIG with more than 500 critical nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d critical nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -341,9 +343,9 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(p) > 500 ) + if ( Gia_ManAndNum(p) > NODE_MAX ) { - fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -678,9 +680,9 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In int fConstIsUsed = 0; int nFadds = Ree_ManCountFadds( vAdds ); - if ( Gia_ManAndNum(p) > 1000 ) + if ( Gia_ManAndNum(p) > NODE_MAX ) { - fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1e94f28fc..9db3d7d65 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -42690,7 +42690,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); -// Gia_PolynExplore( pAbc->pGia ); + Acec_MultFindPPsTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index f09b8783d..d952518fb 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -1692,6 +1692,24 @@ static inline int Vec_IntTwoFindCommon( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Ve } return Vec_IntSize(vArr); } +static inline int Vec_IntTwoFindCommonReverse( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vArr ) +{ + int * pBeg1 = vArr1->pArray; + int * pBeg2 = vArr2->pArray; + int * pEnd1 = vArr1->pArray + vArr1->nSize; + int * pEnd2 = vArr2->pArray + vArr2->nSize; + Vec_IntClear( vArr ); + while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 ) + { + if ( *pBeg1 == *pBeg2 ) + Vec_IntPush( vArr, *pBeg1 ), pBeg1++, pBeg2++; + else if ( *pBeg1 > *pBeg2 ) + pBeg1++; + else + pBeg2++; + } + return Vec_IntSize(vArr); +} /**Function************************************************************* diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h index e4e925034..8180e9847 100644 --- a/src/misc/vec/vecWec.h +++ b/src/misc/vec/vecWec.h @@ -303,6 +303,23 @@ static inline Vec_Int_t * Vec_WecPushLevel( Vec_Wec_t * p ) ++p->nSize; return Vec_WecEntryLast( p ); } +static inline Vec_Int_t * Vec_WecInsertLevel( Vec_Wec_t * p, int i ) +{ + Vec_Int_t * pTemp; + if ( p->nSize == p->nCap ) + { + if ( p->nCap < 16 ) + Vec_WecGrow( p, 16 ); + else + Vec_WecGrow( p, 2 * p->nCap ); + } + ++p->nSize; + assert( i >= 0 && i < p->nSize ); + for ( pTemp = p->pArray + p->nSize - 2; pTemp >= p->pArray + i; pTemp-- ) + pTemp[1] = pTemp[0]; + Vec_IntZero( p->pArray + i ); + return p->pArray + i; +} /**Function************************************************************* diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 4a91663f5..6b631a1b3 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -20,6 +20,8 @@ #include "acecInt.h" #include "proof/cec/cec.h" +#include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -118,18 +120,19 @@ Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase ) } void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) { + abctime clk = Abc_Clock(); Gia_Man_t * pBase, * pRepr; pBase = Acec_CommonStart( NULL, pOne ); pBase = Acec_CommonStart( pBase, pTwo ); Acec_CommonFinish( pBase ); - //Gia_ManShow( pBase, NULL, 0, 0, 0 ); - pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 ); *pvMap1 = Acec_CountRemap( pOne, pBase ); *pvMap2 = Acec_CountRemap( pTwo, pBase ); Gia_ManStop( pBase ); Gia_ManStop( pRepr ); + printf( "Finished computing equivalent nodes. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) { @@ -143,8 +146,10 @@ void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) ABC_SWAP( int, pArray[i], pArray[best_i] ); } } -void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) +void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose ) { + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel; int i, k, Entry; printf( "Leaf literals and their classes:\n" ); @@ -155,6 +160,85 @@ void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); printf( "\n" ); } + if ( !fVerbose ) + return; + Vec_WecForEachLevel( vLits, vLevel, i ) + { + if ( i != 20 ) + continue; + Vec_IntForEachEntry( vLevel, Entry, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); + printf( "Rank = %4d : ", i ); + printf( "Obj = %4d ", Abc_Lit2Var(Entry) ); + if ( Vec_IntSize(vSupp) > 6 ) + { + printf( "Supp = %d.\n", Vec_IntSize(vSupp) ); + continue; + } + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + { + printf( "Supp = %d.\n", Vec_IntSize(vSupp) ); + continue; + } + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + printf( "\n" ); + } + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); +} +Vec_Wec_t * Acec_MatchCopy( Vec_Wec_t * vLits, Vec_Int_t * vMap ) +{ + Vec_Wec_t * vRes = Vec_WecStart( Vec_WecSize(vLits) ); + Vec_Int_t * vLevel; int i, k, iLit; + Vec_WecForEachLevel( vLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + Vec_WecPush( vRes, i, Abc_Lit2LitL(Vec_IntArray(vMap), iLit) ); + return vRes; +} +int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Vec_Int_t * vLevel1, * vLevel2; + int i, nCommon = 0; + Vec_WecForEachLevel( vLits1, vLevel1, i ) + { + if ( i+Shift < 0 || i+Shift >= Vec_WecSize(vLits2) ) + continue; + vLevel2 = Vec_WecEntry( vLits2, i+Shift ); + nCommon += Vec_IntTwoFindCommonReverse( vLevel1, vLevel2, vRes ); + } + Vec_IntFree( vRes ); + return nCommon; +} +void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) +{ + Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); + Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 ); + int nCommon = Acec_MatchCountCommon( vRes0, vRes1, 0 ); + int nCommonPlus = Acec_MatchCountCommon( vRes0, vRes1, 1 ); + int nCommonMinus = Acec_MatchCountCommon( vRes0, vRes1, -1 ); + if ( nCommonPlus >= nCommonMinus && nCommonPlus > nCommon ) + { + Vec_WecInsertLevel( vLits0, 0 ); + Vec_WecInsertLevel( vRoots0, 0 ); + } + else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) + { + Vec_WecInsertLevel( vLits1, 0 ); + Vec_WecInsertLevel( vRoots1, 0 ); + } + Vec_WecPrint( vRes0, 0 ); + Vec_WecPrint( vRes1, 0 ); + Vec_WecFree( vRes0 ); + Vec_WecFree( vRes1 ); } int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) { @@ -166,8 +250,11 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); - //Acec_MatchPrintEquivLits( pBox0->vLeafLits, Vec_IntArray(vMap0) ); - //Acec_MatchPrintEquivLits( pBox1->vLeafLits, Vec_IntArray(vMap1) ); + Acec_MatchCheckShift( pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); + + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); + // reorder nodes to have the same order assert( pBox0->vShared == NULL ); assert( pBox1->vShared == NULL ); @@ -216,11 +303,15 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); } - Vec_IntFree( vMap0 ); - Vec_IntFree( vMap1 ); nTotal = Vec_WecSizeSize(pBox0->vShared); printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 ); + + Vec_IntFree( vMap0 ); + Vec_IntFree( vMap1 ); return nTotal; } @@ -258,6 +349,9 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) pGia1n = Acec_InsertBox( pBox1, 1 ); printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + // remove the last output + //Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); + //Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 0733c00bf..d868c3995 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -504,14 +504,18 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) break; } } -/* - Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); - if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); - if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); - if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); - printf( " " ); - Vec_IntPrint( vSupp ); -*/ + /* + if ( Saved[i] ) + { + printf( "Obj = %4d ", iObj ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + */ } Gia_ManCleanMark0(p); printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 4ed32e7b4..0d2095240 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -112,7 +112,7 @@ int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) assert( Gia_ObjIsAnd(pObj) ); Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); - return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); + return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); } Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) { diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 161b6fbb5..7f87df854 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -147,6 +147,7 @@ static inline int Ree_ManCutFind( int iObj, int * pCut ) } static inline int Ree_ManCutNotFind( int iObj1, int iObj2, int * pCut ) { + assert( pCut[0] == 3 ); if ( pCut[3] != iObj1 && pCut[3] != iObj2 ) return 0; if ( pCut[2] != iObj1 && pCut[2] != iObj2 ) return 1; if ( pCut[1] != iObj1 && pCut[1] != iObj2 ) return 2; @@ -162,13 +163,19 @@ static inline int Ree_ManCutTruthOne( int * pCut0, int * pCut ) Truth0 = fComp0 ? ~Truth0 : Truth0; if ( pCut0[0] == 2 ) { - int Truths[3][8] = { - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-} - { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1} - { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1} - }; - int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7]; - return 0xFF & (fComp0 ? ~Truth : Truth); + if ( pCut[0] == 3 ) + { + int Truths[3][8] = { + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-} + { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1} + { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1} + }; + int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7]; + return 0xFF & (fComp0 ? ~Truth : Truth); + } + assert( pCut[0] == 2 ); + assert( pCut[1] == pCut0[1] && pCut[2] == pCut0[2] ); + return pCut0[pCut0[0]+1]; } if ( pCut0[0] == 1 ) { @@ -236,10 +243,10 @@ int Ree_ObjComputeTruth( Gia_Man_t * p, int iObj, int * pCut ) SeeAlso [] ***********************************************************************/ -void Ree_ManCutPrint( int * pCut, int Count, word Truth ) +void Ree_ManCutPrint( int * pCut, int Count, word Truth, int iObj ) { int c; - printf( "%d : ", Count ); + printf( "%d : %d : ", Count, iObj ); for ( c = 1; c <= pCut[0]; c++ ) printf( "%3d ", pCut[c] ); for ( ; c <= 4; c++ ) @@ -290,7 +297,7 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I Vec_IntPushThree( vData, iObj, Value, TruthC ); } if ( fVerbose ) - Ree_ManCutPrint( pCut, ++Count, TruthC ); + Ree_ManCutPrint( pCut, ++Count, TruthC, iObj ); } if ( !vXors ) return; diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index fef369238..295fd7387 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -392,7 +392,7 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - Acec_TreeFilterTrees( p, vAdds, vTrees ); + //Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -478,7 +478,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, j, k, Box, Rank; + int i, j, k, Box, Rank, Count = 0; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -532,6 +532,30 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) Vec_IntSort( vLevel, 0 ); + //return pBox; + // push literals forward + //Vec_WecPrint( pBox->vLeafLits, 0 ); + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + { + int This, Prev = Vec_IntEntry(vLevel, 0); + Vec_IntForEachEntryStart( vLevel, This, j, 1 ) + { + if ( Prev != This ) + { + Prev = This; + continue; + } + if ( i+1 >= Vec_WecSize(pBox->vLeafLits) ) + continue; + Vec_IntPushOrder( Vec_WecEntry(pBox->vLeafLits, i+1), This ); + Vec_IntDrop( vLevel, j-- ); + Vec_IntDrop( vLevel, j-- ); + Prev = -1; + Count++; + } + } + printf( "Pushed forward %d input literals.\n", Count ); + //Vec_WecPrint( pBox->vLeafLits, 0 ); return pBox; } void Acec_CreateBoxTest( Gia_Man_t * p ) From 153b71c1403ed79d7650ad702bb343e0490e36c9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 15 Jan 2017 20:59:59 +0700 Subject: [PATCH 56/61] Updates to arithmetic verification. --- abcexe.dsp | 4 ++ src/aig/gia/gia.h | 2 + src/aig/gia/giaDup.c | 65 ++++++++++++++++++ src/aig/gia/giaShow.c | 13 +++- src/base/abci/abc.c | 54 ++++++++++++++- src/misc/vec/vecWec.h | 12 ++++ src/proof/acec/acec.h | 2 + src/proof/acec/acecCl.c | 88 ++++++++++++++++++++++++ src/proof/acec/acecCore.c | 124 +++++++++++++++++++++++++++++++--- src/proof/acec/acecInt.h | 2 + src/proof/acec/acecRe.c | 5 ++ src/proof/acec/acecTree.c | 138 ++++++++++++++++++++++++++++++++++---- src/proof/acec/acecUtil.c | 23 +++++++ 13 files changed, 505 insertions(+), 27 deletions(-) diff --git a/abcexe.dsp b/abcexe.dsp index 9d5152fc2..9ef992c07 100644 --- a/abcexe.dsp +++ b/abcexe.dsp @@ -88,6 +88,10 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE=.\src\proof\acec\acecTree.c +# End Source File +# Begin Source File + SOURCE=.\src\base\main\main.c # End Source File # End Group diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index dc6c679ad..3bc97e6b0 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1242,6 +1242,8 @@ extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ); extern Gia_Man_t * Gia_ManDupWithConstraints( Gia_Man_t * p, Vec_Int_t * vPoTypes ); extern Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis ); extern Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrimPis ); +extern Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level ); +extern Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level ); extern Gia_Man_t * Gia_ManDupOneHot( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupLevelized( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupFromVecs( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index cdb6a2085..b0ba3472e 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3045,6 +3045,71 @@ Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrim Vec_PtrFree( vRoots ); return pNew; +} +void Gia_ManDupAndConesLimit_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( ~pObj->Value ) + return; + if ( !Gia_ObjIsAnd(pObj) || Gia_ObjLevel(p, pObj) < Level ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + //printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); + return; + } + Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level ); + Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); +} +Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level ) +{ + Gia_Man_t * pNew; + int i; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManLevelNum( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < nAnds; i++ ) + Gia_ManDupAndConesLimit_rec( pNew, p, pAnds[i], Level ); + for ( i = 0; i < nAnds; i++ ) + Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value ); + return pNew; +} + +void Gia_ManDupAndConesLimit2_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( ~pObj->Value ) + return; + if ( !Gia_ObjIsAnd(pObj) || Level <= 0 ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + //printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); + return; + } + Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level-1 ); + Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level-1 ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); +} +Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level ) +{ + Gia_Man_t * pNew; + int i; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < nAnds; i++ ) + Gia_ManDupAndConesLimit2_rec( pNew, p, pAnds[i], Level ); + for ( i = 0; i < nAnds; i++ ) + Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value ); + return pNew; + } /**Function************************************************************* diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 4dd85aab6..4deebd7a1 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -1014,16 +1014,23 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds ) +Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds, Vec_Int_t * vBold ) { - Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + Vec_Bit_t * vIsBold = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i, Entry; + if ( vBold ) + Vec_IntForEachEntry( vBold, Entry, i ) + Vec_BitWriteEntry( vIsBold, Entry, 1 ); for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { if ( fFadds && Vec_IntEntry(vAdds, 6*i+2) == 0 ) continue; + if ( Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+4)) ) + continue; Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i ); Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i ); } + Vec_BitFree( vIsBold ); return vMapAdds; } Vec_Int_t * Gia_ShowMapXors( Gia_Man_t * p, Vec_Int_t * vXors ) @@ -1105,7 +1112,7 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v ***********************************************************************/ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { - Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); + Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds, vBold ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); Gia_WriteDotAig( p, pFileName, vBold, vAdds, vXors, vMapAdds, vMapXors, vOrder ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 9db3d7d65..58a14e817 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -482,6 +482,7 @@ static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Decla ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1126,6 +1127,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&decla", Abc_CommandAbc9Decla, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 ); @@ -40788,6 +40790,57 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Decla( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + int c, fBooth = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fBooth ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Decla(): There is no AIG.\n" ); + return 0; + } + pTemp = Acec_ManDecla( pAbc->pGia, fBooth, fVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &decla [-bvh]\n" ); + Abc_Print( -2, "\t removes carry look ahead adders\n" ); + Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + /**Function************************************************************* Synopsis [] @@ -42690,7 +42743,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); - Acec_MultFindPPsTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h index 8180e9847..c8c897017 100644 --- a/src/misc/vec/vecWec.h +++ b/src/misc/vec/vecWec.h @@ -561,6 +561,18 @@ static inline void Vec_WecPrint( Vec_Wec_t * p, int fSkipSingles ) printf( " }\n" ); } } +static inline void Vec_WecPrintLits( Vec_Wec_t * p ) +{ + Vec_Int_t * vVec; + int i, k, iLit; + Vec_WecForEachLevel( p, vVec, i ) + { + printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); + Vec_IntForEachEntry( vVec, iLit, k ) + printf( " %c%d", Abc_LitIsCompl(iLit) ? '-' : '+', Abc_Lit2Var(iLit) ); + printf( " }\n" ); + } +} /**Function************************************************************* diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 5a24bec7d..fcbd32df1 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -66,6 +66,8 @@ struct Acec_ParCec_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== acecCl.c ========================================================*/ +extern Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ); /*=== acecCore.c ========================================================*/ extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ); extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ); diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 145f2e0b2..6a5f4040e 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -335,6 +335,94 @@ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 ); + Vec_Int_t * vLevel; + int i, k, iLit; + Vec_WecPrintLits( pBox->vRootLits ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + { + int In[3] = {0}, Out[2]; + assert( Vec_IntSize(vLevel) > 0 ); + assert( Vec_IntSize(vLevel) <= 3 ); + if ( Vec_IntSize(vLevel) == 1 ) + { + Vec_IntPush( vRes, Vec_IntEntry(vLevel, 0) ); + continue; + } + Vec_IntForEachEntry( vLevel, iLit, k ) + In[k] = iLit; + Acec_InsertFadd( p, In, Out ); + Vec_IntPush( vRes, Out[0] ); + if ( i+1 < Vec_WecSize(pBox->vRootLits) ) + Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] ); + else + Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] ); + } + assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) ); + Vec_IntShrink( vRes, Gia_ManCoNum(p) ); + return vRes; +} +Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; int i; + assert( Gia_ManCoNum(p) == Vec_IntSize(vRes) ); + // create new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManSetPhase( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + { + int iLit = Vec_IntEntry( vRes, i ); + int Phase1 = Gia_ObjPhase(pObj); + int Phase2 = Abc_LitIsCompl(iLit) ^ Gia_ObjPhase(Gia_ManObj(p, Abc_Lit2Var(iLit))); + int iLitNew = Abc_Var2Lit( Abc_Lit2Var(iLit), Phase1 ^ Phase2 ); + pObj->Value = Gia_ManAppendCo( pNew, iLitNew ); + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} +Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) +{ + int status = -1; + abctime clk = Abc_Clock(); + Gia_Man_t * pNew = NULL; + Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL; + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Vec_Int_t * vResult; + Vec_BitFreeP( &vIgnore ); + if ( pBox == NULL ) // cannot match + { + printf( "Cannot find arithmetic boxes.\n" ); + return Gia_ManDup( pGia ); + } + vResult = Acec_RewriteTop( pGia, pBox ); + pNew = Acec_RewriteReplace( pGia, vResult ); + Vec_IntFree( vResult ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 6b631a1b3..4fddcfab2 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define TRUTH_UNUSED 0x1234567812345678 + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -59,6 +61,79 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) p->iOutFail = -1; // the number of failed output } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_VerifyClasses( Gia_Man_t * p, Vec_Wec_t * vLits, Vec_Wec_t * vReprs ) +{ + Vec_Ptr_t * vFunc = Vec_PtrAlloc( Vec_WecSize(vLits) ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, j, k, Entry, Entry2, nOvers = 0, nErrors = 0; + Vec_WecForEachLevel( vLits, vLevel, i ) + { + Vec_Wrd_t * vTruths = Vec_WrdAlloc( Vec_IntSize(vLevel) ); + Vec_IntForEachEntry( vLevel, Entry, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); + if ( Vec_IntSize(vSupp) > 6 ) + { + nOvers++; + Vec_WrdPush( vTruths, TRUTH_UNUSED ); + continue; + } + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + { + nOvers++; + Vec_WrdPush( vTruths, TRUTH_UNUSED ); + continue; + } + Vec_WrdPush( vTruths, Truth ); + } + Vec_PtrPush( vFunc, vTruths ); + } + if ( nOvers ) + printf( "Detected %d oversize support nodes.\n", nOvers ); + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + // verify the classes + Vec_WecForEachLevel( vReprs, vLevel, i ) + { + Vec_Wrd_t * vTruths = (Vec_Wrd_t *)Vec_PtrEntry( vFunc, i ); + Vec_IntForEachEntry( vLevel, Entry, k ) + Vec_IntForEachEntryStart( vLevel, Entry2, j, k+1 ) + { + word Truth = Vec_WrdEntry( vTruths, k ); + word Truth2 = Vec_WrdEntry( vTruths, j ); + if ( Entry == Entry2 ) + { + nErrors++; + if ( Truth != Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED ) + printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j ); + } + if ( Entry == Abc_LitNot(Entry2) ) + { + nErrors++; + if ( Truth != ~Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED ) + printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j ); + } + } + } + if ( nErrors ) + printf( "Total errors in equivalence classes = %d.\n", nErrors ); + Vec_VecFree( (Vec_Vec_t *)vFunc ); +} + /**Function************************************************************* Synopsis [] @@ -148,13 +223,15 @@ void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) } void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose ) { - Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); - Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vSupp; + Vec_Wrd_t * vTemp; Vec_Int_t * vLevel; int i, k, Entry; printf( "Leaf literals and their classes:\n" ); Vec_WecForEachLevel( vLits, vLevel, i ) { + if ( Vec_IntSize(vLevel) == 0 ) + continue; printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, Entry, k ) printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); @@ -162,13 +239,25 @@ void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits } if ( !fVerbose ) return; + vSupp = Vec_IntAlloc( 100 ); + vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_WecForEachLevel( vLits, vLevel, i ) { - if ( i != 20 ) + //if ( i != 20 ) + // continue; + if ( Vec_IntSize(vLevel) == 0 ) continue; Vec_IntForEachEntry( vLevel, Entry, k ) { word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); +/* + { + int iObj = Abc_Lit2Var(Entry); + Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 ); + Gia_ManShow( pGia0, NULL, 0, 0, 0 ); + Gia_ManStop( pGia0 ); + } +*/ printf( "Rank = %4d : ", i ); printf( "Obj = %4d ", Abc_Lit2Var(Entry) ); if ( Vec_IntSize(vSupp) > 6 ) @@ -218,7 +307,7 @@ int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) Vec_IntFree( vRes ); return nCommon; } -void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) +void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) { Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 ); @@ -229,14 +318,24 @@ void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * v { Vec_WecInsertLevel( vLits0, 0 ); Vec_WecInsertLevel( vRoots0, 0 ); + printf( "Shifted one level up.\n" ); } else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) { Vec_WecInsertLevel( vLits1, 0 ); Vec_WecInsertLevel( vRoots1, 0 ); + printf( "Shifted one level down.\n" ); } - Vec_WecPrint( vRes0, 0 ); - Vec_WecPrint( vRes1, 0 ); + //printf( "Input literals:\n" ); + //Vec_WecPrintLits( vLits0 ); + printf( "Equiv classes:\n" ); + Vec_WecPrintLits( vRes0 ); + //printf( "Input literals:\n" ); + //Vec_WecPrintLits( vLits1 ); + printf( "Equiv classes:\n" ); + Vec_WecPrintLits( vRes1 ); + //Acec_VerifyClasses( pGia0, vLits0, vRes0 ); + //Acec_VerifyClasses( pGia1, vLits1, vRes1 ); Vec_WecFree( vRes0 ); Vec_WecFree( vRes1 ); } @@ -250,10 +349,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); - Acec_MatchCheckShift( pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); + Acec_MatchCheckShift( pBox0->pGia, pBox1->pGia, pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox0->vRootLits ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox1->vRootLits ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); @@ -350,8 +453,11 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // remove the last output - //Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); - //Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); + Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); + Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); + + Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-2, 0 ); + Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-2, 0 ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index cc5786bb8..c49945dba 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -71,8 +71,10 @@ extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdd extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ); /*=== acecNorm.c ========================================================*/ +extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ +extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ); extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 7f87df854..5e5ca6886 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -450,6 +450,7 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Hash_IntManStop( pHash ); Ree_ManRemoveTrivial( p, vAdds ); Ree_ManRemoveContained( p, vAdds ); + //Ree_ManPrintAdders( vAdds, 1 ); return vAdds; } @@ -523,6 +524,10 @@ void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ) { pObjX = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+3) ); pObjM = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+4) ); + // rule out if MAJ is a fanout of XOR + //if ( pObjX == Gia_ObjFanin0(pObjM) || pObjX == Gia_ObjFanin1(pObjM) ) + // continue; + // rule out if MAJ is a fanin of XOR and has no other fanouts if ( (pObjM == Gia_ObjFanin0(pObjX) || pObjM == Gia_ObjFanin1(pObjX)) && Gia_ObjRefNum(p, pObjM) == 1 ) continue; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 295fd7387..2b3565747 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -64,6 +64,30 @@ void Acec_BoxFreeP( Acec_Box_t ** ppBox ) *ppBox = NULL; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_VerifyBoxLeaves( Acec_Box_t * pBox, Vec_Bit_t * vIgnore ) +{ + Vec_Int_t * vLevel; + int i, k, iLit, Count = 0; + if ( vIgnore == NULL ) + return; + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( Gia_ObjIsAnd(Gia_ManObj(pBox->pGia, Abc_Lit2Var(iLit))) && !Vec_BitEntry(vIgnore, Abc_Lit2Var(iLit)) ) + printf( "Internal node %d of rank %d is not part of PPG.\n", Abc_Lit2Var(iLit), i ), Count++; + printf( "Detected %d suspicious leaves.\n", Count ); +} + /**Function************************************************************* Synopsis [Filters trees by removing TFO of roots.] @@ -103,6 +127,18 @@ void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) // remove those that overlap with roots Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { +/* + if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 ) + { + printf( "**** removing special one \n" ); + continue; + } + if ( Vec_IntEntry(vAdds, 6*Box+3) == 48 && Vec_IntEntry(vAdds, 6*Box+4) == 49 ) + { + printf( "**** removing special one \n" ); + continue; + } +*/ if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) { printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); @@ -123,6 +159,73 @@ void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees Acec_TreeFilterOne( p, vAdds, vLevel ); } +/**Function************************************************************* + + Synopsis [Filters trees by removing TFO of roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeMarkTFI_rec( Gia_Man_t * p, int Id, Vec_Bit_t * vMarked ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, Id); + if ( Vec_BitEntry(vMarked, Id) ) + return; + Vec_BitWriteEntry( vMarked, Id, 1 ); + if ( !Gia_ObjIsAnd(pObj) ) + return; + Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId0(pObj, Id), vMarked ); + Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId1(pObj, Id), vMarked ); +} +void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ; + Gia_Obj_t * pObj; + int i, k = 0, Box, Rank; + // mark leaves + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+3), 0 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4), 0 ); + } + // mark TFI of leaves + Gia_ManForEachAnd( p, pObj, i ) + if ( Vec_BitEntry(vIsLeaf, i) ) + Acec_TreeMarkTFI_rec( p, i, vMarked ); + // remove those that overlap with the marked TFI + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) + { + printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); + continue; + } + Vec_IntWriteEntry( vTree, k++, Box ); + Vec_IntWriteEntry( vTree, k++, Rank ); + } + Vec_IntShrink( vTree, k ); + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vMarked ); +} +void Acec_TreeFilterTrees2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees ) +{ + Vec_Int_t * vLevel; + int i; + Vec_WecForEachLevel( vTrees, vLevel, i ) + Acec_TreeFilterOne2( p, vAdds, vLevel ); +} + /**Function************************************************************* Synopsis [] @@ -392,7 +495,7 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - //Acec_TreeFilterTrees( p, vAdds, vTrees ); + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -437,20 +540,11 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) { printf( " %4d : %2d {", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iBox, k ) + { printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); - printf( " }\n" ); - } -} -void Vec_WecPrintLits( Vec_Wec_t * p ) -{ - Vec_Int_t * vVec; - int i, k, Entry; - Vec_WecForEachLevel( p, vVec, i ) - { - printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); - Vec_IntForEachEntry( vVec, Entry, k ) - printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); + //printf( "(%d,%d,%d)", Vec_IntEntry(vAdds, 6*iBox+0), Vec_IntEntry(vAdds, 6*iBox+1), Vec_IntEntry(vAdds, 6*iBox+2) ); + } printf( " }\n" ); } } @@ -505,7 +599,10 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i ) Vec_IntForEachEntry( vLevel, Box, k ) if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + { + //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box ); Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit ); + } Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds ); Vec_BitFree( vVisit ); @@ -521,7 +618,14 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); for ( k = 3; k < 5; k++ ) if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + { + //if ( Vec_IntEntry(vAdds, 6*Box+k) == 10942 ) + //{ + // printf( "++++++++++++ Skipping special\n" ); + // continue; + //} Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + } if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) ) Vec_WecPush( pBox->vLeafLits, i, 1 ); } @@ -531,8 +635,9 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) - Vec_IntSort( vLevel, 0 ); + Vec_IntSort( vLevel, 1 ); //return pBox; +/* // push literals forward //Vec_WecPrint( pBox->vLeafLits, 0 ); Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) @@ -555,6 +660,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree } } printf( "Pushed forward %d input literals.\n", Count ); +*/ //Vec_WecPrint( pBox->vLeafLits, 0 ); return pBox; } @@ -607,13 +713,17 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) + { pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + Acec_VerifyBoxLeaves( pBox, vIgnore ); + } if ( pBox )//&& fVerbose ) printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); + //Acec_PrintAdders( pBox0->vAdds, vAdds ); //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); diff --git a/src/proof/acec/acecUtil.c b/src/proof/acec/acecUtil.c index 191856cfd..be12afeff 100644 --- a/src/proof/acec/acecUtil.c +++ b/src/proof/acec/acecUtil.c @@ -90,6 +90,29 @@ void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ) Vec_IntFree( vXors ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupTopMostRange( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Vec_Int_t * vTops = Vec_IntAlloc( 10 ); + int i; + for ( i = 45; i < 52; i++ ) + Vec_IntPush( vTops, Gia_ObjId( p, Gia_ObjFanin0(Gia_ManCo(p, i)) ) ); + pNew = Gia_ManDupAndConesLimit( p, Vec_IntArray(vTops), Vec_IntSize(vTops), 100 ); + Vec_IntFree( vTops ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 7457b8a64ae92880b8c04f1128298ee51becb76f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 16 Jan 2017 22:36:23 +0700 Subject: [PATCH 57/61] Updates to arithmetic verification. --- src/proof/acec/acecCl.c | 33 +++++++++++++++++++++++---------- src/proof/acec/acecCore.c | 20 ++++++++++---------- src/proof/acec/acecInt.h | 2 +- src/proof/acec/acecNorm.c | 2 +- src/proof/acec/acecTree.c | 28 ++++++++++++++++++++-------- 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 6a5f4040e..6185677b7 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -350,9 +350,15 @@ Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) { Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 ); Vec_Int_t * vLevel; - int i, k, iLit; - Vec_WecPrintLits( pBox->vRootLits ); - Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + int i, k, iStart, iLit, Driver, Count = 0; + // determine how much to shift + Driver = Gia_ObjFaninId0p( p, Gia_ManCo(p, 0) ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, iStart ) + if ( Abc_Lit2Var(Vec_IntEntry(vLevel,0)) == Driver ) + break; + assert( iStart < Gia_ManCoNum(p) ); + //Vec_WecPrintLits( pBox->vRootLits ); + Vec_WecForEachLevelStart( pBox->vRootLits, vLevel, i, iStart ) { int In[3] = {0}, Out[2]; assert( Vec_IntSize(vLevel) > 0 ); @@ -370,9 +376,11 @@ Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] ); else Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] ); + Count++; } assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) ); Vec_IntShrink( vRes, Gia_ManCoNum(p) ); + printf( "Added %d adders for replace CLAs. ", Count ); return vRes; } Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) @@ -384,7 +392,6 @@ Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Gia_ManSetPhase( p ); Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) @@ -394,22 +401,26 @@ Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) Gia_ManForEachCo( p, pObj, i ) { int iLit = Vec_IntEntry( vRes, i ); - int Phase1 = Gia_ObjPhase(pObj); - int Phase2 = Abc_LitIsCompl(iLit) ^ Gia_ObjPhase(Gia_ManObj(p, Abc_Lit2Var(iLit))); - int iLitNew = Abc_Var2Lit( Abc_Lit2Var(iLit), Phase1 ^ Phase2 ); - pObj->Value = Gia_ManAppendCo( pNew, iLitNew ); + Gia_Obj_t * pRepr = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + pObj->Value = Gia_ManAppendCo( pNew, pRepr->Value ); } + // set correct phase + Gia_ManSetPhase( p ); + Gia_ManSetPhase( pNew ); + Gia_ManForEachCo( pNew, pObj, i ) + if ( Gia_ObjPhase(pObj) != Gia_ObjPhase(Gia_ManCo(p, i)) ) + Gia_ObjFlipFaninC0( pObj ); + // remove dangling nodes pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; } Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) { - int status = -1; abctime clk = Abc_Clock(); Gia_Man_t * pNew = NULL; Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL; - Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose ); Vec_Int_t * vResult; Vec_BitFreeP( &vIgnore ); if ( pBox == NULL ) // cannot match @@ -418,8 +429,10 @@ Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) return Gia_ManDup( pGia ); } vResult = Acec_RewriteTop( pGia, pBox ); + Acec_BoxFreeP( &pBox ); pNew = Acec_RewriteReplace( pGia, vResult ); Vec_IntFree( vResult ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return pNew; } diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 4fddcfab2..06385f3c6 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -328,12 +328,12 @@ void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLi } //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits0 ); - printf( "Equiv classes:\n" ); - Vec_WecPrintLits( vRes0 ); + //printf( "Equiv classes:\n" ); + //Vec_WecPrintLits( vRes0 ); //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits1 ); - printf( "Equiv classes:\n" ); - Vec_WecPrintLits( vRes1 ); + //printf( "Equiv classes:\n" ); + //Vec_WecPrintLits( vRes1 ); //Acec_VerifyClasses( pGia0, vLits0, vRes0 ); //Acec_VerifyClasses( pGia1, vLits1, vRes1 ); Vec_WecFree( vRes0 ); @@ -353,10 +353,10 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); - printf( "Outputs:\n" ); - Vec_WecPrintLits( pBox0->vRootLits ); - printf( "Outputs:\n" ); - Vec_WecPrintLits( pBox1->vRootLits ); + //printf( "Outputs:\n" ); + //Vec_WecPrintLits( pBox0->vRootLits ); + //printf( "Outputs:\n" ); + //Vec_WecPrintLits( pBox1->vRootLits ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); @@ -438,8 +438,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, pPars->fVerbose ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, pPars->fVerbose ); + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose ); Vec_BitFreeP( &vIgnore0 ); Vec_BitFreeP( &vIgnore1 ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index c49945dba..b8ec24554 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -75,7 +75,7 @@ extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ); -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 0d2095240..6b36589cd 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -201,7 +201,7 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ) { Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL; - Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose ); Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); Acec_BoxFreeP( &pBox ); Vec_BitFreeP( &vIgnore ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 2b3565747..fe5ca01b0 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -127,6 +127,10 @@ void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) // remove those that overlap with roots Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { + // special case of the first bit +// if ( i == 0 ) +// continue; + /* if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 ) { @@ -415,7 +419,7 @@ Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * v int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { - if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) && Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); @@ -468,7 +472,7 @@ void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); } -Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut ) { Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore ); @@ -495,7 +499,10 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - Acec_TreeFilterTrees( p, vAdds, vTrees ); + if ( fFilterIn ) + Acec_TreeFilterTrees2( p, vAdds, vTrees ); + else if ( fFilterOut ) + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -511,7 +518,7 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Vec_WecPrint( vTrees, 0 ); @@ -572,7 +579,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, j, k, Box, Rank, Count = 0; + int i, j, k, Box, Rank;//, Count = 0; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -583,6 +590,11 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree // collect boxes; mark inputs/outputs Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { +// if ( 37 == Box && 6 == Rank ) +// { +// printf( "Skipping one adder...\n" ); +// continue; +// } Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); @@ -677,7 +689,7 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); //Vec_WecPrint( vTrees, 0 ); @@ -707,11 +719,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose ) { Acec_Box_t * pBox = NULL; Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); - Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore, fFilterIn, fFilterOut ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) { pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); From b193ef056d2fb11d5e24b7e4f250e07d069c2ae2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 19 Jan 2017 13:24:47 +0800 Subject: [PATCH 58/61] Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 58 +++++++++++++++++++++++++++++++++++++-- src/proof/acec/acecNorm.c | 51 ++++++++++++++++++++-------------- src/proof/acec/acecTree.c | 5 +++- 3 files changed, 90 insertions(+), 24 deletions(-) diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 06385f3c6..a23417042 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -307,6 +307,50 @@ int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) Vec_IntFree( vRes ); return nCommon; } +void Vec_IntInsertOrder( Vec_Int_t * vLits, Vec_Int_t * vClasses, int Lit, int Class ) +{ + int i; + for ( i = Vec_IntSize(vClasses)-1; i >= 0; i-- ) + if ( Vec_IntEntry(vClasses,i) >= Class ) + break; + Vec_IntInsert( vLits, i+1, Lit ); + Vec_IntInsert( vClasses, i+1, Class ); +} +void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses ) +{ + Vec_Int_t * vLevel1, * vLevel2; + int i, k, Prev, This, Entry; + Vec_WecForEachLevel( vLits, vLevel1, i ) + { + if ( i == Vec_WecSize(vLits) - 1 ) + break; + vLevel2 = Vec_WecEntry(vClasses, i); + assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) ); + Prev = -1; + Vec_IntForEachEntry( vLevel2, This, k ) + { + if ( Prev != This ) + { + Prev = This; + continue; + } + Prev = -1; + Entry = Vec_IntEntry( vLevel1, k ); + + Vec_IntDrop( vLevel1, k ); + Vec_IntDrop( vLevel2, k-- ); + + Vec_IntDrop( vLevel1, k ); + Vec_IntDrop( vLevel2, k-- ); + + Vec_IntInsertOrder( Vec_WecEntry(vLits, i+1), Vec_WecEntry(vClasses, i+1), Entry, This ); + + assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) ); + assert( Vec_IntSize(Vec_WecEntry(vLits, i+1)) == Vec_IntSize(Vec_WecEntry(vClasses, i+1)) ); + } + } +} + void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) { Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); @@ -318,14 +362,20 @@ void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLi { Vec_WecInsertLevel( vLits0, 0 ); Vec_WecInsertLevel( vRoots0, 0 ); + Vec_WecInsertLevel( vRes0, 0 ); printf( "Shifted one level up.\n" ); } else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) { Vec_WecInsertLevel( vLits1, 0 ); Vec_WecInsertLevel( vRoots1, 0 ); + Vec_WecInsertLevel( vRes1, 0 ); printf( "Shifted one level down.\n" ); } + Acec_MoveDuplicates( vLits0, vRes0 ); + Acec_MoveDuplicates( vLits1, vRes1 ); + + //Vec_WecPrintLits( vLits1 ); //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits0 ); //printf( "Equiv classes:\n" ); @@ -410,6 +460,10 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vShared, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vShared, Vec_IntArray(vMap1), 0 ); + //printf( "\n" ); + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 ); @@ -448,8 +502,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" ); else { - pGia0n = Acec_InsertBox( pBox0, 1 ); - pGia1n = Acec_InsertBox( pBox1, 1 ); + pGia0n = Acec_InsertBox( pBox0, 0 ); + pGia1n = Acec_InsertBox( pBox1, 0 ); printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // remove the last output diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 6b36589cd..f2acb37b2 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -76,9 +76,19 @@ Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) { if ( Vec_IntSize(vLevel) == 2 ) Vec_IntPush( vLevel, 0 ); - In[2] = Vec_IntPop( vLevel ); - In[1] = Vec_IntPop( vLevel ); - In[0] = Vec_IntPop( vLevel ); + //In[2] = Vec_IntPop( vLevel ); + //In[1] = Vec_IntPop( vLevel ); + //In[0] = Vec_IntPop( vLevel ); + + In[0] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + + In[1] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + + In[2] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + Acec_InsertFadd( pNew, In, Out ); Vec_IntPush( vLevel, Out[0] ); if ( i+1 < Vec_WecSize(vLeafMap) ) @@ -114,11 +124,22 @@ int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); } -Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Int_t * vRootLits ) { Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); Vec_Int_t * vLevel, * vRootRanks; int i, k, iLit, iLitNew; + // add roo literals + if ( vRootLits ) + Vec_IntForEachEntry( vRootLits, iLit, i ) + { + if ( i < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, iLit ); + } + // add other literals Vec_WecForEachLevel( vLeafLits, vLevel, i ) Vec_IntForEachEntry( vLevel, iLit, k ) { @@ -137,7 +158,7 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) Gia_Man_t * p = pBox->pGia; Gia_Man_t * pNew; Gia_Obj_t * pObj; - Vec_Int_t * vRootRanks, * vLevel; + Vec_Int_t * vRootRanks, * vLevel, * vTemp; int i, k, iLit, iLitNew; pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); @@ -148,26 +169,14 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) pObj->Value = Gia_ManAppendCi( pNew ); // implement tree if ( fAll ) - vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits, NULL ); else { - Vec_Wec_t * vLeafLits; assert( pBox->vShared != NULL ); assert( pBox->vUnique != NULL ); - vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); - // add these roots to the unique ones - vLeafLits = Vec_WecDup( pBox->vUnique ); - Vec_IntForEachEntry( vRootRanks, iLit, i ) - { - if ( i < Vec_WecSize(vLeafLits) ) - vLevel = Vec_WecEntry(vLeafLits, i); - else - vLevel = Vec_WecPushLevel(vLeafLits); - Vec_IntPush( vLevel, iLit ); - } - Vec_IntFree( vRootRanks ); - vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); - Vec_WecFree( vLeafLits ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vShared, NULL ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vUnique, vTemp = vRootRanks ); + Vec_IntFree( vTemp ); } // update polarity of literals Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index fe5ca01b0..2461c89bd 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -207,6 +207,9 @@ void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) Gia_ManForEachAnd( p, pObj, i ) if ( Vec_BitEntry(vIsLeaf, i) ) Acec_TreeMarkTFI_rec( p, i, vMarked ); + // additional one +//if ( 10942 < Gia_ManObjNum(p) ) +// Acec_TreeMarkTFI_rec( p, 10942, vMarked ); // remove those that overlap with the marked TFI Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { @@ -419,7 +422,7 @@ Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * v int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { - if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) && Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); From a28be94ac79c0cbb0960565573985838d7a27a79 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Jan 2017 11:59:01 +0800 Subject: [PATCH 59/61] Small fixes and a change to &cec to allow two files names given as command-line arguments. --- src/aig/gia/giaIf.c | 16 ++--- src/aig/gia/giaTim.c | 2 + src/base/abci/abc.c | 125 +++++++++++++++++++++++++------------- src/base/abci/abcVerify.c | 14 +++-- 4 files changed, 103 insertions(+), 54 deletions(-) diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index ac748f8c7..ab80a7628 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -544,20 +544,20 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) fprintf( pTable, "%d ", Gia_ManAndNum(p) ); fprintf( pTable, "%d ", nLuts ); fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); - fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); - fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); - fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); + //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + //fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } else { - printf( "This part of the code is currently not used.\n" ); - assert( 0 ); + //printf( "This part of the code is currently not used.\n" ); + //assert( 0 ); fprintf( pTable, " " ); fprintf( pTable, "%d ", nLuts ); - fprintf( pTable, "%d ", LevelMax ); - fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); - fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); + //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } diff --git a/src/aig/gia/giaTim.c b/src/aig/gia/giaTim.c index 71b9a4757..29aa93f8e 100644 --- a/src/aig/gia/giaTim.c +++ b/src/aig/gia/giaTim.c @@ -584,6 +584,8 @@ int Gia_ManLutLevelWithBoxes( Gia_Man_t * p ) Gia_Obj_t * pObj, * pObjIn; int i, k, j, curCi, curCo, LevelMax; assert( Gia_ManRegNum(p) == 0 ); + if ( pManTime == NULL ) + return Gia_ManLutLevel(p, NULL); // copy const and real PIs Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); Gia_ObjSetLevel( p, Gia_ManConst0(p), 0 ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 58a14e817..806a5de79 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -32927,8 +32927,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) { Cec_ParCec_t ParsCec, * pPars = &ParsCec; FILE * pFile; - Gia_Man_t * pSecond, * pMiter; - char * FileName, * pTemp; + Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; char ** pArgvNew; int c, nArgcNew, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; Cec_ManCecSetDefaultParams( pPars ); @@ -32983,13 +32982,15 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( pAbc->pGia == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no AIG.\n" ); - return 1; - } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; if ( fMiter ) { + if ( pAbc->pGia == NULL || nArgcNew != 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): A miter cannot be given as an argument of command &cec and should be entered using &r.\n" ); + return 1; + } if ( fDualOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) @@ -32998,14 +32999,14 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a double-output miter.\n" ); pAbc->Status = Cec_ManVerify( pAbc->pGia, pPars ); } else { Gia_Man_t * pTemp; if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a single-output miter.\n" ); pTemp = Gia_ManDemiterToDual( pAbc->pGia ); pAbc->Status = Cec_ManVerify( pTemp, pPars ); ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb ); @@ -33014,41 +33015,81 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); return 0; } - - pArgvNew = argv + globalUtilOptind; - nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 1 ) + if ( nArgcNew > 2 ) { - if ( pAbc->pGia->pSpec == NULL ) - { - Abc_Print( -1, "File name is not given on the command line.\n" ); - return 1; - } - FileName = pAbc->pGia->pSpec; - } - else - FileName = pArgvNew[0]; - // fix the wrong symbol - for ( pTemp = FileName; *pTemp; pTemp++ ) - if ( *pTemp == '>' ) - *pTemp = '\\'; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); - if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", FileName ); - Abc_Print( 1, "\n" ); + Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" ); return 1; } - fclose( pFile ); - pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); - if ( pSecond == NULL ) + if ( nArgcNew == 2 ) { - Abc_Print( -1, "Reading AIGER has failed.\n" ); - return 0; + char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp; + int n; + for ( n = 0; n < 2; n++ ) + { + // fix the wrong symbol + for ( pTemp = pFileNames[n]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( pFileNames[n], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] ); + if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 ); + if ( pGias[n] == NULL ) + { + Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] ); + return 0; + } + } + } + else + { + char * FileName, * pTemp; + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" ); + return 1; + } + pGias[0] = pAbc->pGia; + if ( nArgcNew == 1 ) + FileName = pArgvNew[0]; + else + { + assert( nArgcNew == 0 ); + if ( pAbc->pGia->pSpec == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } + FileName = pAbc->pGia->pSpec; + } + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pGias[1] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } } // compute the miter - pMiter = Gia_ManMiter( pAbc->pGia, pSecond, 0, 1, 0, 0, pPars->fVerbose ); + pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, 1, 0, 0, pPars->fVerbose ); if ( pMiter ) { if ( fDumpMiter ) @@ -33057,10 +33098,12 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0 ); } pAbc->Status = Cec_ManVerify( pMiter, pPars ); - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); Gia_ManStop( pMiter ); } - Gia_ManStop( pSecond ); + if ( pGias[0] != pAbc->pGia ) + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); return 0; usage: @@ -36178,7 +36221,7 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: &satlut [-NICDQ num] [-drwvh]\n" ); - Abc_Print( -2, "\t performs SAT-based remapping of the 4-LUT network\n" ); + Abc_Print( -2, "\t performs SAT-based remapping of the LUT-mapped network\n" ); Abc_Print( -2, "\t-N num : the limit on AIG nodes in the window (num <= 128) [default = %d]\n", nNumber ); Abc_Print( -2, "\t-I num : the limit on the number of improved windows [default = %d]\n", nImproves ); Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nBTLimit ); diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c index 25d1d1130..7199c5296 100644 --- a/src/base/abci/abcVerify.c +++ b/src/base/abci/abcVerify.c @@ -122,6 +122,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI ***********************************************************************/ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ) { + abctime clk = Abc_Clock(); Prove_Params_t Params, * pParams = &Params; // Fraig_Params_t Params; // Fraig_Man_t * pMan; @@ -170,18 +171,20 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV RetValue = Abc_NtkMiterIsConstant( pMiter ); if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); + printf( "Networks are NOT EQUIVALENT after structural hashing. " ); // report the error pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 ); Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); ABC_FREE( pMiter->pModel ); Abc_NtkDelete( pMiter ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return; } if ( RetValue == 1 ) { - printf( "Networks are equivalent after structural hashing.\n" ); + printf( "Networks are equivalent after structural hashing. " ); Abc_NtkDelete( pMiter ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return; } /* @@ -220,18 +223,19 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV // pParams->fVerbose = 1; RetValue = Abc_NtkIvyProve( &pMiter, pParams ); if ( RetValue == -1 ) - printf( "Networks are undecided (resource limits is reached).\n" ); + printf( "Networks are undecided (resource limits is reached). " ); else if ( RetValue == 0 ) { int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel ); if ( pSimInfo[0] != 1 ) printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" ); else - printf( "Networks are NOT EQUIVALENT.\n" ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_FREE( pSimInfo ); } else - printf( "Networks are equivalent.\n" ); + printf( "Networks are equivalent. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); if ( pMiter->pModel ) Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); Abc_NtkDelete( pMiter ); From cf539dcca475d1c7f862834e8718bb318b54d5fd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Jan 2017 12:48:40 +0800 Subject: [PATCH 60/61] Fix mismatch in output formatting. --- src/aig/saig/saigMiter.c | 4 ++-- src/base/abci/abcDar.c | 12 ++++++------ src/proof/cec/cecCec.c | 6 +++--- src/proof/fra/fraCec.c | 6 +++--- src/proof/fra/fraSec.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c index 67aed490d..598103de9 100644 --- a/src/aig/saig/saigMiter.c +++ b/src/aig/saig/saigMiter.c @@ -1111,12 +1111,12 @@ int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int nFrames, int fVe // report the miter if ( RetValue == 1 ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); if ( pMiterCec->pData == NULL ) printf( "Counter-example is not available.\n" ); diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 9f6724853..147f7c2ff 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -1946,17 +1946,17 @@ finish: // report the miter if ( RetValue == 1 ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); @@ -3695,17 +3695,17 @@ int Abc_NtkDarInduction( Abc_Ntk_t * pNtk, int nTimeOut, int nFramesMax, int nCo RetValue = Saig_ManInduction( pMan, nTimeOut, nFramesMax, nConfMax, fUnique, fUniqueAll, fGetCex, fVerbose, fVeryVerbose ); if ( RetValue == 1 ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( fGetCex ) diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c index 77a6ed4a7..f7e45c57a 100644 --- a/src/proof/cec/cecCec.c +++ b/src/proof/cec/cecCec.c @@ -85,7 +85,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime { if ( !fSilent ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } } @@ -93,7 +93,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime { if ( !fSilent ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } if ( pMiterCec->pData == NULL ) @@ -120,7 +120,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime } else if ( !fSilent ) { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); diff --git a/src/proof/fra/fraCec.c b/src/proof/fra/fraCec.c index 130036a61..84f37930d 100644 --- a/src/proof/fra/fraCec.c +++ b/src/proof/fra/fraCec.c @@ -547,17 +547,17 @@ int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int n // report the miter if ( RetValue == 1 ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - printf( "Networks are UNDECIDED. " ); + printf( "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); diff --git a/src/proof/fra/fraSec.c b/src/proof/fra/fraSec.c index 06011d2e9..7e382fc89 100644 --- a/src/proof/fra/fraSec.c +++ b/src/proof/fra/fraSec.c @@ -606,7 +606,7 @@ finish: { if ( !pParSec->fSilent ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( pParSec->fReportSolution && !pParSec->fRecursive ) @@ -630,7 +630,7 @@ ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( !pParSec->fSilent ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( pParSec->fReportSolution && !pParSec->fRecursive ) From 51f4dab475af1ffd22d23b5aeb8d7cf243739f75 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:02:19 -0800 Subject: [PATCH 61/61] Adding features for invariant minimization. --- src/base/main/mainFrame.c | 4 - src/base/main/mainInt.h | 2 - src/base/wlc/wlcAbc.c | 155 ++++++++++--- src/base/wlc/wlcCom.c | 456 ++++++++++++++++++++++++++++---------- src/proof/pdr/pdrCore.c | 4 +- src/proof/pdr/pdrInv.c | 228 +++++++++++++++++++ src/proof/pdr/pdrUtil.c | 2 +- 7 files changed, 686 insertions(+), 165 deletions(-) diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index 05cb09c13..9647d020e 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -95,8 +95,6 @@ void Abc_FrameSetStatus( int Status ) { ABC_FREE( s_Globa void Abc_FrameSetManDsd( void * pMan ) { if (s_GlobalFrame->pManDsd && s_GlobalFrame->pManDsd != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd, 0); s_GlobalFrame->pManDsd = pMan; } void Abc_FrameSetManDsd2( void * pMan ) { if (s_GlobalFrame->pManDsd2 && s_GlobalFrame->pManDsd2 != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd2, 0); s_GlobalFrame->pManDsd2 = pMan; } void Abc_FrameSetInv( Vec_Int_t * vInv ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcInv); s_GlobalFrame->pAbcWlcInv = vInv; } -void Abc_FrameSetCnf( Vec_Int_t * vCnf ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcCnf); s_GlobalFrame->pAbcWlcCnf = vCnf; } -void Abc_FrameSetStr( Vec_Str_t * vStr ) { Vec_StrFreeP(&s_GlobalFrame->pAbcWlcStr); s_GlobalFrame->pAbcWlcStr = vStr; } void Abc_FrameSetJsonStrs( Abc_Nam_t * pStrs ) { Abc_NamDeref( s_GlobalFrame->pJsonStrs ); s_GlobalFrame->pJsonStrs = pStrs; } void Abc_FrameSetJsonObjs( Vec_Wec_t * vObjs ) { Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); s_GlobalFrame->vJsonObjs = vObjs; } @@ -227,8 +225,6 @@ void Abc_FrameDeallocate( Abc_Frame_t * p ) ABC_FREE( p->pCex2 ); ABC_FREE( p->pCex ); Vec_IntFreeP( &p->pAbcWlcInv ); - Vec_IntFreeP( &p->pAbcWlcCnf ); - Vec_StrFreeP( &p->pAbcWlcStr ); Abc_NamDeref( s_GlobalFrame->pJsonStrs ); Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); ABC_FREE( p ); diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index ff59b81a7..278a9191e 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -129,8 +129,6 @@ struct Abc_Frame_t_ void * pAbc85Delay; void * pAbcWlc; Vec_Int_t * pAbcWlcInv; - Vec_Int_t * pAbcWlcCnf; - Vec_Str_t * pAbcWlcStr; void * pAbcBac; void * pAbcCba; void * pAbcPla; diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 0bf27f7b3..1a98fb71c 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) +void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose ) { Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; @@ -53,7 +53,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) nRange = Wlc_ObjRange(pObj); for ( k = 0; k < nRange; k++ ) { - nNum = Vec_IntEntry(vInv, nBits + k); + nNum = Vec_IntEntry(vCounts, nBits + k); if ( nNum ) break; } @@ -65,7 +65,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); for ( k = 0; k < nRange; k++ ) { - nNum = Vec_IntEntry( vInv, nBits + k ); + nNum = Vec_IntEntry( vCounts, nBits + k ); if ( nNum == 0 ) continue; printf( " [%d] -> %d", k, nNum ); @@ -73,8 +73,8 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) printf( "\n"); nBits += nRange; } - //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); - assert( Vec_IntSize(vInv) == nBits ); + //printf( "%d %d\n", Vec_IntSize(vCounts), nBits ); + assert( Vec_IntSize(vCounts) == nBits ); } /**Function************************************************************* @@ -88,8 +88,14 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ) +Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) { + extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); + extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ); + + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts ); + Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; Abc_Ntk_t * pMainNtk = NULL; @@ -98,46 +104,69 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, // start the network pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); // duplicate the name and the spec - pMainNtk->pName = Extra_UtilStrsav(pNtk->pName); + pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv"); // create primary inputs - Wlc_NtkForEachCi( pNtk, pObj, i ) + if ( pNtk == NULL ) { - if ( pObj->Type != WLC_OBJ_FO ) - continue; - nRange = Wlc_ObjRange(pObj); - for ( k = 0; k < nRange; k++ ) + int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) ); + Vec_IntForEachEntry( vCounts, Entry, i ) { - nNum = Vec_IntEntry(vInv, nBits + k); - if ( nNum ) - break; - } - if ( k == nRange ) - { - nBits += nRange; - continue; - } - //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); - for ( k = 0; k < nRange; k++ ) - { - nNum = Vec_IntEntry( vInv, nBits + k ); - if ( nNum == 0 ) + if ( Entry == 0 ) continue; - //printf( " [%d] -> %d", k, nNum ); pMainObj = Abc_NtkCreatePi( pMainNtk ); - sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); + sprintf( Buffer, "pi%d", i ); Abc_ObjAssignName( pMainObj, Buffer, NULL ); - } - //printf( "\n"); - nBits += nRange; + if ( Abc_NtkPiNum(pMainNtk) != nInputs ) + { + printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" ); + Abc_NtkDelete( pMainNtk ); + return NULL; + } } - //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); - assert( Vec_IntSize(vInv) == nBits ); + else + { + Wlc_NtkForEachCi( pNtk, pObj, i ) + { + if ( pObj->Type != WLC_OBJ_FO ) + continue; + nRange = Wlc_ObjRange(pObj); + for ( k = 0; k < nRange; k++ ) + { + nNum = Vec_IntEntry(vCounts, nBits + k); + if ( nNum ) + break; + } + if ( k == nRange ) + { + nBits += nRange; + continue; + } + //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); + for ( k = 0; k < nRange; k++ ) + { + nNum = Vec_IntEntry( vCounts, nBits + k ); + if ( nNum == 0 ) + continue; + //printf( " [%d] -> %d", k, nNum ); + pMainObj = Abc_NtkCreatePi( pMainNtk ); + sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); + Abc_ObjAssignName( pMainObj, Buffer, NULL ); + + } + //printf( "\n"); + nBits += nRange; + } + } + //printf( "%d %d\n", Vec_IntSize(vCounts), nBits ); + assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits ); // create node pMainObj = Abc_NtkCreateNode( pMainNtk ); Abc_NtkForEachPi( pMainNtk, pMainTemp, i ) Abc_ObjAddFanin( pMainObj, pMainTemp ); pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vSop ); // create PO pMainTemp = Abc_NtkCreatePo( pMainNtk ); Abc_ObjAddFanin( pMainTemp, pMainObj ); @@ -145,6 +174,66 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, return pMainNtk; } +/**Function************************************************************* + + Synopsis [Translate current network into an interpolant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) +{ + Vec_Int_t * vRes = NULL; + if ( Abc_NtkPoNum(pNtk) != 1 ) + printf( "The number of outputs is other than 1.\n" ); + else if ( Abc_NtkNodeNum(pNtk) != 1 ) + printf( "The number of internal nodes is other than 1.\n" ); + else + { + Abc_Obj_t * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); + char * pName, * pCube, * pSop = (char *)pNode->pData; + Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) ); + Abc_Obj_t * pFanin; int i, k, Value, nLits; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + assert( Abc_ObjIsCi(pFanin) ); + pName = Abc_ObjName(pFanin); + for ( k = (int)strlen(pName)-1; k >= 0; k-- ) + if ( pName[k] < '0' || pName[k] > '9' ) + break; + if ( k == (int)strlen(pName)-1 ) + { + printf( "Cannot read input name of fanin %d.\n", i ); + Value = i; + } + else + Value = atoi(pName + k + 1); + Vec_IntPush( vFanins, Value ); + } + assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) ); + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) ); + Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube ) + { + nLits = 0; + Abc_CubeForEachVar( pCube, Value, k ) + if ( Value != '-' ) + nLits++; + Vec_IntPush( vRes, nLits ); + Abc_CubeForEachVar( pCube, Value, k ) + if ( Value != '-' ) + Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') ); + } + Vec_IntPush( vRes, nRegs ); + Vec_IntFree( vFanins ); + } + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index f3eb6dd7a..93614938a 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,18 +32,21 @@ static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); + static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; } static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; } -static inline Vec_Int_t * Wlc_AbcGetCnf( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcCnf; } -static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcStr; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -66,10 +69,15 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); + + Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); } /**Function******************************************************************** @@ -429,122 +437,6 @@ usage: return 1; } -/**Function******************************************************************** - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ); - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, fVerbose = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) - { - switch ( c ) - { - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - Abc_Print( 1, "Abc_CommandPsInv(): There is no current design.\n" ); - return 0; - } - if ( Wlc_AbcGetNtk(pAbc) == NULL ) - { - Abc_Print( 1, "Abc_CommandPsInv(): There is no saved invariant.\n" ); - return 0; - } - if ( Wlc_AbcGetInv(pAbc) == NULL ) - { - Abc_Print( 1, "Abc_CommandPsInv(): Invariant is not available.\n" ); - return 0; - } - Wlc_NtkPrintInvStats( pNtk, Wlc_AbcGetInv(pAbc), fVerbose ); - return 0; - usage: - Abc_Print( -2, "usage: %%psinv [-vh]\n" ); - Abc_Print( -2, "\t prints statistics for inductive invariant\n" ); - Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); - 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; -} - -/**Function******************************************************************** - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ); - Abc_Ntk_t * pMainNtk; - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, fVerbose = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) - { - switch ( c ) - { - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - Abc_Print( 1, "Abc_CommandGetInv(): There is no current design.\n" ); - return 0; - } - if ( Wlc_AbcGetNtk(pAbc) == NULL ) - { - Abc_Print( 1, "Abc_CommandGetInv(): There is no saved invariant.\n" ); - return 0; - } - if ( Wlc_AbcGetInv(pAbc) == NULL ) - { - Abc_Print( 1, "Abc_CommandGetInv(): Invariant is not available.\n" ); - return 0; - } - // derive the network - pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), Wlc_AbcGetStr(pAbc), fVerbose ); - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); - return 0; - usage: - Abc_Print( -2, "usage: %%getinv [-vh]\n" ); - Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" ); - Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); - 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; -} - /**Function******************************************************************** Synopsis [] @@ -641,6 +533,326 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); + extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ); + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Vec_Int_t * vCounts; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPs(): There is no current design.\n" ); + return 0; + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); + return 0; + } + vCounts = Pdr_InvCounts( Wlc_AbcGetInv(pAbc) ); + Wlc_NtkPrintInvStats( pNtk, vCounts, fVerbose ); + Vec_IntFree( vCounts ); + return 0; +usage: + Abc_Print( -2, "usage: inv_ps [-vh]\n" ); + Abc_Print( -2, "\t prints statistics for inductive invariant\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + 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; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Pdr_InvPrint( Vec_Int_t * vInv ); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); + return 0; + } + Pdr_InvPrint( Wlc_AbcGetInv(pAbc) ); + return 0; +usage: + Abc_Print( -2, "usage: inv_print [-vh]\n" ); + Abc_Print( -2, "\t prints the current inductive invariant\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + 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; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" ); + return 0; + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): There is no saved invariant.\n" ); + return 0; + } + if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(Wlc_AbcGetInv(pAbc)) ) + { + Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); + return 0; + } + Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + return 0; +usage: + Abc_Print( -2, "usage: inv_check [-vh]\n" ); + Abc_Print( -2, "\t checks that the invariant is indeed an inductive invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + 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; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ); + Abc_Ntk_t * pMainNtk; + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" ); + return 0; + } + // derive the network + pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) ); + // replace the current network + if ( pMainNtk ) + Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); + return 0; +usage: + Abc_Print( -2, "usage: inv_get [-vh]\n" ); + Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + 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; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ); + Vec_Int_t * vInv = NULL; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPut(): There is no current design.\n" ); + return 0; + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPut(): There is no current AIG.\n" ); + return 0; + } + // derive the network + vInv = Wlc_NtkGetPut( pNtk, Gia_ManRegNum(pAbc->pGia) ); + if ( vInv ) + Abc_FrameSetInv( vInv ); + return 0; +usage: + Abc_Print( -2, "usage: inv_put [-vh]\n" ); + Abc_Print( -2, "\t inputs the current network in the main-space as an invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + 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; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); + Vec_Int_t * vInv, * vInv2; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" ); + return 0; + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): Invariant is not available.\n" ); + return 0; + } + vInv = Wlc_AbcGetInv(pAbc); + if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(vInv) ) + { + Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); + return 0; + } + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + if ( vInv2 ) + Abc_FrameSetInv( vInv2 ); + return 0; +usage: + Abc_Print( -2, "usage: inv_min [-vh]\n" ); + Abc_Print( -2, "\t minimizes the number of clauses in the current invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + 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; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 66cae36e8..c625e366d 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -923,9 +923,7 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) if ( p->pPars->fDumpInv ) { char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); - Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); - Abc_FrameSetStr( Pdr_ManDumpString(p) ); - Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) ); + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); } p->tTotal += Abc_Clock() - clk; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 02b90a360..f29b792cf 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -605,9 +605,237 @@ Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce ) //Vec_PtrFree( vCubes ); Vec_PtrFreeP( &p->vInfCubes ); p->vInfCubes = vCubes; + Vec_IntPush( vResult, Aig_ManRegNum(p->pAig) ); return vResult; } + + +/**Function************************************************************* + + Synopsis [Remove clauses while maintaining the invariant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#define Pdr_ForEachCube( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 1 ) + +extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + +Vec_Int_t * Pdr_InvMap( Vec_Int_t * vCounts ) +{ + int i, k = 0, Count; + Vec_Int_t * vMap = Vec_IntStart( Vec_IntSize(vCounts) ); + Vec_IntForEachEntry( vCounts, Count, i ) + if ( Count ) + Vec_IntWriteEntry( vMap, i, k++ ); + return vMap; +} +Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ) +{ + int i, k, * pCube, * pList = Vec_IntArray(vInv); + Vec_Int_t * vCounts = Vec_IntStart( Vec_IntEntryLast(vInv) ); + Pdr_ForEachCube( pList, pCube, i ) + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntAddToEntry( vCounts, Abc_Lit2Var(pCube[k+1]), 1 ); + return vCounts; +} +int Pdr_InvUsedFlopNum( Vec_Int_t * vInv ) +{ + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + int nZeros = Vec_IntCountZero( vCounts ); + Vec_IntFree( vCounts ); + return Vec_IntEntryLast(vInv) - nZeros; +} + +Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ) +{ + Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); + Vec_Int_t * vMap = Pdr_InvMap( vCounts ); + int nVars = Vec_IntSize(vCounts) - Vec_IntCountZero(vCounts); + int i, k, * pCube, * pList = Vec_IntArray(vInv); + char * pBuffer = ABC_ALLOC( char, nVars ); + for ( i = 0; i < nVars; i++ ) + pBuffer[i] = '-'; + Pdr_ForEachCube( pList, pCube, i ) + { + for ( k = 0; k < pCube[0]; k++ ) + pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '0' + !Abc_LitIsCompl(pCube[k+1]); + for ( k = 0; k < nVars; k++ ) + Vec_StrPush( vStr, pBuffer[k] ); + Vec_StrPush( vStr, ' ' ); + Vec_StrPush( vStr, '1' ); + Vec_StrPush( vStr, '\n' ); + for ( k = 0; k < pCube[0]; k++ ) + pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '-'; + } + Vec_StrPush( vStr, '\0' ); + ABC_FREE( pBuffer ); + Vec_IntFree( vMap ); + return vStr; +} +void Pdr_InvPrint( Vec_Int_t * vInv ) +{ + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts ); + printf( "Invariant contains %d clauses with %d literals and %d flops (out of %d).\n", Vec_IntEntry(vInv, 0), Vec_IntSize(vInv)-Vec_IntEntry(vInv, 0)-2, Pdr_InvUsedFlopNum(vInv), Vec_IntEntryLast(vInv) ); + printf( "%s", Vec_StrArray( vStr ) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vStr ); +} + +void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) +{ + int nBTLimit = 0; + int i, k, status, nFailed = 0; + // create SAT solver + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + // collect cubes + int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; + // create variables + Vec_Int_t * vLits = Vec_IntAlloc(100); + int nVars = Gia_ManRegNum(p); + int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); + int iFiVarBeg = 1 + Gia_ManPoNum(p); + assert( Gia_ManPoNum(p) == 1 ); + // add cubes + Pdr_ForEachCube( pList, pCube, i ) + { + // collect literals + Vec_IntClear( vLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + // add it to the solver + status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); + assert( status == 1 ); + } + // iterate through cubes in the direct order + Pdr_ForEachCube( pList, pCube, i ) + { + // collect cube + Vec_IntClear( vLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); + // check if this cube intersects with the complement of other cubes in the solver + // if it does not intersect, then it is redundant and can be skipped + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + break; + if ( status == l_False ) // unsat -- correct + continue; + assert( status == l_True ); + nFailed++; + } + if ( nFailed ) + printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, nCubes ); + else + printf( "Invariant verification passes.\n" ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_IntFree( vLits ); +} + +Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) +{ + int nBTLimit = 0; + int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; + Vec_Int_t * vRes = NULL; + // create SAT solver + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; + // create variables + Vec_Int_t * vLits = Vec_IntAlloc(100); + Vec_Bit_t * vRemoved = Vec_BitStart( nCubes ); + int nVars = Gia_ManRegNum(p); + int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); + int iFiVarBeg = 1 + Gia_ManPoNum(p); + int iAuxVarBeg = sat_solver_nvars(pSat); + assert( Gia_ManPoNum(p) == 1 ); + // allocate auxiliary variables + sat_solver_setnvars( pSat, sat_solver_nvars(pSat) + nCubes ); + // add clauses + Pdr_ForEachCube( pList, pCube, i ) + { + // collect literals + Vec_IntFill( vLits, 1, Abc_Var2Lit(iAuxVarBeg + i, 1) ); // neg aux literal + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + // add it to the solver + status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); + assert( status == 1 ); + } + // iterate through clauses + Pdr_ForEachCube( pList, pCube, i ) + { + if ( Vec_BitEntry(vRemoved, i) ) + continue; + // collect aux literals for remaining clauses + Vec_IntClear( vLits ); + for ( k = 0; k < nCubes; k++ ) + if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes + Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal + nLits = Vec_IntSize( vLits ); + // try removing other clauses + fCannot = 0; + Pdr_ForEachCube( pList, pCube, n ) + { + if ( Vec_BitEntry(vRemoved, n) || n == i ) + continue; + // collect cube + Vec_IntShrink( vLits, nLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); + // check if this cube intersects with the complement of other cubes in the solver + // if it does not intersect, then it is redundant and can be skipped + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + { + fFailed = 1; + break; + } + if ( status == l_False ) // unsat -- correct + continue; + assert( status == l_True ); + // cannot remove + fCannot = 1; + break; + } + if ( fFailed ) + break; + if ( fCannot ) + continue; + printf( "Removing clause %d.\n", i ); + Vec_BitWriteEntry( vRemoved, i, 1 ); + nRemoved++; + } + if ( nRemoved ) + printf( "Invariant minimization reduced %d clauses (out of %d).\n", nRemoved, nCubes ); + else + printf( "Invariant minimization did not change the invariant.\n" ); + // cleanup cover + if ( !fFailed && nRemoved > 0 ) // finished without timeout and removed some cubes + { + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, nCubes-nRemoved ); + Pdr_ForEachCube( pList, pCube, i ) + if ( !Vec_BitEntry(vRemoved, i) ) + for ( k = 0; k <= pCube[0]; k++ ) + Vec_IntPush( vRes, pCube[k] ); + Vec_IntPush( vRes, Vec_IntEntryLast(vInv) ); + } + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_BitFree( vRemoved ); + Vec_IntFree( vLits ); + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c index 53a8a54ae..32e977727 100644 --- a/src/proof/pdr/pdrUtil.c +++ b/src/proof/pdr/pdrUtil.c @@ -284,7 +284,7 @@ void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vF } Vec_StrPushBuffer( vStr, pBuff, k ); Vec_StrPush( vStr, ' ' ); - Vec_StrPush( vStr, '0' ); + Vec_StrPush( vStr, '1' ); Vec_StrPush( vStr, '\n' ); ABC_FREE( pBuff ); }