From d51f798956a9f9fbdd1fc4eeecc483e511b1c3d3 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 3 May 2020 10:32:30 -0700 Subject: Experimental resubstitution. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaResub.c | 695 +++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaSimBase.c | 8 +- src/aig/gia/giaUtil.c | 88 ++++++ 4 files changed, 789 insertions(+), 3 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index ae9835ee..45291702 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1704,6 +1704,7 @@ extern int Gia_ManCheckSuppOverlap( Gia_Man_t * p, int iNode1, i extern int Gia_ManCountPisWithFanout( Gia_Man_t * p ); extern int Gia_ManCountPosWithNonZeroDrivers( Gia_Man_t * p ); extern void Gia_ManUpdateCopy( Vec_Int_t * vCopy, Gia_Man_t * p ); +extern Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, int fVerbose ); /*=== giaCTas.c ===========================================================*/ typedef struct Tas_Man_t_ Tas_Man_t; diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index b8c0e294..4dd8951f 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -22,6 +22,7 @@ #include "misc/vec/vecWec.h" #include "misc/vec/vecQue.h" #include "misc/vec/vecHsh.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -271,6 +272,214 @@ Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ); } + + + +/**Function************************************************************* + + Synopsis [Resubstitution data-structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +typedef struct Gia_ResbMan_t_ Gia_ResbMan_t; +struct Gia_ResbMan_t_ +{ + int nWords; + Vec_Ptr_t * vDivs; + Vec_Int_t * vGates; + Vec_Int_t * vUnateLits[2]; + Vec_Int_t * vNotUnateVars[2]; + Vec_Int_t * vUnatePairs[2]; + Vec_Int_t * vBinateVars; + Vec_Int_t * vUnateLitsW[2]; + Vec_Int_t * vUnatePairsW[2]; + word * pDivA; + word * pDivB; +}; +Gia_ResbMan_t * Gia_ResbAlloc( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vGates ) +{ + Gia_ResbMan_t * p = ABC_CALLOC( Gia_ResbMan_t, 1 ); + p->nWords = nWords; + p->vDivs = vDivs; + p->vGates = vGates; + p->vUnateLits[0] = Vec_IntAlloc( 100 ); + p->vUnateLits[1] = Vec_IntAlloc( 100 ); + p->vNotUnateVars[0] = Vec_IntAlloc( 100 ); + p->vNotUnateVars[1] = Vec_IntAlloc( 100 ); + p->vUnatePairs[0] = Vec_IntAlloc( 100 ); + p->vUnatePairs[1] = Vec_IntAlloc( 100 ); + p->vUnateLitsW[0] = Vec_IntAlloc( 100 ); + p->vUnateLitsW[1] = Vec_IntAlloc( 100 ); + p->vUnatePairsW[0] = Vec_IntAlloc( 100 ); + p->vUnatePairsW[1] = Vec_IntAlloc( 100 ); + p->vBinateVars = Vec_IntAlloc( 100 ); + p->pDivA = ABC_CALLOC( word, nWords ); + p->pDivB = ABC_CALLOC( word, nWords ); + return p; +} +void Gia_ResbReset( Gia_ResbMan_t * p ) +{ + Vec_IntClear( p->vUnateLits[0] ); + Vec_IntClear( p->vUnateLits[1] ); + Vec_IntClear( p->vNotUnateVars[0] ); + Vec_IntClear( p->vNotUnateVars[1] ); + Vec_IntClear( p->vUnatePairs[0] ); + Vec_IntClear( p->vUnatePairs[1] ); + Vec_IntClear( p->vUnateLitsW[0] ); + Vec_IntClear( p->vUnateLitsW[1] ); + Vec_IntClear( p->vUnatePairsW[0] ); + Vec_IntClear( p->vUnatePairsW[1] ); + Vec_IntClear( p->vBinateVars ); +} +void Gia_ResbFree( Gia_ResbMan_t * p ) +{ + Vec_IntFree( p->vUnateLits[0] ); + Vec_IntFree( p->vUnateLits[1] ); + Vec_IntFree( p->vNotUnateVars[0] ); + Vec_IntFree( p->vNotUnateVars[1] ); + Vec_IntFree( p->vUnatePairs[0] ); + Vec_IntFree( p->vUnatePairs[1] ); + Vec_IntFree( p->vUnateLitsW[0] ); + Vec_IntFree( p->vUnateLitsW[1] ); + Vec_IntFree( p->vUnatePairsW[0] ); + Vec_IntFree( p->vUnatePairsW[1] ); + Vec_IntFree( p->vBinateVars ); + ABC_FREE( p->pDivA ); + ABC_FREE( p->pDivB ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Verify resubstitution.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManResubVerify( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vGates, int iTopLit ) +{ + int i, iLit0, iLit1, RetValue, nDivs = Vec_PtrSize(vDivs); + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + word * pDivRes; + Vec_Wrd_t * vSims = NULL; + if ( iTopLit <= -1 ) + return -1; + if ( iTopLit == 0 ) + return Abc_TtIsConst0( pOnSet, nWords ); + if ( iTopLit == 1 ) + return Abc_TtIsConst0( pOffSet, nWords ); + if ( Abc_Lit2Var(iTopLit) < nDivs ) + { + assert( Vec_IntSize(vGates) == 0 ); + pDivRes = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iTopLit) ); + } + else + { + assert( Vec_IntSize(vGates) > 0 ); + assert( Vec_IntSize(vGates) % 2 == 0 ); + assert( Abc_Lit2Var(iTopLit)-nDivs == Vec_IntSize(vGates)/2-1 ); + vSims = Vec_WrdStart( nWords * Vec_IntSize(vGates)/2 ); + Vec_IntForEachEntryDouble( vGates, iLit0, iLit1, i ) + { + int iVar0 = Abc_Lit2Var(iLit0); + int iVar1 = Abc_Lit2Var(iLit1); + word * pDiv0 = iVar0 < nDivs ? (word *)Vec_PtrEntry(vDivs, iVar0) : Vec_WrdEntryP(vSims, nWords*(nDivs - iVar0)); + word * pDiv1 = iVar1 < nDivs ? (word *)Vec_PtrEntry(vDivs, iVar1) : Vec_WrdEntryP(vSims, nWords*(nDivs - iVar1)); + word * pDiv = Vec_WrdEntryP(vSims, nWords*i/2); + if ( iVar0 < iVar1 ) + Abc_TtAndCompl( pDiv, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ); + else if ( iVar0 > iVar1 ) + { + assert( !Abc_LitIsCompl(iLit0) ); + assert( !Abc_LitIsCompl(iLit1) ); + Abc_TtXor( pDiv, pDiv0, pDiv1, nWords, 0 ); + } + else assert( 0 ); + } + pDivRes = Vec_WrdEntryP( vSims, nWords*(Vec_IntSize(vGates)/2-1) ); + } + if ( Abc_LitIsCompl(iTopLit) ) + RetValue = !Abc_TtIntersectOne(pOnSet, 0, pDivRes, 0, nWords) && !Abc_TtIntersectOne(pOffSet, 0, pDivRes, 1, nWords); + else + RetValue = !Abc_TtIntersectOne(pOffSet, 0, pDivRes, 0, nWords) && !Abc_TtIntersectOne(pOnSet, 0, pDivRes, 1, nWords); + Vec_WrdFreeP( &vSims ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Construct AIG manager from gates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManGetVar( Gia_Man_t * pNew, Vec_Int_t * vUsed, int iVar ) +{ + if ( Vec_IntEntry(vUsed, iVar) == -1 ) + Vec_IntWriteEntry( vUsed, iVar, Gia_ManAppendCi(pNew) ); + return Vec_IntEntry(vUsed, iVar); +} +Gia_Man_t * Gia_ManConstructFromGates( int nVars, Vec_Int_t * vGates, int iTopLit ) +{ + int i, iLit0, iLit1, iLitRes; + Gia_Man_t * pNew = Gia_ManStart( 100 ); + pNew->pName = Abc_UtilStrsav( "resub" ); + assert( iTopLit >= 0 ); + if ( iTopLit == 0 || iTopLit == 1 ) + iLitRes = 0; + else if ( Abc_Lit2Var(iTopLit) < nVars ) + { + assert( Vec_IntSize(vGates) == 0 ); + iLitRes = Gia_ManAppendCi(pNew); + } + else + { + Vec_Int_t * vUsed = Vec_IntStartFull( nVars ); + Vec_Int_t * vCopy = Vec_IntAlloc( Vec_IntSize(vGates)/2 ); + assert( Vec_IntSize(vGates) > 0 ); + assert( Vec_IntSize(vGates) % 2 == 0 ); + assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(vGates)/2-1 ); + Vec_IntForEachEntryDouble( vGates, iLit0, iLit1, i ) + { + int iVar0 = Abc_Lit2Var(iLit0); + int iVar1 = Abc_Lit2Var(iLit1); + int iRes0 = iVar0 < nVars ? Gia_ManGetVar(pNew, vUsed, iVar0) : Vec_IntEntry(vCopy, nVars - iVar0); + int iRes1 = iVar1 < nVars ? Gia_ManGetVar(pNew, vUsed, iVar1) : Vec_IntEntry(vCopy, nVars - iVar1); + if ( iVar0 < iVar1 ) + iLitRes = Gia_ManAppendAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); + else if ( iVar0 > iVar1 ) + { + assert( !Abc_LitIsCompl(iLit0) ); + assert( !Abc_LitIsCompl(iLit1) ); + iLitRes = Gia_ManAppendXor( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); + } + else assert( 0 ); + Vec_IntPush( vCopy, iLitRes ); + } + assert( Vec_IntSize(vCopy) == Vec_IntSize(vGates)/2 ); + iLitRes = Vec_IntEntry( vCopy, Vec_IntSize(vGates)/2-1 ); + Vec_IntFree( vUsed ); + Vec_IntFree( vCopy ); + } + Gia_ManAppendCo( pNew, Abc_LitNotCond(iLitRes, Abc_LitIsCompl(iTopLit)) ); + return pNew; +} + + /**Function************************************************************* Synopsis [Perform resubstitution.] @@ -282,6 +491,492 @@ Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ); SeeAlso [] ***********************************************************************/ +static inline int Gia_ManFindFirstCommonLit( Vec_Int_t * vArr1, Vec_Int_t * vArr2 ) +{ + int * pBeg1 = vArr1->pArray; + int * pBeg2 = vArr2->pArray; + int * pEnd1 = vArr1->pArray + vArr1->nSize; + int * pEnd2 = vArr2->pArray + vArr2->nSize; + int * pStart1 = vArr1->pArray; + int * pStart2 = vArr2->pArray; + int nRemoved = 0; + while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 ) + { + if ( Abc_Lit2Var(*pBeg1) == Abc_Lit2Var(*pBeg2) ) + { + if ( *pBeg1 != *pBeg2 ) + return *pBeg1; + else + pBeg1++, pBeg2++; + nRemoved++; + } + else if ( *pBeg1 < *pBeg2 ) + *pStart1++ = *pBeg1++; + else + *pStart2++ = *pBeg2++; + } + while ( pBeg1 < pEnd1 ) + *pStart1++ = *pBeg1++; + while ( pBeg2 < pEnd2 ) + *pStart2++ = *pBeg2++; + Vec_IntShrink( vArr1, pStart1 - vArr1->pArray ); + Vec_IntShrink( vArr2, pStart2 - vArr2->pArray ); + printf( "Removed %d duplicated entries. Array1 = %d. Array2 = %d.\n", nRemoved, Vec_IntSize(vArr1), Vec_IntSize(vArr2) ); + return -1; +} + +void Gia_ManFindOneUnateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vNotUnateVars ) +{ + word * pDiv; int i; + Vec_IntClear( vUnateLits ); + Vec_IntClear( vNotUnateVars ); + Vec_PtrForEachEntryStart( word *, vDivs, pDiv, i, 2 ) + if ( !Abc_TtIntersectOne( pOffSet, 0, pDiv, 0, nWords ) ) + Vec_IntPush( vUnateLits, Abc_Var2Lit(i, 0) ); + else if ( !Abc_TtIntersectOne( pOffSet, 0, pDiv, 1, nWords ) ) + Vec_IntPush( vUnateLits, Abc_Var2Lit(i, 1) ); + else + Vec_IntPush( vNotUnateVars, i ); +} +int Gia_ManFindOneUnate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vNotUnateVars[2] ) +{ + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int n; + for ( n = 0; n < 2; n++ ) + { + Vec_IntClear( vUnateLits[n] ); + Vec_IntClear( vNotUnateVars[n] ); + Gia_ManFindOneUnateInt( pOffSet, pOnSet, vDivs, nWords, vUnateLits[n], vNotUnateVars[n] ); + ABC_SWAP( word *, pOffSet, pOnSet ); + printf( "Found %d %d-unate divs.\n", Vec_IntSize(vUnateLits[n]), n ); + } + return Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1] ); +} + +static inline int Gia_ManDivCover( word * pOffSet, word * pOnSet, word * pDivA, int ComplA, word * pDivB, int ComplB, int nWords ) +{ + assert( !Abc_TtIntersectOne(pOffSet, 0, pDivA, ComplA, nWords) ); + assert( !Abc_TtIntersectOne(pOffSet, 0, pDivB, ComplB, nWords) ); + return !Abc_TtIntersectTwo( pOnSet, 0, pDivA, !ComplA, pDivB, !ComplB, nWords ); +} +int Gia_ManFindTwoUnateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits ) +{ + int i, k, iDiv0, iDiv1; + Vec_IntForEachEntry( vUnateLits, iDiv1, i ) + Vec_IntForEachEntryStop( vUnateLits, iDiv0, k, i ) + { + word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); + word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1)); + if ( Gia_ManDivCover(pOffSet, pOnSet, pDiv0, Abc_LitIsCompl(iDiv0), pDiv1, Abc_LitIsCompl(iDiv1), nWords) ) + return Abc_Var2Lit((Abc_LitNot(iDiv0) << 16) | Abc_LitNot(iDiv1), 0); + } + return -1; +} +int Gia_ManFindTwoUnate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2] ) +{ + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int n, iLit; + for ( n = 0; n < 2; n++ ) + { + printf( "Trying %d pairs of %d-unate divs.\n", Vec_IntSize(vUnateLits[n])*(Vec_IntSize(vUnateLits[n])-1)/2, n ); + iLit = Gia_ManFindTwoUnateInt( pOffSet, pOnSet, vDivs, nWords, vUnateLits[n] ); + if ( iLit >= 0 ) + return Abc_LitNotCond(iLit, !n); + ABC_SWAP( word *, pOffSet, pOnSet ); + } + return -1; +} + +void Gia_ManFindXorInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits ) +{ + int i, k, iDiv0, iDiv1; + Vec_IntClear( vUnateLits ); + Vec_IntForEachEntry( vBinate, iDiv1, i ) + Vec_IntForEachEntryStop( vBinate, iDiv0, k, i ) + { + word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0); + word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1); + if ( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, 0, nWords ) ) + Vec_IntPush( vUnateLits, Abc_Var2Lit((Abc_Var2Lit(iDiv1, 0) << 16) | Abc_Var2Lit(iDiv0, 0), 0) ); + else if ( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, 1, nWords ) ) + Vec_IntPush( vUnateLits, Abc_Var2Lit((Abc_Var2Lit(iDiv1, 0) << 16) | Abc_Var2Lit(iDiv0, 0), 1) ); + } +} +int Gia_ManFindXor( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnateLits[2] ) +{ + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int n; + for ( n = 0; n < 2; n++ ) + { + Vec_IntClear( vUnateLits[n] ); + Gia_ManFindXorInt( pOffSet, pOnSet, vBinateVars, vDivs, nWords, vUnateLits[n] ); + ABC_SWAP( word *, pOffSet, pOnSet ); + printf( "Found %d %d-unate XOR divs.\n", Vec_IntSize(vUnateLits[n]), n ); + } + return Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1] ); +} + +void Gia_ManFindUnatePairsInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits ) +{ + int n, i, k, iDiv0, iDiv1; + Vec_IntClear( vUnateLits ); + Vec_IntForEachEntry( vBinate, iDiv1, i ) + Vec_IntForEachEntryStop( vBinate, iDiv0, k, i ) + { + word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0); + word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1); + for ( n = 0; n < 4; n++ ) + { + int iLit0 = Abc_Var2Lit( iDiv0, n&1 ); + int iLit1 = Abc_Var2Lit( iDiv1, n>>1 ); + if ( !Abc_TtIntersectTwo( pOffSet, 0, pDiv0, n&1, pDiv1, n>>1, nWords ) ) + Vec_IntPush( vUnateLits, Abc_Var2Lit((iLit0 << 16) | iLit1, 0) ); + } + } +} +void Gia_ManFindUnatePairs( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnateLits[2] ) +{ + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int n, RetValue; + for ( n = 0; n < 2; n++ ) + { + int nBefore = Vec_IntSize(vUnateLits[n]); + Gia_ManFindUnatePairsInt( pOffSet, pOnSet, vBinateVars, vDivs, nWords, vUnateLits[n] ); + ABC_SWAP( word *, pOffSet, pOnSet ); + printf( "Found %d %d-unate pair divs.\n", Vec_IntSize(vUnateLits[n])-nBefore, n ); + } + RetValue = Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1] ); + assert( RetValue == -1 ); +} + +int Gia_ManFindAndGateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnatePairs, word * pDivTemp ) +{ + int i, k, iDiv0, iDiv1; + Vec_IntForEachEntry( vUnateLits, iDiv0, i ) + Vec_IntForEachEntry( vUnatePairs, iDiv1, k ) + { + int fCompl = Abc_LitIsCompl(iDiv1); + int iDiv10 = Abc_Lit2Var(iDiv1) >> 16; + int iDiv11 = Abc_Lit2Var(iDiv1) & 0xFFF; + word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); + word * pDiv10 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv10)); + word * pDiv11 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv11)); + Abc_TtAndCompl( pDivTemp, pDiv10, Abc_LitIsCompl(iDiv10), pDiv11, Abc_LitIsCompl(iDiv11), nWords ); + if ( Gia_ManDivCover(pOnSet, pOffSet, pDiv0, Abc_LitIsCompl(iDiv0), pDivTemp, fCompl, nWords) ) + return Abc_Var2Lit((Abc_LitNot(iDiv0) << 16) | Abc_Var2Lit(k, 1), 0); + } + return -1; +} +int Gia_ManFindAndGate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnatePairs[2], word * pDivTemp ) +{ + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int n, iLit; + for ( n = 0; n < 2; n++ ) + { + iLit = Gia_ManFindAndGateInt( pOffSet, pOnSet, vDivs, nWords, vUnateLits[n], vUnatePairs[n], pDivTemp ); + if ( iLit > 0 ) + return Abc_LitNotCond( iLit, !n ); + ABC_SWAP( word *, pOffSet, pOnSet ); + } + return -1; +} + +int Gia_ManFindGateGateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, word * pDivTempA, word * pDivTempB ) +{ + int i, k, iDiv0, iDiv1; + Vec_IntForEachEntry( vUnatePairs, iDiv0, i ) + { + int fCompA = Abc_LitIsCompl(iDiv0); + int iDiv00 = Abc_Lit2Var(iDiv0 >> 16); + int iDiv01 = Abc_Lit2Var(iDiv0 & 0xFFF); + word * pDiv00 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv00)); + word * pDiv01 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv01)); + Abc_TtAndCompl( pDivTempA, pDiv00, Abc_LitIsCompl(iDiv00), pDiv01, Abc_LitIsCompl(iDiv01), nWords ); + Vec_IntForEachEntryStop( vUnatePairs, iDiv1, k, i ) + { + int fCompB = Abc_LitIsCompl(iDiv1); + int iDiv10 = Abc_Lit2Var(iDiv1 >> 16); + int iDiv11 = Abc_Lit2Var(iDiv1 & 0xFFF); + word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); + word * pDiv10 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv10)); + word * pDiv11 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv11)); + Abc_TtAndCompl( pDivTempB, pDiv10, Abc_LitIsCompl(iDiv10), pDiv11, Abc_LitIsCompl(iDiv11), nWords ); + if ( Gia_ManDivCover(pOnSet, pOffSet, pDivTempA, fCompA, pDivTempB, fCompB, nWords) ) + return Abc_Var2Lit((iDiv1 << 16) | iDiv0, 0); + } + } + return -1; +} +int Gia_ManFindGateGate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], word * pDivTempA, word * pDivTempB ) +{ + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int n, iLit; + for ( n = 0; n < 2; n++ ) + { + iLit = Gia_ManFindGateGateInt( pOffSet, pOnSet, vDivs, nWords, vUnatePairs[n], pDivTempA, pDivTempB ); + ABC_SWAP( word *, pOffSet, pOnSet ); + if ( iLit > 0 ) + return iLit; + } + return -1; +} + +void Gia_ManComputeLitWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnateLitsW ) +{ + int i, iLit; + Vec_IntClear( vUnateLitsW ); + Vec_IntForEachEntry( vUnateLits, iLit, i ) + { + word * pDiv = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit) ); + assert( !Abc_TtIntersectOne( pOffSet, 0, pDiv, Abc_LitIsCompl(iLit), nWords ) ); + Vec_IntPush( vUnateLitsW, Abc_TtCountOnesVecMask(pDiv, pOnSet, nWords, Abc_LitIsCompl(iLit)) ); + } +} +void Gia_ManComputeLitWeights( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2] ) +{ + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int n; + for ( n = 0; n < 2; n++ ) + { + Vec_IntClear( vUnateLitsW[n] ); + Gia_ManComputeLitWeightsInt( pOffSet, pOnSet, vDivs, nWords, vUnateLits[n], vUnateLitsW[n] ); + ABC_SWAP( word *, pOffSet, pOnSet ); + } + for ( n = 0; n < 2; n++ ) + { + int i, * pPerm = Abc_MergeSortCost( Vec_IntArray(vUnateLitsW[n]), Vec_IntSize(vUnateLitsW[n]) ); + Abc_ReverseOrder( pPerm, Vec_IntSize(vUnateLitsW[n]) ); + printf( "Top 10 %d-unate:\n", n ); + for ( i = 0; i < 10 && i < Vec_IntSize(vUnateLits[n]); i++ ) + { + printf( "%5d : ", i ); + printf( "Obj = %5d ", Vec_IntEntry(vUnateLits[n], pPerm[i]) ); + printf( "Cost = %5d\n", Vec_IntEntry(vUnateLitsW[n], pPerm[i]) ); + } + ABC_FREE( pPerm ); + } +} + +void Gia_ManComputePairWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW ) +{ + int i, iPair; + Vec_IntClear( vUnatePairsW ); + Vec_IntForEachEntry( vUnatePairs, iPair, i ) + { + int fCompl = Abc_LitIsCompl(iPair); + int Pair = Abc_Lit2Var(iPair); + int iLit0 = Pair >> 16; + int iLit1 = Pair & 0xFFFF; + word * pDiv0 = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit0) ); + word * pDiv1 = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit1) ); + if ( iLit0 < iLit1 ) + { + assert( !fCompl ); + assert( !Abc_TtIntersectTwo( pOffSet, 0, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ) ); + Vec_IntPush( vUnatePairsW, Abc_TtCountOnesVecMask2(pDiv0, pDiv1, Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), pOnSet, nWords) ); + } + else + { + assert( !Abc_LitIsCompl(iLit0) ); + assert( !Abc_LitIsCompl(iLit1) ); + assert( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, 0, nWords ) ); + Vec_IntPush( vUnatePairsW, Abc_TtCountOnesVecXorMask(pDiv0, pDiv1, fCompl, pOnSet, nWords) ); + } + } +} +void Gia_ManComputePairWeights( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnatePairsW[2] ) +{ + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int n; + for ( n = 0; n < 2; n++ ) + { + Gia_ManComputePairWeightsInt( pOffSet, pOnSet, vDivs, nWords, vUnatePairs[n], vUnatePairsW[n] ); + ABC_SWAP( word *, pOffSet, pOnSet ); + } + for ( n = 0; n < 2; n++ ) + { + int i, * pPerm = Abc_MergeSortCost( Vec_IntArray(vUnatePairsW[n]), Vec_IntSize(vUnatePairsW[n]) ); + Abc_ReverseOrder( pPerm, Vec_IntSize(vUnatePairsW[n]) ); + printf( "Top 10 %d-unate:\n", n ); + for ( i = 0; i < 10 && i < Vec_IntSize(vUnatePairs[n]); i++ ) + { + printf( "%5d : ", i ); + printf( "Obj = %5d ", Vec_IntEntry(vUnatePairs[n], pPerm[i]) ); + printf( "Cost = %5d\n", Vec_IntEntry(vUnatePairsW[n], pPerm[i]) ); + } + ABC_FREE( pPerm ); + } +} + + +/**Function************************************************************* + + Synopsis [Perform resubstitution.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManResubInt2( Vec_Ptr_t * vDivs, int nWords, int NodeLimit, int ChoiceType, Vec_Int_t * vGates ) +{ + return 0; +} +int Gia_ManResubInt( Gia_ResbMan_t * p ) +{ + int nDivs = Vec_PtrSize(p->vDivs); + int iResLit = Gia_ManFindOneUnate( p->vDivs, p->nWords, p->vUnateLits, p->vNotUnateVars ); + if ( iResLit >= 0 ) // buffer + { + printf( "Creating %s (%d).\n", Abc_LitIsCompl(iResLit) ? "inverter" : "buffer", Abc_Lit2Var(iResLit) ); + return iResLit; + } + iResLit = Gia_ManFindTwoUnate( p->vDivs, p->nWords, p->vUnateLits ); + if ( iResLit >= 0 ) // and + { + int fCompl = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) >> 16; + int iDiv1 = Abc_Lit2Var(iResLit) & 0xFFFF; + Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); + printf( "Creating one AND-gate.\n" ); + return Abc_Var2Lit( nDivs + Vec_IntSize(p->vGates)/2-1, fCompl ); + } + Vec_IntTwoFindCommon( p->vNotUnateVars[0], p->vNotUnateVars[1], p->vBinateVars ); + if ( Vec_IntSize(p->vBinateVars) > 1000 ) + { + printf( "Reducing binate divs from %d to 1000.\n", Vec_IntSize(p->vBinateVars) ); + Vec_IntShrink( p->vBinateVars, 1000 ); + } + iResLit = Gia_ManFindXor( p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs ); + if ( iResLit >= 0 ) // xor + { + int fCompl = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) >> 16; + int iDiv1 = Abc_Lit2Var(iResLit) & 0xFFFF; + assert( !Abc_LitIsCompl(iDiv0) ); + assert( !Abc_LitIsCompl(iDiv1) ); + Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); // xor + printf( "Creating one XOR-gate.\n" ); + return Abc_Var2Lit( nDivs + Vec_IntSize(p->vGates)/2-1, fCompl ); + } + Gia_ManFindUnatePairs( p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs ); +/* + iResLit = Gia_ManFindAndGate( p->vDivs, p->nWords, p->vUnateLits, p->vUnatePairs, p->pDivA ); + if ( iResLit >= 0 ) // and-gate + { + int New = nDivs + Vec_IntSize(p->vGates)/2; + int fCompl = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) >> 16; + int iDiv1 = Abc_Lit2Var(iResLit) & 0xFFFF; + Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv1), Abc_LitNot(iDiv0) ); + Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv0), New ); + printf( "Creating one two gates.\n" ); + return Abc_Var2Lit( nDivs + Vec_IntSize(p->vGates)/2-1, 1 ); + } + iResLit = Gia_ManFindGateGate( p->vDivs, p->nWords, p->vUnatePairs, p->pDivA, p->pDivB ); + if ( iResLit >= 0 ) // and-(gate,gate) + { + printf( "Creating one three gates.\n" ); + return -1; + } +*/ + Gia_ManComputeLitWeights( p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW ); + Gia_ManComputePairWeights( p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW ); + return -1; +} + +/**Function************************************************************* + + Synopsis [Top level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCheckResub( Vec_Ptr_t * vDivs, int nWords ) +{ + int i, Set[10] = { 2, 189, 2127, 2125, 177, 178 }; + word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + Vec_Int_t * vValue = Vec_IntStartFull( 1 << 6 ); + printf( "Verifying resub:\n" ); + for ( i = 0; i < 64*nWords; i++ ) + { + int v, Mint = 0, Value = Abc_TtGetBit(pOnSet, i); + if ( !Abc_TtGetBit(pOffSet, i) && !Value ) + continue; + for ( v = 0; v < 6; v++ ) + if ( Abc_TtGetBit((word *)Vec_PtrEntry(vDivs, Set[v]), i) ) + Mint |= 1 << v; + if ( Vec_IntEntry(vValue, Mint) == -1 ) + Vec_IntWriteEntry(vValue, Mint, Value); + else if ( Vec_IntEntry(vValue, Mint) != Value ) + printf( "Mismatch in pattern %d\n", i ); + } + printf( "Finished verifying resub.\n" ); + Vec_IntFree( vValue ); +} +Vec_Ptr_t * Gia_ManDeriveDivs( Vec_Wrd_t * vSims, int nWords ) +{ + int i, nDivs = Vec_WrdSize(vSims)/nWords; + Vec_Ptr_t * vDivs = Vec_PtrAlloc( nDivs ); + for ( i = 0; i < nDivs; i++ ) + Vec_PtrPush( vDivs, Vec_WrdEntryP(vSims, nWords*i) ); + return vDivs; +} +Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, int fVerbose, int fVeryVerbose ) +{ + return NULL; +} +Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int fVerbose, int fVeryVerbose ) +{ + extern Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName, int * pnWords ); + int iTopLit, nWords = 0; + Gia_Man_t * pMan = NULL; + Vec_Wrd_t * vSims = Gia_ManSimPatRead( pFileName, &nWords ); + Vec_Ptr_t * vDivs = vSims ? Gia_ManDeriveDivs( vSims, nWords ) : NULL; + Vec_Int_t * vGates = vDivs ? Vec_IntAlloc( 100 ) : NULL; + Gia_ResbMan_t * p = vDivs ? Gia_ResbAlloc( vDivs, nWords, vGates ) : NULL; + if ( p == NULL ) + return NULL; + assert( Vec_PtrSize(vDivs) < (1<<15) ); + printf( "OFF = %5d (%6.2f %%) ", Abc_TtCountOnesVec(Vec_PtrEntry(vDivs, 0), nWords), 100.0*Abc_TtCountOnesVec(Vec_PtrEntry(vDivs, 0), nWords)/(64*nWords) ); + printf( "ON = %5d (%6.2f %%)\n", Abc_TtCountOnesVec(Vec_PtrEntry(vDivs, 1), nWords), 100.0*Abc_TtCountOnesVec(Vec_PtrEntry(vDivs, 1), nWords)/(64*nWords) ); + if ( Vec_PtrSize(vDivs) > 4000 ) + { + printf( "Reducing all divs from %d to 4000.\n", Vec_PtrSize(vDivs) ); + Vec_PtrShrink( vDivs, 4000 ); + } + Gia_ResbReset( p ); +// Gia_ManCheckResub( vDivs, nWords ); + iTopLit = Gia_ManResubInt( p ); + if ( iTopLit >= 0 ) + { + printf( "Verification %s.\n", Gia_ManResubVerify( vDivs, nWords, vGates, iTopLit ) ? "succeeded" : "FAILED" ); + pMan = Gia_ManConstructFromGates( Vec_PtrSize(vDivs), vGates, iTopLit ); + } + else + printf( "Decomposition did not succeed.\n" ); + Gia_ResbFree( p ); + Vec_IntFree( vGates ); + Vec_PtrFree( vDivs ); + Vec_WrdFree( vSims ); + return pMan; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index c53c1db8..f9539faf 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -343,7 +343,7 @@ void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ) for ( i = 0; i < nNodes; i++ ) Gia_ManSimPatWriteOne( pFile, Vec_WrdEntryP(vSimsIn, i*nWords), nWords ); fclose( pFile ); - printf( "Written %d words of simulation data into file \"%s\".\n", nWords, pFileName ); + printf( "Written %d words of simulation data for %d objects into file \"%s\".\n", nWords, Vec_WrdSize(vSimsIn)/nWords, pFileName ); } int Gia_ManSimPatReadOne( char c ) { @@ -358,7 +358,7 @@ int Gia_ManSimPatReadOne( char c ) assert( Digit >= 0 && Digit < 16 ); return Digit; } -Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName ) +Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName, int * pnWords ) { Vec_Wrd_t * vSimsIn = NULL; int c, nWords = -1, nChars = 0; word Num = 0; @@ -384,7 +384,9 @@ Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName ) } assert( Vec_WrdSize(vSimsIn) % nWords == 0 ); fclose( pFile ); - printf( "Read %d words of simulation data.\n", nWords ); + printf( "Read %d words of simulation data for %d objects.\n", nWords, Vec_WrdSize(vSimsIn)/nWords ); + if ( pnWords ) + *pnWords = nWords; return vSimsIn; } diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index d0ec969f..5ee20e6a 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2290,6 +2290,94 @@ Gia_Man_t * Gia_ManDupWithMuxPos( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Collect distance info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManRingAdd( Gia_Man_t * p, int iObj, Vec_Int_t * vRes, Vec_Int_t * vDists, int Dist ) +{ + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + Vec_IntWriteEntry( vDists, iObj, Dist ); + Vec_IntPush( vRes, iObj ); +} +void Gia_ManCollectRing( Gia_Man_t * p, Vec_Int_t * vStart, Vec_Int_t * vRes, Vec_Int_t * vDists ) +{ + int i, k, iObj, iFan; + Vec_IntForEachEntry( vStart, iObj, i ) + { + int Weight = Vec_IntEntry( vDists, iObj ); + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + assert( Weight > 0 ); + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManRingAdd( p, Gia_ObjFaninId0(pObj, iObj), vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ObjFanin0(pObj)) ); + Gia_ManRingAdd( p, Gia_ObjFaninId1(pObj, iObj), vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ObjFanin1(pObj)) ); + } + Gia_ObjForEachFanoutStaticId( p, iObj, iFan, k ) + Gia_ManRingAdd( p, iFan, vRes, vDists, Weight + 1*!Gia_ObjIsBuf(Gia_ManObj(p, iFan)) ); + } +} +Vec_Int_t * Gia_ManComputeDistanceInt( Gia_Man_t * p, int iTarg, Vec_Int_t * vObjs, int fVerbose ) +{ + int i, iObj; + Vec_Int_t * vDists, * vStart, * vNexts; + vStart = Vec_IntAlloc( 100 ); + vNexts = Vec_IntAlloc( 100 ); + vDists = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_ManIncrementTravId( p ); + if ( vObjs ) + { + Vec_IntForEachEntry( vObjs, iObj, i ) + { + Gia_ObjSetTravIdCurrentId(p, iObj); + Vec_IntWriteEntry( vDists, iObj, 1 ); + Vec_IntPush( vStart, iObj ); + } + } + else + { + Gia_ObjSetTravIdCurrentId(p, iTarg); + Vec_IntWriteEntry( vDists, iTarg, 1 ); + Vec_IntPush( vStart, iTarg ); + } + for ( i = 0; ; i++ ) + { + if ( fVerbose ) + printf( "Ring %2d : %6d\n", i, Vec_IntSize(vDists)-Vec_IntCountZero(vDists) ); + Gia_ManCollectRing( p, vStart, vNexts, vDists ); + if ( Vec_IntSize(vNexts) == 0 ) + break; + Vec_IntClear( vStart ); + ABC_SWAP( Vec_Int_t, *vStart, *vNexts ); + } + Vec_IntFree( vStart ); + Vec_IntFree( vNexts ); + return vDists; +} +Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, int fVerbose ) +{ + Vec_Int_t * vDists; + if ( p->vFanoutNums ) + vDists = Gia_ManComputeDistanceInt( p, iObj, vObjs, fVerbose ); + else + { + Gia_ManStaticFanoutStart( p ); + vDists = Gia_ManComputeDistanceInt( p, iObj, vObjs, fVerbose ); + Gia_ManStaticFanoutStop( p ); + } + return vDists; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -- cgit v1.2.3 From e149cdcd77de5023782cf2cd16e98aa20473b89c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 3 May 2020 12:15:54 -0700 Subject: Compiler warnings. --- src/aig/gia/giaResub.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 4dd8951f..9de0ffb8 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -702,7 +702,6 @@ int Gia_ManFindGateGateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, in int fCompB = Abc_LitIsCompl(iDiv1); int iDiv10 = Abc_Lit2Var(iDiv1 >> 16); int iDiv11 = Abc_Lit2Var(iDiv1 & 0xFFF); - word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); word * pDiv10 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv10)); word * pDiv11 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv11)); Abc_TtAndCompl( pDivTempB, pDiv10, Abc_LitIsCompl(iDiv10), pDiv11, Abc_LitIsCompl(iDiv11), nWords ); -- cgit v1.2.3 From f026e6533987a1628be38cfe828f167d4aaff760 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 3 May 2020 19:09:02 -0700 Subject: Compiler warnings and errors. --- src/aig/gia/gia.h | 3 +++ src/aig/gia/giaResub.c | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 45291702..4e10cbe6 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1557,6 +1557,9 @@ extern void Gia_ManIncrSimStart( Gia_Man_t * p, int nWords, int n extern void Gia_ManIncrSimSet( Gia_Man_t * p, Vec_Int_t * vObjLits ); extern int Gia_ManIncrSimCheckOver( Gia_Man_t * p, int iLit0, int iLit1 ); extern int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 ); +/*=== giaSimBase.c ============================================================*/ +extern Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName, int * pnWords ); +extern void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ); /*=== giaSpeedup.c ============================================================*/ extern float Gia_ManDelayTraceLut( Gia_Man_t * p ); extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ); diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 9de0ffb8..092603ed 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -942,7 +942,6 @@ Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, i } Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int fVerbose, int fVeryVerbose ) { - extern Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName, int * pnWords ); int iTopLit, nWords = 0; Gia_Man_t * pMan = NULL; Vec_Wrd_t * vSims = Gia_ManSimPatRead( pFileName, &nWords ); @@ -952,8 +951,8 @@ Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, i if ( p == NULL ) return NULL; assert( Vec_PtrSize(vDivs) < (1<<15) ); - printf( "OFF = %5d (%6.2f %%) ", Abc_TtCountOnesVec(Vec_PtrEntry(vDivs, 0), nWords), 100.0*Abc_TtCountOnesVec(Vec_PtrEntry(vDivs, 0), nWords)/(64*nWords) ); - printf( "ON = %5d (%6.2f %%)\n", Abc_TtCountOnesVec(Vec_PtrEntry(vDivs, 1), nWords), 100.0*Abc_TtCountOnesVec(Vec_PtrEntry(vDivs, 1), nWords)/(64*nWords) ); + printf( "OFF = %5d (%6.2f %%) ", Abc_TtCountOnesVec((word *)Vec_PtrEntry(vDivs, 0), nWords), 100.0*Abc_TtCountOnesVec((word *)Vec_PtrEntry(vDivs, 0), nWords)/(64*nWords) ); + printf( "ON = %5d (%6.2f %%)\n", Abc_TtCountOnesVec((word *)Vec_PtrEntry(vDivs, 1), nWords), 100.0*Abc_TtCountOnesVec((word *)Vec_PtrEntry(vDivs, 1), nWords)/(64*nWords) ); if ( Vec_PtrSize(vDivs) > 4000 ) { printf( "Reducing all divs from %d to 4000.\n", Vec_PtrSize(vDivs) ); -- cgit v1.2.3 From f543d39ec89dc0513784e189b537e6d45fd3db31 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 3 May 2020 21:09:02 -0700 Subject: Experiment with permutations. --- src/aig/gia/gia.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c index 7947a60e..d57a4a74 100644 --- a/src/aig/gia/gia.c +++ b/src/aig/gia/gia.c @@ -297,6 +297,101 @@ void Gia_ManStructExperiment( Gia_Man_t * p ) Vec_PtrFree( vGias ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_EnumFirstUnused( int * pUsed, int nVars ) +{ + int i; + for ( i = 0; i < nVars; i++ ) + if ( pUsed[i] == 0 ) + return i; + return -1; +} +void Gia_EnumPerms_rec( int * pUsed, int nVars, int * pPerm, int nPerm, int * pCount, FILE * pFile, int nLogVars ) +{ + int i, k, New; + if ( nPerm == nVars ) + { + if ( pFile ) + { + for ( i = 0; i < nLogVars; i++ ) + fprintf( pFile, "%c", '0' + ((*pCount) >> (nLogVars-1-i) & 1) ); + fprintf( pFile, " " ); + for ( i = 0; i < nVars; i++ ) + for ( k = 0; k < nVars; k++ ) + fprintf( pFile, "%c", '0' + (pPerm[i] == k) ); + fprintf( pFile, "\n" ); + } + else + { + if ( *pCount < 20 ) + { + printf( "%5d : ", (*pCount) ); + for ( i = 0; i < nVars; i += 2 ) + printf( "%d %d ", pPerm[i], pPerm[i+1] ); + printf( "\n" ); + } + } + (*pCount)++; + return; + } + New = Gia_EnumFirstUnused( pUsed, nVars ); + assert( New >= 0 ); + pPerm[nPerm] = New; + assert( pUsed[New] == 0 ); + pUsed[New] = 1; + // try remaining ones + for ( i = 0; i < nVars; i++ ) + { + if ( pUsed[i] == 1 ) + continue; + pPerm[nPerm+1] = i; + assert( pUsed[i] == 0 ); + pUsed[i] = 1; + Gia_EnumPerms_rec( pUsed, nVars, pPerm, nPerm+2, pCount, pFile, nLogVars ); + assert( pUsed[i] == 1 ); + pUsed[i] = 0; + } + assert( pUsed[New] == 1 ); + pUsed[New] = 0; +} +void Gia_EnumPerms( int nVars ) +{ + int nLogVars = 0, Count = 0; + int * pUsed = ABC_CALLOC( int, nVars ); + int * pPerm = ABC_CALLOC( int, nVars ); + FILE * pFile = fopen( "pairset.pla", "wb" ); + assert( nVars % 2 == 0 ); + + printf( "Printing sets of pairs for %d objects:\n", nVars ); + Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, NULL, -1 ); + if ( Count > 20 ) + printf( "...\n" ); + printf( "Finished enumerating %d sets of pairs.\n", Count ); + + nLogVars = Abc_Base2Log( Count ); + printf( "Need %d variables to encode %d sets.\n", nLogVars, Count ); + Count = 0; + fprintf( pFile, ".i %d\n", 10 ); + fprintf( pFile, ".o %d\n", nVars*nVars ); + Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, pFile, nLogVars ); + fprintf( pFile, ".e\n" ); + fclose( pFile ); + printf( "Finished dumping file \"%s\".\n", "pairset.pla" ); + + ABC_FREE( pUsed ); + ABC_FREE( pPerm ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 234b5d771be8173ad8677fb397a381b06ff621de Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 3 May 2020 21:59:33 -0700 Subject: Experiment with permutations. --- src/aig/gia/gia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c index d57a4a74..cf7c0ddd 100644 --- a/src/aig/gia/gia.c +++ b/src/aig/gia/gia.c @@ -381,7 +381,7 @@ void Gia_EnumPerms( int nVars ) nLogVars = Abc_Base2Log( Count ); printf( "Need %d variables to encode %d sets.\n", nLogVars, Count ); Count = 0; - fprintf( pFile, ".i %d\n", 10 ); + fprintf( pFile, ".i %d\n", nLogVars ); fprintf( pFile, ".o %d\n", nVars*nVars ); Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, pFile, nLogVars ); fprintf( pFile, ".e\n" ); -- cgit v1.2.3 From 372eb7bdefbb3da989746ea1abbab6dc10a19dd8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 7 May 2020 20:06:39 -0700 Subject: Experimental resubstitution. --- src/aig/gia/giaResub.c | 675 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 442 insertions(+), 233 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 092603ed..7b57db15 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -26,7 +26,6 @@ ABC_NAMESPACE_IMPL_START - //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -290,6 +289,7 @@ typedef struct Gia_ResbMan_t_ Gia_ResbMan_t; struct Gia_ResbMan_t_ { int nWords; + int fVerbose; Vec_Ptr_t * vDivs; Vec_Int_t * vGates; Vec_Int_t * vUnateLits[2]; @@ -298,15 +298,15 @@ struct Gia_ResbMan_t_ Vec_Int_t * vBinateVars; Vec_Int_t * vUnateLitsW[2]; Vec_Int_t * vUnatePairsW[2]; + word * pSets[2]; word * pDivA; word * pDivB; + Vec_Wrd_t * vSims; }; -Gia_ResbMan_t * Gia_ResbAlloc( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vGates ) +Gia_ResbMan_t * Gia_ResbAlloc( int nWords ) { Gia_ResbMan_t * p = ABC_CALLOC( Gia_ResbMan_t, 1 ); p->nWords = nWords; - p->vDivs = vDivs; - p->vGates = vGates; p->vUnateLits[0] = Vec_IntAlloc( 100 ); p->vUnateLits[1] = Vec_IntAlloc( 100 ); p->vNotUnateVars[0] = Vec_IntAlloc( 100 ); @@ -318,12 +318,22 @@ Gia_ResbMan_t * Gia_ResbAlloc( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vGates p->vUnatePairsW[0] = Vec_IntAlloc( 100 ); p->vUnatePairsW[1] = Vec_IntAlloc( 100 ); p->vBinateVars = Vec_IntAlloc( 100 ); + p->pSets[0] = ABC_CALLOC( word, nWords ); + p->pSets[1] = ABC_CALLOC( word, nWords ); p->pDivA = ABC_CALLOC( word, nWords ); p->pDivB = ABC_CALLOC( word, nWords ); + p->vSims = Vec_WrdAlloc( 100 ); return p; } -void Gia_ResbReset( Gia_ResbMan_t * p ) +void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vGates, int fVerbose ) { + assert( p->nWords == nWords ); + p->fVerbose = fVerbose; + Abc_TtCopy( p->pSets[0], (word *)Vec_PtrEntry(vDivs, 0), nWords, 0 ); + Abc_TtCopy( p->pSets[1], (word *)Vec_PtrEntry(vDivs, 1), nWords, 0 ); + p->vDivs = vDivs; + p->vGates = vGates; + Vec_IntClear( p->vGates ); Vec_IntClear( p->vUnateLits[0] ); Vec_IntClear( p->vUnateLits[1] ); Vec_IntClear( p->vNotUnateVars[0] ); @@ -349,11 +359,69 @@ void Gia_ResbFree( Gia_ResbMan_t * p ) Vec_IntFree( p->vUnatePairsW[0] ); Vec_IntFree( p->vUnatePairsW[1] ); Vec_IntFree( p->vBinateVars ); + Vec_WrdFree( p->vSims ); + ABC_FREE( p->pSets[0] ); + ABC_FREE( p->pSets[1] ); ABC_FREE( p->pDivA ); ABC_FREE( p->pDivB ); ABC_FREE( p ); } +/**Function************************************************************* + + Synopsis [Print resubstitution.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManResubPrintNode( Vec_Int_t * vRes, int nVars, int Node, int fCompl ) +{ + extern void Gia_ManResubPrintLit( Vec_Int_t * vRes, int nVars, int iLit ); + int iLit0 = Vec_IntEntry( vRes, 2*Node + 0 ); + int iLit1 = Vec_IntEntry( vRes, 2*Node + 1 ); + assert( iLit0 != iLit1 ); + if ( iLit0 > iLit1 && Abc_LitIsCompl(fCompl) ) // xor + { + printf( "~" ); + fCompl = 0; + } + printf( "(" ); + Gia_ManResubPrintLit( vRes, nVars, Abc_LitNotCond(iLit0, fCompl) ); + printf( " %c ", iLit0 > iLit1 ? '^' : (fCompl ? '|' : '&') ); + Gia_ManResubPrintLit( vRes, nVars, Abc_LitNotCond(iLit1, fCompl) ); + printf( ")" ); +} +void Gia_ManResubPrintLit( Vec_Int_t * vRes, int nVars, int iLit ) +{ + if ( Abc_Lit2Var(iLit) < nVars ) + { + if ( nVars < 26 ) + printf( "%s%c", Abc_LitIsCompl(iLit) ? "~":"", 'a' + Abc_Lit2Var(iLit)-2 ); + else + printf( "%si%d", Abc_LitIsCompl(iLit) ? "~":"", Abc_Lit2Var(iLit)-2 ); + } + else + Gia_ManResubPrintNode( vRes, nVars, Abc_Lit2Var(iLit) - nVars, Abc_LitIsCompl(iLit) ); +} +int Gia_ManResubPrint( Vec_Int_t * vRes, int nVars ) +{ + int iTopLit; + if ( Vec_IntSize(vRes) == 0 ) + return printf( "none" ); + assert( Vec_IntSize(vRes) % 2 == 1 ); + iTopLit = Vec_IntEntryLast(vRes); + if ( iTopLit == 0 ) + return printf( "const0" ); + if ( iTopLit == 1 ) + return printf( "const1" ); + Gia_ManResubPrintLit( vRes, nVars, iTopLit ); + return 0; +} + /**Function************************************************************* Synopsis [Verify resubstitution.] @@ -365,54 +433,54 @@ void Gia_ResbFree( Gia_ResbMan_t * p ) SeeAlso [] ***********************************************************************/ -int Gia_ManResubVerify( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vGates, int iTopLit ) +int Gia_ManResubVerify( Gia_ResbMan_t * p ) { - int i, iLit0, iLit1, RetValue, nDivs = Vec_PtrSize(vDivs); - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + int nVars = Vec_PtrSize(p->vDivs); + int iTopLit, RetValue; word * pDivRes; - Vec_Wrd_t * vSims = NULL; - if ( iTopLit <= -1 ) + if ( Vec_IntSize(p->vGates) == 0 ) return -1; + iTopLit = Vec_IntEntryLast(p->vGates); + assert( iTopLit >= 0 ); if ( iTopLit == 0 ) - return Abc_TtIsConst0( pOnSet, nWords ); + return Abc_TtIsConst0( p->pSets[1], p->nWords ); if ( iTopLit == 1 ) - return Abc_TtIsConst0( pOffSet, nWords ); - if ( Abc_Lit2Var(iTopLit) < nDivs ) + return Abc_TtIsConst0( p->pSets[0], p->nWords ); + if ( Abc_Lit2Var(iTopLit) < nVars ) { - assert( Vec_IntSize(vGates) == 0 ); - pDivRes = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iTopLit) ); + assert( Vec_IntSize(p->vGates) == 1 ); + pDivRes = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iTopLit) ); } else { - assert( Vec_IntSize(vGates) > 0 ); - assert( Vec_IntSize(vGates) % 2 == 0 ); - assert( Abc_Lit2Var(iTopLit)-nDivs == Vec_IntSize(vGates)/2-1 ); - vSims = Vec_WrdStart( nWords * Vec_IntSize(vGates)/2 ); - Vec_IntForEachEntryDouble( vGates, iLit0, iLit1, i ) + int i, iLit0, iLit1; + assert( Vec_IntSize(p->vGates) > 1 ); + assert( Vec_IntSize(p->vGates) % 2 == 1 ); + assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(p->vGates)/2-1 ); + Vec_WrdFill( p->vSims, p->nWords * Vec_IntSize(p->vGates)/2, 0 ); + Vec_IntForEachEntryDouble( p->vGates, iLit0, iLit1, i ) { int iVar0 = Abc_Lit2Var(iLit0); int iVar1 = Abc_Lit2Var(iLit1); - word * pDiv0 = iVar0 < nDivs ? (word *)Vec_PtrEntry(vDivs, iVar0) : Vec_WrdEntryP(vSims, nWords*(nDivs - iVar0)); - word * pDiv1 = iVar1 < nDivs ? (word *)Vec_PtrEntry(vDivs, iVar1) : Vec_WrdEntryP(vSims, nWords*(nDivs - iVar1)); - word * pDiv = Vec_WrdEntryP(vSims, nWords*i/2); + word * pDiv0 = iVar0 < nVars ? (word *)Vec_PtrEntry(p->vDivs, iVar0) : Vec_WrdEntryP(p->vSims, p->nWords*(iVar0 - nVars)); + word * pDiv1 = iVar1 < nVars ? (word *)Vec_PtrEntry(p->vDivs, iVar1) : Vec_WrdEntryP(p->vSims, p->nWords*(iVar1 - nVars)); + word * pDiv = Vec_WrdEntryP(p->vSims, p->nWords*i/2); if ( iVar0 < iVar1 ) - Abc_TtAndCompl( pDiv, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ); + Abc_TtAndCompl( pDiv, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), p->nWords ); else if ( iVar0 > iVar1 ) { assert( !Abc_LitIsCompl(iLit0) ); assert( !Abc_LitIsCompl(iLit1) ); - Abc_TtXor( pDiv, pDiv0, pDiv1, nWords, 0 ); + Abc_TtXor( pDiv, pDiv0, pDiv1, p->nWords, 0 ); } else assert( 0 ); } - pDivRes = Vec_WrdEntryP( vSims, nWords*(Vec_IntSize(vGates)/2-1) ); + pDivRes = Vec_WrdEntryP( p->vSims, p->nWords*(Vec_IntSize(p->vGates)/2-1) ); } if ( Abc_LitIsCompl(iTopLit) ) - RetValue = !Abc_TtIntersectOne(pOnSet, 0, pDivRes, 0, nWords) && !Abc_TtIntersectOne(pOffSet, 0, pDivRes, 1, nWords); + RetValue = !Abc_TtIntersectOne(p->pSets[1], 0, pDivRes, 0, p->nWords) && !Abc_TtIntersectOne(p->pSets[0], 0, pDivRes, 1, p->nWords); else - RetValue = !Abc_TtIntersectOne(pOffSet, 0, pDivRes, 0, nWords) && !Abc_TtIntersectOne(pOnSet, 0, pDivRes, 1, nWords); - Vec_WrdFreeP( &vSims ); + RetValue = !Abc_TtIntersectOne(p->pSets[0], 0, pDivRes, 0, p->nWords) && !Abc_TtIntersectOne(p->pSets[1], 0, pDivRes, 1, p->nWords); return RetValue; } @@ -433,32 +501,36 @@ int Gia_ManGetVar( Gia_Man_t * pNew, Vec_Int_t * vUsed, int iVar ) Vec_IntWriteEntry( vUsed, iVar, Gia_ManAppendCi(pNew) ); return Vec_IntEntry(vUsed, iVar); } -Gia_Man_t * Gia_ManConstructFromGates( int nVars, Vec_Int_t * vGates, int iTopLit ) +Gia_Man_t * Gia_ManConstructFromGates( Vec_Int_t * vGates, int nVars ) { - int i, iLit0, iLit1, iLitRes; - Gia_Man_t * pNew = Gia_ManStart( 100 ); + int i, iLit0, iLit1, iTopLit, iLitRes; + Gia_Man_t * pNew; + if ( Vec_IntSize(vGates) == 0 ) + return NULL; + assert( Vec_IntSize(vGates) % 2 == 1 ); + pNew = Gia_ManStart( 100 ); pNew->pName = Abc_UtilStrsav( "resub" ); - assert( iTopLit >= 0 ); + iTopLit = Vec_IntEntryLast( vGates ); if ( iTopLit == 0 || iTopLit == 1 ) iLitRes = 0; else if ( Abc_Lit2Var(iTopLit) < nVars ) { - assert( Vec_IntSize(vGates) == 0 ); + assert( Vec_IntSize(vGates) == 1 ); iLitRes = Gia_ManAppendCi(pNew); } else { Vec_Int_t * vUsed = Vec_IntStartFull( nVars ); Vec_Int_t * vCopy = Vec_IntAlloc( Vec_IntSize(vGates)/2 ); - assert( Vec_IntSize(vGates) > 0 ); - assert( Vec_IntSize(vGates) % 2 == 0 ); + assert( Vec_IntSize(vGates) > 1 ); + assert( Vec_IntSize(vGates) % 2 == 1 ); assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(vGates)/2-1 ); Vec_IntForEachEntryDouble( vGates, iLit0, iLit1, i ) { int iVar0 = Abc_Lit2Var(iLit0); int iVar1 = Abc_Lit2Var(iLit1); - int iRes0 = iVar0 < nVars ? Gia_ManGetVar(pNew, vUsed, iVar0) : Vec_IntEntry(vCopy, nVars - iVar0); - int iRes1 = iVar1 < nVars ? Gia_ManGetVar(pNew, vUsed, iVar1) : Vec_IntEntry(vCopy, nVars - iVar1); + int iRes0 = iVar0 < nVars ? Gia_ManGetVar(pNew, vUsed, iVar0) : Vec_IntEntry(vCopy, iVar0 - nVars); + int iRes1 = iVar1 < nVars ? Gia_ManGetVar(pNew, vUsed, iVar1) : Vec_IntEntry(vCopy, iVar1 - nVars); if ( iVar0 < iVar1 ) iLitRes = Gia_ManAppendAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); else if ( iVar0 > iVar1 ) @@ -491,7 +563,7 @@ Gia_Man_t * Gia_ManConstructFromGates( int nVars, Vec_Int_t * vGates, int iTopLi SeeAlso [] ***********************************************************************/ -static inline int Gia_ManFindFirstCommonLit( Vec_Int_t * vArr1, Vec_Int_t * vArr2 ) +static inline int Gia_ManFindFirstCommonLit( Vec_Int_t * vArr1, Vec_Int_t * vArr2, int fVerbose ) { int * pBeg1 = vArr1->pArray; int * pBeg2 = vArr2->pArray; @@ -521,7 +593,7 @@ static inline int Gia_ManFindFirstCommonLit( Vec_Int_t * vArr1, Vec_Int_t * vArr *pStart2++ = *pBeg2++; Vec_IntShrink( vArr1, pStart1 - vArr1->pArray ); Vec_IntShrink( vArr2, pStart2 - vArr2->pArray ); - printf( "Removed %d duplicated entries. Array1 = %d. Array2 = %d.\n", nRemoved, Vec_IntSize(vArr1), Vec_IntSize(vArr2) ); + if ( fVerbose ) printf( "Removed %d duplicated entries. Array1 = %d. Array2 = %d.\n", nRemoved, Vec_IntSize(vArr1), Vec_IntSize(vArr2) ); return -1; } @@ -538,20 +610,17 @@ void Gia_ManFindOneUnateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, i else Vec_IntPush( vNotUnateVars, i ); } -int Gia_ManFindOneUnate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vNotUnateVars[2] ) +int Gia_ManFindOneUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vNotUnateVars[2], int fVerbose ) { - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); int n; for ( n = 0; n < 2; n++ ) { Vec_IntClear( vUnateLits[n] ); Vec_IntClear( vNotUnateVars[n] ); - Gia_ManFindOneUnateInt( pOffSet, pOnSet, vDivs, nWords, vUnateLits[n], vNotUnateVars[n] ); - ABC_SWAP( word *, pOffSet, pOnSet ); - printf( "Found %d %d-unate divs.\n", Vec_IntSize(vUnateLits[n]), n ); + Gia_ManFindOneUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vNotUnateVars[n] ); + if ( fVerbose ) printf( "Found %d %d-unate divs.\n", Vec_IntSize(vUnateLits[n]), n ); } - return Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1] ); + return Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1], fVerbose ); } static inline int Gia_ManDivCover( word * pOffSet, word * pOnSet, word * pDivA, int ComplA, word * pDivB, int ComplB, int nWords ) @@ -568,61 +637,54 @@ int Gia_ManFindTwoUnateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, in { word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1)); - if ( Gia_ManDivCover(pOffSet, pOnSet, pDiv0, Abc_LitIsCompl(iDiv0), pDiv1, Abc_LitIsCompl(iDiv1), nWords) ) - return Abc_Var2Lit((Abc_LitNot(iDiv0) << 16) | Abc_LitNot(iDiv1), 0); + if ( Gia_ManDivCover(pOffSet, pOnSet, pDiv1, Abc_LitIsCompl(iDiv1), pDiv0, Abc_LitIsCompl(iDiv0), nWords) ) + return Abc_Var2Lit((Abc_LitNot(iDiv1) << 15) | Abc_LitNot(iDiv0), 1); } return -1; } -int Gia_ManFindTwoUnate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2] ) +int Gia_ManFindTwoUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], int fVerbose ) { - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); int n, iLit; for ( n = 0; n < 2; n++ ) { - printf( "Trying %d pairs of %d-unate divs.\n", Vec_IntSize(vUnateLits[n])*(Vec_IntSize(vUnateLits[n])-1)/2, n ); - iLit = Gia_ManFindTwoUnateInt( pOffSet, pOnSet, vDivs, nWords, vUnateLits[n] ); + int nPairs = Vec_IntSize(vUnateLits[n])*(Vec_IntSize(vUnateLits[n])-1)/2; + if ( fVerbose ) printf( "Trying %d pairs of %d-unate divs.\n", nPairs, n ); + iLit = Gia_ManFindTwoUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n] ); if ( iLit >= 0 ) - return Abc_LitNotCond(iLit, !n); - ABC_SWAP( word *, pOffSet, pOnSet ); + return Abc_LitNotCond(iLit, n); } return -1; } -void Gia_ManFindXorInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits ) +void Gia_ManFindXorInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs ) { int i, k, iDiv0, iDiv1; - Vec_IntClear( vUnateLits ); Vec_IntForEachEntry( vBinate, iDiv1, i ) Vec_IntForEachEntryStop( vBinate, iDiv0, k, i ) { word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0); word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1); if ( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, 0, nWords ) ) - Vec_IntPush( vUnateLits, Abc_Var2Lit((Abc_Var2Lit(iDiv1, 0) << 16) | Abc_Var2Lit(iDiv0, 0), 0) ); + Vec_IntPush( vUnatePairs, Abc_Var2Lit((Abc_Var2Lit(iDiv0, 0) << 15) | Abc_Var2Lit(iDiv1, 0), 0) ); else if ( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, 1, nWords ) ) - Vec_IntPush( vUnateLits, Abc_Var2Lit((Abc_Var2Lit(iDiv1, 0) << 16) | Abc_Var2Lit(iDiv0, 0), 1) ); + Vec_IntPush( vUnatePairs, Abc_Var2Lit((Abc_Var2Lit(iDiv0, 0) << 15) | Abc_Var2Lit(iDiv1, 0), 1) ); } } -int Gia_ManFindXor( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnateLits[2] ) +int Gia_ManFindXor( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnatePairs[2], int fVerbose ) { - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); int n; for ( n = 0; n < 2; n++ ) { - Vec_IntClear( vUnateLits[n] ); - Gia_ManFindXorInt( pOffSet, pOnSet, vBinateVars, vDivs, nWords, vUnateLits[n] ); - ABC_SWAP( word *, pOffSet, pOnSet ); - printf( "Found %d %d-unate XOR divs.\n", Vec_IntSize(vUnateLits[n]), n ); + Vec_IntClear( vUnatePairs[n] ); + Gia_ManFindXorInt( pSets[n], pSets[!n], vBinateVars, vDivs, nWords, vUnatePairs[n] ); + if ( fVerbose ) printf( "Found %d %d-unate XOR divs.\n", Vec_IntSize(vUnatePairs[n]), n ); } - return Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1] ); + return Gia_ManFindFirstCommonLit( vUnatePairs[0], vUnatePairs[1], fVerbose ); } -void Gia_ManFindUnatePairsInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits ) +void Gia_ManFindUnatePairsInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs ) { int n, i, k, iDiv0, iDiv1; - Vec_IntClear( vUnateLits ); Vec_IntForEachEntry( vBinate, iDiv1, i ) Vec_IntForEachEntryStop( vBinate, iDiv0, k, i ) { @@ -632,56 +694,67 @@ void Gia_ManFindUnatePairsInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinat { int iLit0 = Abc_Var2Lit( iDiv0, n&1 ); int iLit1 = Abc_Var2Lit( iDiv1, n>>1 ); - if ( !Abc_TtIntersectTwo( pOffSet, 0, pDiv0, n&1, pDiv1, n>>1, nWords ) ) - Vec_IntPush( vUnateLits, Abc_Var2Lit((iLit0 << 16) | iLit1, 0) ); + if ( !Abc_TtIntersectTwo( pOffSet, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) ) + Vec_IntPush( vUnatePairs, Abc_Var2Lit((iLit1 << 15) | iLit0, 0) ); } } } -void Gia_ManFindUnatePairs( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnateLits[2] ) +void Gia_ManFindUnatePairs( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnatePairs[2], int fVerbose ) { - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); int n, RetValue; for ( n = 0; n < 2; n++ ) { - int nBefore = Vec_IntSize(vUnateLits[n]); - Gia_ManFindUnatePairsInt( pOffSet, pOnSet, vBinateVars, vDivs, nWords, vUnateLits[n] ); - ABC_SWAP( word *, pOffSet, pOnSet ); - printf( "Found %d %d-unate pair divs.\n", Vec_IntSize(vUnateLits[n])-nBefore, n ); + int nBefore = Vec_IntSize(vUnatePairs[n]); + Gia_ManFindUnatePairsInt( pSets[n], pSets[!n], vBinateVars, vDivs, nWords, vUnatePairs[n] ); + if ( fVerbose ) printf( "Found %d %d-unate pair divs.\n", Vec_IntSize(vUnatePairs[n])-nBefore, n ); } - RetValue = Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1] ); + RetValue = Gia_ManFindFirstCommonLit( vUnatePairs[0], vUnatePairs[1], fVerbose ); assert( RetValue == -1 ); } -int Gia_ManFindAndGateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnatePairs, word * pDivTemp ) +void Gia_ManDeriveDivPair( int iDiv, Vec_Ptr_t * vDivs, int nWords, word * pRes ) +{ + int fComp = Abc_LitIsCompl(iDiv); + int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF; + int iDiv1 = Abc_Lit2Var(iDiv) >> 15; + word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); + word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1)); + if ( iDiv0 < iDiv1 ) + { + assert( !fComp ); + Abc_TtAndCompl( pRes, pDiv0, Abc_LitIsCompl(iDiv0), pDiv1, Abc_LitIsCompl(iDiv1), nWords ); + } + else + { + assert( !Abc_LitIsCompl(iDiv0) ); + assert( !Abc_LitIsCompl(iDiv1) ); + Abc_TtXor( pRes, pDiv0, pDiv1, nWords, 0 ); + } +} +int Gia_ManFindDivGateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnatePairs, word * pDivTemp ) { int i, k, iDiv0, iDiv1; - Vec_IntForEachEntry( vUnateLits, iDiv0, i ) - Vec_IntForEachEntry( vUnatePairs, iDiv1, k ) - { - int fCompl = Abc_LitIsCompl(iDiv1); - int iDiv10 = Abc_Lit2Var(iDiv1) >> 16; - int iDiv11 = Abc_Lit2Var(iDiv1) & 0xFFF; - word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); - word * pDiv10 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv10)); - word * pDiv11 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv11)); - Abc_TtAndCompl( pDivTemp, pDiv10, Abc_LitIsCompl(iDiv10), pDiv11, Abc_LitIsCompl(iDiv11), nWords ); - if ( Gia_ManDivCover(pOnSet, pOffSet, pDiv0, Abc_LitIsCompl(iDiv0), pDivTemp, fCompl, nWords) ) - return Abc_Var2Lit((Abc_LitNot(iDiv0) << 16) | Abc_Var2Lit(k, 1), 0); + int Limit1 = Abc_MinInt( Vec_IntSize(vUnateLits), 1000 ); + int Limit2 = Abc_MinInt( Vec_IntSize(vUnatePairs), 1000 ); + Vec_IntForEachEntryStop( vUnateLits, iDiv0, i, Limit1 ) + Vec_IntForEachEntryStop( vUnatePairs, iDiv1, k, Limit2 ) + { + word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); + int fComp1 = Abc_LitIsCompl(iDiv1); + Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTemp ); + if ( Gia_ManDivCover(pOffSet, pOnSet, pDiv0, Abc_LitIsCompl(iDiv0), pDivTemp, fComp1, nWords) ) + return Abc_Var2Lit((Abc_Var2Lit(k, 1) << 15) | Abc_LitNot(iDiv0), 1); } return -1; } -int Gia_ManFindAndGate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnatePairs[2], word * pDivTemp ) +int Gia_ManFindDivGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnatePairs[2], word * pDivTemp ) { - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); int n, iLit; for ( n = 0; n < 2; n++ ) { - iLit = Gia_ManFindAndGateInt( pOffSet, pOnSet, vDivs, nWords, vUnateLits[n], vUnatePairs[n], pDivTemp ); - if ( iLit > 0 ) - return Abc_LitNotCond( iLit, !n ); - ABC_SWAP( word *, pOffSet, pOnSet ); + iLit = Gia_ManFindDivGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnatePairs[n], pDivTemp ); + if ( iLit >= 0 ) + return Abc_LitNotCond( iLit, n ); } return -1; } @@ -689,39 +762,29 @@ int Gia_ManFindAndGate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2] int Gia_ManFindGateGateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, word * pDivTempA, word * pDivTempB ) { int i, k, iDiv0, iDiv1; - Vec_IntForEachEntry( vUnatePairs, iDiv0, i ) - { - int fCompA = Abc_LitIsCompl(iDiv0); - int iDiv00 = Abc_Lit2Var(iDiv0 >> 16); - int iDiv01 = Abc_Lit2Var(iDiv0 & 0xFFF); - word * pDiv00 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv00)); - word * pDiv01 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv01)); - Abc_TtAndCompl( pDivTempA, pDiv00, Abc_LitIsCompl(iDiv00), pDiv01, Abc_LitIsCompl(iDiv01), nWords ); - Vec_IntForEachEntryStop( vUnatePairs, iDiv1, k, i ) + int Limit2 = Abc_MinInt( Vec_IntSize(vUnatePairs), 1000 ); + Vec_IntForEachEntryStop( vUnatePairs, iDiv1, i, Limit2 ) + { + int fCompB = Abc_LitIsCompl(iDiv1); + Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTempB ); + Vec_IntForEachEntryStop( vUnatePairs, iDiv0, k, i ) { - int fCompB = Abc_LitIsCompl(iDiv1); - int iDiv10 = Abc_Lit2Var(iDiv1 >> 16); - int iDiv11 = Abc_Lit2Var(iDiv1 & 0xFFF); - word * pDiv10 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv10)); - word * pDiv11 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv11)); - Abc_TtAndCompl( pDivTempB, pDiv10, Abc_LitIsCompl(iDiv10), pDiv11, Abc_LitIsCompl(iDiv11), nWords ); - if ( Gia_ManDivCover(pOnSet, pOffSet, pDivTempA, fCompA, pDivTempB, fCompB, nWords) ) - return Abc_Var2Lit((iDiv1 << 16) | iDiv0, 0); + int fCompA = Abc_LitIsCompl(iDiv0); + Gia_ManDeriveDivPair( iDiv0, vDivs, nWords, pDivTempA ); + if ( Gia_ManDivCover(pOffSet, pOnSet, pDivTempA, fCompA, pDivTempB, fCompB, nWords) ) + return Abc_Var2Lit((Abc_Var2Lit(i, 1) << 15) | Abc_Var2Lit(k, 1), 1); } } return -1; } -int Gia_ManFindGateGate( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], word * pDivTempA, word * pDivTempB ) +int Gia_ManFindGateGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], word * pDivTempA, word * pDivTempB ) { - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); int n, iLit; for ( n = 0; n < 2; n++ ) { - iLit = Gia_ManFindGateGateInt( pOffSet, pOnSet, vDivs, nWords, vUnatePairs[n], pDivTempA, pDivTempB ); - ABC_SWAP( word *, pOffSet, pOnSet ); - if ( iLit > 0 ) - return iLit; + iLit = Gia_ManFindGateGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnatePairs[n], pDivTempA, pDivTempB ); + if ( iLit >= 0 ) + return Abc_LitNotCond( iLit, n ); } return -1; } @@ -734,33 +797,36 @@ void Gia_ManComputeLitWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDi { word * pDiv = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit) ); assert( !Abc_TtIntersectOne( pOffSet, 0, pDiv, Abc_LitIsCompl(iLit), nWords ) ); - Vec_IntPush( vUnateLitsW, Abc_TtCountOnesVecMask(pDiv, pOnSet, nWords, Abc_LitIsCompl(iLit)) ); + Vec_IntPush( vUnateLitsW, -Abc_TtCountOnesVecMask(pDiv, pOnSet, nWords, Abc_LitIsCompl(iLit)) ); } } -void Gia_ManComputeLitWeights( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2] ) +void Gia_ManComputeLitWeights( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], int TopW[2], int fVerbose ) { - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); - int n; + int n, TopNum = 5; + TopW[0] = TopW[1] = 0; for ( n = 0; n < 2; n++ ) - { - Vec_IntClear( vUnateLitsW[n] ); - Gia_ManComputeLitWeightsInt( pOffSet, pOnSet, vDivs, nWords, vUnateLits[n], vUnateLitsW[n] ); - ABC_SWAP( word *, pOffSet, pOnSet ); - } + Gia_ManComputeLitWeightsInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n] ); for ( n = 0; n < 2; n++ ) - { - int i, * pPerm = Abc_MergeSortCost( Vec_IntArray(vUnateLitsW[n]), Vec_IntSize(vUnateLitsW[n]) ); - Abc_ReverseOrder( pPerm, Vec_IntSize(vUnateLitsW[n]) ); - printf( "Top 10 %d-unate:\n", n ); - for ( i = 0; i < 10 && i < Vec_IntSize(vUnateLits[n]); i++ ) + if ( Vec_IntSize(vUnateLitsW[n]) ) { - printf( "%5d : ", i ); - printf( "Obj = %5d ", Vec_IntEntry(vUnateLits[n], pPerm[i]) ); - printf( "Cost = %5d\n", Vec_IntEntry(vUnateLitsW[n], pPerm[i]) ); + int i, * pPerm = Abc_MergeSortCost( Vec_IntArray(vUnateLitsW[n]), Vec_IntSize(vUnateLitsW[n]) ); + TopW[n] = -Vec_IntEntry(vUnateLitsW[n], pPerm[0]); + if ( fVerbose ) + { + printf( "Top %d %d-unate divs:\n", TopNum, n ); + for ( i = 0; i < TopNum && i < Vec_IntSize(vUnateLits[n]); i++ ) + { + printf( "%5d : ", i ); + printf( "Lit = %5d ", Vec_IntEntry(vUnateLits[n], pPerm[i]) ); + printf( "Cost = %5d\n", -Vec_IntEntry(vUnateLitsW[n], pPerm[i]) ); + } + } + for ( i = 0; i < Vec_IntSize(vUnateLits[n]); i++ ) + pPerm[i] = Vec_IntEntry(vUnateLits[n], pPerm[i]); + for ( i = 0; i < Vec_IntSize(vUnateLits[n]); i++ ) + vUnateLits[n]->pArray[i] = pPerm[i]; + ABC_FREE( pPerm ); } - ABC_FREE( pPerm ); - } } void Gia_ManComputePairWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW ) @@ -769,50 +835,59 @@ void Gia_ManComputePairWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vD Vec_IntClear( vUnatePairsW ); Vec_IntForEachEntry( vUnatePairs, iPair, i ) { - int fCompl = Abc_LitIsCompl(iPair); - int Pair = Abc_Lit2Var(iPair); - int iLit0 = Pair >> 16; - int iLit1 = Pair & 0xFFFF; + int fComp = Abc_LitIsCompl(iPair); + int iLit0 = Abc_Lit2Var(iPair) & 0x7FFF; + int iLit1 = Abc_Lit2Var(iPair) >> 15; word * pDiv0 = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit0) ); word * pDiv1 = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit1) ); if ( iLit0 < iLit1 ) { - assert( !fCompl ); + assert( !fComp ); assert( !Abc_TtIntersectTwo( pOffSet, 0, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ) ); - Vec_IntPush( vUnatePairsW, Abc_TtCountOnesVecMask2(pDiv0, pDiv1, Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), pOnSet, nWords) ); + Vec_IntPush( vUnatePairsW, -Abc_TtCountOnesVecMask2(pDiv0, pDiv1, Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), pOnSet, nWords) ); } else { assert( !Abc_LitIsCompl(iLit0) ); assert( !Abc_LitIsCompl(iLit1) ); - assert( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, 0, nWords ) ); - Vec_IntPush( vUnatePairsW, Abc_TtCountOnesVecXorMask(pDiv0, pDiv1, fCompl, pOnSet, nWords) ); + assert( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, fComp, nWords ) ); + Vec_IntPush( vUnatePairsW, -Abc_TtCountOnesVecXorMask(pDiv0, pDiv1, fComp, pOnSet, nWords) ); } } } -void Gia_ManComputePairWeights( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnatePairsW[2] ) +void Gia_ManComputePairWeights( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnatePairsW[2], int TopW[2], int fVerbose ) { - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); - int n; + int n, TopNum = 5; + TopW[0] = TopW[1] = 0; for ( n = 0; n < 2; n++ ) - { - Gia_ManComputePairWeightsInt( pOffSet, pOnSet, vDivs, nWords, vUnatePairs[n], vUnatePairsW[n] ); - ABC_SWAP( word *, pOffSet, pOnSet ); - } + Gia_ManComputePairWeightsInt( pSets[n], pSets[!n], vDivs, nWords, vUnatePairs[n], vUnatePairsW[n] ); for ( n = 0; n < 2; n++ ) - { - int i, * pPerm = Abc_MergeSortCost( Vec_IntArray(vUnatePairsW[n]), Vec_IntSize(vUnatePairsW[n]) ); - Abc_ReverseOrder( pPerm, Vec_IntSize(vUnatePairsW[n]) ); - printf( "Top 10 %d-unate:\n", n ); - for ( i = 0; i < 10 && i < Vec_IntSize(vUnatePairs[n]); i++ ) + if ( Vec_IntSize(vUnatePairsW[n]) ) { - printf( "%5d : ", i ); - printf( "Obj = %5d ", Vec_IntEntry(vUnatePairs[n], pPerm[i]) ); - printf( "Cost = %5d\n", Vec_IntEntry(vUnatePairsW[n], pPerm[i]) ); + int i, * pPerm = Abc_MergeSortCost( Vec_IntArray(vUnatePairsW[n]), Vec_IntSize(vUnatePairsW[n]) ); + TopW[n] = -Vec_IntEntry(vUnatePairsW[n], pPerm[0]); + if ( fVerbose ) + { + printf( "Top %d %d-unate pairs:\n", TopNum, n ); + for ( i = 0; i < TopNum && i < Vec_IntSize(vUnatePairs[n]); i++ ) + { + int Pair = Vec_IntEntry(vUnatePairs[n], pPerm[i]); + int Div0 = Abc_Lit2Var(Pair) & 0x7FFF; + int Div1 = Abc_Lit2Var(Pair) >> 15; + printf( "%5d : ", i ); + printf( "Compl = %5d ", Abc_LitIsCompl(Pair) ); + printf( "Type = %s ", Div0 < Div1 ? "and" : "xor" ); + printf( "Div0 = %5d ", Div0 ); + printf( "Div1 = %5d ", Div1 ); + printf( "Cost = %5d\n", -Vec_IntEntry(vUnatePairsW[n], pPerm[i]) ); + } + } + for ( i = 0; i < Vec_IntSize(vUnatePairs[n]); i++ ) + pPerm[i] = Vec_IntEntry(vUnatePairs[n], pPerm[i]); + for ( i = 0; i < Vec_IntSize(vUnatePairs[n]); i++ ) + vUnatePairs[n]->pArray[i] = pPerm[i]; + ABC_FREE( pPerm ); } - ABC_FREE( pPerm ); - } } @@ -827,28 +902,32 @@ void Gia_ManComputePairWeights( Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnat SeeAlso [] ***********************************************************************/ -int Gia_ManResubInt2( Vec_Ptr_t * vDivs, int nWords, int NodeLimit, int ChoiceType, Vec_Int_t * vGates ) +int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) { - return 0; -} -int Gia_ManResubInt( Gia_ResbMan_t * p ) -{ - int nDivs = Vec_PtrSize(p->vDivs); - int iResLit = Gia_ManFindOneUnate( p->vDivs, p->nWords, p->vUnateLits, p->vNotUnateVars ); - if ( iResLit >= 0 ) // buffer + int TopOneW[2], TopTwoW[2], Max, iResLit, nVars = Vec_PtrSize(p->vDivs); + if ( p->fVerbose ) { - printf( "Creating %s (%d).\n", Abc_LitIsCompl(iResLit) ? "inverter" : "buffer", Abc_Lit2Var(iResLit) ); - return iResLit; + printf( "\nCalling decomposition for ISF: " ); + printf( "OFF = %5d (%6.2f %%) ", Abc_TtCountOnesVec(p->pSets[0], p->nWords), 100.0*Abc_TtCountOnesVec(p->pSets[0], p->nWords)/(64*p->nWords) ); + printf( "ON = %5d (%6.2f %%)\n", Abc_TtCountOnesVec(p->pSets[1], p->nWords), 100.0*Abc_TtCountOnesVec(p->pSets[1], p->nWords)/(64*p->nWords) ); } - iResLit = Gia_ManFindTwoUnate( p->vDivs, p->nWords, p->vUnateLits ); + if ( Abc_TtIsConst0( p->pSets[1], p->nWords ) ) + return 0; + if ( Abc_TtIsConst0( p->pSets[0], p->nWords ) ) + return 1; + iResLit = Gia_ManFindOneUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vNotUnateVars, p->fVerbose ); + if ( iResLit >= 0 ) // buffer + return iResLit; + iResLit = Gia_ManFindTwoUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->fVerbose ); if ( iResLit >= 0 ) // and { - int fCompl = Abc_LitIsCompl(iResLit); - int iDiv0 = Abc_Lit2Var(iResLit) >> 16; - int iDiv1 = Abc_Lit2Var(iResLit) & 0xFFFF; + int iNode = nVars + Vec_IntSize(p->vGates)/2; + int fComp = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; + int iDiv1 = Abc_Lit2Var(iResLit) >> 15; + assert( iDiv0 < iDiv1 ); Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); - printf( "Creating one AND-gate.\n" ); - return Abc_Var2Lit( nDivs + Vec_IntSize(p->vGates)/2-1, fCompl ); + return Abc_Var2Lit( iNode, fComp ); } Vec_IntTwoFindCommon( p->vNotUnateVars[0], p->vNotUnateVars[1], p->vBinateVars ); if ( Vec_IntSize(p->vBinateVars) > 1000 ) @@ -856,43 +935,181 @@ int Gia_ManResubInt( Gia_ResbMan_t * p ) printf( "Reducing binate divs from %d to 1000.\n", Vec_IntSize(p->vBinateVars) ); Vec_IntShrink( p->vBinateVars, 1000 ); } - iResLit = Gia_ManFindXor( p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs ); + iResLit = Gia_ManFindXor( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose ); if ( iResLit >= 0 ) // xor { - int fCompl = Abc_LitIsCompl(iResLit); - int iDiv0 = Abc_Lit2Var(iResLit) >> 16; - int iDiv1 = Abc_Lit2Var(iResLit) & 0xFFFF; + int iNode = nVars + Vec_IntSize(p->vGates)/2; + int fComp = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; + int iDiv1 = Abc_Lit2Var(iResLit) >> 15; assert( !Abc_LitIsCompl(iDiv0) ); assert( !Abc_LitIsCompl(iDiv1) ); - Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); // xor - printf( "Creating one XOR-gate.\n" ); - return Abc_Var2Lit( nDivs + Vec_IntSize(p->vGates)/2-1, fCompl ); - } - Gia_ManFindUnatePairs( p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs ); -/* - iResLit = Gia_ManFindAndGate( p->vDivs, p->nWords, p->vUnateLits, p->vUnatePairs, p->pDivA ); - if ( iResLit >= 0 ) // and-gate - { - int New = nDivs + Vec_IntSize(p->vGates)/2; - int fCompl = Abc_LitIsCompl(iResLit); - int iDiv0 = Abc_Lit2Var(iResLit) >> 16; - int iDiv1 = Abc_Lit2Var(iResLit) & 0xFFFF; - Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv1), Abc_LitNot(iDiv0) ); - Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv0), New ); - printf( "Creating one two gates.\n" ); - return Abc_Var2Lit( nDivs + Vec_IntSize(p->vGates)/2-1, 1 ); - } - iResLit = Gia_ManFindGateGate( p->vDivs, p->nWords, p->vUnatePairs, p->pDivA, p->pDivB ); - if ( iResLit >= 0 ) // and-(gate,gate) - { - printf( "Creating one three gates.\n" ); + assert( iDiv0 > iDiv1 ); + Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); + return Abc_Var2Lit( iNode, fComp ); + } + Gia_ManFindUnatePairs( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose ); + iResLit = Gia_ManFindDivGate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnatePairs, p->pDivA ); + if ( iResLit >= 0 ) // and(div,pair) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + + int fComp = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; // div + int iDiv1 = Abc_Lit2Var(iResLit) >> 15; // pair + + int Div1 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv1) ); + int fComp1 = Abc_LitIsCompl(Div1) ^ Abc_LitIsCompl(iDiv1); + int iDiv10 = Abc_Lit2Var(Div1) & 0x7FFF; + int iDiv11 = Abc_Lit2Var(Div1) >> 15; + + Vec_IntPushTwo( p->vGates, iDiv10, iDiv11 ); + Vec_IntPushTwo( p->vGates, iDiv0, Abc_Var2Lit(iNode, fComp1) ); + return Abc_Var2Lit( iNode+1, fComp ); + } + iResLit = Gia_ManFindGateGate( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->pDivA, p->pDivB ); + if ( iResLit >= 0 ) // and(pair,pair) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + + int fComp = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; // pair + int iDiv1 = Abc_Lit2Var(iResLit) >> 15; // pair + + int Div0 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv0) ); + int fComp0 = Abc_LitIsCompl(Div0) ^ Abc_LitIsCompl(iDiv0); + int iDiv00 = Abc_Lit2Var(Div0) & 0x7FFF; + int iDiv01 = Abc_Lit2Var(Div0) >> 15; + + int Div1 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv1) ); + int fComp1 = Abc_LitIsCompl(Div1) ^ Abc_LitIsCompl(iDiv1); + int iDiv10 = Abc_Lit2Var(Div1) & 0x7FFF; + int iDiv11 = Abc_Lit2Var(Div1) >> 15; + + Vec_IntPushTwo( p->vGates, iDiv00, iDiv01 ); + Vec_IntPushTwo( p->vGates, iDiv10, iDiv11 ); + Vec_IntPushTwo( p->vGates, Abc_Var2Lit(iNode, fComp0), Abc_Var2Lit(iNode+1, fComp1) ); + return Abc_Var2Lit( iNode+2, fComp ); + } + if ( Vec_IntSize(p->vUnateLits[0]) + Vec_IntSize(p->vUnateLits[1]) + Vec_IntSize(p->vUnatePairs[0]) + Vec_IntSize(p->vUnatePairs[1]) == 0 ) return -1; + Gia_ManComputeLitWeights( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, TopOneW, p->fVerbose ); + Gia_ManComputePairWeights( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, TopTwoW, p->fVerbose ); + //Max = Abc_MaxInt( Abc_MaxInt(TopOneW[0], TopOneW[1]), Abc_MaxInt(TopTwoW[0], TopTwoW[1]) ); + Max = Abc_MaxInt(TopOneW[0], TopOneW[1]); + if ( Max == 0 ) + return -1; + if ( Max == TopOneW[0] || Max == TopOneW[1] ) + { + int fUseOr = Max == TopOneW[0]; + int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 ); + int fComp = Abc_LitIsCompl(iDiv); + word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) ); + Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); + iResLit = Gia_ManResubPerformInt( p ); + if ( iResLit >= 0 ) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) ); + return Abc_Var2Lit( iNode, fUseOr ); + } + } + if ( Max == TopTwoW[0] || Max == TopTwoW[1] ) + { + int fUseOr = Max == TopTwoW[0]; + int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 ); + int fComp = Abc_LitIsCompl(iDiv); + Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA ); + Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); + iResLit = Gia_ManResubPerformInt( p ); + if ( iResLit >= 0 ) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF; + int iDiv1 = Abc_Lit2Var(iDiv) >> 15; + Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); + Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_Var2Lit(iNode, !fComp) ); + return Abc_Var2Lit( iNode+1, fUseOr ); + } } -*/ - Gia_ManComputeLitWeights( p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW ); - Gia_ManComputePairWeights( p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW ); return -1; } +void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vRes, int fVerbose ) +{ + int Res; + Vec_IntClear( vRes ); + Gia_ResbInit( p, vDivs, nWords, vRes, fVerbose ); + Res = Gia_ManResubPerformInt( p ); + if ( Res == -1 ) + { + printf( "\n" ); + return; + } + Vec_IntPush( vRes, Res ); + Gia_ManResubPrint( vRes, Vec_PtrSize(vDivs) ); + printf( " Verification %s.\n", Gia_ManResubVerify(p) ? "succeeded" : "FAILED *******************************" ); +} +void Gia_ManResubTest3() +{ + int nVars = 3; + Gia_ResbMan_t * p = Gia_ResbAlloc( 1 ); + word Divs[6] = { 0, 0, + ABC_CONST(0xAAAAAAAAAAAAAAAA), + ABC_CONST(0xCCCCCCCCCCCCCCCC), + ABC_CONST(0xF0F0F0F0F0F0F0F0), + ABC_CONST(0xFF00FF00FF00FF00) + }; + Vec_Ptr_t * vDivs = Vec_PtrAlloc( 6 ); + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + int i; + for ( i = 0; i < 6; i++ ) + Vec_PtrPush( vDivs, Divs+i ); + for ( i = 0; i < (1<<(1< 4000 ) - { - printf( "Reducing all divs from %d to 4000.\n", Vec_PtrSize(vDivs) ); - Vec_PtrShrink( vDivs, 4000 ); - } - Gia_ResbReset( p ); + Gia_ResbMan_t * p = Gia_ResbAlloc( nWords ); // Gia_ManCheckResub( vDivs, nWords ); - iTopLit = Gia_ManResubInt( p ); - if ( iTopLit >= 0 ) + if ( Vec_PtrSize(vDivs) >= (1<<14) ) { - printf( "Verification %s.\n", Gia_ManResubVerify( vDivs, nWords, vGates, iTopLit ) ? "succeeded" : "FAILED" ); - pMan = Gia_ManConstructFromGates( Vec_PtrSize(vDivs), vGates, iTopLit ); + printf( "Reducing all divs from %d to %d.\n", Vec_PtrSize(vDivs), (1<<14)-1 ); + Vec_PtrShrink( vDivs, (1<<14)-1 ); } + assert( Vec_PtrSize(vDivs) < (1<<14) ); + Gia_ManResubPerform( p, vDivs, nWords, vGates, 1 ); + if ( Vec_IntSize(vGates) ) + pMan = Gia_ManConstructFromGates( vGates, Vec_PtrSize(vDivs) ); else printf( "Decomposition did not succeed.\n" ); Gia_ResbFree( p ); -- cgit v1.2.3 From a918e2dab1f951eb7e869f07b57f648b9a583561 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 7 May 2020 21:44:35 -0700 Subject: Experimental resubstitution. --- src/aig/gia/giaResub.c | 122 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 35 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 7b57db15..7a2790e2 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -615,8 +615,6 @@ int Gia_ManFindOneUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int int n; for ( n = 0; n < 2; n++ ) { - Vec_IntClear( vUnateLits[n] ); - Vec_IntClear( vNotUnateVars[n] ); Gia_ManFindOneUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vNotUnateVars[n] ); if ( fVerbose ) printf( "Found %d %d-unate divs.\n", Vec_IntSize(vUnateLits[n]), n ); } @@ -904,7 +902,7 @@ void Gia_ManComputePairWeights( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, ***********************************************************************/ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) { - int TopOneW[2], TopTwoW[2], Max, iResLit, nVars = Vec_PtrSize(p->vDivs); + int TopOneW[2] = {0}, TopTwoW[2] = {0}, Max1, Max2, iResLit, nVars = Vec_PtrSize(p->vDivs); if ( p->fVerbose ) { printf( "\nCalling decomposition for ISF: " ); @@ -995,41 +993,84 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) return -1; Gia_ManComputeLitWeights( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, TopOneW, p->fVerbose ); Gia_ManComputePairWeights( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, TopTwoW, p->fVerbose ); - //Max = Abc_MaxInt( Abc_MaxInt(TopOneW[0], TopOneW[1]), Abc_MaxInt(TopTwoW[0], TopTwoW[1]) ); - Max = Abc_MaxInt(TopOneW[0], TopOneW[1]); - if ( Max == 0 ) + Max1 = Abc_MaxInt(TopOneW[0], TopOneW[1]); + Max2 = Abc_MaxInt(TopTwoW[0], TopTwoW[1]); + if ( Abc_MaxInt(Max1, Max2) == 0 ) return -1; - if ( Max == TopOneW[0] || Max == TopOneW[1] ) + if ( Max1 > Max2/2 ) { - int fUseOr = Max == TopOneW[0]; - int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 ); - int fComp = Abc_LitIsCompl(iDiv); - word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) ); - Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); - iResLit = Gia_ManResubPerformInt( p ); - if ( iResLit >= 0 ) + if ( Max1 == TopOneW[0] || Max1 == TopOneW[1] ) { - int iNode = nVars + Vec_IntSize(p->vGates)/2; - Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) ); - return Abc_Var2Lit( iNode, fUseOr ); + int fUseOr = Max1 == TopOneW[0]; + int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 ); + int fComp = Abc_LitIsCompl(iDiv); + word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) ); + Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); + iResLit = Gia_ManResubPerformInt( p ); + if ( iResLit >= 0 ) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) ); + return Abc_Var2Lit( iNode, fUseOr ); + } + } + if ( Max2 == 0 ) + return -1; + if ( Max2 == TopTwoW[0] || Max2 == TopTwoW[1] ) + { + int fUseOr = Max2 == TopTwoW[0]; + int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 ); + int fComp = Abc_LitIsCompl(iDiv); + Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA ); + Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); + iResLit = Gia_ManResubPerformInt( p ); + if ( iResLit >= 0 ) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF; + int iDiv1 = Abc_Lit2Var(iDiv) >> 15; + Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); + Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_Var2Lit(iNode, !fComp) ); + return Abc_Var2Lit( iNode+1, fUseOr ); + } } } - if ( Max == TopTwoW[0] || Max == TopTwoW[1] ) + else { - int fUseOr = Max == TopTwoW[0]; - int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 ); - int fComp = Abc_LitIsCompl(iDiv); - Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA ); - Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); - iResLit = Gia_ManResubPerformInt( p ); - if ( iResLit >= 0 ) + if ( Max2 == TopTwoW[0] || Max2 == TopTwoW[1] ) { - int iNode = nVars + Vec_IntSize(p->vGates)/2; - int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF; - int iDiv1 = Abc_Lit2Var(iDiv) >> 15; - Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); - Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_Var2Lit(iNode, !fComp) ); - return Abc_Var2Lit( iNode+1, fUseOr ); + int fUseOr = Max2 == TopTwoW[0]; + int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 ); + int fComp = Abc_LitIsCompl(iDiv); + Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA ); + Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); + iResLit = Gia_ManResubPerformInt( p ); + if ( iResLit >= 0 ) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + int iDiv0 = Abc_Lit2Var(iDiv) & 0x7FFF; + int iDiv1 = Abc_Lit2Var(iDiv) >> 15; + Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); + Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_Var2Lit(iNode, !fComp) ); + return Abc_Var2Lit( iNode+1, fUseOr ); + } + } + if ( Max1 == 0 ) + return -1; + if ( Max1 == TopOneW[0] || Max1 == TopOneW[1] ) + { + int fUseOr = Max1 == TopOneW[0]; + int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 ); + int fComp = Abc_LitIsCompl(iDiv); + word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) ); + Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); + iResLit = Gia_ManResubPerformInt( p ); + if ( iResLit >= 0 ) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) ); + return Abc_Var2Lit( iNode, fUseOr ); + } } } return -1; @@ -1047,8 +1088,16 @@ void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, Vec_ } Vec_IntPush( vRes, Res ); Gia_ManResubPrint( vRes, Vec_PtrSize(vDivs) ); - printf( " Verification %s.\n", Gia_ManResubVerify(p) ? "succeeded" : "FAILED *******************************" ); + if ( !Gia_ManResubVerify(p) ) + printf( " Verification FAILED." ); +// else +// printf( " Verification succeeded." ); + printf( "\n" ); } + +extern void Extra_PrintHex( FILE * pFile, unsigned * pTruth, int nVars ); +extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit ); + void Gia_ManResubTest3() { int nVars = 3; @@ -1072,9 +1121,12 @@ void Gia_ManResubTest3() printf( "%3d : ", i ); Extra_PrintHex( stdout, (unsigned*)&Truth, nVars ); printf( " " ); - Dau_DsdPrintFromTruth2( (unsigned*)&Truth, nVars ); - printf( " " ); + Dau_DsdPrintFromTruth2( &Truth, nVars ); + printf( " " ); Gia_ManResubPerform( p, vDivs, 1, vRes, 0 ); + + if ( i == 1000 ) + break; } Gia_ResbFree( p ); Vec_IntFree( vRes ); @@ -1102,7 +1154,7 @@ void Gia_ManResubTest3_() Divs[1] = Truth; Extra_PrintHex( stdout, (unsigned*)&Truth, 6 ); printf( " " ); - Dau_DsdPrintFromTruth2( (unsigned*)&Truth, 6 ); + Dau_DsdPrintFromTruth2( &Truth, 6 ); printf( " " ); Gia_ManResubPerform( p, vDivs, 1, vRes, 0 ); } -- cgit v1.2.3 From a7871d24cdcd08c782a3165203ce3e4e76042344 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 8 May 2020 13:50:29 -0700 Subject: Experimental resubstitution. --- src/aig/gia/giaResub.c | 156 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 119 insertions(+), 37 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 7a2790e2..4731bcb5 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -289,6 +289,8 @@ typedef struct Gia_ResbMan_t_ Gia_ResbMan_t; struct Gia_ResbMan_t_ { int nWords; + int nLimit; + int fDebug; int fVerbose; Vec_Ptr_t * vDivs; Vec_Int_t * vGates; @@ -318,6 +320,8 @@ Gia_ResbMan_t * Gia_ResbAlloc( int nWords ) p->vUnatePairsW[0] = Vec_IntAlloc( 100 ); p->vUnatePairsW[1] = Vec_IntAlloc( 100 ); p->vBinateVars = Vec_IntAlloc( 100 ); + p->vGates = Vec_IntAlloc( 100 ); + p->vDivs = Vec_PtrAlloc( 100 ); p->pSets[0] = ABC_CALLOC( word, nWords ); p->pSets[1] = ABC_CALLOC( word, nWords ); p->pDivA = ABC_CALLOC( word, nWords ); @@ -325,14 +329,16 @@ Gia_ResbMan_t * Gia_ResbAlloc( int nWords ) p->vSims = Vec_WrdAlloc( 100 ); return p; } -void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vGates, int fVerbose ) +void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int fDebug, int fVerbose ) { assert( p->nWords == nWords ); + p->nLimit = nLimit; + p->fDebug = fDebug; p->fVerbose = fVerbose; Abc_TtCopy( p->pSets[0], (word *)Vec_PtrEntry(vDivs, 0), nWords, 0 ); Abc_TtCopy( p->pSets[1], (word *)Vec_PtrEntry(vDivs, 1), nWords, 0 ); - p->vDivs = vDivs; - p->vGates = vGates; + Vec_PtrClear( p->vDivs ); + Vec_PtrAppend( p->vDivs, vDivs ); Vec_IntClear( p->vGates ); Vec_IntClear( p->vUnateLits[0] ); Vec_IntClear( p->vUnateLits[1] ); @@ -359,7 +365,9 @@ void Gia_ResbFree( Gia_ResbMan_t * p ) Vec_IntFree( p->vUnatePairsW[0] ); Vec_IntFree( p->vUnatePairsW[1] ); Vec_IntFree( p->vBinateVars ); + Vec_IntFree( p->vGates ); Vec_WrdFree( p->vSims ); + Vec_PtrFree( p->vDivs ); ABC_FREE( p->pSets[0] ); ABC_FREE( p->pSets[1] ); ABC_FREE( p->pDivA ); @@ -623,8 +631,8 @@ int Gia_ManFindOneUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int static inline int Gia_ManDivCover( word * pOffSet, word * pOnSet, word * pDivA, int ComplA, word * pDivB, int ComplB, int nWords ) { - assert( !Abc_TtIntersectOne(pOffSet, 0, pDivA, ComplA, nWords) ); - assert( !Abc_TtIntersectOne(pOffSet, 0, pDivB, ComplB, nWords) ); + //assert( !Abc_TtIntersectOne(pOffSet, 0, pDivA, ComplA, nWords) ); + //assert( !Abc_TtIntersectOne(pOffSet, 0, pDivB, ComplB, nWords) ); return !Abc_TtIntersectTwo( pOnSet, 0, pDivA, !ComplA, pDivB, !ComplB, nWords ); } int Gia_ManFindTwoUnateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits ) @@ -794,7 +802,7 @@ void Gia_ManComputeLitWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDi Vec_IntForEachEntry( vUnateLits, iLit, i ) { word * pDiv = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit) ); - assert( !Abc_TtIntersectOne( pOffSet, 0, pDiv, Abc_LitIsCompl(iLit), nWords ) ); + //assert( !Abc_TtIntersectOne( pOffSet, 0, pDiv, Abc_LitIsCompl(iLit), nWords ) ); Vec_IntPush( vUnateLitsW, -Abc_TtCountOnesVecMask(pDiv, pOnSet, nWords, Abc_LitIsCompl(iLit)) ); } } @@ -841,14 +849,14 @@ void Gia_ManComputePairWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vD if ( iLit0 < iLit1 ) { assert( !fComp ); - assert( !Abc_TtIntersectTwo( pOffSet, 0, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ) ); + //assert( !Abc_TtIntersectTwo( pOffSet, 0, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ) ); Vec_IntPush( vUnatePairsW, -Abc_TtCountOnesVecMask2(pDiv0, pDiv1, Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), pOnSet, nWords) ); } else { assert( !Abc_LitIsCompl(iLit0) ); assert( !Abc_LitIsCompl(iLit1) ); - assert( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, fComp, nWords ) ); + //assert( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, fComp, nWords ) ); Vec_IntPush( vUnatePairsW, -Abc_TtCountOnesVecXorMask(pDiv0, pDiv1, fComp, pOnSet, nWords) ); } } @@ -900,7 +908,7 @@ void Gia_ManComputePairWeights( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, SeeAlso [] ***********************************************************************/ -int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) +int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) { int TopOneW[2] = {0}, TopTwoW[2] = {0}, Max1, Max2, iResLit, nVars = Vec_PtrSize(p->vDivs); if ( p->fVerbose ) @@ -916,6 +924,8 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) iResLit = Gia_ManFindOneUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vNotUnateVars, p->fVerbose ); if ( iResLit >= 0 ) // buffer return iResLit; + if ( nLimit == 0 ) + return -1; iResLit = Gia_ManFindTwoUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->fVerbose ); if ( iResLit >= 0 ) // and { @@ -946,6 +956,8 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); return Abc_Var2Lit( iNode, fComp ); } + if ( nLimit == 1 ) + return -1; Gia_ManFindUnatePairs( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose ); iResLit = Gia_ManFindDivGate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnatePairs, p->pDivA ); if ( iResLit >= 0 ) // and(div,pair) @@ -965,6 +977,8 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) Vec_IntPushTwo( p->vGates, iDiv0, Abc_Var2Lit(iNode, fComp1) ); return Abc_Var2Lit( iNode+1, fComp ); } + if ( nLimit == 2 ) + return -1; iResLit = Gia_ManFindGateGate( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->pDivA, p->pDivB ); if ( iResLit >= 0 ) // and(pair,pair) { @@ -989,6 +1003,8 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) Vec_IntPushTwo( p->vGates, Abc_Var2Lit(iNode, fComp0), Abc_Var2Lit(iNode+1, fComp1) ); return Abc_Var2Lit( iNode+2, fComp ); } + if ( nLimit == 3 ) + return -1; if ( Vec_IntSize(p->vUnateLits[0]) + Vec_IntSize(p->vUnateLits[1]) + Vec_IntSize(p->vUnatePairs[0]) + Vec_IntSize(p->vUnatePairs[1]) == 0 ) return -1; Gia_ManComputeLitWeights( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, TopOneW, p->fVerbose ); @@ -1006,7 +1022,7 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) int fComp = Abc_LitIsCompl(iDiv); word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) ); Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); - iResLit = Gia_ManResubPerformInt( p ); + iResLit = Gia_ManResubPerform_rec( p, nLimit-1 ); if ( iResLit >= 0 ) { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1023,7 +1039,7 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) int fComp = Abc_LitIsCompl(iDiv); Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA ); Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); - iResLit = Gia_ManResubPerformInt( p ); + iResLit = Gia_ManResubPerform_rec( p, nLimit-2 ); if ( iResLit >= 0 ) { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1044,7 +1060,7 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) int fComp = Abc_LitIsCompl(iDiv); Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA ); Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); - iResLit = Gia_ManResubPerformInt( p ); + iResLit = Gia_ManResubPerform_rec( p, nLimit-2 ); if ( iResLit >= 0 ) { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1064,7 +1080,7 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) int fComp = Abc_LitIsCompl(iDiv); word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) ); Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); - iResLit = Gia_ManResubPerformInt( p ); + iResLit = Gia_ManResubPerform_rec( p, nLimit-1 ); if ( iResLit >= 0 ) { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1075,33 +1091,92 @@ int Gia_ManResubPerformInt( Gia_ResbMan_t * p ) } return -1; } -void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vRes, int fVerbose ) +void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int fDebug, int fVerbose ) { int Res; - Vec_IntClear( vRes ); - Gia_ResbInit( p, vDivs, nWords, vRes, fVerbose ); - Res = Gia_ManResubPerformInt( p ); - if ( Res == -1 ) + Gia_ResbInit( p, vDivs, nWords, nLimit, fDebug, fVerbose ); + Res = Gia_ManResubPerform_rec( p, nLimit ); + if ( Res >= 0 ) + Vec_IntPush( p->vGates, Res ); +} + +/**Function************************************************************* + + Synopsis [Top level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static Gia_ResbMan_t * s_pResbMan = NULL; + +void Abc_ResubPrepareManager( int nWords ) +{ + if ( s_pResbMan != NULL ) + Gia_ResbFree( s_pResbMan ); + if ( nWords > 0 ) + s_pResbMan = Gia_ResbAlloc( nWords ); +} + +int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int fDebug, int fVerbose, int ** ppArray ) +{ + Vec_Ptr_t Divs = { nDivs, nDivs, ppDivs }; + assert( s_pResbMan != NULL ); // first call Abc_ResubPrepareManager() + Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, fDebug, 0 ); + if ( fVerbose ) { + Gia_ManResubPrint( s_pResbMan->vGates, nDivs ); printf( "\n" ); - return; } - Vec_IntPush( vRes, Res ); - Gia_ManResubPrint( vRes, Vec_PtrSize(vDivs) ); - if ( !Gia_ManResubVerify(p) ) - printf( " Verification FAILED." ); -// else -// printf( " Verification succeeded." ); - printf( "\n" ); + if ( fDebug ) + { + if ( !Gia_ManResubVerify(s_pResbMan) ) + { + Gia_ManResubPrint( s_pResbMan->vGates, nDivs ); + printf( "Verification FAILED.\n" ); + } + //else + // printf( "Verification succeeded.\n" ); + } + *ppArray = Vec_IntArray(s_pResbMan->vGates); + assert( Vec_IntSize(s_pResbMan->vGates)/2 <= nLimit ); + return Vec_IntSize(s_pResbMan->vGates); +} + +void Abc_ResubDumpProblem( char * pFileName, void ** ppDivs, int nDivs, int nWords ) +{ + Vec_Wrd_t * vSims = Vec_WrdAlloc( nDivs * nWords ); + word ** pDivs = (word **)ppDivs; + int d, w; + for ( d = 0; d < nDivs; d++ ) + for ( w = 0; w < nWords; w++ ) + Vec_WrdPush( vSims, pDivs[d][w] ); + Gia_ManSimPatWrite( pFileName, vSims, nWords ); + Vec_WrdFree( vSims ); } +/**Function************************************************************* + + Synopsis [Top level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + extern void Extra_PrintHex( FILE * pFile, unsigned * pTruth, int nVars ); extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit ); void Gia_ManResubTest3() { int nVars = 3; - Gia_ResbMan_t * p = Gia_ResbAlloc( 1 ); + int fVerbose = 1; word Divs[6] = { 0, 0, ABC_CONST(0xAAAAAAAAAAAAAAAA), ABC_CONST(0xCCCCCCCCCCCCCCCC), @@ -1110,9 +1185,10 @@ void Gia_ManResubTest3() }; Vec_Ptr_t * vDivs = Vec_PtrAlloc( 6 ); Vec_Int_t * vRes = Vec_IntAlloc( 100 ); - int i; + int i, k, ArraySize, * pArray; for ( i = 0; i < 6; i++ ) Vec_PtrPush( vDivs, Divs+i ); + Abc_ResubPrepareManager( 1 ); for ( i = 0; i < (1<<(1<= (1<<14) ) @@ -1224,13 +1307,12 @@ Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, i Vec_PtrShrink( vDivs, (1<<14)-1 ); } assert( Vec_PtrSize(vDivs) < (1<<14) ); - Gia_ManResubPerform( p, vDivs, nWords, vGates, 1 ); - if ( Vec_IntSize(vGates) ) - pMan = Gia_ManConstructFromGates( vGates, Vec_PtrSize(vDivs) ); + Gia_ManResubPerform( p, vDivs, nWords, 100, 1, 1 ); + if ( Vec_IntSize(p->vGates) ) + pMan = Gia_ManConstructFromGates( p->vGates, Vec_PtrSize(vDivs) ); else printf( "Decomposition did not succeed.\n" ); Gia_ResbFree( p ); - Vec_IntFree( vGates ); Vec_PtrFree( vDivs ); Vec_WrdFree( vSims ); return pMan; -- cgit v1.2.3 From 9bfccf76c192bed7006d648cffa0959d913f2803 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 11 May 2020 17:40:40 -0700 Subject: Experimental resubstitution. --- src/aig/gia/giaResub.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 4731bcb5..55807a2a 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -1032,6 +1032,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) } if ( Max2 == 0 ) return -1; +/* if ( Max2 == TopTwoW[0] || Max2 == TopTwoW[1] ) { int fUseOr = Max2 == TopTwoW[0]; @@ -1050,6 +1051,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) return Abc_Var2Lit( iNode+1, fUseOr ); } } +*/ } else { @@ -1073,6 +1075,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) } if ( Max1 == 0 ) return -1; +/* if ( Max1 == TopOneW[0] || Max1 == TopOneW[1] ) { int fUseOr = Max1 == TopOneW[0]; @@ -1088,6 +1091,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) return Abc_Var2Lit( iNode, fUseOr ); } } +*/ } return -1; } @@ -1117,6 +1121,7 @@ void Abc_ResubPrepareManager( int nWords ) { if ( s_pResbMan != NULL ) Gia_ResbFree( s_pResbMan ); + s_pResbMan = NULL; if ( nWords > 0 ) s_pResbMan = Gia_ResbAlloc( nWords ); } @@ -1260,7 +1265,8 @@ void Gia_ManResubTest3_() ***********************************************************************/ void Gia_ManCheckResub( Vec_Ptr_t * vDivs, int nWords ) { - int i, Set[10] = { 2, 189, 2127, 2125, 177, 178 }; + //int i, nVars = 6, pVarSet[10] = { 2, 189, 2127, 2125, 177, 178 }; + int i, nVars = 3, pVarSet[10] = { 2, 3, 4 }; word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); Vec_Int_t * vValue = Vec_IntStartFull( 1 << 6 ); @@ -1270,8 +1276,8 @@ void Gia_ManCheckResub( Vec_Ptr_t * vDivs, int nWords ) int v, Mint = 0, Value = Abc_TtGetBit(pOnSet, i); if ( !Abc_TtGetBit(pOffSet, i) && !Value ) continue; - for ( v = 0; v < 6; v++ ) - if ( Abc_TtGetBit((word *)Vec_PtrEntry(vDivs, Set[v]), i) ) + for ( v = 0; v < nVars; v++ ) + if ( Abc_TtGetBit((word *)Vec_PtrEntry(vDivs, pVarSet[v]), i) ) Mint |= 1 << v; if ( Vec_IntEntry(vValue, Mint) == -1 ) Vec_IntWriteEntry(vValue, Mint, Value); @@ -1300,7 +1306,7 @@ Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, i Vec_Wrd_t * vSims = Gia_ManSimPatRead( pFileName, &nWords ); Vec_Ptr_t * vDivs = vSims ? Gia_ManDeriveDivs( vSims, nWords ) : NULL; Gia_ResbMan_t * p = Gia_ResbAlloc( nWords ); -// Gia_ManCheckResub( vDivs, nWords ); + //Gia_ManCheckResub( vDivs, nWords ); if ( Vec_PtrSize(vDivs) >= (1<<14) ) { printf( "Reducing all divs from %d to %d.\n", Vec_PtrSize(vDivs), (1<<14)-1 ); -- cgit v1.2.3 From a8bd59bd685cafc2926c314727dedee874632254 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 13 May 2020 10:40:09 -0700 Subject: Experimental resubstitution. --- src/aig/gia/giaResub.c | 288 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 221 insertions(+), 67 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 55807a2a..66f27310 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -290,6 +290,8 @@ struct Gia_ResbMan_t_ { int nWords; int nLimit; + int nChoice; + int fUseXor; int fDebug; int fVerbose; Vec_Ptr_t * vDivs; @@ -329,10 +331,12 @@ Gia_ResbMan_t * Gia_ResbAlloc( int nWords ) p->vSims = Vec_WrdAlloc( 100 ); return p; } -void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int fDebug, int fVerbose ) +void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nChoice, int fUseXor, int fDebug, int fVerbose ) { assert( p->nWords == nWords ); p->nLimit = nLimit; + p->nChoice = nChoice; + p->fUseXor = fUseXor; p->fDebug = fDebug; p->fVerbose = fVerbose; Abc_TtCopy( p->pSets[0], (word *)Vec_PtrEntry(vDivs, 0), nWords, 0 ); @@ -441,7 +445,7 @@ int Gia_ManResubPrint( Vec_Int_t * vRes, int nVars ) SeeAlso [] ***********************************************************************/ -int Gia_ManResubVerify( Gia_ResbMan_t * p ) +int Gia_ManResubVerify( Gia_ResbMan_t * p, word * pFunc ) { int nVars = Vec_PtrSize(p->vDivs); int iTopLit, RetValue; @@ -451,9 +455,15 @@ int Gia_ManResubVerify( Gia_ResbMan_t * p ) iTopLit = Vec_IntEntryLast(p->vGates); assert( iTopLit >= 0 ); if ( iTopLit == 0 ) + { + if ( pFunc ) Abc_TtClear( pFunc, p->nWords ); return Abc_TtIsConst0( p->pSets[1], p->nWords ); + } if ( iTopLit == 1 ) + { + if ( pFunc ) Abc_TtFill( pFunc, p->nWords ); return Abc_TtIsConst0( p->pSets[0], p->nWords ); + } if ( Abc_Lit2Var(iTopLit) < nVars ) { assert( Vec_IntSize(p->vGates) == 1 ); @@ -489,6 +499,7 @@ int Gia_ManResubVerify( Gia_ResbMan_t * p ) RetValue = !Abc_TtIntersectOne(p->pSets[1], 0, pDivRes, 0, p->nWords) && !Abc_TtIntersectOne(p->pSets[0], 0, pDivRes, 1, p->nWords); else RetValue = !Abc_TtIntersectOne(p->pSets[0], 0, pDivRes, 0, p->nWords) && !Abc_TtIntersectOne(p->pSets[1], 0, pDivRes, 1, p->nWords); + if ( pFunc ) Abc_TtCopy( pFunc, pDivRes, p->nWords, Abc_LitIsCompl(iTopLit) ); return RetValue; } @@ -503,63 +514,178 @@ int Gia_ManResubVerify( Gia_ResbMan_t * p ) SeeAlso [] ***********************************************************************/ -int Gia_ManGetVar( Gia_Man_t * pNew, Vec_Int_t * vUsed, int iVar ) +int Gia_ManConstructFromMap( Gia_Man_t * pNew, Vec_Int_t * vGates, int nVars, Vec_Int_t * vUsed, Vec_Int_t * vCopy, int fHash ) { - if ( Vec_IntEntry(vUsed, iVar) == -1 ) - Vec_IntWriteEntry( vUsed, iVar, Gia_ManAppendCi(pNew) ); - return Vec_IntEntry(vUsed, iVar); + int i, iLit0, iLit1, iLitRes, iTopLit = Vec_IntEntryLast( vGates ); + assert( Vec_IntSize(vUsed) == nVars ); + assert( Vec_IntSize(vGates) > 1 ); + assert( Vec_IntSize(vGates) % 2 == 1 ); + assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(vGates)/2-1 ); + Vec_IntClear( vCopy ); + Vec_IntForEachEntryDouble( vGates, iLit0, iLit1, i ) + { + int iVar0 = Abc_Lit2Var(iLit0); + int iVar1 = Abc_Lit2Var(iLit1); + int iRes0 = iVar0 < nVars ? Vec_IntEntry(vUsed, iVar0) : Vec_IntEntry(vCopy, iVar0 - nVars); + int iRes1 = iVar1 < nVars ? Vec_IntEntry(vUsed, iVar1) : Vec_IntEntry(vCopy, iVar1 - nVars); + if ( iVar0 < iVar1 ) + { + if ( fHash ) + iLitRes = Gia_ManHashAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); + else + iLitRes = Gia_ManAppendAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); + } + else if ( iVar0 > iVar1 ) + { + assert( !Abc_LitIsCompl(iLit0) ); + assert( !Abc_LitIsCompl(iLit1) ); + if ( fHash ) + iLitRes = Gia_ManHashXor( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); + else + iLitRes = Gia_ManAppendXor( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); + } + else assert( 0 ); + Vec_IntPush( vCopy, iLitRes ); + } + assert( Vec_IntSize(vCopy) == Vec_IntSize(vGates)/2 ); + iLitRes = Vec_IntEntry( vCopy, Vec_IntSize(vGates)/2-1 ); + return iLitRes; } -Gia_Man_t * Gia_ManConstructFromGates( Vec_Int_t * vGates, int nVars ) +Gia_Man_t * Gia_ManConstructFromGates( Vec_Wec_t * vFuncs, int nVars ) { - int i, iLit0, iLit1, iTopLit, iLitRes; - Gia_Man_t * pNew; - if ( Vec_IntSize(vGates) == 0 ) - return NULL; - assert( Vec_IntSize(vGates) % 2 == 1 ); - pNew = Gia_ManStart( 100 ); + Vec_Int_t * vGates; int i, k, iLit; + Vec_Int_t * vCopy = Vec_IntAlloc( 100 ); + Vec_Int_t * vUsed = Vec_IntStartFull( nVars ); + Gia_Man_t * pNew = Gia_ManStart( 100 ); pNew->pName = Abc_UtilStrsav( "resub" ); - iTopLit = Vec_IntEntryLast( vGates ); - if ( iTopLit == 0 || iTopLit == 1 ) - iLitRes = 0; - else if ( Abc_Lit2Var(iTopLit) < nVars ) + Vec_WecForEachLevel( vFuncs, vGates, i ) { - assert( Vec_IntSize(vGates) == 1 ); - iLitRes = Gia_ManAppendCi(pNew); + assert( Vec_IntSize(vGates) % 2 == 1 ); + Vec_IntForEachEntry( vGates, iLit, k ) + { + int iVar = Abc_Lit2Var(iLit); + if ( iVar > 0 && iVar < nVars && Vec_IntEntry(vUsed, iVar) == -1 ) + Vec_IntWriteEntry( vUsed, iVar, Gia_ManAppendCi(pNew) ); + } } - else + Vec_WecForEachLevel( vFuncs, vGates, i ) { - Vec_Int_t * vUsed = Vec_IntStartFull( nVars ); - Vec_Int_t * vCopy = Vec_IntAlloc( Vec_IntSize(vGates)/2 ); - assert( Vec_IntSize(vGates) > 1 ); - assert( Vec_IntSize(vGates) % 2 == 1 ); - assert( Abc_Lit2Var(iTopLit)-nVars == Vec_IntSize(vGates)/2-1 ); - Vec_IntForEachEntryDouble( vGates, iLit0, iLit1, i ) + int iLitRes, iTopLit = Vec_IntEntryLast( vGates ); + if ( Abc_Lit2Var(iTopLit) == 0 ) + iLitRes = 0; + else if ( Abc_Lit2Var(iTopLit) < nVars ) + iLitRes = Gia_ManAppendCi(pNew); + else + iLitRes = Gia_ManConstructFromMap( pNew, vGates, nVars, vUsed, vCopy, 0 ); + Gia_ManAppendCo( pNew, Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ) ); + } + Vec_IntFree( vCopy ); + Vec_IntFree( vUsed ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Construct AIG manager from gates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManInsertOrder_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs, Vec_Int_t * vNodes ) +{ + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( iObj == 0 ) + return; + if ( pObj->fPhase ) + { + int nVars = Gia_ManObjNum(p); + int k, iLit, Index = Vec_IntFind( vObjs, iObj ); + Vec_Int_t * vGates = Vec_WecEntry( vFuncs, Index ); + assert( Gia_ObjIsCo(pObj) || Gia_ObjIsAnd(pObj) ); + Vec_IntForEachEntry( vGates, iLit, k ) + if ( Abc_Lit2Var(iLit) < nVars ) + Gia_ManInsertOrder_rec( p, Abc_Lit2Var(iLit), vObjs, vFuncs, vNodes ); + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ManInsertOrder_rec( p, Gia_ObjFaninId0p(p, pObj), vObjs, vFuncs, vNodes ); + else if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManInsertOrder_rec( p, Gia_ObjFaninId0p(p, pObj), vObjs, vFuncs, vNodes ); + Gia_ManInsertOrder_rec( p, Gia_ObjFaninId1p(p, pObj), vObjs, vFuncs, vNodes ); + } + else assert( Gia_ObjIsCi(pObj) ); + if ( !Gia_ObjIsCi(pObj) ) + Vec_IntPush( vNodes, iObj ); +} +Vec_Int_t * Gia_ManInsertOrder( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs ) +{ + int i, Id; + Vec_Int_t * vNodes = Vec_IntAlloc( Gia_ManObjNum(p) ); + Gia_ManForEachCoId( p, Id, i ) + Gia_ManInsertOrder_rec( p, Id, vObjs, vFuncs, vNodes ); + return vNodes; +} +Gia_Man_t * Gia_ManInsertFromGates( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Wec_t * vFuncs ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i, nVars = Gia_ManObjNum(p); + Vec_Int_t * vUsed = Vec_IntStartFull( nVars ); + Vec_Int_t * vNodes, * vCopy = Vec_IntAlloc(100); + Gia_ManForEachObjVec( vObjs, p, pObj, i ) + pObj->fPhase = 1; + vNodes = Gia_ManInsertOrder( p, vObjs, vFuncs ); + pNew = Gia_ManStart( Gia_ManObjNum(p) + 1000 ); + Gia_ManHashStart( pNew ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + if ( !pObj->fPhase ) { - int iVar0 = Abc_Lit2Var(iLit0); - int iVar1 = Abc_Lit2Var(iLit1); - int iRes0 = iVar0 < nVars ? Gia_ManGetVar(pNew, vUsed, iVar0) : Vec_IntEntry(vCopy, iVar0 - nVars); - int iRes1 = iVar1 < nVars ? Gia_ManGetVar(pNew, vUsed, iVar1) : Vec_IntEntry(vCopy, iVar1 - nVars); - if ( iVar0 < iVar1 ) - iLitRes = Gia_ManAppendAnd( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); - else if ( iVar0 > iVar1 ) + if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + else if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else assert( 0 ); + } + else + { + int k, iLit, Index = Vec_IntFind( vObjs, Gia_ObjId(p, pObj) ); + Vec_Int_t * vGates = Vec_WecEntry( vFuncs, Index ); + int iLitRes, iTopLit = Vec_IntEntryLast( vGates ); + if ( Abc_Lit2Var(iTopLit) == 0 ) + iLitRes = 0; + else if ( Abc_Lit2Var(iTopLit) < nVars ) + iLitRes = Gia_ManObj(p, Abc_Lit2Var(iTopLit))->Value; + else { - assert( !Abc_LitIsCompl(iLit0) ); - assert( !Abc_LitIsCompl(iLit1) ); - iLitRes = Gia_ManAppendXor( pNew, Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)), Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) ); + Vec_IntForEachEntry( vGates, iLit, k ) + Vec_IntWriteEntry( vUsed, Abc_Lit2Var(iLit), Gia_ManObj(p, Abc_Lit2Var(iLit))->Value ); + iLitRes = Gia_ManConstructFromMap( pNew, vGates, nVars, vUsed, vCopy, 1 ); + Vec_IntForEachEntry( vGates, iLit, k ) + Vec_IntWriteEntry( vUsed, Abc_Lit2Var(iLit), -1 ); } - else assert( 0 ); - Vec_IntPush( vCopy, iLitRes ); + pObj->Value = Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ); } - assert( Vec_IntSize(vCopy) == Vec_IntSize(vGates)/2 ); - iLitRes = Vec_IntEntry( vCopy, Vec_IntSize(vGates)/2-1 ); - Vec_IntFree( vUsed ); - Vec_IntFree( vCopy ); - } - Gia_ManAppendCo( pNew, Abc_LitNotCond(iLitRes, Abc_LitIsCompl(iTopLit)) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, pObj->Value ); + Gia_ManForEachObjVec( vObjs, p, pObj, i ) + pObj->fPhase = 0; + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Vec_IntFree( vNodes ); + Vec_IntFree( vUsed ); + Vec_IntFree( vCopy ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); return pNew; } - /**Function************************************************************* Synopsis [Perform resubstitution.] @@ -943,18 +1069,21 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) printf( "Reducing binate divs from %d to 1000.\n", Vec_IntSize(p->vBinateVars) ); Vec_IntShrink( p->vBinateVars, 1000 ); } - iResLit = Gia_ManFindXor( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose ); - if ( iResLit >= 0 ) // xor + if ( p->fUseXor ) { - int iNode = nVars + Vec_IntSize(p->vGates)/2; - int fComp = Abc_LitIsCompl(iResLit); - int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; - int iDiv1 = Abc_Lit2Var(iResLit) >> 15; - assert( !Abc_LitIsCompl(iDiv0) ); - assert( !Abc_LitIsCompl(iDiv1) ); - assert( iDiv0 > iDiv1 ); - Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); - return Abc_Var2Lit( iNode, fComp ); + iResLit = Gia_ManFindXor( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose ); + if ( iResLit >= 0 ) // xor + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; + int fComp = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; + int iDiv1 = Abc_Lit2Var(iResLit) >> 15; + assert( !Abc_LitIsCompl(iDiv0) ); + assert( !Abc_LitIsCompl(iDiv1) ); + assert( iDiv0 > iDiv1 ); + Vec_IntPushTwo( p->vGates, iDiv0, iDiv1 ); + return Abc_Var2Lit( iNode, fComp ); + } } if ( nLimit == 1 ) return -1; @@ -1095,14 +1224,34 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) } return -1; } -void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int fDebug, int fVerbose ) +void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nChoice, int fUseXor, int fDebug, int fVerbose ) { int Res; - Gia_ResbInit( p, vDivs, nWords, nLimit, fDebug, fVerbose ); + Gia_ResbInit( p, vDivs, nWords, nLimit, nChoice, fUseXor, fDebug, fVerbose ); Res = Gia_ManResubPerform_rec( p, nLimit ); if ( Res >= 0 ) Vec_IntPush( p->vGates, Res ); } +Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc ) +{ + Vec_Int_t * vRes; + Gia_ResbMan_t * p = Gia_ResbAlloc( nWords ); + Gia_ManResubPerform( p, vDivs, nWords, nLimit, nChoice, fUseXor, fDebug, 0 ); + if ( fVerbose ) + Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); + if ( !Gia_ManResubVerify(p, pFunc) ) + { + Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); + printf( "Verification FAILED.\n" ); + } + else if ( fDebug && fVerbose ) + printf( "Verification succeeded." ); + if ( fVerbose ) + printf( "\n" ); + vRes = Vec_IntDup( p->vGates ); + Gia_ResbFree( p ); + return vRes; +} /**Function************************************************************* @@ -1126,11 +1275,11 @@ void Abc_ResubPrepareManager( int nWords ) s_pResbMan = Gia_ResbAlloc( nWords ); } -int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int fDebug, int fVerbose, int ** ppArray ) +int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray ) { Vec_Ptr_t Divs = { nDivs, nDivs, ppDivs }; assert( s_pResbMan != NULL ); // first call Abc_ResubPrepareManager() - Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, fDebug, 0 ); + Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, nChoice, fUseXor, fDebug, 0 ); if ( fVerbose ) { Gia_ManResubPrint( s_pResbMan->vGates, nDivs ); @@ -1138,7 +1287,7 @@ int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, } if ( fDebug ) { - if ( !Gia_ManResubVerify(s_pResbMan) ) + if ( !Gia_ManResubVerify(s_pResbMan, NULL) ) { Gia_ManResubPrint( s_pResbMan->vGates, nDivs ); printf( "Verification FAILED.\n" ); @@ -1206,7 +1355,7 @@ void Gia_ManResubTest3() printf( " " ); //Abc_ResubDumpProblem( "temp.resub", (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1 ); - ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1, 4, 1, fVerbose, &pArray ); + ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1, 4, 0, 0, 1, fVerbose, &pArray ); if ( !fVerbose ) printf( "\n" ); @@ -1245,7 +1394,7 @@ void Gia_ManResubTest3_() printf( " " ); Dau_DsdPrintFromTruth2( &Truth, 6 ); printf( " " ); - Gia_ManResubPerform( p, vDivs, 1, 100, 1, 0 ); + Gia_ManResubPerform( p, vDivs, 1, 100, 0, 1, 1, 0 ); } Gia_ResbFree( p ); Vec_IntFree( vRes ); @@ -1295,11 +1444,11 @@ Vec_Ptr_t * Gia_ManDeriveDivs( Vec_Wrd_t * vSims, int nWords ) Vec_PtrPush( vDivs, Vec_WrdEntryP(vSims, nWords*i) ); return vDivs; } -Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, int fVerbose, int fVeryVerbose ) +Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, int nChoice, int fUseXor, int fVerbose, int fVeryVerbose ) { return NULL; } -Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int fVerbose, int fVeryVerbose ) +Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int nChoice, int fUseXor, int fVerbose, int fVeryVerbose ) { int nWords = 0; Gia_Man_t * pMan = NULL; @@ -1313,9 +1462,14 @@ Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, i Vec_PtrShrink( vDivs, (1<<14)-1 ); } assert( Vec_PtrSize(vDivs) < (1<<14) ); - Gia_ManResubPerform( p, vDivs, nWords, 100, 1, 1 ); + Gia_ManResubPerform( p, vDivs, nWords, 100, nChoice, fUseXor, 1, 1 ); if ( Vec_IntSize(p->vGates) ) - pMan = Gia_ManConstructFromGates( p->vGates, Vec_PtrSize(vDivs) ); + { + Vec_Wec_t * vGates = Vec_WecStart(1); + Vec_IntAppend( Vec_WecEntry(vGates, 0), p->vGates ); + pMan = Gia_ManConstructFromGates( vGates, Vec_PtrSize(vDivs) ); + Vec_WecFree( vGates ); + } else printf( "Decomposition did not succeed.\n" ); Gia_ResbFree( p ); -- cgit v1.2.3 From 0ae0744e73b978593a054e8bf80c35723c9f4b03 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 15 May 2020 22:11:10 -0700 Subject: Experimental resubstitution. --- src/aig/gia/gia.h | 4 +- src/aig/gia/giaResub.c | 534 ++++++++++++++++++++++++++++++++--------------- src/aig/gia/giaSimBase.c | 83 -------- src/aig/gia/giaUtil.c | 23 +- 4 files changed, 386 insertions(+), 258 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 4e10cbe6..2458b152 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1558,8 +1558,7 @@ extern void Gia_ManIncrSimSet( Gia_Man_t * p, Vec_Int_t * vObjLit extern int Gia_ManIncrSimCheckOver( Gia_Man_t * p, int iLit0, int iLit1 ); extern int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 ); /*=== giaSimBase.c ============================================================*/ -extern Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName, int * pnWords ); -extern void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ); +extern Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * p ); /*=== giaSpeedup.c ============================================================*/ extern float Gia_ManDelayTraceLut( Gia_Man_t * p ); extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ); @@ -1685,6 +1684,7 @@ extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE ); extern int Gia_ObjRecognizeMuxLits( Gia_Man_t * p, Gia_Obj_t * pNode, int * iLitT, int * iLitE ); extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode ); +extern int Gia_NodeMffcSizeMark( Gia_Man_t * p, Gia_Obj_t * pNode ); extern int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp ); extern int Gia_ManHasDangling( Gia_Man_t * p ); extern int Gia_ManMarkDangling( Gia_Man_t * p ); diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 66f27310..a32d0094 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -290,10 +290,12 @@ struct Gia_ResbMan_t_ { int nWords; int nLimit; - int nChoice; + int nDivsMax; + int iChoice; int fUseXor; int fDebug; int fVerbose; + int fVeryVerbose; Vec_Ptr_t * vDivs; Vec_Int_t * vGates; Vec_Int_t * vUnateLits[2]; @@ -302,6 +304,7 @@ struct Gia_ResbMan_t_ Vec_Int_t * vBinateVars; Vec_Int_t * vUnateLitsW[2]; Vec_Int_t * vUnatePairsW[2]; + Vec_Wec_t * vSorter; word * pSets[2]; word * pDivA; word * pDivB; @@ -321,6 +324,7 @@ Gia_ResbMan_t * Gia_ResbAlloc( int nWords ) p->vUnateLitsW[1] = Vec_IntAlloc( 100 ); p->vUnatePairsW[0] = Vec_IntAlloc( 100 ); p->vUnatePairsW[1] = Vec_IntAlloc( 100 ); + p->vSorter = Vec_WecAlloc( nWords*64 ); p->vBinateVars = Vec_IntAlloc( 100 ); p->vGates = Vec_IntAlloc( 100 ); p->vDivs = Vec_PtrAlloc( 100 ); @@ -331,14 +335,16 @@ Gia_ResbMan_t * Gia_ResbAlloc( int nWords ) p->vSims = Vec_WrdAlloc( 100 ); return p; } -void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nChoice, int fUseXor, int fDebug, int fVerbose ) +void Gia_ResbInit( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int fVeryVerbose ) { assert( p->nWords == nWords ); - p->nLimit = nLimit; - p->nChoice = nChoice; - p->fUseXor = fUseXor; - p->fDebug = fDebug; - p->fVerbose = fVerbose; + p->nLimit = nLimit; + p->nDivsMax = nDivsMax; + p->iChoice = iChoice; + p->fUseXor = fUseXor; + p->fDebug = fDebug; + p->fVerbose = fVerbose; + p->fVeryVerbose = fVeryVerbose; Abc_TtCopy( p->pSets[0], (word *)Vec_PtrEntry(vDivs, 0), nWords, 0 ); Abc_TtCopy( p->pSets[1], (word *)Vec_PtrEntry(vDivs, 1), nWords, 0 ); Vec_PtrClear( p->vDivs ); @@ -372,6 +378,7 @@ void Gia_ResbFree( Gia_ResbMan_t * p ) Vec_IntFree( p->vGates ); Vec_WrdFree( p->vSims ); Vec_PtrFree( p->vDivs ); + Vec_WecFree( p->vSorter ); ABC_FREE( p->pSets[0] ); ABC_FREE( p->pSets[1] ); ABC_FREE( p->pDivA ); @@ -727,19 +734,19 @@ static inline int Gia_ManFindFirstCommonLit( Vec_Int_t * vArr1, Vec_Int_t * vArr *pStart2++ = *pBeg2++; Vec_IntShrink( vArr1, pStart1 - vArr1->pArray ); Vec_IntShrink( vArr2, pStart2 - vArr2->pArray ); - if ( fVerbose ) printf( "Removed %d duplicated entries. Array1 = %d. Array2 = %d.\n", nRemoved, Vec_IntSize(vArr1), Vec_IntSize(vArr2) ); + //if ( fVerbose ) printf( "Removed %d duplicated entries. Array1 = %d. Array2 = %d.\n", nRemoved, Vec_IntSize(vArr1), Vec_IntSize(vArr2) ); return -1; } -void Gia_ManFindOneUnateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vNotUnateVars ) +void Gia_ManFindOneUnateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vNotUnateVars ) { word * pDiv; int i; Vec_IntClear( vUnateLits ); Vec_IntClear( vNotUnateVars ); Vec_PtrForEachEntryStart( word *, vDivs, pDiv, i, 2 ) - if ( !Abc_TtIntersectOne( pOffSet, 0, pDiv, 0, nWords ) ) + if ( !Abc_TtIntersectOne( pOff, 0, pDiv, 0, nWords ) ) Vec_IntPush( vUnateLits, Abc_Var2Lit(i, 0) ); - else if ( !Abc_TtIntersectOne( pOffSet, 0, pDiv, 1, nWords ) ) + else if ( !Abc_TtIntersectOne( pOff, 0, pDiv, 1, nWords ) ) Vec_IntPush( vUnateLits, Abc_Var2Lit(i, 1) ); else Vec_IntPush( vNotUnateVars, i ); @@ -747,86 +754,107 @@ void Gia_ManFindOneUnateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, i int Gia_ManFindOneUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vNotUnateVars[2], int fVerbose ) { int n; + if ( fVerbose ) printf( " " ); for ( n = 0; n < 2; n++ ) { Gia_ManFindOneUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vNotUnateVars[n] ); - if ( fVerbose ) printf( "Found %d %d-unate divs.\n", Vec_IntSize(vUnateLits[n]), n ); + if ( fVerbose ) printf( "U%d =%4d ", n, Vec_IntSize(vUnateLits[n]) ); } return Gia_ManFindFirstCommonLit( vUnateLits[0], vUnateLits[1], fVerbose ); } -static inline int Gia_ManDivCover( word * pOffSet, word * pOnSet, word * pDivA, int ComplA, word * pDivB, int ComplB, int nWords ) +static inline int Gia_ManDivCover( word * pOff, word * pOn, word * pDivA, int ComplA, word * pDivB, int ComplB, int nWords ) { - //assert( !Abc_TtIntersectOne(pOffSet, 0, pDivA, ComplA, nWords) ); - //assert( !Abc_TtIntersectOne(pOffSet, 0, pDivB, ComplB, nWords) ); - return !Abc_TtIntersectTwo( pOnSet, 0, pDivA, !ComplA, pDivB, !ComplB, nWords ); + //assert( !Abc_TtIntersectOne(pOff, 0, pDivA, ComplA, nWords) ); + //assert( !Abc_TtIntersectOne(pOff, 0, pDivB, ComplB, nWords) ); + return !Abc_TtIntersectTwo( pOn, 0, pDivA, !ComplA, pDivB, !ComplB, nWords ); } -int Gia_ManFindTwoUnateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits ) +int Gia_ManFindTwoUnateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnateLitsW, int * pnPairs ) { - int i, k, iDiv0, iDiv1; - Vec_IntForEachEntry( vUnateLits, iDiv1, i ) - Vec_IntForEachEntryStop( vUnateLits, iDiv0, k, i ) + int i, k, iDiv0_, iDiv1_, Cover0, Cover1; + int nTotal = Abc_TtCountOnesVec( pOn, nWords ); + (*pnPairs) = 0; + Vec_IntForEachEntryTwo( vUnateLits, vUnateLitsW, iDiv0_, Cover0, i ) { - word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); - word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1)); - if ( Gia_ManDivCover(pOffSet, pOnSet, pDiv1, Abc_LitIsCompl(iDiv1), pDiv0, Abc_LitIsCompl(iDiv0), nWords) ) - return Abc_Var2Lit((Abc_LitNot(iDiv1) << 15) | Abc_LitNot(iDiv0), 1); + if ( 2*Cover0 < nTotal ) + break; + Vec_IntForEachEntryTwoStart( vUnateLits, vUnateLitsW, iDiv1_, Cover1, k, i+1 ) + { + int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ ); + int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ ); + word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); + word * pDiv1 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv1)); + if ( Cover0 + Cover1 < nTotal ) + break; + (*pnPairs)++; + if ( Gia_ManDivCover(pOff, pOn, pDiv1, Abc_LitIsCompl(iDiv1), pDiv0, Abc_LitIsCompl(iDiv0), nWords) ) + return Abc_Var2Lit((Abc_LitNot(iDiv1) << 15) | Abc_LitNot(iDiv0), 1); + } } return -1; } -int Gia_ManFindTwoUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], int fVerbose ) +int Gia_ManFindTwoUnate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], int fVerbose ) { - int n, iLit; + int n, iLit, nPairs; + if ( fVerbose ) printf( " " ); for ( n = 0; n < 2; n++ ) { - int nPairs = Vec_IntSize(vUnateLits[n])*(Vec_IntSize(vUnateLits[n])-1)/2; - if ( fVerbose ) printf( "Trying %d pairs of %d-unate divs.\n", nPairs, n ); - iLit = Gia_ManFindTwoUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n] ); + //int nPairsAll = Vec_IntSize(vUnateLits[n])*(Vec_IntSize(vUnateLits[n])-1)/2; + iLit = Gia_ManFindTwoUnateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], &nPairs ); + if ( fVerbose ) printf( "UU%d =%5d ", n, nPairs ); if ( iLit >= 0 ) return Abc_LitNotCond(iLit, n); } return -1; } -void Gia_ManFindXorInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs ) +void Gia_ManFindXorInt( word * pOff, word * pOn, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs ) { - int i, k, iDiv0, iDiv1; - Vec_IntForEachEntry( vBinate, iDiv1, i ) - Vec_IntForEachEntryStop( vBinate, iDiv0, k, i ) + int i, k, iDiv0_, iDiv1_; + int Limit2 = Vec_IntSize(vBinate);//Abc_MinInt( Vec_IntSize(vBinate), 100 ); + Vec_IntForEachEntryStop( vBinate, iDiv1_, i, Limit2 ) + Vec_IntForEachEntryStop( vBinate, iDiv0_, k, i ) { + int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ ); + int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ ); word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0); word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1); - if ( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, 0, nWords ) ) + if ( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, 0, nWords ) ) Vec_IntPush( vUnatePairs, Abc_Var2Lit((Abc_Var2Lit(iDiv0, 0) << 15) | Abc_Var2Lit(iDiv1, 0), 0) ); - else if ( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, 1, nWords ) ) + else if ( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, 1, nWords ) ) Vec_IntPush( vUnatePairs, Abc_Var2Lit((Abc_Var2Lit(iDiv0, 0) << 15) | Abc_Var2Lit(iDiv1, 0), 1) ); } } int Gia_ManFindXor( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnatePairs[2], int fVerbose ) { int n; + if ( fVerbose ) printf( " " ); for ( n = 0; n < 2; n++ ) { Vec_IntClear( vUnatePairs[n] ); Gia_ManFindXorInt( pSets[n], pSets[!n], vBinateVars, vDivs, nWords, vUnatePairs[n] ); - if ( fVerbose ) printf( "Found %d %d-unate XOR divs.\n", Vec_IntSize(vUnatePairs[n]), n ); + if ( fVerbose ) printf( "UX%d =%5d ", n, Vec_IntSize(vUnatePairs[n]) ); } return Gia_ManFindFirstCommonLit( vUnatePairs[0], vUnatePairs[1], fVerbose ); } -void Gia_ManFindUnatePairsInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs ) +void Gia_ManFindUnatePairsInt( word * pOff, word * pOn, Vec_Int_t * vBinate, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs ) { - int n, i, k, iDiv0, iDiv1; - Vec_IntForEachEntry( vBinate, iDiv1, i ) - Vec_IntForEachEntryStop( vBinate, iDiv0, k, i ) + int n, i, k, iDiv0_, iDiv1_; + int Limit2 = Vec_IntSize(vBinate);//Abc_MinInt( Vec_IntSize(vBinate), 100 ); + Vec_IntForEachEntryStop( vBinate, iDiv1_, i, Limit2 ) + Vec_IntForEachEntryStop( vBinate, iDiv0_, k, i ) { + int iDiv0 = Abc_MinInt( iDiv0_, iDiv1_ ); + int iDiv1 = Abc_MaxInt( iDiv0_, iDiv1_ ); word * pDiv0 = (word *)Vec_PtrEntry(vDivs, iDiv0); word * pDiv1 = (word *)Vec_PtrEntry(vDivs, iDiv1); for ( n = 0; n < 4; n++ ) { int iLit0 = Abc_Var2Lit( iDiv0, n&1 ); int iLit1 = Abc_Var2Lit( iDiv1, n>>1 ); - if ( !Abc_TtIntersectTwo( pOffSet, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) ) + //if ( !Abc_TtIntersectTwo( pOff, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) ) + if ( !Abc_TtIntersectTwo( pOff, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) && Abc_TtIntersectTwo( pOn, 0, pDiv1, n>>1, pDiv0, n&1, nWords ) ) Vec_IntPush( vUnatePairs, Abc_Var2Lit((iLit1 << 15) | iLit0, 0) ); } } @@ -834,11 +862,12 @@ void Gia_ManFindUnatePairsInt( word * pOffSet, word * pOnSet, Vec_Int_t * vBinat void Gia_ManFindUnatePairs( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Int_t * vUnatePairs[2], int fVerbose ) { int n, RetValue; + if ( fVerbose ) printf( " " ); for ( n = 0; n < 2; n++ ) { int nBefore = Vec_IntSize(vUnatePairs[n]); Gia_ManFindUnatePairsInt( pSets[n], pSets[!n], vBinateVars, vDivs, nWords, vUnatePairs[n] ); - if ( fVerbose ) printf( "Found %d %d-unate pair divs.\n", Vec_IntSize(vUnatePairs[n])-nBefore, n ); + if ( fVerbose ) printf( "UP%d =%5d ", n, Vec_IntSize(vUnatePairs[n])-nBefore ); } RetValue = Gia_ManFindFirstCommonLit( vUnatePairs[0], vUnatePairs[1], fVerbose ); assert( RetValue == -1 ); @@ -863,108 +892,107 @@ void Gia_ManDeriveDivPair( int iDiv, Vec_Ptr_t * vDivs, int nWords, word * pRes Abc_TtXor( pRes, pDiv0, pDiv1, nWords, 0 ); } } -int Gia_ManFindDivGateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnatePairs, word * pDivTemp ) +int Gia_ManFindDivGateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnateLitsW, Vec_Int_t * vUnatePairsW, word * pDivTemp ) { - int i, k, iDiv0, iDiv1; - int Limit1 = Abc_MinInt( Vec_IntSize(vUnateLits), 1000 ); - int Limit2 = Abc_MinInt( Vec_IntSize(vUnatePairs), 1000 ); - Vec_IntForEachEntryStop( vUnateLits, iDiv0, i, Limit1 ) - Vec_IntForEachEntryStop( vUnatePairs, iDiv1, k, Limit2 ) + int i, k, iDiv0, iDiv1, Cover0, Cover1; + int nTotal = Abc_TtCountOnesVec( pOn, nWords ); + Vec_IntForEachEntryTwo( vUnateLits, vUnateLitsW, iDiv0, Cover0, i ) { word * pDiv0 = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iDiv0)); - int fComp1 = Abc_LitIsCompl(iDiv1); - Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTemp ); - if ( Gia_ManDivCover(pOffSet, pOnSet, pDiv0, Abc_LitIsCompl(iDiv0), pDivTemp, fComp1, nWords) ) - return Abc_Var2Lit((Abc_Var2Lit(k, 1) << 15) | Abc_LitNot(iDiv0), 1); + if ( 2*Cover0 < nTotal ) + break; + Vec_IntForEachEntryTwo( vUnatePairs, vUnatePairsW, iDiv1, Cover1, k ) + { + int fComp1 = Abc_LitIsCompl(iDiv1); + if ( Cover0 + Cover1 < nTotal ) + break; + Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTemp ); + if ( Gia_ManDivCover(pOff, pOn, pDiv0, Abc_LitIsCompl(iDiv0), pDivTemp, fComp1, nWords) ) + return Abc_Var2Lit((Abc_Var2Lit(k, 1) << 15) | Abc_LitNot(iDiv0), 1); + } } return -1; } -int Gia_ManFindDivGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnatePairs[2], word * pDivTemp ) +int Gia_ManFindDivGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnateLitsW[2], Vec_Int_t * vUnatePairsW[2], word * pDivTemp ) { int n, iLit; for ( n = 0; n < 2; n++ ) { - iLit = Gia_ManFindDivGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnatePairs[n], pDivTemp ); + iLit = Gia_ManFindDivGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnatePairs[n], vUnateLitsW[n], vUnatePairsW[n], pDivTemp ); if ( iLit >= 0 ) return Abc_LitNotCond( iLit, n ); } return -1; } -int Gia_ManFindGateGateInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, word * pDivTempA, word * pDivTempB ) +int Gia_ManFindGateGateInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW, word * pDivTempA, word * pDivTempB ) { - int i, k, iDiv0, iDiv1; - int Limit2 = Abc_MinInt( Vec_IntSize(vUnatePairs), 1000 ); - Vec_IntForEachEntryStop( vUnatePairs, iDiv1, i, Limit2 ) + int i, k, iDiv0, iDiv1, Cover0, Cover1; + int nTotal = Abc_TtCountOnesVec( pOn, nWords ); + Vec_IntForEachEntryTwo( vUnatePairs, vUnatePairsW, iDiv0, Cover0, k ) { - int fCompB = Abc_LitIsCompl(iDiv1); - Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTempB ); - Vec_IntForEachEntryStop( vUnatePairs, iDiv0, k, i ) + int fCompA = Abc_LitIsCompl(iDiv0); + if ( 2*Cover0 < nTotal ) + break; + Gia_ManDeriveDivPair( iDiv0, vDivs, nWords, pDivTempA ); + Vec_IntForEachEntryTwoStart( vUnatePairs, vUnatePairsW, iDiv1, Cover1, i, k+1 ) { - int fCompA = Abc_LitIsCompl(iDiv0); - Gia_ManDeriveDivPair( iDiv0, vDivs, nWords, pDivTempA ); - if ( Gia_ManDivCover(pOffSet, pOnSet, pDivTempA, fCompA, pDivTempB, fCompB, nWords) ) + int fCompB = Abc_LitIsCompl(iDiv1); + if ( Cover0 + Cover1 < nTotal ) + break; + Gia_ManDeriveDivPair( iDiv1, vDivs, nWords, pDivTempB ); + if ( Gia_ManDivCover(pOff, pOn, pDivTempA, fCompA, pDivTempB, fCompB, nWords) ) return Abc_Var2Lit((Abc_Var2Lit(i, 1) << 15) | Abc_Var2Lit(k, 1), 1); } } return -1; } -int Gia_ManFindGateGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], word * pDivTempA, word * pDivTempB ) +int Gia_ManFindGateGate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnatePairsW[2], word * pDivTempA, word * pDivTempB ) { int n, iLit; for ( n = 0; n < 2; n++ ) { - iLit = Gia_ManFindGateGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnatePairs[n], pDivTempA, pDivTempB ); + iLit = Gia_ManFindGateGateInt( pSets[n], pSets[!n], vDivs, nWords, vUnatePairs[n], vUnatePairsW[n], pDivTempA, pDivTempB ); if ( iLit >= 0 ) return Abc_LitNotCond( iLit, n ); } return -1; } -void Gia_ManComputeLitWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnateLitsW ) +void Gia_ManSortUnatesInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits, Vec_Int_t * vUnateLitsW, Vec_Wec_t * vSorter ) { - int i, iLit; - Vec_IntClear( vUnateLitsW ); + int i, k, iLit; + Vec_Int_t * vLevel; + Vec_WecInit( vSorter, nWords*64 ); Vec_IntForEachEntry( vUnateLits, iLit, i ) { - word * pDiv = (word *)Vec_PtrEntry( vDivs, Abc_Lit2Var(iLit) ); - //assert( !Abc_TtIntersectOne( pOffSet, 0, pDiv, Abc_LitIsCompl(iLit), nWords ) ); - Vec_IntPush( vUnateLitsW, -Abc_TtCountOnesVecMask(pDiv, pOnSet, nWords, Abc_LitIsCompl(iLit)) ); + word * pDiv = (word *)Vec_PtrEntry(vDivs, Abc_Lit2Var(iLit)); + //assert( !Abc_TtIntersectOne( pOff, 0, pDiv, Abc_LitIsCompl(iLit), nWords ) ); + Vec_WecPush( vSorter, Abc_TtCountOnesVecMask(pDiv, pOn, nWords, Abc_LitIsCompl(iLit)), iLit ); } + Vec_IntClear( vUnateLits ); + Vec_IntClear( vUnateLitsW ); + Vec_WecForEachLevelReverse( vSorter, vLevel, k ) + Vec_IntForEachEntry( vLevel, iLit, i ) + { + Vec_IntPush( vUnateLits, iLit ); + Vec_IntPush( vUnateLitsW, k ); + } + //Vec_IntPrint( Vec_WecEntry(vSorter, 0) ); + Vec_WecClear( vSorter ); } -void Gia_ManComputeLitWeights( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], int TopW[2], int fVerbose ) +void Gia_ManSortUnates( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], Vec_Wec_t * vSorter ) { - int n, TopNum = 5; - TopW[0] = TopW[1] = 0; - for ( n = 0; n < 2; n++ ) - Gia_ManComputeLitWeightsInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n] ); + int n; for ( n = 0; n < 2; n++ ) - if ( Vec_IntSize(vUnateLitsW[n]) ) - { - int i, * pPerm = Abc_MergeSortCost( Vec_IntArray(vUnateLitsW[n]), Vec_IntSize(vUnateLitsW[n]) ); - TopW[n] = -Vec_IntEntry(vUnateLitsW[n], pPerm[0]); - if ( fVerbose ) - { - printf( "Top %d %d-unate divs:\n", TopNum, n ); - for ( i = 0; i < TopNum && i < Vec_IntSize(vUnateLits[n]); i++ ) - { - printf( "%5d : ", i ); - printf( "Lit = %5d ", Vec_IntEntry(vUnateLits[n], pPerm[i]) ); - printf( "Cost = %5d\n", -Vec_IntEntry(vUnateLitsW[n], pPerm[i]) ); - } - } - for ( i = 0; i < Vec_IntSize(vUnateLits[n]); i++ ) - pPerm[i] = Vec_IntEntry(vUnateLits[n], pPerm[i]); - for ( i = 0; i < Vec_IntSize(vUnateLits[n]); i++ ) - vUnateLits[n]->pArray[i] = pPerm[i]; - ABC_FREE( pPerm ); - } + Gia_ManSortUnatesInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], vSorter ); } -void Gia_ManComputePairWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW ) +void Gia_ManSortPairsInt( word * pOff, word * pOn, Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs, Vec_Int_t * vUnatePairsW, Vec_Wec_t * vSorter ) { - int i, iPair; - Vec_IntClear( vUnatePairsW ); + int i, k, iPair; + Vec_Int_t * vLevel; + Vec_WecInit( vSorter, nWords*64 ); Vec_IntForEachEntry( vUnatePairs, iPair, i ) { int fComp = Abc_LitIsCompl(iPair); @@ -975,53 +1003,70 @@ void Gia_ManComputePairWeightsInt( word * pOffSet, word * pOnSet, Vec_Ptr_t * vD if ( iLit0 < iLit1 ) { assert( !fComp ); - //assert( !Abc_TtIntersectTwo( pOffSet, 0, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ) ); - Vec_IntPush( vUnatePairsW, -Abc_TtCountOnesVecMask2(pDiv0, pDiv1, Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), pOnSet, nWords) ); + //assert( !Abc_TtIntersectTwo( pOff, 0, pDiv0, Abc_LitIsCompl(iLit0), pDiv1, Abc_LitIsCompl(iLit1), nWords ) ); + Vec_WecPush( vSorter, Abc_TtCountOnesVecMask2(pDiv0, pDiv1, Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), pOn, nWords), iPair ); } else { assert( !Abc_LitIsCompl(iLit0) ); assert( !Abc_LitIsCompl(iLit1) ); - //assert( !Abc_TtIntersectXor( pOffSet, 0, pDiv0, pDiv1, fComp, nWords ) ); - Vec_IntPush( vUnatePairsW, -Abc_TtCountOnesVecXorMask(pDiv0, pDiv1, fComp, pOnSet, nWords) ); + //assert( !Abc_TtIntersectXor( pOff, 0, pDiv0, pDiv1, fComp, nWords ) ); + Vec_WecPush( vSorter, Abc_TtCountOnesVecXorMask(pDiv0, pDiv1, fComp, pOn, nWords), iPair ); } } + Vec_IntClear( vUnatePairs ); + Vec_IntClear( vUnatePairsW ); + Vec_WecForEachLevelReverse( vSorter, vLevel, k ) + Vec_IntForEachEntry( vLevel, iPair, i ) + { + Vec_IntPush( vUnatePairs, iPair ); + Vec_IntPush( vUnatePairsW, k ); + } + //Vec_IntPrint( Vec_WecEntry(vSorter, 0) ); + Vec_WecClear( vSorter ); + } -void Gia_ManComputePairWeights( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnatePairs[2], Vec_Int_t * vUnatePairsW[2], int TopW[2], int fVerbose ) +void Gia_ManSortPairs( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vUnateLits[2], Vec_Int_t * vUnateLitsW[2], Vec_Wec_t * vSorter ) { - int n, TopNum = 5; - TopW[0] = TopW[1] = 0; - for ( n = 0; n < 2; n++ ) - Gia_ManComputePairWeightsInt( pSets[n], pSets[!n], vDivs, nWords, vUnatePairs[n], vUnatePairsW[n] ); + int n; for ( n = 0; n < 2; n++ ) - if ( Vec_IntSize(vUnatePairsW[n]) ) + Gia_ManSortPairsInt( pSets[n], pSets[!n], vDivs, nWords, vUnateLits[n], vUnateLitsW[n], vSorter ); +} + +void Gia_ManSortBinate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_t * vBinateVars, Vec_Wec_t * vSorter ) +{ + Vec_Int_t * vLevel; + int nMints[2] = { Abc_TtCountOnesVec(pSets[0], nWords), Abc_TtCountOnesVec(pSets[1], nWords) }; + word * pBig = nMints[0] > nMints[1] ? pSets[0] : pSets[1]; + word * pSmo = nMints[0] > nMints[1] ? pSets[1] : pSets[0]; + int Big = Abc_MaxInt( nMints[0], nMints[1] ); + int Smo = Abc_MinInt( nMints[0], nMints[1] ); + int i, k, iDiv, Gain; + + Vec_WecInit( vSorter, nWords*64 ); + Vec_IntForEachEntry( vBinateVars, iDiv, i ) + { + word * pDiv = (word *)Vec_PtrEntry( vDivs, iDiv ); + int nInter[2] = { Abc_TtCountOnesVecMask(pBig, pDiv, nWords, 0), Abc_TtCountOnesVecMask(pSmo, pDiv, nWords, 0) }; + if ( nInter[0] < Big/2 ) // complement the divisor { - int i, * pPerm = Abc_MergeSortCost( Vec_IntArray(vUnatePairsW[n]), Vec_IntSize(vUnatePairsW[n]) ); - TopW[n] = -Vec_IntEntry(vUnatePairsW[n], pPerm[0]); - if ( fVerbose ) - { - printf( "Top %d %d-unate pairs:\n", TopNum, n ); - for ( i = 0; i < TopNum && i < Vec_IntSize(vUnatePairs[n]); i++ ) - { - int Pair = Vec_IntEntry(vUnatePairs[n], pPerm[i]); - int Div0 = Abc_Lit2Var(Pair) & 0x7FFF; - int Div1 = Abc_Lit2Var(Pair) >> 15; - printf( "%5d : ", i ); - printf( "Compl = %5d ", Abc_LitIsCompl(Pair) ); - printf( "Type = %s ", Div0 < Div1 ? "and" : "xor" ); - printf( "Div0 = %5d ", Div0 ); - printf( "Div1 = %5d ", Div1 ); - printf( "Cost = %5d\n", -Vec_IntEntry(vUnatePairsW[n], pPerm[i]) ); - } - } - for ( i = 0; i < Vec_IntSize(vUnatePairs[n]); i++ ) - pPerm[i] = Vec_IntEntry(vUnatePairs[n], pPerm[i]); - for ( i = 0; i < Vec_IntSize(vUnatePairs[n]); i++ ) - vUnatePairs[n]->pArray[i] = pPerm[i]; - ABC_FREE( pPerm ); + nInter[0] = Big - nInter[0]; + nInter[1] = Smo - nInter[1]; } -} + assert( nInter[0] >= Big/2 ); + Gain = Abc_MaxInt( 0, nInter[0] - Big/2 + Smo/2 - nInter[1] ); + Vec_WecPush( vSorter, Gain, iDiv ); + } + Vec_IntClear( vBinateVars ); + Vec_WecForEachLevelReverse( vSorter, vLevel, k ) + Vec_IntForEachEntry( vLevel, iDiv, i ) + Vec_IntPush( vBinateVars, iDiv ); + Vec_WecClear( vSorter ); + + if ( Vec_IntSize(vBinateVars) > 2000 ) + Vec_IntShrink( vBinateVars, 2000 ); +} /**Function************************************************************* @@ -1039,9 +1084,11 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) int TopOneW[2] = {0}, TopTwoW[2] = {0}, Max1, Max2, iResLit, nVars = Vec_PtrSize(p->vDivs); if ( p->fVerbose ) { - printf( "\nCalling decomposition for ISF: " ); - printf( "OFF = %5d (%6.2f %%) ", Abc_TtCountOnesVec(p->pSets[0], p->nWords), 100.0*Abc_TtCountOnesVec(p->pSets[0], p->nWords)/(64*p->nWords) ); - printf( "ON = %5d (%6.2f %%)\n", Abc_TtCountOnesVec(p->pSets[1], p->nWords), 100.0*Abc_TtCountOnesVec(p->pSets[1], p->nWords)/(64*p->nWords) ); + int nMints[2] = { Abc_TtCountOnesVec(p->pSets[0], p->nWords), Abc_TtCountOnesVec(p->pSets[1], p->nWords) }; + printf( " " ); + printf( "ISF: " ); + printf( "0=%5d (%5.2f %%) ", nMints[0], 100.0*nMints[0]/(64*p->nWords) ); + printf( "1=%5d (%5.2f %%) ", nMints[1], 100.0*nMints[1]/(64*p->nWords) ); } if ( Abc_TtIsConst0( p->pSets[1], p->nWords ) ) return 0; @@ -1052,7 +1099,8 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) return iResLit; if ( nLimit == 0 ) return -1; - iResLit = Gia_ManFindTwoUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->fVerbose ); + Gia_ManSortUnates( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, p->vSorter ); + iResLit = Gia_ManFindTwoUnate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, p->fVerbose ); if ( iResLit >= 0 ) // and { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1064,11 +1112,10 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) return Abc_Var2Lit( iNode, fComp ); } Vec_IntTwoFindCommon( p->vNotUnateVars[0], p->vNotUnateVars[1], p->vBinateVars ); - if ( Vec_IntSize(p->vBinateVars) > 1000 ) - { - printf( "Reducing binate divs from %d to 1000.\n", Vec_IntSize(p->vBinateVars) ); - Vec_IntShrink( p->vBinateVars, 1000 ); - } + if ( Vec_IntSize(p->vBinateVars) > p->nDivsMax ) + Vec_IntShrink( p->vBinateVars, p->nDivsMax ); + if ( p->fVerbose ) printf( " B = %3d", Vec_IntSize(p->vBinateVars) ); + //Gia_ManSortBinate( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vSorter ); if ( p->fUseXor ) { iResLit = Gia_ManFindXor( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose ); @@ -1088,7 +1135,8 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) if ( nLimit == 1 ) return -1; Gia_ManFindUnatePairs( p->pSets, p->vDivs, p->nWords, p->vBinateVars, p->vUnatePairs, p->fVerbose ); - iResLit = Gia_ManFindDivGate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnatePairs, p->pDivA ); + Gia_ManSortPairs( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, p->vSorter ); + iResLit = Gia_ManFindDivGate( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnatePairs, p->vUnateLitsW, p->vUnatePairsW, p->pDivA ); if ( iResLit >= 0 ) // and(div,pair) { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1108,7 +1156,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) } if ( nLimit == 2 ) return -1; - iResLit = Gia_ManFindGateGate( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->pDivA, p->pDivB ); + iResLit = Gia_ManFindGateGate( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, p->pDivA, p->pDivB ); if ( iResLit >= 0 ) // and(pair,pair) { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1136,8 +1184,13 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) return -1; if ( Vec_IntSize(p->vUnateLits[0]) + Vec_IntSize(p->vUnateLits[1]) + Vec_IntSize(p->vUnatePairs[0]) + Vec_IntSize(p->vUnatePairs[1]) == 0 ) return -1; - Gia_ManComputeLitWeights( p->pSets, p->vDivs, p->nWords, p->vUnateLits, p->vUnateLitsW, TopOneW, p->fVerbose ); - Gia_ManComputePairWeights( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, TopTwoW, p->fVerbose ); + + TopOneW[0] = Vec_IntSize(p->vUnateLitsW[0]) ? Vec_IntEntry(p->vUnateLitsW[0], 0) : 0; + TopOneW[1] = Vec_IntSize(p->vUnateLitsW[1]) ? Vec_IntEntry(p->vUnateLitsW[1], 0) : 0; + + TopTwoW[0] = Vec_IntSize(p->vUnatePairsW[0]) ? Vec_IntEntry(p->vUnatePairsW[0], 0) : 0; + TopTwoW[1] = Vec_IntSize(p->vUnatePairsW[1]) ? Vec_IntEntry(p->vUnatePairsW[1], 0) : 0; + Max1 = Abc_MaxInt(TopOneW[0], TopOneW[1]); Max2 = Abc_MaxInt(TopTwoW[0], TopTwoW[1]); if ( Abc_MaxInt(Max1, Max2) == 0 ) @@ -1151,6 +1204,8 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) int fComp = Abc_LitIsCompl(iDiv); word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) ); Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); + if ( p->fVerbose ) + printf( "\n" ); iResLit = Gia_ManResubPerform_rec( p, nLimit-1 ); if ( iResLit >= 0 ) { @@ -1169,6 +1224,8 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) int fComp = Abc_LitIsCompl(iDiv); Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA ); Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); + if ( p->fVerbose ) + printf( "\n " ); iResLit = Gia_ManResubPerform_rec( p, nLimit-2 ); if ( iResLit >= 0 ) { @@ -1191,6 +1248,8 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) int fComp = Abc_LitIsCompl(iDiv); Gia_ManDeriveDivPair( iDiv, p->vDivs, p->nWords, p->pDivA ); Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); + if ( p->fVerbose ) + printf( "\n" ); iResLit = Gia_ManResubPerform_rec( p, nLimit-2 ); if ( iResLit >= 0 ) { @@ -1212,6 +1271,8 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) int fComp = Abc_LitIsCompl(iDiv); word * pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDiv) ); Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); + if ( p->fVerbose ) + printf( "\n " ); iResLit = Gia_ManResubPerform_rec( p, nLimit-1 ); if ( iResLit >= 0 ) { @@ -1224,21 +1285,24 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) } return -1; } -void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nChoice, int fUseXor, int fDebug, int fVerbose ) +void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose ) { int Res; - Gia_ResbInit( p, vDivs, nWords, nLimit, nChoice, fUseXor, fDebug, fVerbose ); + Gia_ResbInit( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, fVerbose ); Res = Gia_ManResubPerform_rec( p, nLimit ); - if ( Res >= 0 ) - Vec_IntPush( p->vGates, Res ); + if ( Res >= 0 ) Vec_IntPush( p->vGates, Res ); + if ( fVerbose ) + printf( "\n" ); } -Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc ) +Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc ) { Vec_Int_t * vRes; Gia_ResbMan_t * p = Gia_ResbAlloc( nWords ); - Gia_ManResubPerform( p, vDivs, nWords, nLimit, nChoice, fUseXor, fDebug, 0 ); + Gia_ManResubPerform( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose ); if ( fVerbose ) Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); + if ( fVerbose ) + printf( "\n" ); if ( !Gia_ManResubVerify(p, pFunc) ) { Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); @@ -1275,15 +1339,20 @@ void Abc_ResubPrepareManager( int nWords ) s_pResbMan = Gia_ResbAlloc( nWords ); } -int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray ) +int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray ) { Vec_Ptr_t Divs = { nDivs, nDivs, ppDivs }; assert( s_pResbMan != NULL ); // first call Abc_ResubPrepareManager() - Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, nChoice, fUseXor, fDebug, 0 ); + Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose==2 ); if ( fVerbose ) { - Gia_ManResubPrint( s_pResbMan->vGates, nDivs ); - printf( "\n" ); + int nGates = Vec_IntSize(s_pResbMan->vGates)/2; + if ( nGates ) + { + printf( " Gain = %2d Gates = %2d __________ F = ", nLimit+1-nGates, nGates ); + Gia_ManResubPrint( s_pResbMan->vGates, nDivs ); + printf( "\n" ); + } } if ( fDebug ) { @@ -1308,7 +1377,7 @@ void Abc_ResubDumpProblem( char * pFileName, void ** ppDivs, int nDivs, int nWor for ( d = 0; d < nDivs; d++ ) for ( w = 0; w < nWords; w++ ) Vec_WrdPush( vSims, pDivs[d][w] ); - Gia_ManSimPatWrite( pFileName, vSims, nWords ); + Vec_WrdDumpHex( pFileName, vSims, nWords, 1 ); Vec_WrdFree( vSims ); } @@ -1355,7 +1424,7 @@ void Gia_ManResubTest3() printf( " " ); //Abc_ResubDumpProblem( "temp.resub", (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1 ); - ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1, 4, 0, 0, 1, fVerbose, &pArray ); + ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), 1, 4, 50, 0, 0, 1, fVerbose, &pArray ); if ( !fVerbose ) printf( "\n" ); @@ -1394,7 +1463,7 @@ void Gia_ManResubTest3_() printf( " " ); Dau_DsdPrintFromTruth2( &Truth, 6 ); printf( " " ); - Gia_ManResubPerform( p, vDivs, 1, 100, 0, 1, 1, 0 ); + Gia_ManResubPerform( p, vDivs, 1, 100, 0, 50, 1, 1, 0 ); } Gia_ResbFree( p ); Vec_IntFree( vRes ); @@ -1416,14 +1485,14 @@ void Gia_ManCheckResub( Vec_Ptr_t * vDivs, int nWords ) { //int i, nVars = 6, pVarSet[10] = { 2, 189, 2127, 2125, 177, 178 }; int i, nVars = 3, pVarSet[10] = { 2, 3, 4 }; - word * pOffSet = (word *)Vec_PtrEntry( vDivs, 0 ); - word * pOnSet = (word *)Vec_PtrEntry( vDivs, 1 ); + word * pOff = (word *)Vec_PtrEntry( vDivs, 0 ); + word * pOn = (word *)Vec_PtrEntry( vDivs, 1 ); Vec_Int_t * vValue = Vec_IntStartFull( 1 << 6 ); printf( "Verifying resub:\n" ); for ( i = 0; i < 64*nWords; i++ ) { - int v, Mint = 0, Value = Abc_TtGetBit(pOnSet, i); - if ( !Abc_TtGetBit(pOffSet, i) && !Value ) + int v, Mint = 0, Value = Abc_TtGetBit(pOn, i); + if ( !Abc_TtGetBit(pOff, i) && !Value ) continue; for ( v = 0; v < nVars; v++ ) if ( Abc_TtGetBit((word *)Vec_PtrEntry(vDivs, pVarSet[v]), i) ) @@ -1444,15 +1513,15 @@ Vec_Ptr_t * Gia_ManDeriveDivs( Vec_Wrd_t * vSims, int nWords ) Vec_PtrPush( vDivs, Vec_WrdEntryP(vSims, nWords*i) ); return vDivs; } -Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, int nChoice, int fUseXor, int fVerbose, int fVeryVerbose ) +Gia_Man_t * Gia_ManResub2( Gia_Man_t * pGia, int nNodes, int nSupp, int nDivs, int iChoice, int fUseXor, int fVerbose, int fVeryVerbose ) { return NULL; } -Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int nChoice, int fUseXor, int fVerbose, int fVeryVerbose ) +Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, int iChoice, int fUseXor, int fVerbose, int fVeryVerbose ) { int nWords = 0; Gia_Man_t * pMan = NULL; - Vec_Wrd_t * vSims = Gia_ManSimPatRead( pFileName, &nWords ); + Vec_Wrd_t * vSims = Vec_WrdReadHex( pFileName, &nWords, 1 ); Vec_Ptr_t * vDivs = vSims ? Gia_ManDeriveDivs( vSims, nWords ) : NULL; Gia_ResbMan_t * p = Gia_ResbAlloc( nWords ); //Gia_ManCheckResub( vDivs, nWords ); @@ -1462,7 +1531,7 @@ Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, i Vec_PtrShrink( vDivs, (1<<14)-1 ); } assert( Vec_PtrSize(vDivs) < (1<<14) ); - Gia_ManResubPerform( p, vDivs, nWords, 100, nChoice, fUseXor, 1, 1 ); + Gia_ManResubPerform( p, vDivs, nWords, 100, 50, iChoice, fUseXor, 1, 1 ); if ( Vec_IntSize(p->vGates) ) { Vec_Wec_t * vGates = Vec_WecStart(1); @@ -1478,6 +1547,135 @@ Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, i return pMan; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManUnivTfo_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes, Vec_Int_t * vPos ) +{ + int i, iFan, Count = 1; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 0; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( vNodes && Gia_ObjIsCo(Gia_ManObj(p, iObj)) ) + Vec_IntPush( vNodes, iObj ); + if ( vPos && Gia_ObjIsCo(Gia_ManObj(p, iObj)) ) + Vec_IntPush( vPos, iObj ); + Gia_ObjForEachFanoutStaticId( p, iObj, iFan, i ) + Count += Gia_ManUnivTfo_rec( p, iFan, vNodes, vPos ); + return Count; +} +int Gia_ManUnivTfo( Gia_Man_t * p, int * pObjs, int nObjs, Vec_Int_t ** pvNodes, Vec_Int_t ** pvPos ) +{ + int i, Count = 0; + if ( pvNodes ) + { + if ( *pvNodes ) + Vec_IntClear( *pvNodes ); + else + *pvNodes = Vec_IntAlloc( 100 ); + } + if ( pvPos ) + { + if ( *pvPos ) + Vec_IntClear( *pvPos ); + else + *pvPos = Vec_IntAlloc( 100 ); + } + Gia_ManIncrementTravId( p ); + for ( i = 0; i < nObjs; i++ ) + Count += Gia_ManUnivTfo_rec( p, pObjs[i], pvNodes ? *pvNodes : NULL, pvPos ? *pvPos : NULL ); + if ( pvNodes ) + Vec_IntSort( *pvNodes, 0 ); + if ( pvPos ) + Vec_IntSort( *pvPos, 0 ); + return Count; +} + +/**Function************************************************************* + + Synopsis [Tuning resub.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTryResub( Gia_Man_t * p ) +{ + int nLimit = 20; + int nDivsMax = 200; + int iChoice = 0; + int fUseXor = 1; + int fDebug = 1; + int fVerbose = 0; + abctime clk, clkResub = 0, clkStart = Abc_Clock(); + Vec_Ptr_t * vvSims = Vec_PtrAlloc( 100 ); + Vec_Wrd_t * vSims; + word * pSets[2], * pFunc; + Gia_Obj_t * pObj, * pObj2; + int i, i2, nWords, nNonDec = 0, nTotal = 0; + assert( Gia_ManCiNum(p) < 16 ); + Vec_WrdFreeP( &p->vSimsPi ); + p->vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) ); + nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p); + //Vec_WrdPrintHex( p->vSimsPi, nWords ); + pSets[0] = ABC_CALLOC( word, nWords ); + pSets[1] = ABC_CALLOC( word, nWords ); + vSims = Gia_ManSimPatSim( p ); + Gia_ManLevelNum(p); + Gia_ManCreateRefs(p); + Abc_ResubPrepareManager( nWords ); + Gia_ManStaticFanoutStart( p ); + Gia_ManForEachAnd( p, pObj, i ) + { + Vec_Int_t vGates; + int * pArray, nArray, nTfo, iObj = Gia_ObjId(p, pObj); + int Level = Gia_ObjLevel(p, pObj); + int nMffc = Gia_NodeMffcSizeMark(p, pObj); + pFunc = Vec_WrdEntryP( vSims, nWords*iObj ); + Abc_TtCopy( pSets[0], pFunc, nWords, 1 ); + Abc_TtCopy( pSets[1], pFunc, nWords, 0 ); + Vec_PtrClear( vvSims ); + Vec_PtrPushTwo( vvSims, pSets[0], pSets[1] ); + nTfo = Gia_ManUnivTfo( p, &iObj, 1, NULL, NULL ); + Gia_ManForEachCi( p, pObj2, i2 ) + Vec_PtrPush( vvSims, Vec_WrdEntryP(vSims, nWords*Gia_ObjId(p, pObj2)) ); + Gia_ManForEachAnd( p, pObj2, i2 ) + if ( !Gia_ObjIsTravIdCurrent(p, pObj2) && !Gia_ObjIsTravIdPrevious(p, pObj2) && Gia_ObjLevel(p, pObj2) <= Level ) + Vec_PtrPush( vvSims, Vec_WrdEntryP(vSims, nWords*Gia_ObjId(p, pObj2)) ); + if ( fVerbose ) + printf( "%3d : Lev = %2d Mffc = %2d Divs = %3d Tfo = %3d\n", iObj, Level, nMffc, Vec_PtrSize(vvSims)-2, nTfo ); + clk = Abc_Clock(); + nArray = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vvSims), Vec_PtrSize(vvSims), nWords, Abc_MinInt(nMffc-1, nLimit), nDivsMax, iChoice, fUseXor, fDebug, fVerbose, &pArray ); + clkResub += Abc_Clock() - clk; + vGates.nSize = vGates.nCap = nArray; + vGates.pArray = pArray; + assert( nMffc > Vec_IntSize(&vGates)/2 ); + if ( Vec_IntSize(&vGates) > 0 ) + nTotal += nMffc - Vec_IntSize(&vGates)/2; + nNonDec += Vec_IntSize(&vGates) == 0; + } + printf( "Total nodes = %5d. Non-realizable = %5d. Gain = %6d. ", Gia_ManAndNum(p), nNonDec, nTotal ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ); + Abc_PrintTime( 1, "Pure resub time", clkResub ); + Abc_ResubPrepareManager( 0 ); + Gia_ManStaticFanoutStop( p ); + Vec_PtrFree( vvSims ); + Vec_WrdFree( vSims ); + ABC_FREE( pSets[0] ); + ABC_FREE( pSets[1] ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index f9539faf..00581de8 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -306,89 +306,6 @@ Gia_Man_t * Gia_ManSimPatGenMiter( Gia_Man_t * p, Vec_Wrd_t * vSims ) } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManSimPatWriteOne( FILE * pFile, word * pSim, int nWords ) -{ - int k, Digit, nDigits = nWords*16; - for ( k = 0; k < nDigits; k++ ) - { - Digit = (int)((pSim[k/16] >> ((k%16) * 4)) & 15); - if ( Digit < 10 ) - fprintf( pFile, "%d", Digit ); - else - fprintf( pFile, "%c", 'A' + Digit-10 ); - } - fprintf( pFile, "\n" ); -} -void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ) -{ - int i, nNodes = Vec_WrdSize(vSimsIn) / nWords; - FILE * pFile = fopen( pFileName, "wb" ); - if ( pFile == NULL ) - { - printf( "Cannot open file \"%s\" for writing.\n", pFileName ); - return; - } - assert( Vec_WrdSize(vSimsIn) % nWords == 0 ); - for ( i = 0; i < nNodes; i++ ) - Gia_ManSimPatWriteOne( pFile, Vec_WrdEntryP(vSimsIn, i*nWords), nWords ); - fclose( pFile ); - printf( "Written %d words of simulation data for %d objects into file \"%s\".\n", nWords, Vec_WrdSize(vSimsIn)/nWords, pFileName ); -} -int Gia_ManSimPatReadOne( char c ) -{ - int Digit = 0; - if ( c >= '0' && c <= '9' ) - Digit = c - '0'; - else if ( c >= 'A' && c <= 'F' ) - Digit = c - 'A' + 10; - else if ( c >= 'a' && c <= 'f' ) - Digit = c - 'a' + 10; - else assert( 0 ); - assert( Digit >= 0 && Digit < 16 ); - return Digit; -} -Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName, int * pnWords ) -{ - Vec_Wrd_t * vSimsIn = NULL; - int c, nWords = -1, nChars = 0; word Num = 0; - FILE * pFile = fopen( pFileName, "rb" ); - if ( pFile == NULL ) - { - printf( "Cannot open file \"%s\" for reading.\n", pFileName ); - return NULL; - } - vSimsIn = Vec_WrdAlloc( 1000 ); - while ( (c = fgetc(pFile)) != EOF ) - { - if ( c == '\n' && nWords == -1 ) - nWords = Vec_WrdSize(vSimsIn); - if ( c == '\n' || c == '\r' || c == '\t' || c == ' ' ) - continue; - Num |= (word)Gia_ManSimPatReadOne((char)c) << (nChars * 4); - if ( ++nChars < 16 ) - continue; - Vec_WrdPush( vSimsIn, Num ); - nChars = 0; - Num = 0; - } - assert( Vec_WrdSize(vSimsIn) % nWords == 0 ); - fclose( pFile ); - printf( "Read %d words of simulation data for %d objects.\n", nWords, Vec_WrdSize(vSimsIn)/nWords ); - if ( pnWords ) - *pnWords = nWords; - return vSimsIn; -} /**Function************************************************************* diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 5ee20e6a..007faeca 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -1101,19 +1101,20 @@ int Gia_NodeDeref_rec( Gia_Man_t * p, Gia_Obj_t * pNode ) SeeAlso [] ***********************************************************************/ -int Gia_NodeRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode ) +int Gia_NodeRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode, int fMark ) { Gia_Obj_t * pFanin; int Counter = 0; if ( Gia_ObjIsCi(pNode) ) return 0; assert( Gia_ObjIsAnd(pNode) ); + if ( fMark ) Gia_ObjSetTravIdCurrent(p, pNode); pFanin = Gia_ObjFanin0(pNode); if ( Gia_ObjRefInc(p, pFanin) == 0 ) - Counter += Gia_NodeRef_rec( p, pFanin ); + Counter += Gia_NodeRef_rec( p, pFanin, fMark ); pFanin = Gia_ObjFanin1(pNode); if ( Gia_ObjRefInc(p, pFanin) == 0 ) - Counter += Gia_NodeRef_rec( p, pFanin ); + Counter += Gia_NodeRef_rec( p, pFanin, fMark ); return Counter + 1; } @@ -1152,7 +1153,19 @@ int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode ) assert( !Gia_IsComplement(pNode) ); assert( Gia_ObjIsCand(pNode) ); ConeSize1 = Gia_NodeDeref_rec( p, pNode ); - ConeSize2 = Gia_NodeRef_rec( p, pNode ); + ConeSize2 = Gia_NodeRef_rec( p, pNode, 0 ); + assert( ConeSize1 == ConeSize2 ); + assert( ConeSize1 >= 0 ); + return ConeSize1; +} +int Gia_NodeMffcSizeMark( Gia_Man_t * p, Gia_Obj_t * pNode ) +{ + int ConeSize1, ConeSize2; + assert( !Gia_IsComplement(pNode) ); + assert( Gia_ObjIsCand(pNode) ); + ConeSize1 = Gia_NodeDeref_rec( p, pNode ); + Gia_ManIncrementTravId( p ); + ConeSize2 = Gia_NodeRef_rec( p, pNode, 1 ); assert( ConeSize1 == ConeSize2 ); assert( ConeSize1 >= 0 ); return ConeSize1; @@ -1193,7 +1206,7 @@ int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp ) ConeSize1 = Gia_NodeDeref_rec( p, pNode ); Gia_NodeCollect_rec( p, Gia_ObjFanin0(pNode), vSupp ); Gia_NodeCollect_rec( p, Gia_ObjFanin1(pNode), vSupp ); - ConeSize2 = Gia_NodeRef_rec( p, pNode ); + ConeSize2 = Gia_NodeRef_rec( p, pNode, 0 ); assert( ConeSize1 == ConeSize2 ); assert( ConeSize1 >= 0 ); return ConeSize1; -- cgit v1.2.3 From 491e4ebfd1fd0a484ce45ecb4baf21c9ae8ccb08 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 3 Jun 2020 14:52:42 -0700 Subject: Experimental simulation. --- src/aig/gia/giaSimBase.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 00581de8..3154f018 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -128,6 +128,67 @@ Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia ) return vSims; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimPatAssignInputs2( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsIn ) +{ + int i, Id; + assert( Vec_WrdSize(vSims) == 2 * nWords * Gia_ManObjNum(p) ); + assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) ); + Gia_ManForEachCiId( p, Id, i ) + { + Abc_TtCopy( Vec_WrdEntryP(vSims, 2*Id*nWords+0), Vec_WrdEntryP(vSimsIn, i*nWords), nWords, 0 ); + Abc_TtCopy( Vec_WrdEntryP(vSims, 2*Id*nWords+1), Vec_WrdEntryP(vSimsIn, i*nWords), nWords, 1 ); + } +} +static inline void Gia_ManSimPatSimAnd2( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims ) +{ + word * pSims = Vec_WrdArray(vSims); + word * pSims0 = pSims + nWords*Gia_ObjFaninLit0(pObj, i); + word * pSims1 = pSims + nWords*Gia_ObjFaninLit1(pObj, i); + word * pSims2 = pSims + nWords*(2*i+0); + word * pSims3 = pSims + nWords*(2*i+1); int w; +// if ( Gia_ObjIsXor(pObj) ) +// for ( w = 0; w < nWords; w++ ) +// pSims2[w] = pSims0[w] ^ pSims1[w]; +// else + for ( w = 0; w < nWords; w++ ) + { + pSims2[w] = pSims0[w] & pSims1[w]; + pSims3[w] = ~pSims2[w]; + } +} +static inline void Gia_ManSimPatSimPo2( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims ) +{ + word * pSims = Vec_WrdArray(vSims); + word * pSims0 = pSims + nWords*Gia_ObjFaninLit0(pObj, i); + word * pSims2 = pSims + nWords*i; int w; + for ( w = 0; w < nWords; w++ ) + pSims2[w] = pSims0[w]; +} +Vec_Wrd_t * Gia_ManSimPatSim2( Gia_Man_t * pGia ) +{ + Gia_Obj_t * pObj; + int i, nWords = Vec_WrdSize(pGia->vSimsPi) / Gia_ManCiNum(pGia); + Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords * 2 ); + assert( Vec_WrdSize(pGia->vSimsPi) % Gia_ManCiNum(pGia) == 0 ); + Gia_ManSimPatAssignInputs2( pGia, nWords, vSims, pGia->vSimsPi ); + Gia_ManForEachAnd( pGia, pObj, i ) + Gia_ManSimPatSimAnd2( pGia, i, pObj, nWords, vSims ); + Gia_ManForEachCo( pGia, pObj, i ) + Gia_ManSimPatSimPo2( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); + return vSims; +} + /**Function************************************************************* Synopsis [] @@ -1948,6 +2009,44 @@ void Gia_ManPatRareImprove( Gia_Man_t * p, int RareLimit, int fVerbose ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } +/**Function************************************************************* + + Synopsis [Improving quality of simulation patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimTest( Gia_Man_t * pGia ) +{ + int n, nWords = 8; + Vec_Wrd_t * vSim1, * vSim2; + Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords ); + abctime clk = Abc_Clock(); + + pGia->vSimsPi = vSim0; + for ( n = 0; n < 10; n++ ) + { + vSim1 = Gia_ManSimPatSim( pGia ); + Vec_WrdFree( vSim1 ); + } + Abc_PrintTime( 1, "Time1", Abc_Clock() - clk ); + + clk = Abc_Clock(); + for ( n = 0; n < 10; n++ ) + { + vSim2 = Gia_ManSimPatSim2( pGia ); + Vec_WrdFree( vSim2 ); + } + Abc_PrintTime( 1, "Time2", Abc_Clock() - clk ); + + pGia->vSimsPi = NULL; + Vec_WrdFree( vSim0 ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From a3c6f33a87c3bbee5f0ebb61907d0416ae5bc661 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 4 Jun 2020 16:24:43 -0700 Subject: Experimental simulation. --- src/aig/gia/giaSimBase.c | 81 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 9 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 3154f018..efa4c187 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -21,6 +21,7 @@ #include "gia.h" #include "misc/util/utilTruth.h" #include "misc/extra/extra.h" +//#include ABC_NAMESPACE_IMPL_START @@ -157,15 +158,17 @@ static inline void Gia_ManSimPatSimAnd2( Gia_Man_t * p, int i, Gia_Obj_t * pObj, word * pSims1 = pSims + nWords*Gia_ObjFaninLit1(pObj, i); word * pSims2 = pSims + nWords*(2*i+0); word * pSims3 = pSims + nWords*(2*i+1); int w; + assert( !Gia_ObjIsXor(pObj) ); // if ( Gia_ObjIsXor(pObj) ) // for ( w = 0; w < nWords; w++ ) // pSims2[w] = pSims0[w] ^ pSims1[w]; // else - for ( w = 0; w < nWords; w++ ) - { - pSims2[w] = pSims0[w] & pSims1[w]; - pSims3[w] = ~pSims2[w]; - } + for ( w = 0; w < nWords; w++ ) + { + pSims2[w] = pSims0[w] & pSims1[w]; + pSims3[w] = ~pSims2[w]; + } + //_mm256_storeu_ps( (float *)pSims2, _mm256_and_ps(_mm256_loadu_ps((float *)pSims0), _mm256_loadu_ps((float *)pSims1)) ); } static inline void Gia_ManSimPatSimPo2( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims ) { @@ -2011,7 +2014,7 @@ void Gia_ManPatRareImprove( Gia_Man_t * p, int RareLimit, int fVerbose ) /**Function************************************************************* - Synopsis [Improving quality of simulation patterns.] + Synopsis [Trying vectorized simulation.] Description [] @@ -2022,13 +2025,13 @@ void Gia_ManPatRareImprove( Gia_Man_t * p, int RareLimit, int fVerbose ) ***********************************************************************/ void Gia_ManSimTest( Gia_Man_t * pGia ) { - int n, nWords = 8; + int n, nWords = 4; Vec_Wrd_t * vSim1, * vSim2; Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords ); abctime clk = Abc_Clock(); pGia->vSimsPi = vSim0; - for ( n = 0; n < 10; n++ ) + for ( n = 0; n < 20; n++ ) { vSim1 = Gia_ManSimPatSim( pGia ); Vec_WrdFree( vSim1 ); @@ -2036,7 +2039,7 @@ void Gia_ManSimTest( Gia_Man_t * pGia ) Abc_PrintTime( 1, "Time1", Abc_Clock() - clk ); clk = Abc_Clock(); - for ( n = 0; n < 10; n++ ) + for ( n = 0; n < 20; n++ ) { vSim2 = Gia_ManSimPatSim2( pGia ); Vec_WrdFree( vSim2 ); @@ -2047,6 +2050,66 @@ void Gia_ManSimTest( Gia_Man_t * pGia ) Vec_WrdFree( vSim0 ); } +/**Function************************************************************* + + Synopsis [Trying compiled simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimGen( Gia_Man_t * pGia ) +{ + int nWords = 4; + Gia_Obj_t * pObj; + Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords ); + FILE * pFile = fopen( "comp_sim.c", "wb" ); + int i, k, Id; + fprintf( pFile, "#include \n" ); + fprintf( pFile, "#include \n" ); + fprintf( pFile, "#include \n" ); + fprintf( pFile, "int main()\n" ); + fprintf( pFile, "{\n" ); + fprintf( pFile, " clock_t clkThis = clock();\n" ); + fprintf( pFile, " unsigned long Res = 0;\n" ); + fprintf( pFile, " int i;\n" ); + fprintf( pFile, " srand(time(NULL));\n" ); + fprintf( pFile, " for ( i = 0; i < 2000; i++ )\n" ); + fprintf( pFile, " {\n" ); + for ( k = 0; k < nWords; k++ ) + fprintf( pFile, " unsigned long s%07d_%d = 0x%08x%08x;\n", 0, k, 0, 0 ); + Gia_ManForEachCiId( pGia, Id, i ) + { + word * pSim = Vec_WrdEntryP(vSim0, i*nWords); + unsigned * pSimU = (unsigned *)pSim; + for ( k = 0; k < nWords; k++ ) + fprintf( pFile, " unsigned long s%07d_%d = ((unsigned long)rand() << 48) | ((unsigned long)rand() << 32) | ((unsigned long)rand() << 16) | (unsigned long)rand();\n", Id, k ); + } + Gia_ManForEachAnd( pGia, pObj, Id ) + { + for ( k = 0; k < nWords; k++ ) + fprintf( pFile, " unsigned long s%07d_%d = %cs%07d_%d & %cs%07d_%d;\n", Id, k, + Gia_ObjFaninC0(pObj) ? '~' : ' ', Gia_ObjFaninId0(pObj, Id), k, + Gia_ObjFaninC1(pObj) ? ' ' : '~', Gia_ObjFaninId1(pObj, Id), k ); + } + Gia_ManForEachCoId( pGia, Id, i ) + { + pObj = Gia_ManObj(pGia, Id); + for ( k = 0; k < nWords; k++ ) + fprintf( pFile, " Res ^= %cs%07d_%d;\n", Gia_ObjFaninC0(pObj) ? '~' : ' ', Gia_ObjFaninId0(pObj, Id), k ); + } + Vec_WrdFree( vSim0 ); + fprintf( pFile, " }\n" ); + fprintf( pFile, " printf( \"Res = 0x%%08x \", (unsigned)Res );\n" ); + fprintf( pFile, " printf( \"Time = %%6.2f sec\\n\", (float)(clock() - clkThis)/CLOCKS_PER_SEC );\n" ); + fprintf( pFile, " return 1;\n" ); + fprintf( pFile, "}\n" ); + fclose( pFile ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 0b734d10e0ecf498865f5ff5f900c0a3bb5ece32 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Jul 2020 10:56:59 -0700 Subject: Adding new resub code. --- src/aig/gia/giaResub2.c | 579 ++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 1 + 2 files changed, 580 insertions(+) create mode 100644 src/aig/gia/giaResub2.c (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c new file mode 100644 index 00000000..c051c465 --- /dev/null +++ b/src/aig/gia/giaResub2.c @@ -0,0 +1,579 @@ +/**CFile**************************************************************** + + FileName [giaResub2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaResub2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gia_Rsb2Man_t_ Gia_Rsb2Man_t; +struct Gia_Rsb2Man_t_ +{ + // hyper-parameters + int nDivsMax; + int nLevelIncrease; + int fUseXor; + int fUseZeroCost; + int fDebug; + int fVerbose; + // input AIG + int nObjs; + int nPis; + int nNodes; + int nPos; + int iFirstPo; + int Level; + int nMffc; + // intermediate data + Vec_Int_t vObjs; + Vec_Wrd_t vSims; + Vec_Ptr_t vpDivs; + Vec_Int_t vDivs; + Vec_Int_t vLevels; + Vec_Int_t vRefs; + Vec_Int_t vCopies; + word Truth0; + word Truth1; + word CareSet; +}; + +extern int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray ) +{ + *ppArray = NULL; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManToResub( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int * pObjs = ABC_CALLOC( int, 2*Gia_ManObjNum(p) ); + int i, iFirstPo = 1 + Gia_ManCiNum(p) + Gia_ManAndNum(p); + assert( Gia_ManIsNormalized(p) ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + continue; + pObjs[2*i+0] = Gia_ObjFaninLit0(Gia_ManObj(p, i), i); + if ( Gia_ObjIsCo(pObj) ) + pObjs[2*i+1] = pObjs[2*i+0]; + else if ( Gia_ObjIsAnd(pObj) ) + pObjs[2*i+1] = Gia_ObjFaninLit1(Gia_ManObj(p, i), i); + else assert( 0 ); + } + return pObjs; +} +Gia_Man_t * Gia_ManFromResub( int * pObjs, int nObjs ) +{ + int i; + Gia_Man_t * pNew = Gia_ManStart( nObjs ); + for ( i = 1; i < nObjs; i++ ) + { + if ( pObjs[2*i] == 0 ) // pi + Gia_ManAppendCi( pNew ); + else if ( pObjs[2*i] == pObjs[2*i+1] ) // po + Gia_ManAppendCo( pNew, pObjs[2*i] ); + else if ( pObjs[2*i] < pObjs[2*i+1] ) + Gia_ManAppendAnd( pNew, pObjs[2*i], pObjs[2*i+1] ); + else if ( pObjs[2*i] > pObjs[2*i+1] ) + Gia_ManAppendXor( pNew, pObjs[2*i], pObjs[2*i+1] ); + else assert( 0 ); + } + return pNew; +} +Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p ) +{ + int * pObjsNew, * pObjs = Gia_ManToResub( p ); + int nObjsNew = Abc_ResubComputeWindow( pObjs, Gia_ManObjNum(p), 1000, 0, 0, 0, 0, 0, &pObjsNew ); + Gia_Man_t * pNew = Gia_ManFromResub( pObjsNew, nObjsNew ); + ABC_FREE( pObjs ); + ABC_FREE( pObjsNew ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Rsb2Man_t * Gia_Rsb2ManAlloc() +{ + Gia_Rsb2Man_t * p = ABC_CALLOC( Gia_Rsb2Man_t, 1 ); + return p; +} +void Gia_Rsb2ManFree( Gia_Rsb2Man_t * p ) +{ + Vec_IntErase( &p->vObjs ); + Vec_WrdErase( &p->vSims ); + Vec_PtrErase( &p->vpDivs ); + Vec_IntErase( &p->vDivs ); + Vec_IntErase( &p->vLevels ); + Vec_IntErase( &p->vRefs ); + Vec_IntErase( &p->vCopies ); + ABC_FREE( p ); +} +int Gia_Rsb2ManLevel( Gia_Rsb2Man_t * p ) +{ + int i, * pLevs, Level = 0; + Vec_IntClear( &p->vLevels ); + Vec_IntGrow( &p->vLevels, p->nObjs ); + pLevs = Vec_IntArray( &p->vLevels ); + for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) + pLevs[i] = 1 + Abc_MaxInt( pLevs[2*i+0]/2, pLevs[2*i+1]/2 ); + for ( i = p->iFirstPo; i < p->nObjs; i++ ) + Level = Abc_MaxInt( Level, pLevs[i] = pLevs[2*i+0]/2 ); + return Level; +} +void Gia_Rsb2ManStart( Gia_Rsb2Man_t * p, int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose ) +{ + int i; + // hyper-parameters + p->nDivsMax = nDivsMax; + p->nLevelIncrease = nLevelIncrease; + p->fUseXor = fUseXor; + p->fUseZeroCost = fUseZeroCost; + p->fDebug = fDebug; + p->fVerbose = fVerbose; + // user data + Vec_IntClear( &p->vObjs ); + Vec_IntPushArray( &p->vObjs, pObjs, nObjs ); + assert( pObjs[0] == 0 ); + assert( pObjs[1] == 0 ); + p->nObjs = nObjs; + p->nPis = 0; + p->nNodes = 0; + p->nPos = 0; + p->iFirstPo = 0; + for ( i = 1; i < nObjs; i++ ) + { + if ( pObjs[0] == 0 && pObjs[1] == 0 ) + p->nPis++; + else if ( pObjs[0] == pObjs[1] ) + p->nPos++; + else + p->nNodes++; + } + assert( nObjs == 1 + p->nPis + p->nNodes + p->nPos ); + p->iFirstPo = nObjs - p->nPos; + p->Level = Gia_Rsb2ManLevel(p); + Vec_WrdClear( &p->vSims ); + Vec_WrdGrow( &p->vSims, 2*nObjs ); + Vec_WrdPush( &p->vSims, 0 ); + Vec_WrdPush( &p->vSims, 0 ); + for ( i = 0; i < p->nPis; i++ ) + { + Vec_WrdPush( &p->vSims, s_Truths6[i] ); + Vec_WrdPush( &p->vSims, ~s_Truths6[i] ); + } + Vec_IntClear( &p->vDivs ); + Vec_IntClear( &p->vLevels ); + Vec_IntClear( &p->vRefs ); + Vec_IntClear( &p->vCopies ); + Vec_PtrClear( &p->vpDivs ); + Vec_IntGrow( &p->vDivs, nObjs ); + Vec_IntGrow( &p->vLevels, nObjs ); + Vec_IntGrow( &p->vRefs, nObjs ); + Vec_IntGrow( &p->vCopies, nObjs ); + Vec_PtrGrow( &p->vpDivs, nObjs ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Gia_Rsb2ManOdcs( Gia_Rsb2Man_t * p, int iNode ) +{ + int i; word Res = 0; + int * pObjs = Vec_IntArray( &p->vObjs ); + word * pSims = Vec_WrdArray( &p->vSims ); + for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) + { + if ( pObjs[2*i+0] < pObjs[2*i+1] ) + pSims[2*i+0] = pSims[pObjs[2*i+0]] & pSims[pObjs[2*i+1]]; + else + pSims[2*i+0] = pSims[pObjs[2*i+0]] ^ pSims[pObjs[2*i+1]]; + pSims[2*i+1] = ~pSims[2*i+0]; + } + for ( i = p->iFirstPo; i < p->nObjs; i++ ) + pSims[2*i+0] = pSims[pObjs[2*i+0]]; + ABC_SWAP( word, pSims[2*iNode+0], pSims[2*iNode+1] ); + for ( i = iNode + 1; i < p->iFirstPo; i++ ) + { + if ( pObjs[2*i+0] < pObjs[2*i+1] ) + pSims[2*i+0] = pSims[pObjs[2*i+0]] & pSims[pObjs[2*i+1]]; + else + pSims[2*i+0] = pSims[pObjs[2*i+0]] ^ pSims[pObjs[2*i+1]]; + pSims[2*i+1] = ~pSims[2*i+0]; + } + for ( i = p->iFirstPo; i < p->nObjs; i++ ) + Res |= pSims[2*i+0] ^ pSims[pObjs[2*i+0]]; + return Res; +} +// marks MFFC and returns its size +int Gia_Rsb2ManMffc( Gia_Rsb2Man_t * p, int iNode ) +{ + int i, * pRefs, * pObjs, nMffc = 0; + Vec_IntFill( &p->vRefs, p->nObjs, 0 ); + pRefs = Vec_IntArray( &p->vRefs ); + pObjs = Vec_IntArray( &p->vObjs ); + for ( i = p->nObjs - 1; i >= p->iFirstPo; i-- ) + pRefs[pObjs[2*i+0]] = 1; + for ( i = p->iFirstPo - 1; i > p->nPis; i-- ) + if ( i != iNode && pRefs[i] ) + pRefs[pObjs[2*i+0]] = pRefs[pObjs[2*i+1]] = 1; + for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) + nMffc += !pRefs[i]; + return nMffc; +} +// collects divisors and maps them into nodes +// assumes MFFC is already marked +int Gia_Rsb2ManDivs( Gia_Rsb2Man_t * p, int iNode ) +{ + int i; + int * pRefs = Vec_IntArray( &p->vRefs ); + int * pObjs = Vec_IntArray( &p->vObjs ); + p->CareSet = Gia_Rsb2ManOdcs( p, iNode ); + p->Truth1 = p->CareSet & Vec_WrdEntry(&p->vSims, iNode); + p->Truth0 = p->CareSet & ~p->Truth1; + Vec_PtrClear( &p->vpDivs ); + Vec_PtrPush( &p->vpDivs, &p->Truth0 ); + Vec_PtrPush( &p->vpDivs, &p->Truth1 ); + Vec_IntClear( &p->vDivs ); + Vec_IntPushTwo( &p->vDivs, -1, -1 ); + for ( i = 1; i <= p->nPis; i++ ) + { + Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, i) ); + Vec_IntPush( &p->vDivs, i ); + } + p->nMffc = Gia_Rsb2ManMffc( p, iNode ); + assert( pRefs[iNode] == 1 ); + pRefs[iNode] = 0; + for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) + { + if ( i > iNode ) + pRefs[i] = pRefs[pObjs[2*i+0]] && pRefs[pObjs[2*i+1]]; + if ( !pRefs[i] ) + continue; + Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, i) ); + Vec_IntPush( &p->vDivs, i ); + } + assert( Vec_IntSize(&p->vDivs) == Vec_PtrSize(&p->vpDivs) ); + return Vec_IntSize(&p->vDivs); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_Rsb2AddNode( Vec_Int_t * vRes, int iLit0, int iLit1, int iRes0, int iRes1 ) +{ + int iLitMin = iRes0 < iRes1 ? Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)) : Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)); + int iLitMax = iRes0 < iRes1 ? Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) : Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)); + int iLitRes = Vec_IntSize(vRes); + if ( iLit0 < iLit1 ) // and + Vec_IntPushTwo( vRes, iLitMin, iLitMax ); + else if ( iLit0 > iLit1 ) // xor + { + assert( !Abc_LitIsCompl(iLit0) ); + assert( !Abc_LitIsCompl(iLit1) ); + Vec_IntPushTwo( vRes, iLitMax, iLitMin ); + } + else assert( 0 ); + return iLitRes; +} +int Gia_Rsb2ManInsert_rec( Vec_Int_t * vRes, int nPis, Vec_Int_t * vObjs, int iNode, Vec_Int_t * vResub, Vec_Int_t * vDivs, Vec_Int_t * vCopies, int iObj ) +{ + if ( Vec_IntEntry(vCopies, iObj) >= 0 ) + return Vec_IntEntry(vCopies, iObj); + assert( iObj > nPis ); + if ( iObj == iNode ) + { + int nVars = Vec_IntSize(vDivs); + int iLitRes, iTopLit = Vec_IntEntryLast( vResub ); + if ( Abc_Lit2Var(iTopLit) == 0 ) + iLitRes = 0; + else if ( Abc_Lit2Var(iTopLit) < nVars ) + iLitRes = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, -1, vResub, vDivs, vCopies, Vec_IntEntry(vDivs, Abc_Lit2Var(iTopLit)) ); + else + { + Vec_Int_t * vCopy = Vec_IntAlloc( 10 ); + int k, iLit, iLit0, iLit1; + Vec_IntForEachEntryStop( vResub, iLit, k, Vec_IntSize(vResub)-1 ) + if ( Abc_Lit2Var(iLit) < nVars ) + Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, -1, vResub, vDivs, vCopies, Vec_IntEntry(vDivs, Abc_Lit2Var(iLit)) ); + Vec_IntForEachEntryDouble( vResub, iLit0, iLit1, k ) + { + int iVar0 = Abc_Lit2Var(iLit0); + int iVar1 = Abc_Lit2Var(iLit1); + int iRes0 = iVar0 < nVars ? Vec_IntEntry(vCopies, Vec_IntEntry(vDivs, iVar0)) : Vec_IntEntry(vCopy, iVar0 - nVars); + int iRes1 = iVar1 < nVars ? Vec_IntEntry(vCopies, Vec_IntEntry(vDivs, iVar1)) : Vec_IntEntry(vCopy, iVar1 - nVars); + iLitRes = Gia_Rsb2AddNode( vRes, iLit0, iLit1, iRes0, iRes1 ); + Vec_IntPush( vCopy, iLitRes ); + } + Vec_IntFree( vCopy ); + } + iLitRes = Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ); + Vec_IntWriteEntry( vCopies, iObj, iLitRes ); + return iLitRes; + } + else + { + int iLit0 = Vec_IntEntry( vObjs, 2*iObj+0 ); + int iLit1 = Vec_IntEntry( vObjs, 2*iObj+1 ); + int iRes0 = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var(iLit0) ); + int iRes1 = Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var(iLit1) ); + int iLitRes = Gia_Rsb2AddNode( vRes, iLit0, iLit1, iRes0, iRes1 ); + Vec_IntWriteEntry( vCopies, iObj, iLitRes ); + return iLitRes; + } +} +Vec_Int_t * Gia_Rsb2ManInsert( int nPis, int nPos, Vec_Int_t * vObjs, int iNode, Vec_Int_t * vResub, Vec_Int_t * vDivs, Vec_Int_t * vCopies ) +{ + int i, iFirstPo = Vec_IntSize(vObjs) - nPos; + Vec_Int_t * vRes = Vec_IntAlloc( 2*Vec_IntSize(vObjs) ); + Vec_IntFill( vCopies, Vec_IntSize(vObjs), -1 ); + Vec_IntFill( vRes, 2*(nPis + 1), 0 ); + for ( i = 0; i <= nPis; i++ ) + Vec_IntPush( vCopies, 2*i ); + for ( i = 0; i < nPos; i++ ) + Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var(Vec_IntEntry(vObjs, 2*(iFirstPo+1))) ); + for ( i = 0; i < nPos; i++ ) + { + int iLitNew = Abc_Lit2LitL( Vec_IntArray(vCopies), Vec_IntEntry(vObjs, 2*(iFirstPo+1)) ); + Vec_IntPushTwo( vRes, iLitNew, iLitNew ); + } + return vRes; +} + +/**Function************************************************************* + + Synopsis [Creating a window with support composed of primary inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// returns the number of nodes added to the window when is iPivot is added +// the window nodes in vNodes are labeled with the current traversal ID +// the new node iPivot and its fanout are temporarily labeled and then unlabeled +int Gia_WinTryAddingNode( Gia_Man_t * p, int iPivot, Vec_Wec_t * vLevels, Vec_Int_t * vNodes ) +{ + Vec_Int_t * vLevel; + Gia_Obj_t * pObj, * pFanout; + int k, i, f, Count = 0; + // precondition: the levelized structure is empty + assert( Vec_WecSizeSize(vLevels) == 0 ); + // precondition: the new object to be added (iPivot) is not in the window + assert( !Gia_ObjIsTravIdCurrentId(p, iPivot) ); + // add the object to the window and to the levelized structure + Gia_ObjSetTravIdCurrentId( p, iPivot ); + Vec_WecPush( vLevels, Gia_ObjLevelId(p, iPivot), iPivot ); + // iterate through all objects and explore their fanouts + Vec_WecForEachLevel( vLevels, vLevel, k ) + Gia_ManForEachObjVec( vLevel, p, pObj, i ) + if ( Gia_ObjFanoutNum(p, pObj) > 10 ) // do not explore objects with high fanout + Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f ) + if ( Gia_ObjIsAnd(pFanout) && // internal node + !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window + Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are + Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window + { + // add fanout to the window and to the levelized structure + Gia_ObjSetTravIdCurrent( p, pFanout ); + Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) ); + // count the number of nodes in the structure + Count++; + } + // iterate through the nodes in the levelized structure + Vec_WecForEachLevel( vLevels, vLevel, k ) + { + Gia_ManForEachObjVec( vLevel, p, pObj, i ) + if ( vNodes == NULL ) // it was a test run - unmark the node + Gia_ObjSetTravIdPrevious( p, pObj ); + else // it was a real run - permanently add to the node to the window + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); + // clean the levelized structure + Vec_IntClear( vLevel ); + } + // return the number of nodes to be added + return Count; +} +// find the first PI to add based on the fanout count +int Gia_WinAddCiWithMaxFanouts( Gia_Man_t * p ) +{ + int i, Id, nMaxFan = -1, iMaxFan = -1; + Gia_ManForEachCiId( p, Id, i ) + if ( nMaxFan < Gia_ObjFanoutNumId(p, Id) ) + { + nMaxFan = Gia_ObjFanoutNumId(p, Id); + iMaxFan = Id; + } + assert( iMaxFan >= 0 ); + return iMaxFan; +} +// find the next PI to add based on how many nodes will be added to the window +int Gia_WinAddCiWithMaxDivisors( Gia_Man_t * p, Vec_Wec_t * vLevels ) +{ + int i, Id, nCurFan, nMaxFan = -1, iMaxFan = -1; + Gia_ManForEachCiId( p, Id, i ) + { + if ( Gia_ObjIsTravIdCurrentId( p, Id ) ) + continue; + nCurFan = Gia_WinTryAddingNode( p, Id, vLevels, NULL ); + if ( nMaxFan < nCurFan ) + { + nMaxFan = nCurFan; + iMaxFan = Id; + } + } + assert( iMaxFan >= 0 ); + return iMaxFan; +} +// check if the node has unmarked fanouts +int Gia_WinNodeHasUnmarkedFanouts( Gia_Man_t * p, int iPivot ) +{ + int f, iFan; + Gia_ObjForEachFanoutStaticId( p, iPivot, iFan, f ) + if ( !Gia_ObjIsTravIdCurrentId(p, iFan) ) + return 1; + return 0; +} +// this is a translation procedure, which converts the array of node IDs (vObjs) +// into the internal represnetation for the resub engine, which is returned +// (this procedure is not needed when we simply construct a window) +Vec_Int_t * Gia_RsbCiTranslate( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Int_t * vMap ) +{ + int i, iObj, Lit0, Lit1, Fan0, Fan1; + Vec_Int_t * vNodes = Vec_IntAlloc( 100 ); + assert( Vec_IntSize(vMap) == Gia_ManObjNum(p) ); + Vec_IntPushTwo( vNodes, 0, 0 ); // const0 node + Vec_IntForEachEntry( vObjs, iObj, i ) + { + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + assert( Gia_ObjIsTravIdCurrentId(p, iObj) ); + Fan0 = Gia_ObjIsCi(pObj) ? 0 : Vec_IntEntry(vMap, Gia_ObjFaninId0(pObj, iObj)); + Fan1 = Gia_ObjIsCi(pObj) ? 0 : Vec_IntEntry(vMap, Gia_ObjFaninId1(pObj, iObj)); + Lit0 = Gia_ObjIsCi(pObj) ? 0 : Abc_LitNotCond( Fan0, Gia_ObjFaninC0(pObj) ); + Lit1 = Gia_ObjIsCi(pObj) ? 0 : Abc_LitNotCond( Fan1, Gia_ObjFaninC1(pObj) ); + Vec_IntWriteEntry( vMap, iObj, Vec_IntSize(vNodes) ); + Vec_IntPushTwo( vNodes, Lit0, Lit1 ); + } + Vec_IntForEachEntry( vObjs, iObj, i ) + if ( Gia_WinNodeHasUnmarkedFanouts( p, iObj ) ) + Vec_IntPushTwo( vNodes, Vec_IntEntry(vMap, iObj), Vec_IntEntry(vMap, iObj) ); + return vNodes; +} +// construct a high-volume window support by the given number (nPis) of primary inputs +Vec_Int_t * Gia_RsbCiWindow( Gia_Man_t * p, int nPis ) +{ + Vec_Int_t * vRes; int i, iMaxFan; + Vec_Int_t * vNodes = Vec_IntAlloc( 100 ); + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 ); + Gia_ManStaticFanoutStart( p ); + Gia_ManIncrementTravId(p); + // add the first one + iMaxFan = Gia_WinAddCiWithMaxFanouts( p ); + Gia_ObjSetTravIdCurrentId( p, iMaxFan ); + Vec_IntPush( vNodes, iMaxFan ); + // add remaining ones + for ( i = 1; i < nPis; i++ ) + { + iMaxFan = Gia_WinAddCiWithMaxDivisors( p, vLevels ); + Gia_WinTryAddingNode( p, iMaxFan, vLevels, vNodes ); + } + Vec_IntSort( vNodes, 0 ); + vRes = Gia_RsbCiTranslate( p, vNodes, vMap ); + Gia_ManStaticFanoutStop( p ); + Vec_WecFree( vLevels ); + Vec_IntFree( vMap ); +Vec_IntPrint( vNodes ); + Vec_IntFree( vNodes ); + return vRes; +} +void Gia_RsbCiWindowTest( Gia_Man_t * p ) +{ + Vec_Int_t * vWin = Gia_RsbCiWindow( p, 6 ); + //Vec_IntPrint( vWin ); + Vec_IntFree( vWin ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 26909410..e092765f 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -59,6 +59,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaPf.c \ src/aig/gia/giaQbf.c \ src/aig/gia/giaResub.c \ + src/aig/gia/giaResub2.c \ src/aig/gia/giaRetime.c \ src/aig/gia/giaRex.c \ src/aig/gia/giaSatEdge.c \ -- cgit v1.2.3 From ba063a1b557a548cbedd963f6bcdf176df14ee8e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 13 Jul 2020 11:23:11 -0700 Subject: Correctly handling transfer of additional AIG info when AIG has no internal nodes. --- src/aig/gia/giaFx.c | 6 +++++- src/aig/gia/giaScript.c | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaFx.c b/src/aig/gia/giaFx.c index c6eae6c7..032ae5fc 100644 --- a/src/aig/gia/giaFx.c +++ b/src/aig/gia/giaFx.c @@ -460,7 +460,11 @@ Gia_Man_t * Gia_ManPerformFx( Gia_Man_t * p, int nNewNodesMax, int LitCountMax, Vec_Wec_t * vCubes; Vec_Str_t * vCompl; if ( Gia_ManAndNum(p) == 0 ) - return Gia_ManDup(p); + { + pNew = Gia_ManDup(p); + Gia_ManTransferTiming( pNew, p ); + return pNew; + } // abctime clk; assert( Gia_ManHasMapping(p) ); // collect information diff --git a/src/aig/gia/giaScript.c b/src/aig/gia/giaScript.c index 334b1ee9..751f5000 100644 --- a/src/aig/gia/giaScript.c +++ b/src/aig/gia/giaScript.c @@ -88,7 +88,11 @@ Gia_Man_t * Gia_ManAigSyn2( Gia_Man_t * pInit, int fOldAlgo, int fCoarsen, int f p = Gia_ManDup( pInit ); Gia_ManTransferTiming( p, pInit ); if ( Gia_ManAndNum(p) == 0 ) - return p; + { + pNew = Gia_ManDup(p); + Gia_ManTransferTiming( pNew, p ); + return pNew; + } // delay optimization if ( fDelayMin && p->pManTime == NULL ) { @@ -157,7 +161,11 @@ Gia_Man_t * Gia_ManAigSyn3( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) pPars->nRelaxRatio = 40; if ( fVerbose ) Gia_ManPrintStats( p, NULL ); if ( Gia_ManAndNum(p) == 0 ) - return Gia_ManDup(p); + { + pNew = Gia_ManDup(p); + Gia_ManTransferTiming( pNew, p ); + return pNew; + } // perform balancing pNew = Gia_ManAreaBalance( p, 0, ABC_INFINITY, fVeryVerbose, 0 ); if ( fVerbose ) Gia_ManPrintStats( pNew, NULL ); @@ -189,7 +197,11 @@ Gia_Man_t * Gia_ManAigSyn4( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) pPars->nRelaxRatio = 40; if ( fVerbose ) Gia_ManPrintStats( p, NULL ); if ( Gia_ManAndNum(p) == 0 ) - return Gia_ManDup(p); + { + pNew = Gia_ManDup(p); + Gia_ManTransferTiming( pNew, p ); + return pNew; + } //Gia_ManAigPrintPiLevels( p ); // perform balancing pNew = Gia_ManAreaBalance( p, 0, ABC_INFINITY, fVeryVerbose, 0 ); -- cgit v1.2.3 From 22d9b1d38b27a6a4c4f4b3b8f489704eed943351 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Jul 2020 20:33:03 -0700 Subject: Experiment with structural similarity. --- src/aig/gia/gia.h | 3 ++ src/aig/gia/giaDfs.c | 28 ++++++++++++++++ src/aig/gia/giaIso3.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaUtil.c | 22 ++++++++++++ 4 files changed, 145 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 2458b152..7f6bbea6 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -570,6 +570,7 @@ static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) { static inline int Gia_ObjLevelId( Gia_Man_t * p, int Id ) { return Vec_IntGetEntry(p->vLevels, Id); } static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjLevelId( p, Gia_ObjId(p,pObj) ); } +static inline void Gia_ObjUpdateLevelId( Gia_Man_t * p, int Id, int l ) { Vec_IntSetEntry(p->vLevels, Id, Abc_MaxInt(Vec_IntEntry(p->vLevels, Id), l)); } static inline void Gia_ObjSetLevelId( Gia_Man_t * p, int Id, int l ) { Vec_IntSetEntry(p->vLevels, Id, l); } static inline void Gia_ObjSetLevel( Gia_Man_t * p, Gia_Obj_t * pObj, int l ) { Gia_ObjSetLevelId( p, Gia_ObjId(p,pObj), l ); } static inline void Gia_ObjSetCoLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetLevel( p, pObj, Gia_ObjLevel(p,Gia_ObjFanin0(pObj)) ); } @@ -1264,6 +1265,7 @@ extern Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes ); extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes ); extern Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p ); +extern Vec_Wec_t * Gia_ManLevelizeR( Gia_Man_t * p ); extern Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p ); extern void Gia_ManCollectTfi( Gia_Man_t * p, Vec_Int_t * vRoots, Vec_Int_t * vNodes ); extern void Gia_ManCollectTfo( Gia_Man_t * p, Vec_Int_t * vRoots, Vec_Int_t * vNodes ); @@ -1670,6 +1672,7 @@ extern void Gia_ManSetPhase1( Gia_Man_t * p ); extern void Gia_ManCleanPhase( Gia_Man_t * p ); extern int Gia_ManCheckCoPhase( Gia_Man_t * p ); extern int Gia_ManLevelNum( Gia_Man_t * p ); +extern int Gia_ManLevelRNum( Gia_Man_t * p ); extern Vec_Int_t * Gia_ManGetCiLevels( Gia_Man_t * p ); extern int Gia_ManSetLevels( Gia_Man_t * p, Vec_Int_t * vCiLevels ); extern Vec_Int_t * Gia_ManReverseLevel( Gia_Man_t * p ); diff --git a/src/aig/gia/giaDfs.c b/src/aig/gia/giaDfs.c index 5cfe3b44..7ed59b9a 100644 --- a/src/aig/gia/giaDfs.c +++ b/src/aig/gia/giaDfs.c @@ -416,6 +416,34 @@ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p ) return vLevels; } +/**Function************************************************************* + + Synopsis [Levelizes the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Gia_ManLevelizeR( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + Vec_Wec_t * vLevels; + int nLevels, Level, i; + nLevels = Gia_ManLevelRNum( p ); + vLevels = Vec_WecStart( nLevels + 1 ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( i == 0 || (!Gia_ObjIsCo(pObj) && !Gia_ObjLevel(p, pObj)) ) + continue; + Level = Gia_ObjLevel( p, pObj ); + assert( Level <= nLevels ); + Vec_WecPush( vLevels, Level, i ); + } + return vLevels; +} /**Function************************************************************* Synopsis [Computes reverse topological order.] diff --git a/src/aig/gia/giaIso3.c b/src/aig/gia/giaIso3.c index a88a0569..a151033a 100644 --- a/src/aig/gia/giaIso3.c +++ b/src/aig/gia/giaIso3.c @@ -158,6 +158,98 @@ void Gia_Iso3Test( Gia_Man_t * p ) Vec_IntFreeP( &vSign ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Gia_Iso4Gia( Gia_Man_t * p ) +{ + Vec_Wec_t * vLevs = Gia_ManLevelizeR( p ); + Vec_Int_t * vLevel; int l; + Abc_Random( 1 ); + Vec_WecForEachLevel( vLevs, vLevel, l ) + { + Gia_Obj_t * pObj; int i; + int RandC[2] = { Abc_Random(0), Abc_Random(0) }; + if ( l == 0 ) + { + Gia_ManForEachObjVec( vLevel, p, pObj, i ) + { + Gia_Obj_t * pfanin = Gia_ObjFanin0(pObj); + assert( Gia_ObjIsCo(pObj) ); + pObj->Value = Abc_Random(0); + Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)]; + } + } + else + { + Gia_ManForEachObjVec( vLevel, p, pObj, i ) if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)]; + Gia_ObjFanin1(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC1(pObj)]; + } + } + } + return vLevs; +} +void Gia_Iso4Test( Gia_Man_t * p ) +{ + Vec_Wec_t * vLevs = Gia_Iso4Gia( p ); + Vec_Int_t * vLevel; int l; + Vec_WecForEachLevel( vLevs, vLevel, l ) + { + Gia_Obj_t * pObj; int i; + printf( "Level %d\n", l ); + Gia_ManForEachObjVec( vLevel, p, pObj, i ) + printf( "Obj = %5d. Value = %08x.\n", Gia_ObjId(p, pObj), pObj->Value ); + } + Vec_WecFree( vLevs ); +} +Vec_Int_t * Gia_IsoCollectData( Gia_Man_t * p, Vec_Int_t * vObjs ) +{ + Gia_Obj_t * pObj; int i; + Vec_Int_t * vData = Vec_IntAlloc( Vec_IntSize(vObjs) ); + Gia_ManForEachObjVec( vObjs, p, pObj, i ) + Vec_IntPush( vData, pObj->Value ); + return vData; +} +void Gia_IsoCompareVecs( Gia_Man_t * pGia0, Vec_Wec_t * vLevs0, Gia_Man_t * pGia1, Vec_Wec_t * vLevs1 ) +{ + int i, Common, nLevels = Abc_MinInt( Vec_WecSize(vLevs0), Vec_WecSize(vLevs1) ); + Gia_ManPrintStats( pGia0, NULL ); + Gia_ManPrintStats( pGia1, NULL ); + printf( "Printing %d shared levels:\n", nLevels ); + for ( i = 0; i < nLevels; i++ ) + { + Vec_Int_t * vLev0 = Vec_WecEntry(vLevs0, i); + Vec_Int_t * vLev1 = Vec_WecEntry(vLevs1, i); + Vec_Int_t * vData0 = Gia_IsoCollectData( pGia0, vLev0 ); + Vec_Int_t * vData1 = Gia_IsoCollectData( pGia1, vLev1 ); + Vec_IntSort( vData0, 0 ); + Vec_IntSort( vData1, 0 ); + Common = Vec_IntTwoCountCommon( vData0, vData1 ); + printf( "Level = %3d. One = %6d. Two = %6d. Common = %6d.\n", + i, Vec_IntSize(vData0)-Common, Vec_IntSize(vData1)-Common, Common ); + Vec_IntFree( vData0 ); + Vec_IntFree( vData1 ); + } +} +void Gia_Iso4TestTwo( Gia_Man_t * pGia0, Gia_Man_t * pGia1 ) +{ + Vec_Wec_t * vLevs0 = Gia_Iso4Gia( pGia0 ); + Vec_Wec_t * vLevs1 = Gia_Iso4Gia( pGia1 ); + Gia_IsoCompareVecs( pGia0, vLevs0, pGia1, vLevs1 ); + Vec_WecFree( vLevs0 ); + Vec_WecFree( vLevs1 ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 007faeca..2e1830c5 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -522,6 +522,28 @@ int Gia_ManLevelNum( Gia_Man_t * p ) } return p->nLevels; } +int Gia_ManLevelRNum( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); + p->nLevels = 0; + Gia_ManForEachObjReverse( p, pObj, i ) + { + if ( !p->fGiaSimple && Gia_ObjIsBuf(pObj) ) + Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), Gia_ObjLevel(p, pObj) ); + else if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), 1+Gia_ObjLevel(p, pObj) ); + Gia_ObjUpdateLevelId( p, Gia_ObjFaninId1(pObj, i), 1+Gia_ObjLevel(p, pObj) ); + } + else if ( Gia_ObjIsCo(pObj) ) + Gia_ObjUpdateLevelId( p, Gia_ObjFaninId0(pObj, i), 1 ); + else + p->nLevels = Abc_MaxInt( p->nLevels, Gia_ObjLevel(p, pObj) ); + } + return p->nLevels; +} float Gia_ManLevelAve( Gia_Man_t * p ) { Gia_Obj_t * pObj; -- cgit v1.2.3 From 25538c23c51a5b79af3f70d4c15f2a6f86b98189 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 20 Jul 2020 19:52:45 -0700 Subject: Fixing new resub code. --- src/aig/gia/giaIso3.c | 1 - src/aig/gia/giaResub2.c | 336 +++++++++++++++++++++++++++++++----------------- 2 files changed, 215 insertions(+), 122 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaIso3.c b/src/aig/gia/giaIso3.c index a151033a..8bea4bbf 100644 --- a/src/aig/gia/giaIso3.c +++ b/src/aig/gia/giaIso3.c @@ -182,7 +182,6 @@ Vec_Wec_t * Gia_Iso4Gia( Gia_Man_t * p ) { Gia_ManForEachObjVec( vLevel, p, pObj, i ) { - Gia_Obj_t * pfanin = Gia_ObjFanin0(pObj); assert( Gia_ObjIsCo(pObj) ); pObj->Value = Abc_Random(0); Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)]; diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index c051c465..05f3e40b 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -54,92 +54,19 @@ struct Gia_Rsb2Man_t_ Vec_Int_t vLevels; Vec_Int_t vRefs; Vec_Int_t vCopies; + Vec_Int_t vTried; word Truth0; word Truth1; word CareSet; }; +extern void Abc_ResubPrepareManager( int nWords ); extern int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int ** ppArray ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray ) -{ - *ppArray = NULL; - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int * Gia_ManToResub( Gia_Man_t * p ) -{ - Gia_Obj_t * pObj; - int * pObjs = ABC_CALLOC( int, 2*Gia_ManObjNum(p) ); - int i, iFirstPo = 1 + Gia_ManCiNum(p) + Gia_ManAndNum(p); - assert( Gia_ManIsNormalized(p) ); - Gia_ManForEachObj1( p, pObj, i ) - { - if ( Gia_ObjIsCi(pObj) ) - continue; - pObjs[2*i+0] = Gia_ObjFaninLit0(Gia_ManObj(p, i), i); - if ( Gia_ObjIsCo(pObj) ) - pObjs[2*i+1] = pObjs[2*i+0]; - else if ( Gia_ObjIsAnd(pObj) ) - pObjs[2*i+1] = Gia_ObjFaninLit1(Gia_ManObj(p, i), i); - else assert( 0 ); - } - return pObjs; -} -Gia_Man_t * Gia_ManFromResub( int * pObjs, int nObjs ) -{ - int i; - Gia_Man_t * pNew = Gia_ManStart( nObjs ); - for ( i = 1; i < nObjs; i++ ) - { - if ( pObjs[2*i] == 0 ) // pi - Gia_ManAppendCi( pNew ); - else if ( pObjs[2*i] == pObjs[2*i+1] ) // po - Gia_ManAppendCo( pNew, pObjs[2*i] ); - else if ( pObjs[2*i] < pObjs[2*i+1] ) - Gia_ManAppendAnd( pNew, pObjs[2*i], pObjs[2*i+1] ); - else if ( pObjs[2*i] > pObjs[2*i+1] ) - Gia_ManAppendXor( pNew, pObjs[2*i], pObjs[2*i+1] ); - else assert( 0 ); - } - return pNew; -} -Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p ) -{ - int * pObjsNew, * pObjs = Gia_ManToResub( p ); - int nObjsNew = Abc_ResubComputeWindow( pObjs, Gia_ManObjNum(p), 1000, 0, 0, 0, 0, 0, &pObjsNew ); - Gia_Man_t * pNew = Gia_ManFromResub( pObjsNew, nObjsNew ); - ABC_FREE( pObjs ); - ABC_FREE( pObjsNew ); - return pNew; -} - /**Function************************************************************* Synopsis [] @@ -165,20 +92,9 @@ void Gia_Rsb2ManFree( Gia_Rsb2Man_t * p ) Vec_IntErase( &p->vLevels ); Vec_IntErase( &p->vRefs ); Vec_IntErase( &p->vCopies ); + Vec_IntErase( &p->vTried ); ABC_FREE( p ); } -int Gia_Rsb2ManLevel( Gia_Rsb2Man_t * p ) -{ - int i, * pLevs, Level = 0; - Vec_IntClear( &p->vLevels ); - Vec_IntGrow( &p->vLevels, p->nObjs ); - pLevs = Vec_IntArray( &p->vLevels ); - for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) - pLevs[i] = 1 + Abc_MaxInt( pLevs[2*i+0]/2, pLevs[2*i+1]/2 ); - for ( i = p->iFirstPo; i < p->nObjs; i++ ) - Level = Abc_MaxInt( Level, pLevs[i] = pLevs[2*i+0]/2 ); - return Level; -} void Gia_Rsb2ManStart( Gia_Rsb2Man_t * p, int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose ) { int i; @@ -191,7 +107,7 @@ void Gia_Rsb2ManStart( Gia_Rsb2Man_t * p, int * pObjs, int nObjs, int nDivsMax, p->fVerbose = fVerbose; // user data Vec_IntClear( &p->vObjs ); - Vec_IntPushArray( &p->vObjs, pObjs, nObjs ); + Vec_IntPushArray( &p->vObjs, pObjs, 2*nObjs ); assert( pObjs[0] == 0 ); assert( pObjs[1] == 0 ); p->nObjs = nObjs; @@ -201,34 +117,36 @@ void Gia_Rsb2ManStart( Gia_Rsb2Man_t * p, int * pObjs, int nObjs, int nDivsMax, p->iFirstPo = 0; for ( i = 1; i < nObjs; i++ ) { - if ( pObjs[0] == 0 && pObjs[1] == 0 ) + if ( pObjs[2*i+0] == 0 && pObjs[2*i+1] == 0 ) p->nPis++; - else if ( pObjs[0] == pObjs[1] ) + else if ( pObjs[2*i+0] == pObjs[2*i+1] ) p->nPos++; else p->nNodes++; } assert( nObjs == 1 + p->nPis + p->nNodes + p->nPos ); p->iFirstPo = nObjs - p->nPos; - p->Level = Gia_Rsb2ManLevel(p); Vec_WrdClear( &p->vSims ); Vec_WrdGrow( &p->vSims, 2*nObjs ); Vec_WrdPush( &p->vSims, 0 ); Vec_WrdPush( &p->vSims, 0 ); for ( i = 0; i < p->nPis; i++ ) { - Vec_WrdPush( &p->vSims, s_Truths6[i] ); + Vec_WrdPush( &p->vSims, s_Truths6[i] ); Vec_WrdPush( &p->vSims, ~s_Truths6[i] ); } + p->vSims.nSize = 2*p->nObjs; Vec_IntClear( &p->vDivs ); Vec_IntClear( &p->vLevels ); Vec_IntClear( &p->vRefs ); Vec_IntClear( &p->vCopies ); + Vec_IntClear( &p->vTried ); Vec_PtrClear( &p->vpDivs ); Vec_IntGrow( &p->vDivs, nObjs ); Vec_IntGrow( &p->vLevels, nObjs ); Vec_IntGrow( &p->vRefs, nObjs ); Vec_IntGrow( &p->vCopies, nObjs ); + Vec_IntGrow( &p->vTried, nObjs ); Vec_PtrGrow( &p->vpDivs, nObjs ); } @@ -243,6 +161,31 @@ void Gia_Rsb2ManStart( Gia_Rsb2Man_t * p, int * pObjs, int nObjs, int nDivsMax, SeeAlso [] ***********************************************************************/ +void Gia_Rsb2ManPrint( Gia_Rsb2Man_t * p ) +{ + int i, * pObjs = Vec_IntArray( &p->vObjs ); + printf( "PI = %d. PO = %d. Obj = %d.\n", p->nPis, p->nPos, p->nObjs ); + for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) + printf( "%2d = %c%2d & %c%2d;\n", i, + Abc_LitIsCompl(pObjs[2*i+0]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+0]), + Abc_LitIsCompl(pObjs[2*i+1]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+1]) ); + for ( i = p->iFirstPo; i < p->nObjs; i++ ) + printf( "%2d = %c%2d;\n", i, + Abc_LitIsCompl(pObjs[2*i+0]) ? '!' : ' ', Abc_Lit2Var(pObjs[2*i+0]) ); +} + +int Gia_Rsb2ManLevel( Gia_Rsb2Man_t * p ) +{ + int i, * pLevs, Level = 0; + Vec_IntClear( &p->vLevels ); + Vec_IntGrow( &p->vLevels, p->nObjs ); + pLevs = Vec_IntArray( &p->vLevels ); + for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) + pLevs[i] = 1 + Abc_MaxInt( pLevs[2*i+0]/2, pLevs[2*i+1]/2 ); + for ( i = p->iFirstPo; i < p->nObjs; i++ ) + Level = Abc_MaxInt( Level, pLevs[i] = pLevs[2*i+0]/2 ); + return Level; +} word Gia_Rsb2ManOdcs( Gia_Rsb2Man_t * p, int iNode ) { int i; word Res = 0; @@ -252,8 +195,9 @@ word Gia_Rsb2ManOdcs( Gia_Rsb2Man_t * p, int iNode ) { if ( pObjs[2*i+0] < pObjs[2*i+1] ) pSims[2*i+0] = pSims[pObjs[2*i+0]] & pSims[pObjs[2*i+1]]; - else + else if ( pObjs[2*i+0] > pObjs[2*i+1] ) pSims[2*i+0] = pSims[pObjs[2*i+0]] ^ pSims[pObjs[2*i+1]]; + else assert( 0 ); pSims[2*i+1] = ~pSims[2*i+0]; } for ( i = p->iFirstPo; i < p->nObjs; i++ ) @@ -263,39 +207,57 @@ word Gia_Rsb2ManOdcs( Gia_Rsb2Man_t * p, int iNode ) { if ( pObjs[2*i+0] < pObjs[2*i+1] ) pSims[2*i+0] = pSims[pObjs[2*i+0]] & pSims[pObjs[2*i+1]]; - else + else if ( pObjs[2*i+0] < pObjs[2*i+1] ) pSims[2*i+0] = pSims[pObjs[2*i+0]] ^ pSims[pObjs[2*i+1]]; + else assert( 0 ); pSims[2*i+1] = ~pSims[2*i+0]; } for ( i = p->iFirstPo; i < p->nObjs; i++ ) Res |= pSims[2*i+0] ^ pSims[pObjs[2*i+0]]; + ABC_SWAP( word, pSims[2*iNode+0], pSims[2*iNode+1] ); return Res; } // marks MFFC and returns its size +int Gia_Rsb2ManDeref_rec( Gia_Rsb2Man_t * p, int * pObjs, int * pRefs, int iNode ) +{ + int Counter = 1; + if ( iNode <= p->nPis ) + return 0; + if ( --pRefs[Abc_Lit2Var(pObjs[2*iNode+0])] == 0 ) + Counter += Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, Abc_Lit2Var(pObjs[2*iNode+0]) ); + if ( --pRefs[Abc_Lit2Var(pObjs[2*iNode+1])] == 0 ) + Counter += Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, Abc_Lit2Var(pObjs[2*iNode+1]) ); + return Counter; +} int Gia_Rsb2ManMffc( Gia_Rsb2Man_t * p, int iNode ) { - int i, * pRefs, * pObjs, nMffc = 0; + int i, * pRefs, * pObjs; Vec_IntFill( &p->vRefs, p->nObjs, 0 ); pRefs = Vec_IntArray( &p->vRefs ); pObjs = Vec_IntArray( &p->vObjs ); - for ( i = p->nObjs - 1; i >= p->iFirstPo; i-- ) - pRefs[pObjs[2*i+0]] = 1; - for ( i = p->iFirstPo - 1; i > p->nPis; i-- ) - if ( i != iNode && pRefs[i] ) - pRefs[pObjs[2*i+0]] = pRefs[pObjs[2*i+1]] = 1; + assert( pObjs[2*iNode+0] != pObjs[2*iNode+1] ); + for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) + pRefs[Abc_Lit2Var(pObjs[2*i+0])]++, + pRefs[Abc_Lit2Var(pObjs[2*i+1])]++; + for ( i = p->iFirstPo; i < p->nObjs; i++ ) + pRefs[Abc_Lit2Var(pObjs[2*i+0])]++; for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) - nMffc += !pRefs[i]; - return nMffc; + assert( pRefs[i] ); + pRefs[iNode] = 0; + for ( i = iNode + 1; i < p->iFirstPo; i++ ) + if ( !pRefs[Abc_Lit2Var(pObjs[2*i+0])] || !pRefs[Abc_Lit2Var(pObjs[2*i+1])] ) + pRefs[i] = 0; + return Gia_Rsb2ManDeref_rec( p, pObjs, pRefs, iNode ); } // collects divisors and maps them into nodes // assumes MFFC is already marked int Gia_Rsb2ManDivs( Gia_Rsb2Man_t * p, int iNode ) { - int i; + int i, iNodeLevel = 0; int * pRefs = Vec_IntArray( &p->vRefs ); int * pObjs = Vec_IntArray( &p->vObjs ); p->CareSet = Gia_Rsb2ManOdcs( p, iNode ); - p->Truth1 = p->CareSet & Vec_WrdEntry(&p->vSims, iNode); + p->Truth1 = p->CareSet & Vec_WrdEntry(&p->vSims, 2*iNode); p->Truth0 = p->CareSet & ~p->Truth1; Vec_PtrClear( &p->vpDivs ); Vec_PtrPush( &p->vpDivs, &p->Truth0 ); @@ -304,19 +266,20 @@ int Gia_Rsb2ManDivs( Gia_Rsb2Man_t * p, int iNode ) Vec_IntPushTwo( &p->vDivs, -1, -1 ); for ( i = 1; i <= p->nPis; i++ ) { - Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, i) ); + Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, 2*i) ); Vec_IntPush( &p->vDivs, i ); } p->nMffc = Gia_Rsb2ManMffc( p, iNode ); - assert( pRefs[iNode] == 1 ); - pRefs[iNode] = 0; + if ( p->nLevelIncrease >= 0 ) + { + p->Level = Gia_Rsb2ManLevel(p); + iNodeLevel = Vec_IntEntry(&p->vLevels, iNode); + } for ( i = p->nPis + 1; i < p->iFirstPo; i++ ) { - if ( i > iNode ) - pRefs[i] = pRefs[pObjs[2*i+0]] && pRefs[pObjs[2*i+1]]; - if ( !pRefs[i] ) + if ( !pRefs[i] || (p->nLevelIncrease >= 0 && Vec_IntEntry(&p->vLevels, i) > iNodeLevel + p->nLevelIncrease) ) continue; - Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, i) ); + Vec_PtrPush( &p->vpDivs, Vec_WrdEntryP(&p->vSims, 2*i) ); Vec_IntPush( &p->vDivs, i ); } assert( Vec_IntSize(&p->vDivs) == Vec_PtrSize(&p->vpDivs) ); @@ -358,7 +321,7 @@ int Gia_Rsb2ManInsert_rec( Vec_Int_t * vRes, int nPis, Vec_Int_t * vObjs, int iN if ( iObj == iNode ) { int nVars = Vec_IntSize(vDivs); - int iLitRes, iTopLit = Vec_IntEntryLast( vResub ); + int iLitRes = -1, iTopLit = Vec_IntEntryLast( vResub ); if ( Abc_Lit2Var(iTopLit) == 0 ) iLitRes = 0; else if ( Abc_Lit2Var(iTopLit) < nVars ) @@ -376,7 +339,7 @@ int Gia_Rsb2ManInsert_rec( Vec_Int_t * vRes, int nPis, Vec_Int_t * vObjs, int iN int iVar1 = Abc_Lit2Var(iLit1); int iRes0 = iVar0 < nVars ? Vec_IntEntry(vCopies, Vec_IntEntry(vDivs, iVar0)) : Vec_IntEntry(vCopy, iVar0 - nVars); int iRes1 = iVar1 < nVars ? Vec_IntEntry(vCopies, Vec_IntEntry(vDivs, iVar1)) : Vec_IntEntry(vCopy, iVar1 - nVars); - iLitRes = Gia_Rsb2AddNode( vRes, iLit0, iLit1, iRes0, iRes1 ); + iLitRes = Gia_Rsb2AddNode( vRes, iLit0, iLit1, iRes0, iRes1 ); Vec_IntPush( vCopy, iLitRes ); } Vec_IntFree( vCopy ); @@ -398,22 +361,153 @@ int Gia_Rsb2ManInsert_rec( Vec_Int_t * vRes, int nPis, Vec_Int_t * vObjs, int iN } Vec_Int_t * Gia_Rsb2ManInsert( int nPis, int nPos, Vec_Int_t * vObjs, int iNode, Vec_Int_t * vResub, Vec_Int_t * vDivs, Vec_Int_t * vCopies ) { - int i, iFirstPo = Vec_IntSize(vObjs) - nPos; - Vec_Int_t * vRes = Vec_IntAlloc( 2*Vec_IntSize(vObjs) ); + int i, nObjs = Vec_IntSize(vObjs)/2, iFirstPo = nObjs - nPos; + Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vObjs) ); +//Vec_IntPrint( vDivs ); +//Vec_IntPrint( vResub ); Vec_IntFill( vCopies, Vec_IntSize(vObjs), -1 ); Vec_IntFill( vRes, 2*(nPis + 1), 0 ); for ( i = 0; i <= nPis; i++ ) - Vec_IntPush( vCopies, 2*i ); - for ( i = 0; i < nPos; i++ ) - Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var(Vec_IntEntry(vObjs, 2*(iFirstPo+1))) ); - for ( i = 0; i < nPos; i++ ) + Vec_IntWriteEntry( vCopies, i, 2*i ); + for ( i = iFirstPo; i < nObjs; i++ ) + Gia_Rsb2ManInsert_rec( vRes, nPis, vObjs, iNode, vResub, vDivs, vCopies, Abc_Lit2Var( Vec_IntEntry(vObjs, 2*i) ) ); + for ( i = iFirstPo; i < nObjs; i++ ) { - int iLitNew = Abc_Lit2LitL( Vec_IntArray(vCopies), Vec_IntEntry(vObjs, 2*(iFirstPo+1)) ); + int iLitNew = Abc_Lit2LitL( Vec_IntArray(vCopies), Vec_IntEntry(vObjs, 2*i) ); Vec_IntPushTwo( vRes, iLitNew, iLitNew ); } return vRes; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ResubNodeToTry( Vec_Int_t * vTried, int iFirst, int iLast ) +{ + int iNode; + //for ( iNode = iFirst; iNode < iLast; iNode++ ) + for ( iNode = iLast - 1; iNode >= iFirst; iNode-- ) + if ( Vec_IntFind(vTried, iNode) == -1 ) + return iNode; + return -1; +} +int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray ) +{ + int RetValue = 0, iNode, fChange = 0; + Gia_Rsb2Man_t * p = Gia_Rsb2ManAlloc(); + Gia_Rsb2ManStart( p, pObjs, nObjs, nDivsMax, nLevelIncrease, fUseXor, fUseZeroCost, fDebug, fVerbose ); + *ppArray = NULL; + while ( (iNode = Abc_ResubNodeToTry(&p->vTried, p->nPis+1, p->iFirstPo)) > 0 ) + { + int nDivs = Gia_Rsb2ManDivs( p, iNode ); + int * pResub, nResub = Abc_ResubComputeFunction( (word **)Vec_PtrArray(&p->vpDivs), nDivs, 1, p->nMffc-1, nDivsMax, 0, fUseXor, fDebug, fVerbose, &pResub ); + if ( nResub == 0 ) + Vec_IntPush( &p->vTried, iNode ); + else + { + int i, k = 0, iTried; + Vec_Int_t vResub = { nResub, nResub, pResub }; + Vec_Int_t * vRes = Gia_Rsb2ManInsert( p->nPis, p->nPos, &p->vObjs, iNode, &vResub, &p->vDivs, &p->vCopies ); +//printf( "\nResubbing node %d:\n", iNode ); +//Gia_Rsb2ManPrint( p ); + p->nObjs = Vec_IntSize(vRes)/2; + p->iFirstPo = p->nObjs - p->nPos; + Vec_IntClear( &p->vObjs ); + Vec_IntAppend( &p->vObjs, vRes ); + Vec_IntFree( vRes ); + Vec_IntForEachEntry( &p->vTried, iTried, i ) + if ( Vec_IntEntry(&p->vCopies, i) > 0 ) + Vec_IntWriteEntry( &p->vTried, k++, iTried ); + Vec_IntShrink( &p->vTried, k ); + fChange = 1; +//Gia_Rsb2ManPrint( p ); + } + } + if ( fChange ) + { + RetValue = p->nObjs; + *ppArray = p->vObjs.pArray; + Vec_IntZero( &p->vObjs ); + } + Gia_Rsb2ManFree( p ); + return RetValue; +} +int Abc_ResubComputeWindow2( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray ) +{ + *ppArray = ABC_ALLOC( int, 2*nObjs ); + memmove( *ppArray, pObjs, 2*nObjs * sizeof(int) ); + return nObjs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManToResub( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, * pObjs = ABC_CALLOC( int, 2*Gia_ManObjNum(p) ); + assert( Gia_ManIsNormalized(p) ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + continue; + pObjs[2*i+0] = Gia_ObjFaninLit0(Gia_ManObj(p, i), i); + if ( Gia_ObjIsCo(pObj) ) + pObjs[2*i+1] = pObjs[2*i+0]; + else if ( Gia_ObjIsAnd(pObj) ) + pObjs[2*i+1] = Gia_ObjFaninLit1(Gia_ManObj(p, i), i); + else assert( 0 ); + } + return pObjs; +} +Gia_Man_t * Gia_ManFromResub( int * pObjs, int nObjs ) +{ + Gia_Man_t * pNew = Gia_ManStart( nObjs ); + int i; + for ( i = 1; i < nObjs; i++ ) + { + if ( pObjs[2*i] == 0 ) // pi + Gia_ManAppendCi( pNew ); + else if ( pObjs[2*i] == pObjs[2*i+1] ) // po + Gia_ManAppendCo( pNew, pObjs[2*i] ); + else if ( pObjs[2*i] < pObjs[2*i+1] ) + Gia_ManAppendAnd( pNew, pObjs[2*i], pObjs[2*i+1] ); + else if ( pObjs[2*i] > pObjs[2*i+1] ) + Gia_ManAppendXor( pNew, pObjs[2*i], pObjs[2*i+1] ); + else assert( 0 ); + } + return pNew; +} +Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + int nObjsNew, * pObjsNew, * pObjs = Gia_ManToResub( p ); + Abc_ResubPrepareManager( 1 ); + nObjsNew = Abc_ResubComputeWindow( pObjs, Gia_ManObjNum(p), 1000, -1, 0, 0, 0, 0, &pObjsNew ); + Abc_ResubPrepareManager( 0 ); + pNew = Gia_ManFromResub( pObjsNew, nObjsNew ); + ABC_FREE( pObjs ); + ABC_FREE( pObjsNew ); + return pNew; +} + /**Function************************************************************* Synopsis [Creating a window with support composed of primary inputs.] @@ -559,7 +653,7 @@ Vec_Int_t * Gia_RsbCiWindow( Gia_Man_t * p, int nPis ) Gia_ManStaticFanoutStop( p ); Vec_WecFree( vLevels ); Vec_IntFree( vMap ); -Vec_IntPrint( vNodes ); +//Vec_IntPrint( vNodes ); Vec_IntFree( vNodes ); return vRes; } -- cgit v1.2.3 From 448f26344325cc78942d576740457036671b0976 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 20 Jul 2020 19:56:06 -0700 Subject: Fixing new resub code. --- src/aig/gia/giaResub2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index 05f3e40b..e14191a9 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -255,7 +255,6 @@ int Gia_Rsb2ManDivs( Gia_Rsb2Man_t * p, int iNode ) { int i, iNodeLevel = 0; int * pRefs = Vec_IntArray( &p->vRefs ); - int * pObjs = Vec_IntArray( &p->vObjs ); p->CareSet = Gia_Rsb2ManOdcs( p, iNode ); p->Truth1 = p->CareSet & Vec_WrdEntry(&p->vSims, 2*iNode); p->Truth0 = p->CareSet & ~p->Truth1; @@ -409,7 +408,7 @@ int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncr while ( (iNode = Abc_ResubNodeToTry(&p->vTried, p->nPis+1, p->iFirstPo)) > 0 ) { int nDivs = Gia_Rsb2ManDivs( p, iNode ); - int * pResub, nResub = Abc_ResubComputeFunction( (word **)Vec_PtrArray(&p->vpDivs), nDivs, 1, p->nMffc-1, nDivsMax, 0, fUseXor, fDebug, fVerbose, &pResub ); + int * pResub, nResub = Abc_ResubComputeFunction( Vec_PtrArray(&p->vpDivs), nDivs, 1, p->nMffc-1, nDivsMax, 0, fUseXor, fDebug, fVerbose, &pResub ); if ( nResub == 0 ) Vec_IntPush( &p->vTried, iNode ); else -- cgit v1.2.3 From aaeadb1438b1a0116cd5912c7c827b6249f22bc4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 29 Jul 2020 19:48:36 -0700 Subject: New ways of reading MiniAIG. --- src/aig/gia/giaMini.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index ce42f73c..ead5e736 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -797,6 +797,274 @@ void Gia_MiniAigVerify( Abc_Frame_t * pAbc, char * pFileName ) Mini_AigStop( p ); } +/**Function************************************************************* + + Synopsis [Collects supergate for the outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MiniAigSuperGates_rec( Mini_Aig_t * p, int iObj, Vec_Int_t * vRes, Vec_Int_t * vMap ) +{ + int iFan0, iFan1; + if ( Mini_AigNodeIsPi(p, iObj) ) + { + assert( Vec_IntEntry(vMap, iObj) >= 0 ); + Vec_IntPush( vRes, Vec_IntEntry(vMap, iObj) ); + return; + } + iFan0 = Mini_AigNodeFanin0( p, iObj ); + iFan1 = Mini_AigNodeFanin1( p, iObj ); + assert( !Abc_LitIsCompl(iFan0) ); + assert( !Abc_LitIsCompl(iFan1) ); + Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan0), vRes, vMap ); + Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan1), vRes, vMap ); +} +Vec_Wec_t * Gia_MiniAigSuperGates( Mini_Aig_t * p ) +{ + Vec_Wec_t * vRes = Vec_WecStart( Mini_AigPoNum(p) ); + Vec_Int_t * vMap = Vec_IntStartFull( Mini_AigNodeNum(p) ); + int i, Index = 0; + Mini_AigForEachPi( p, i ) + Vec_IntWriteEntry( vMap, i, Index++ ); + assert( Index == Mini_AigPiNum(p) ); + Index = 0; + Mini_AigForEachPo( p, i ) + { + int iFan0 = Mini_AigNodeFanin0( p, i ); + assert( !Abc_LitIsCompl(iFan0) ); + Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan0), Vec_WecEntry(vRes, Index++), vMap ); + } + assert( Index == Mini_AigPoNum(p) ); + Vec_IntFree( vMap ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Transform.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_MiniAigSuperPrintDouble( Vec_Int_t * p, int nPis ) +{ + int i, Entry; + printf( "\n" ); + Vec_IntForEachEntry( p, Entry, i ) + printf( "%d(%d) ", Entry%nPis, Entry/nPis ); + printf( " Total = %d\n", Vec_IntSize(p) ); +} +int Gia_MiniAigSuperMerge( Vec_Int_t * p, int nPis ) +{ + int i, k = 0, This, Prev = -1, fChange = 0; + Vec_IntForEachEntry( p, This, i ) + { + if ( Prev == This ) + { + Vec_IntWriteEntry( p, k++, (This/nPis+1)*nPis + This%nPis ); + Prev = -1; + fChange = 1; + } + else + { + if ( Prev != -1 ) + Vec_IntWriteEntry( p, k++, Prev ); + Prev = This; + } + } + if ( Prev != -1 ) + Vec_IntWriteEntry( p, k++, Prev ); + Vec_IntShrink( p, k ); + return fChange; +} +int Gia_MiniAigSuperPreprocess( Mini_Aig_t * p, Vec_Wec_t * vSuper, int nPis, int fVerbose ) +{ + Vec_Int_t * vRes; + int i, nIters, Multi = 1; + Vec_WecForEachLevel( vSuper, vRes, i ) + { + Vec_IntSort( vRes, 0 ); + if ( fVerbose ) + printf( "\nOutput %d\n", i ); + if ( fVerbose ) + Gia_MiniAigSuperPrintDouble( vRes, nPis ); + for ( nIters = 1; Gia_MiniAigSuperMerge(vRes, nPis); nIters++ ) + { + if ( fVerbose ) + Gia_MiniAigSuperPrintDouble( vRes, nPis ); + } + Multi = Abc_MaxInt( Multi, nIters ); + } + if ( fVerbose ) + printf( "Multi = %d.\n", Multi ); + return Multi; +} + +/**Function************************************************************* + + Synopsis [Derive AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_MiniAigSuperDeriveGia( Vec_Wec_t * p, int nPis, int Multi ) +{ + Gia_Man_t * pNew; + Vec_Int_t * vTemp, * vLits = Vec_IntAlloc( 100 ); + Vec_Int_t * vDrivers = Vec_IntAlloc(100); + int i, k, iObj, iLit, nInputs = nPis*Multi; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "tree" ); + for ( i = 0; i < nInputs; i++ ) + Gia_ManAppendCi( pNew ); + Gia_ManHashAlloc( pNew ); + Vec_WecForEachLevel( p, vTemp, i ) + { + Vec_IntClear( vLits ); + Vec_IntForEachEntry( vTemp, iObj, k ) + { + assert( iObj < nInputs ); + Vec_IntPush( vLits, 2+2*((iObj%nPis)*Multi+iObj/nPis) ); + } + Vec_IntPush( vDrivers, Gia_ManHashAndMulti2(pNew, vLits) ); + } + Gia_ManHashStop( pNew ); + Vec_IntFree( vLits ); + Vec_IntForEachEntry( vDrivers, iLit, i ) + Gia_ManAppendCo( pNew, iLit ); + Vec_IntFree( vDrivers ); + return pNew; +} +Gia_Man_t * Gia_MiniAigSuperDerive( char * pFileName, int fVerbose ) +{ + Mini_Aig_t * p = Mini_AigLoad( pFileName ); + Vec_Wec_t * vSuper = Gia_MiniAigSuperGates( p ); + int Multi = Gia_MiniAigSuperPreprocess( p, vSuper, Mini_AigPiNum(p), fVerbose ); + Gia_Man_t * pNew = Gia_MiniAigSuperDeriveGia( vSuper, Mini_AigPiNum(p), Multi ); + Vec_WecFree( vSuper ); + Mini_AigStop( p ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Process file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_MiniAigProcessFile() +{ + Vec_Int_t * vTriples = Vec_IntAlloc( 100 ); + char * pFileName = "test.txt"; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + printf( "Cannot open the file.\n" ); + else + { + int nLines = 0, nLinesAll = 0; + char * pToken; + char Buffer[1000]; + while ( fgets( Buffer, 1000, pFile ) != NULL ) + { + nLinesAll++; + if ( Buffer[0] != '#' ) + continue; + //printf( "%s", Buffer ); + nLines++; + pToken = strtok( Buffer+3, " \r\n\r+=" ); + while ( pToken ) + { + Vec_IntPush( vTriples, atoi(pToken) ); + pToken = strtok( NULL, " \r\n\r+=" ); + } + } + fclose( pFile ); + printf( "Collected %d (out of %d) lines.\n", nLines, nLinesAll ); + printf( "Entries = %d\n", Vec_IntSize(vTriples) ); + } + return vTriples; +} +void Gia_MiniAigGenerate_rec( Mini_Aig_t * p, Vec_Int_t * vTriples, int iObj, Vec_Int_t * vDefs, Vec_Int_t * vMap ) +{ + int Index, Entry0, Entry1, Entry2, Value; + if ( Vec_IntEntry(vMap, iObj) >= 0 ) + return; + Index = Vec_IntEntry( vDefs, iObj ); + Entry0 = Vec_IntEntry( vTriples, 3*Index+0 ); + Entry1 = Vec_IntEntry( vTriples, 3*Index+1 ); + Entry2 = Vec_IntEntry( vTriples, 3*Index+2 ); + Gia_MiniAigGenerate_rec( p, vTriples, Entry1, vDefs, vMap ); + Gia_MiniAigGenerate_rec( p, vTriples, Entry2, vDefs, vMap ); + assert( Vec_IntEntry(vMap, Entry1) >= 0 ); + assert( Vec_IntEntry(vMap, Entry2) >= 0 ); + Value = Mini_AigAnd( p, Vec_IntEntry(vMap, Entry1), Vec_IntEntry(vMap, Entry2) ); + Vec_IntWriteEntry( vMap, Entry0, Value ); +} +void Gia_MiniAigGenerateFromFile() +{ + Mini_Aig_t * p = Mini_AigStart(); + Vec_Int_t * vTriples = Gia_MiniAigProcessFile(); + Vec_Int_t * vDefs = Vec_IntStartFull( Vec_IntSize(vTriples) ); + Vec_Int_t * vMap = Vec_IntStartFull( Vec_IntSize(vTriples) ); + Vec_Int_t * vMapIn = Vec_IntStart( Vec_IntSize(vTriples) ); + Vec_Int_t * vMapOut = Vec_IntStart( Vec_IntSize(vTriples) ); + Vec_Int_t * vPis = Vec_IntAlloc( 100 ); + Vec_Int_t * vPos = Vec_IntAlloc( 100 ); + int i, ObjOut, ObjIn, nIns = 0, nOuts = 0; + assert( Vec_IntSize(vTriples) % 3 == 0 ); + for ( i = 0; i < Vec_IntSize(vTriples)/3; i++ ) + { + int Entry0 = Vec_IntEntry(vTriples, 3*i+0); + int Entry1 = Vec_IntEntry(vTriples, 3*i+1); + int Entry2 = Vec_IntEntry(vTriples, 3*i+2); + Vec_IntWriteEntry( vDefs, Entry0, i ); + Vec_IntAddToEntry( vMapOut, Entry0, 1 ); + Vec_IntAddToEntry( vMapIn, Entry1, 1 ); + Vec_IntAddToEntry( vMapIn, Entry2, 1 ); + } + Vec_IntForEachEntryTwo( vMapOut, vMapIn, ObjOut, ObjIn, i ) + if ( !ObjOut && ObjIn ) + Vec_IntPush( vPis, i ); + else if ( ObjOut && !ObjIn ) + Vec_IntPush( vPos, i ); + Vec_IntForEachEntry( vPis, ObjIn, i ) + Vec_IntWriteEntry( vMap, ObjIn, Mini_AigCreatePi(p) ); + Vec_IntForEachEntry( vPos, ObjOut, i ) + Gia_MiniAigGenerate_rec( p, vTriples, ObjOut, vDefs, vMap ); + Vec_IntForEachEntry( vPos, ObjOut, i ) + { + assert( Vec_IntEntry(vMap, ObjOut) >= 0 ); + Mini_AigCreatePo( p, Vec_IntEntry(vMap, ObjOut) ); + } + Vec_IntFree( vTriples ); + Vec_IntFree( vDefs ); + Vec_IntFree( vMap ); + Vec_IntFree( vMapIn ); + Vec_IntFree( vMapOut ); + Vec_IntFree( vPis ); + Vec_IntFree( vPos ); + Mini_AigDump( p, "test.miniaig" ); + Mini_AigStop( p ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 5c8ee4a2c142d133afe4cbfe567b300fe4d040a8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 29 Jul 2020 19:50:10 -0700 Subject: New ways of reading MiniAIG. --- src/aig/gia/giaMini.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index ead5e736..7a18d2d2 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -1028,7 +1028,7 @@ void Gia_MiniAigGenerateFromFile() Vec_Int_t * vMapOut = Vec_IntStart( Vec_IntSize(vTriples) ); Vec_Int_t * vPis = Vec_IntAlloc( 100 ); Vec_Int_t * vPos = Vec_IntAlloc( 100 ); - int i, ObjOut, ObjIn, nIns = 0, nOuts = 0; + int i, ObjOut, ObjIn; assert( Vec_IntSize(vTriples) % 3 == 0 ); for ( i = 0; i < Vec_IntSize(vTriples)/3; i++ ) { -- cgit v1.2.3 From 26e03ef6a052ce71951d4b832cf8871cc272f27a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 15 Aug 2020 17:12:41 -0700 Subject: Experiments with window computation. --- src/aig/gia/giaResub2.c | 380 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 364 insertions(+), 16 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index e14191a9..18fd5f8f 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -521,7 +521,7 @@ Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p ) // returns the number of nodes added to the window when is iPivot is added // the window nodes in vNodes are labeled with the current traversal ID // the new node iPivot and its fanout are temporarily labeled and then unlabeled -int Gia_WinTryAddingNode( Gia_Man_t * p, int iPivot, Vec_Wec_t * vLevels, Vec_Int_t * vNodes ) +int Gia_WinTryAddingNode( Gia_Man_t * p, int iPivot, int iPivot2, Vec_Wec_t * vLevels, Vec_Int_t * vNodes ) { Vec_Int_t * vLevel; Gia_Obj_t * pObj, * pFanout; @@ -533,22 +533,34 @@ int Gia_WinTryAddingNode( Gia_Man_t * p, int iPivot, Vec_Wec_t * vLevels, Vec_In // add the object to the window and to the levelized structure Gia_ObjSetTravIdCurrentId( p, iPivot ); Vec_WecPush( vLevels, Gia_ObjLevelId(p, iPivot), iPivot ); + // the same about the second node if it is given + if ( iPivot2 != -1 ) + { + // precondition: the new object to be added (iPivot2) is not in the window + assert( !Gia_ObjIsTravIdCurrentId(p, iPivot2) ); + // add the object to the window and to the levelized structure + Gia_ObjSetTravIdCurrentId( p, iPivot2 ); + Vec_WecPush( vLevels, Gia_ObjLevelId(p, iPivot2), iPivot2 ); + } // iterate through all objects and explore their fanouts Vec_WecForEachLevel( vLevels, vLevel, k ) Gia_ManForEachObjVec( vLevel, p, pObj, i ) - if ( Gia_ObjFanoutNum(p, pObj) > 10 ) // do not explore objects with high fanout - Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f ) - if ( Gia_ObjIsAnd(pFanout) && // internal node - !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window - Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are - Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window - { - // add fanout to the window and to the levelized structure - Gia_ObjSetTravIdCurrent( p, pFanout ); - Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) ); - // count the number of nodes in the structure - Count++; - } + Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f ) + { + if ( f == 5 ) // explore first 5 fanouts of the node + break; + if ( Gia_ObjIsAnd(pFanout) && // internal node + !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window + Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are + Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window + { + // add fanout to the window and to the levelized structure + Gia_ObjSetTravIdCurrent( p, pFanout ); + Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) ); + // count the number of nodes in the structure + Count++; + } + } // iterate through the nodes in the levelized structure Vec_WecForEachLevel( vLevels, vLevel, k ) { @@ -584,7 +596,7 @@ int Gia_WinAddCiWithMaxDivisors( Gia_Man_t * p, Vec_Wec_t * vLevels ) { if ( Gia_ObjIsTravIdCurrentId( p, Id ) ) continue; - nCurFan = Gia_WinTryAddingNode( p, Id, vLevels, NULL ); + nCurFan = Gia_WinTryAddingNode( p, Id, -1, vLevels, NULL ); if ( nMaxFan < nCurFan ) { nMaxFan = nCurFan; @@ -645,7 +657,7 @@ Vec_Int_t * Gia_RsbCiWindow( Gia_Man_t * p, int nPis ) for ( i = 1; i < nPis; i++ ) { iMaxFan = Gia_WinAddCiWithMaxDivisors( p, vLevels ); - Gia_WinTryAddingNode( p, iMaxFan, vLevels, vNodes ); + Gia_WinTryAddingNode( p, iMaxFan, -1, vLevels, vNodes ); } Vec_IntSort( vNodes, 0 ); vRes = Gia_RsbCiTranslate( p, vNodes, vMap ); @@ -663,6 +675,342 @@ void Gia_RsbCiWindowTest( Gia_Man_t * p ) Vec_IntFree( vWin ); } + + + +/**Function************************************************************* + + Synopsis [Return initial window for the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Gia_ObjFaninId( Gia_Obj_t * pObj, int iObj, int n ) { return n ? Gia_ObjFaninId1(pObj, iObj) : Gia_ObjFaninId0(pObj, iObj); } + +static inline int Gia_ObjTravIsTopTwo( Gia_Man_t * p, int iNodeA ) { return (p->pTravIds[iNodeA] >= p->nTravIds - 1); } +static inline int Gia_ObjTravIsSame( Gia_Man_t * p, int iNodeA, int iNodeB ) { return (p->pTravIds[iNodeA] == p->pTravIds[iNodeB]); } +static inline void Gia_ObjTravSetSame( Gia_Man_t * p, int iNodeA, int iNodeB ) { p->pTravIds[iNodeA] = p->pTravIds[iNodeB]; } + +// collect nodes on the path from the meeting point to the root node, excluding the meeting point +void Gia_RsbWindowGather( Gia_Man_t * p, Vec_Int_t * vPaths, int iNode, Vec_Int_t * vVisited ) +{ + int iPrev; + if ( iNode == 0 ) + return; + Vec_IntPush( vVisited, iNode ); + iPrev = Vec_IntEntry( vPaths, iNode ); + if ( iPrev == 0 ) + return; + assert( Gia_ObjTravIsSame(p, iPrev, iNode) ); + Gia_RsbWindowGather( p, vPaths, iPrev, vVisited ); +} +// explore the frontier of nodes in the breadth-first traversal +int Gia_RsbWindowExplore( Gia_Man_t * p, Vec_Int_t * vVisited, int iStart, Vec_Int_t * vPaths, int * piMeet, int * piNode ) +{ + int i, n, iObj, iLimit = Vec_IntSize( vVisited ); + *piMeet = *piNode = 0; + Vec_IntForEachEntryStartStop( vVisited, iObj, i, iStart, iLimit ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( !Gia_ObjIsAnd(pObj) ) + continue; + for ( n = 0; n < 2; n++ ) + { + int iFan = Gia_ObjFaninId( pObj, iObj, n ); + // if the node was visited on the paths to both fanins, collect it + if ( Gia_ObjTravIsTopTwo(p, iObj) && Gia_ObjTravIsTopTwo(p, iFan) && !Gia_ObjTravIsSame(p, iObj, iFan) ) + { + *piMeet = iFan; + *piNode = iObj; + return 1; + } + // if the node was visited already on this path, skip it + if ( Gia_ObjTravIsTopTwo(p, iFan) ) + { + assert( Gia_ObjTravIsSame(p, iObj, iFan) ); + continue; + } + // label the node as visited + Gia_ObjTravSetSame( p, iFan, iObj ); + Vec_IntWriteEntry( vPaths, iFan, iObj ); + Vec_IntPush( vVisited, iFan ); + } + } + return 0; +} +Vec_Int_t * Gia_RsbWindowInit( Gia_Man_t * p, Vec_Int_t * vPaths, int iPivot, int nIter ) +{ + Vec_Int_t * vVisited = Vec_IntAlloc( 100 ); + Gia_Obj_t * pPivot = Gia_ManObj( p, iPivot ); + int i, n, iStart = 0; + assert( Gia_ObjIsAnd(pPivot) ); + // start paths for both fanins of the pivot node + for ( n = 0; n < 2; n++ ) + { + int iFan = Gia_ObjFaninId( pPivot, iPivot, n ); + Gia_ManIncrementTravId(p); + Vec_IntPush( vVisited, iFan ); + Vec_IntWriteEntry( vPaths, iFan, 0 ); + Gia_ObjSetTravIdCurrentId( p, iFan ); + } + // perform several iterations of breadth-first search + for ( i = 0; i < nIter; i++ ) + { + int iMeet, iNode, iNext = Vec_IntSize(vVisited); + if ( Gia_RsbWindowExplore( p, vVisited, iStart, vPaths, &iMeet, &iNode ) ) + { + // found the shared path + if ( Gia_ObjIsTravIdCurrentId(p, iMeet) ) + assert( Gia_ObjIsTravIdPreviousId(p, iNode) ); + else if ( Gia_ObjIsTravIdPreviousId(p, iMeet) ) + assert( Gia_ObjIsTravIdCurrentId(p, iNode) ); + else assert( 0 ); + // collect the initial window + Vec_IntClear( vVisited ); + Gia_RsbWindowGather( p, vPaths, Vec_IntEntry(vPaths, iMeet), vVisited ); + Gia_RsbWindowGather( p, vPaths, iNode, vVisited ); + Vec_IntPush( vVisited, iPivot ); + break; + } + iStart = iNext; + } + // if no meeting point is found, make sure to return NULL + if ( i == nIter ) + Vec_IntFreeP( &vVisited ); + return vVisited; +} +Vec_Int_t * Gia_RsbCreateWindowInputs( Gia_Man_t * p, Vec_Int_t * vWin ) +{ + Vec_Int_t * vInputs = Vec_IntAlloc(10); + Gia_Obj_t * pObj; int i, n, iObj; + Gia_ManIncrementTravId(p); + Gia_ManForEachObjVec( vWin, p, pObj, i ) + Gia_ObjSetTravIdCurrent(p, pObj); + Gia_ManForEachObjVec( vWin, p, pObj, i ) + { + assert( Gia_ObjIsAnd(pObj) ); + for ( n = 0; n < 2; n++ ) + { + int iFan = n ? Gia_ObjFaninId1p(p, pObj) : Gia_ObjFaninId0p(p, pObj); + if ( !Gia_ObjIsTravIdCurrentId(p, iFan) ) + Vec_IntPushUnique( vInputs, iFan ); + } + } + Vec_IntForEachEntry( vInputs, iObj, i ) + { + Gia_ObjSetTravIdCurrentId( p, iObj ); + Vec_IntPush( vWin, iObj ); + } + return vInputs; +} + +/**Function************************************************************* + + Synopsis [Grow window for the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_RsbAddSideInputs( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin ) +{ + Vec_Int_t * vLevel; + Gia_Obj_t * pObj, * pFanout; + int k, i, f, iObj; + // precondition: the levelized structure is empty + assert( Vec_WecSizeSize(vLevels) == 0 ); + // precondition: window nodes are labeled with the current ID + Vec_IntForEachEntry( vWin, iObj, i ) + { + assert( Gia_ObjIsTravIdCurrentId(p, iObj) ); + Vec_WecPush( vLevels, Gia_ObjLevelId(p, iObj), iObj ); + } + // iterate through all objects and explore their fanouts + Vec_WecForEachLevel( vLevels, vLevel, k ) + Gia_ManForEachObjVec( vLevel, p, pObj, i ) + Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f ) + { + if ( f == 5 ) // explore first 5 fanouts of the node + break; + if ( Gia_ObjIsAnd(pFanout) && // internal node + !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window + Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are + Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window + { + // add fanout to the window and to the levelized structure + Gia_ObjSetTravIdCurrent( p, pFanout ); + Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) ); + Vec_IntPush( vWin, Gia_ObjId(p, pFanout) ); + } + } + // iterate through the nodes in the levelized structure + Vec_WecForEachLevel( vLevels, vLevel, k ) + Vec_IntClear( vLevel ); +} +// expland inputs until saturation while adding the side-fanouts +void Gia_RsbExpandInputs( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vInputs ) +{ + Gia_Obj_t * pObj; + int i, n, iFans[2], fChange = 1; + while ( fChange ) + { + fChange = 0; + Gia_ManForEachObjVec( vInputs, p, pObj, i ) + { + if ( !Gia_ObjIsAnd(pObj) ) + continue; + iFans[0] = Gia_ObjFaninId0p(p, pObj); + iFans[1] = Gia_ObjFaninId1p(p, pObj); + if ( !Gia_ObjIsTravIdCurrentId(p, iFans[0]) && !Gia_ObjIsTravIdCurrentId(p, iFans[1]) ) + continue; + Vec_IntRemove( vInputs, Gia_ObjId(p, pObj) ); + assert( Vec_IntFind(vWin, Gia_ObjId(p, pObj)) >= 0 ); + for ( n = 0; n < 2; n++ ) + { + if ( Gia_ObjIsTravIdCurrentId(p, iFans[n]) ) + continue; + assert( Vec_IntFind(vInputs, iFans[n]) == -1 ); + Vec_IntPush( vInputs, iFans[n] ); + Gia_WinTryAddingNode( p, iFans[n], -1, vLevels, vWin ); + assert( Gia_ObjIsTravIdCurrentId(p, iFans[n]) ); + } + fChange = 1; + } + } +} +// select the best input to expand, based on its contribution to the window size +int Gia_RsbSelectOneInput( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vIns ) +{ + int i, iNode = 0, WeightThis, WeightBest = -1; + Gia_Obj_t * pObj; + Gia_ManForEachObjVec( vIns, p, pObj, i ) + if ( Gia_ObjIsAnd(pObj) ) + { + int iFan0 = Gia_ObjFaninId0p(p, pObj); + int iFan1 = Gia_ObjFaninId1p(p, pObj); + assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) && !Gia_ObjIsTravIdCurrentId(p, iFan1) ); + WeightThis = Gia_WinTryAddingNode( p, iFan0, iFan1, vLevels, NULL ); + if ( WeightBest < WeightThis ) + { + WeightBest = WeightThis; + iNode = Gia_ObjId(p, pObj); + } + } + return iNode; +} +// grow the initial window as long as it fits the input count limit +void Gia_RsbWindowGrow( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vIns, int nInputsMax ) +{ + int iNode; + Gia_RsbAddSideInputs( p, vLevels, vWin ); + Gia_RsbExpandInputs( p, vLevels, vWin, vIns ); + while ( Vec_IntSize(vIns) < nInputsMax && (iNode = Gia_RsbSelectOneInput(p, vLevels, vIns)) ) + { + int iFan0 = Gia_ObjFaninId0p(p, Gia_ManObj(p, iNode)); + int iFan1 = Gia_ObjFaninId1p(p, Gia_ManObj(p, iNode)); + assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) && !Gia_ObjIsTravIdCurrentId(p, iFan1) ); + Gia_WinTryAddingNode( p, iFan0, iFan1, vLevels, vWin ); + assert( Gia_ObjIsTravIdCurrentId(p, iFan0) && Gia_ObjIsTravIdCurrentId(p, iFan1) ); + Vec_IntRemove( vIns, iNode ); + Vec_IntPushTwo( vIns, iFan0, iFan1 ); + Gia_RsbExpandInputs( p, vLevels, vWin, vIns ); + } +} + +/**Function************************************************************* + + Synopsis [Create window for the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_RsbWindowCompute( Gia_Man_t * p, int iObj, int nInputsMax, int nLevelsMax, Vec_Wec_t * vLevels, Vec_Int_t * vPaths, Vec_Int_t ** pvWin, Vec_Int_t ** pvIns ) +{ + Vec_Int_t * vWin, * vIns; + *pvWin = *pvIns = NULL; + vWin = Gia_RsbWindowInit( p, vPaths, iObj, nLevelsMax ); + if ( vWin == NULL ) + return 0; + vIns = Gia_RsbCreateWindowInputs( p, vWin ); + // vWin and vIns are labeled with the current trav ID + //Vec_IntPrint( vWin ); + //Vec_IntPrint( vIns ); + if ( Vec_IntSize(vIns) <= nInputsMax + 2 ) // consider windows, which initially has a larger input space + Gia_RsbWindowGrow( p, vLevels, vWin, vIns, nInputsMax ); + if ( Vec_IntSize(vIns) <= nInputsMax ) + { + Vec_IntSort( vWin, 0 ); + Vec_IntSort( vIns, 0 ); + *pvWin = vWin; + *pvIns = vIns; + return 1; + } + else + { + Vec_IntFree( vWin ); + Vec_IntFree( vIns ); + return 0; + } +} + +/**Function************************************************************* + + Synopsis [Enumerate windows of the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax ) +{ + int fVerbose = 0; + int i, nWins = 0, nWinSize = 0, nInsSize = 0; + Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 ); + Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj; + abctime clk = Abc_Clock(); + Gia_ManStaticFanoutStart( p ); + Gia_ManForEachAnd( p, pObj, i ) + { + Vec_Int_t * vWin, * vIns; + if ( !Gia_RsbWindowCompute( p, i, nInputsMax, nLevelsMax, vLevels, vPaths, &vWin, &vIns ) ) + continue; + nWins++; + nWinSize += Vec_IntSize(vWin); + nInsSize += Vec_IntSize(vIns); + if ( fVerbose ) + { + printf( "Obj %d\n", i ); + Vec_IntPrint( vWin ); + Vec_IntPrint( vIns ); + printf( "\n" ); + } + Vec_IntFree( vWin ); + Vec_IntFree( vIns ); + + } + Gia_ManStaticFanoutStop( p ); + Vec_WecFree( vLevels ); + Vec_IntFree( vPaths ); + printf( "Computed windows for %d nodes (out of %d). Ave inputs = %.2f. Ave volume = %.2f. ", + nWins, Gia_ManAndNum(p), 1.0*nInsSize/Abc_MaxInt(1,nWins), 1.0*nWinSize/Abc_MaxInt(1,nWins) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 8ef44045420766b66aed22e1d4ed9ce3cd16906a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 6 Sep 2020 22:34:45 -0700 Subject: Verifying new resub code. --- src/aig/gia/giaResub2.c | 174 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 155 insertions(+), 19 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index 18fd5f8f..fc850501 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -399,9 +399,9 @@ int Abc_ResubNodeToTry( Vec_Int_t * vTried, int iFirst, int iLast ) return iNode; return -1; } -int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray ) +int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray, int * pnResubs ) { - int RetValue = 0, iNode, fChange = 0; + int iNode, nChanges = 0, RetValue = 0; Gia_Rsb2Man_t * p = Gia_Rsb2ManAlloc(); Gia_Rsb2ManStart( p, pObjs, nObjs, nDivsMax, nLevelIncrease, fUseXor, fUseZeroCost, fDebug, fVerbose ); *ppArray = NULL; @@ -416,8 +416,8 @@ int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncr int i, k = 0, iTried; Vec_Int_t vResub = { nResub, nResub, pResub }; Vec_Int_t * vRes = Gia_Rsb2ManInsert( p->nPis, p->nPos, &p->vObjs, iNode, &vResub, &p->vDivs, &p->vCopies ); -//printf( "\nResubbing node %d:\n", iNode ); -//Gia_Rsb2ManPrint( p ); + //printf( "\nResubing node %d:\n", iNode ); + //Gia_Rsb2ManPrint( p ); p->nObjs = Vec_IntSize(vRes)/2; p->iFirstPo = p->nObjs - p->nPos; Vec_IntClear( &p->vObjs ); @@ -427,23 +427,27 @@ int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncr if ( Vec_IntEntry(&p->vCopies, i) > 0 ) Vec_IntWriteEntry( &p->vTried, k++, iTried ); Vec_IntShrink( &p->vTried, k ); - fChange = 1; -//Gia_Rsb2ManPrint( p ); + nChanges++; + //Gia_Rsb2ManPrint( p ); } } - if ( fChange ) + if ( nChanges ) { RetValue = p->nObjs; *ppArray = p->vObjs.pArray; Vec_IntZero( &p->vObjs ); } Gia_Rsb2ManFree( p ); + if ( pnResubs ) + *pnResubs = nChanges; return RetValue; } -int Abc_ResubComputeWindow2( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray ) +int Abc_ResubComputeWindow2( int * pObjs, int nObjs, int nDivsMax, int nLevelIncrease, int fUseXor, int fUseZeroCost, int fDebug, int fVerbose, int ** ppArray, int * pnResubs ) { *ppArray = ABC_ALLOC( int, 2*nObjs ); memmove( *ppArray, pObjs, 2*nObjs * sizeof(int) ); + if ( pnResubs ) + *pnResubs = 0; return nObjs; } @@ -476,13 +480,13 @@ int * Gia_ManToResub( Gia_Man_t * p ) } return pObjs; } -Gia_Man_t * Gia_ManFromResub( int * pObjs, int nObjs ) +Gia_Man_t * Gia_ManFromResub( int * pObjs, int nObjs, int nIns ) { Gia_Man_t * pNew = Gia_ManStart( nObjs ); int i; for ( i = 1; i < nObjs; i++ ) { - if ( pObjs[2*i] == 0 ) // pi + if ( pObjs[2*i] == 0 && i <= nIns ) // pi Gia_ManAppendCi( pNew ); else if ( pObjs[2*i] == pObjs[2*i+1] ) // po Gia_ManAppendCo( pNew, pObjs[2*i] ); @@ -497,11 +501,16 @@ Gia_Man_t * Gia_ManFromResub( int * pObjs, int nObjs ) Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p ) { Gia_Man_t * pNew; - int nObjsNew, * pObjsNew, * pObjs = Gia_ManToResub( p ); + int nResubs, nObjsNew, * pObjsNew, * pObjs = Gia_ManToResub( p ); +//Gia_ManPrint( p ); Abc_ResubPrepareManager( 1 ); - nObjsNew = Abc_ResubComputeWindow( pObjs, Gia_ManObjNum(p), 1000, -1, 0, 0, 0, 0, &pObjsNew ); + nObjsNew = Abc_ResubComputeWindow( pObjs, Gia_ManObjNum(p), 1000, -1, 0, 0, 0, 0, &pObjsNew, &nResubs ); + printf( "Performed resub %d times. Reduced %d nodes.\n", nResubs, nObjsNew ? Gia_ManObjNum(p) - nObjsNew : 0 ); Abc_ResubPrepareManager( 0 ); - pNew = Gia_ManFromResub( pObjsNew, nObjsNew ); + if ( nObjsNew ) + pNew = Gia_ManFromResub( pObjsNew, nObjsNew, Gia_ManCiNum(p) ); + else + pNew = Gia_ManDup( p ); ABC_FREE( pObjs ); ABC_FREE( pObjsNew ); return pNew; @@ -964,6 +973,116 @@ int Gia_RsbWindowCompute( Gia_Man_t * p, int iObj, int nInputsMax, int nLevelsMa } } +/**Function************************************************************* + + Synopsis [Derive GIA from the window] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_RsbFindOutputs( Gia_Man_t * p, Vec_Int_t * vWin, Vec_Int_t * vIns, Vec_Int_t * vRefs ) +{ + Vec_Int_t * vOuts = Vec_IntAlloc( 100 ); + Gia_Obj_t * pObj; int i; + Gia_ManForEachObjVec( vWin, p, pObj, i ) + if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), 1 ); + Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1p(p, pObj), 1 ); + } + Gia_ManForEachObjVec( vIns, p, pObj, i ) + Vec_IntWriteEntry( vRefs, Gia_ObjId(p, pObj), Gia_ObjFanoutNum(p, pObj) ); + Gia_ManForEachObjVec( vWin, p, pObj, i ) + if ( Gia_ObjFanoutNum(p, pObj) != Vec_IntEntry(vRefs, Gia_ObjId(p, pObj)) ) + Vec_IntPush( vOuts, Gia_ObjId(p, pObj) ); + Gia_ManForEachObjVec( vWin, p, pObj, i ) + if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), -1 ); + Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1p(p, pObj), -1 ); + } + return vOuts; +} + +Gia_Man_t * Gia_RsbDeriveGiaFromWindows( Gia_Man_t * p, Vec_Int_t * vWin, Vec_Int_t * vIns, Vec_Int_t * vOuts ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManHashAlloc( pNew ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObjVec( vIns, p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachObjVec( vWin, p, pObj, i ) + if ( !~pObj->Value ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachObjVec( vOuts, p, pObj, i ) + Gia_ManAppendCo( pNew, pObj->Value ); + Gia_ManHashStop( pNew ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Naive truth-table-based verification.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Gia_LutComputeTruth66_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + word Truth0, Truth1; + if ( Gia_ObjIsCi(pObj) ) + return s_Truths6[Gia_ObjCioId(pObj)]; + if ( Gia_ObjIsConst0(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Truth0 = Gia_LutComputeTruth66_rec( p, Gia_ObjFanin0(pObj) ); + Truth1 = Gia_LutComputeTruth66_rec( p, Gia_ObjFanin1(pObj) ); + if ( Gia_ObjFaninC0(pObj) ) + Truth0 = ~Truth0; + if ( Gia_ObjFaninC1(pObj) ) + Truth1 = ~Truth1; + return Truth0 & Truth1; +} +void Gia_ManVerifyTwoTruths( Gia_Man_t * p1, Gia_Man_t * p2 ) +{ + int i, fFailed = 0; + assert( Gia_ManCoNum(p1) == Gia_ManCoNum(p2) ); + for ( i = 0; i < Gia_ManCoNum(p1); i++ ) + { + Gia_Obj_t * pPo1 = Gia_ManCo(p1, i); + Gia_Obj_t * pPo2 = Gia_ManCo(p2, i); + word word1 = Gia_LutComputeTruth66_rec( p1, Gia_ObjFanin0(pPo1) ); + word word2 = Gia_LutComputeTruth66_rec( p2, Gia_ObjFanin0(pPo2) ); + if ( Gia_ObjFaninC0(pPo1) ) + word1 = ~word1; + if ( Gia_ObjFaninC0(pPo2) ) + word2 = ~word2; + if ( word1 != word2 ) + { + printf( "Verification failed for output %d (out of %d).\n", i, Gia_ManCoNum(p1) ); + fFailed = 1; + } + } + if ( !fFailed ) + printf( "Verification succeeded for %d outputs.\n", Gia_ManCoNum(p1) ); +} + + + /**Function************************************************************* Synopsis [Enumerate windows of the nodes.] @@ -978,36 +1097,53 @@ int Gia_RsbWindowCompute( Gia_Man_t * p, int iObj, int nInputsMax, int nLevelsMa void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax ) { int fVerbose = 0; - int i, nWins = 0, nWinSize = 0, nInsSize = 0; + int i, nWins = 0, nWinSize = 0, nInsSize = 0, nOutSize = 0; Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 ); Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vRefs = Vec_IntStart( Gia_ManObjNum(p) ); Gia_Obj_t * pObj; + Gia_Man_t * pIn, * pOut; abctime clk = Abc_Clock(); Gia_ManStaticFanoutStart( p ); Gia_ManForEachAnd( p, pObj, i ) { - Vec_Int_t * vWin, * vIns; + Vec_Int_t * vWin, * vIns, * vOuts; if ( !Gia_RsbWindowCompute( p, i, nInputsMax, nLevelsMax, vLevels, vPaths, &vWin, &vIns ) ) continue; + vOuts = Gia_RsbFindOutputs( p, vWin, vIns, vRefs ); nWins++; nWinSize += Vec_IntSize(vWin); nInsSize += Vec_IntSize(vIns); + nOutSize += Vec_IntSize(vOuts); if ( fVerbose ) { - printf( "Obj %d\n", i ); + printf( "\n\nObj %d\n", i ); Vec_IntPrint( vWin ); Vec_IntPrint( vIns ); + Vec_IntPrint( vOuts ); printf( "\n" ); } + else + printf( "\nObj %d. Window: Ins = %d. Ands = %d. Outs = %d.\n", + i, Vec_IntSize(vIns), Vec_IntSize(vWin)-Vec_IntSize(vIns), Vec_IntSize(vOuts) ); + + pIn = Gia_RsbDeriveGiaFromWindows( p, vWin, vIns, vOuts ); + pOut = Gia_ManResub2Test( pIn ); + Gia_ManVerifyTwoTruths( pIn, pOut ); + + Gia_ManStop( pIn ); + Gia_ManStop( pOut ); + Vec_IntFree( vWin ); Vec_IntFree( vIns ); - + Vec_IntFree( vOuts ); } Gia_ManStaticFanoutStop( p ); Vec_WecFree( vLevels ); Vec_IntFree( vPaths ); - printf( "Computed windows for %d nodes (out of %d). Ave inputs = %.2f. Ave volume = %.2f. ", - nWins, Gia_ManAndNum(p), 1.0*nInsSize/Abc_MaxInt(1,nWins), 1.0*nWinSize/Abc_MaxInt(1,nWins) ); + Vec_IntFree( vRefs ); + printf( "\nComputed windows for %d nodes (out of %d). Ave inputs = %.2f. Ave outputs = %.2f. Ave volume = %.2f. ", + nWins, Gia_ManAndNum(p), 1.0*nInsSize/Abc_MaxInt(1,nWins), 1.0*nOutSize/Abc_MaxInt(1,nWins), 1.0*nWinSize/Abc_MaxInt(1,nWins) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } -- cgit v1.2.3 From 07bf95f48019dd5472ffffbd32587879e1bcbb9f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 13 Sep 2020 19:17:16 -0700 Subject: Experiments with iterative synthesis. --- src/aig/gia/giaDeep.c | 107 +++++++++++++++++++++++++++++++++++++++++++++-- src/aig/gia/giaSimBase.c | 22 +++++++++- 2 files changed, 124 insertions(+), 5 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaDeep.c b/src/aig/gia/giaDeep.c index f8b2930e..aa9e9cb2 100644 --- a/src/aig/gia/giaDeep.c +++ b/src/aig/gia/giaDeep.c @@ -19,14 +19,14 @@ ***********************************************************************/ #include "gia.h" +#include "base/main/main.h" +#include "base/cmd/cmd.h" ABC_NAMESPACE_IMPL_START - //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -43,9 +43,108 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int TimeOut, int nAnds, int Seed, int fVerbose ) +Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose ) +{ + abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0; + abctime clkStart = Abc_Clock(); + int s, i, IterMax = 100000, nAndsMin = -1, iIterLast = -1; + Gia_Man_t * pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame()); + Gia_Man_t * pNew = Gia_ManDup( pTemp ); + Abc_Random(1); + for ( s = 0; s < 10+Seed; s++ ) + Abc_Random(0); + for ( i = 0; i < IterMax; i++ ) + { + unsigned Rand = Abc_Random(0); + int fDch = Rand & 1; + //int fCom = (Rand >> 1) & 3; + int fCom = (Rand >> 1) & 1; + int fFx = (Rand >> 2) & 1; + int KLut = fUseTwo ? 2 + (i % 5) : 3 + (i % 4); + int fChange = 0; + char Command[1000]; + char * pComp = NULL; + if ( fCom == 3 ) + pComp = "; &put; compress2rs; compress2rs; compress2rs; &get"; + else if ( fCom == 2 ) + pComp = "; &put; compress2rs; compress2rs; &get"; + else if ( fCom == 1 ) + pComp = "; &put; compress2rs; &get"; + else if ( fCom == 0 ) + pComp = "; &dc2"; + sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s", + fDch ? " -f" : "", KLut, fFx ? "; &fx" : "", pComp ); + if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) ) + { + Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command ); + return NULL; + } + pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame()); + if ( Gia_ManAndNum(pNew) > Gia_ManAndNum(pTemp) ) + { + Gia_ManStop( pNew ); + pNew = Gia_ManDup( pTemp ); + fChange = 1; + iIterLast = i; + } + else if ( Gia_ManAndNum(pNew) + Gia_ManAndNum(pNew)/10 < Gia_ManAndNum(pTemp) ) + { + //printf( "Updating\n" ); + //Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pNew) ); + } + if ( fChange && fVerbose ) + { + printf( "Iter %6d : ", i ); + printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC ); + printf( "And = %6d ", Gia_ManAndNum(pNew) ); + printf( "Lev = %3d ", Gia_ManLevelNum(pNew) ); + if ( fChange ) + printf( "<== best : " ); + else if ( fVerbose ) + printf( " " ); + printf( "%s", Command ); + printf( "\n" ); + } + if ( nTimeToStop && Abc_Clock() > nTimeToStop ) + { + printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i ); + break; + } + if ( i - iIterLast > nNoImpr ) + { + printf( "Completed %d iterations without improvement in %.2f seconds.\n", + nNoImpr, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC ); + break; + } + } + if ( i == IterMax ) + printf( "Iteration limit (%d iters) is reached after %.2f seconds.\n", IterMax, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC ); + else if ( nAnds && nAndsMin <= nAnds ) + printf( "Quality goal (%d nodes <= %d nodes) is achieved after %d iterations and %.2f seconds.\n", + nAndsMin, nAnds, i, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC ); + return pNew; +} +Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose ) { - return NULL; + Gia_Man_t * pInit = Gia_ManDup(pGia); + Gia_Man_t * pBest = Gia_ManDup(pGia); + Gia_Man_t * pThis; + int i; + for ( i = 0; i < nIters; i++ ) + { + Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pInit) ); + pThis = Gia_ManDeepSynOne( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose ); + if ( Gia_ManAndNum(pBest) > Gia_ManAndNum(pThis) ) + { + Gia_ManStop( pBest ); + pBest = pThis; + } + else + Gia_ManStop( pThis ); + + } + Gia_ManStop( pInit ); + return pBest; } //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index efa4c187..f12cc83f 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -113,7 +113,13 @@ static inline void Gia_ManSimPatSimPo( Gia_Man_t * p, int i, Gia_Obj_t * pObj, i word * pSims0 = pSims + nWords*Gia_ObjFaninId0(pObj, i); word * pSims2 = pSims + nWords*i; int w; for ( w = 0; w < nWords; w++ ) - pSims2[w] = (pSims0[w] ^ Diff0); + pSims2[w] = (pSims0[w] ^ Diff0); +} +static inline void Gia_ManSimPatSimNot( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims ) +{ + word * pSims = Vec_WrdArray(vSims) + nWords*i; int w; + for ( w = 0; w < nWords; w++ ) + pSims[w] = ~pSims[w]; } Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia ) { @@ -128,6 +134,20 @@ Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia ) Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); return vSims; } +void Gia_ManSimPatResim( Gia_Man_t * pGia, Vec_Int_t * vObjs, int nWords, Vec_Wrd_t * vSims ) +{ + Gia_Obj_t * pObj; int i; + Gia_ManForEachObjVec( vObjs, pGia, pObj, i ) + if ( i == 0 ) + Gia_ManSimPatSimNot( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); + else if ( Gia_ObjIsAnd(pObj) ) + Gia_ManSimPatSimAnd( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); + else if ( !Gia_ObjIsCo(pObj) ) assert(0); +} +void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ) +{ + Vec_WrdDumpHex( pFileName, vSimsIn, nWords, 0 ); +} /**Function************************************************************* -- cgit v1.2.3 From bab462d5cddf4c7d607cf5396f4cbb0498978a5c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 13 Sep 2020 20:33:59 -0700 Subject: Compiler warnings. --- src/aig/gia/giaSimBase.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index f12cc83f..db29bbed 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -2104,7 +2104,7 @@ void Gia_ManSimGen( Gia_Man_t * pGia ) Gia_ManForEachCiId( pGia, Id, i ) { word * pSim = Vec_WrdEntryP(vSim0, i*nWords); - unsigned * pSimU = (unsigned *)pSim; + //unsigned * pSimU = (unsigned *)pSim; for ( k = 0; k < nWords; k++ ) fprintf( pFile, " unsigned long s%07d_%d = ((unsigned long)rand() << 48) | ((unsigned long)rand() << 32) | ((unsigned long)rand() << 16) | (unsigned long)rand();\n", Id, k ); } -- cgit v1.2.3 From fb769cf9aba46b9c3b690618d7479740917af029 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 16 Sep 2020 19:55:38 -0700 Subject: Bug fixed in the resub code. --- src/aig/gia/giaResub2.c | 85 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 12 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index fc850501..ac086b68 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -20,6 +20,8 @@ #include "gia.h" #include "misc/util/utilTruth.h" +#include "misc/vec/vecHsh.h" +#include "opt/dau/dau.h" ABC_NAMESPACE_IMPL_START @@ -301,6 +303,26 @@ int Gia_Rsb2AddNode( Vec_Int_t * vRes, int iLit0, int iLit1, int iRes0, int iRes int iLitMin = iRes0 < iRes1 ? Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)) : Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)); int iLitMax = iRes0 < iRes1 ? Abc_LitNotCond(iRes1, Abc_LitIsCompl(iLit1)) : Abc_LitNotCond(iRes0, Abc_LitIsCompl(iLit0)); int iLitRes = Vec_IntSize(vRes); + if ( iLit0 < iLit1 ) // and + { + if ( iLitMin == 0 ) + return 0; + if ( iLitMin == 1 ) + return iLitMax; + if ( iLitMin == Abc_LitNot(iLitMax) ) + return 0; + } + else if ( iLit0 > iLit1 ) // xor + { + if ( iLitMin == 0 ) + return iLitMax; + if ( iLitMin == 1 ) + return Abc_LitNot(iLitMax); + if ( iLitMin == Abc_LitNot(iLitMax) ) + return 1; + } + else assert( 0 ); + assert( iLitMin >= 2 && iLitMax >= 2 ); if ( iLit0 < iLit1 ) // and Vec_IntPushTwo( vRes, iLitMin, iLitMax ); else if ( iLit0 > iLit1 ) // xor @@ -390,6 +412,16 @@ Vec_Int_t * Gia_Rsb2ManInsert( int nPis, int nPos, Vec_Int_t * vObjs, int iNode, SeeAlso [] ***********************************************************************/ +void Abc_ResubPrintDivs( void ** ppDivs, int nDivs ) +{ + word ** pDivs = (word **)ppDivs; + int i; + for ( i = 0; i < nDivs; i++ ) + { + printf( "Div %2d : ", i ); + Dau_DsdPrintFromTruth( ppDivs[i], 6 ); + } +} int Abc_ResubNodeToTry( Vec_Int_t * vTried, int iFirst, int iLast ) { int iNode; @@ -424,8 +456,8 @@ int Abc_ResubComputeWindow( int * pObjs, int nObjs, int nDivsMax, int nLevelIncr Vec_IntAppend( &p->vObjs, vRes ); Vec_IntFree( vRes ); Vec_IntForEachEntry( &p->vTried, iTried, i ) - if ( Vec_IntEntry(&p->vCopies, i) > 0 ) - Vec_IntWriteEntry( &p->vTried, k++, iTried ); + if ( Vec_IntEntry(&p->vCopies, iTried) > Abc_Var2Lit(p->nPis, 0) ) // internal node + Vec_IntWriteEntry( &p->vTried, k++, Abc_Lit2Var(Vec_IntEntry(&p->vCopies, iTried)) ); Vec_IntShrink( &p->vTried, k ); nChanges++; //Gia_Rsb2ManPrint( p ); @@ -505,7 +537,7 @@ Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p ) //Gia_ManPrint( p ); Abc_ResubPrepareManager( 1 ); nObjsNew = Abc_ResubComputeWindow( pObjs, Gia_ManObjNum(p), 1000, -1, 0, 0, 0, 0, &pObjsNew, &nResubs ); - printf( "Performed resub %d times. Reduced %d nodes.\n", nResubs, nObjsNew ? Gia_ManObjNum(p) - nObjsNew : 0 ); + //printf( "Performed resub %d times. Reduced %d nodes.\n", nResubs, nObjsNew ? Gia_ManObjNum(p) - nObjsNew : 0 ); Abc_ResubPrepareManager( 0 ); if ( nObjsNew ) pNew = Gia_ManFromResub( pObjsNew, nObjsNew, Gia_ManCiNum(p) ); @@ -1057,7 +1089,7 @@ word Gia_LutComputeTruth66_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) Truth1 = ~Truth1; return Truth0 & Truth1; } -void Gia_ManVerifyTwoTruths( Gia_Man_t * p1, Gia_Man_t * p2 ) +int Gia_ManVerifyTwoTruths( Gia_Man_t * p1, Gia_Man_t * p2 ) { int i, fFailed = 0; assert( Gia_ManCoNum(p1) == Gia_ManCoNum(p2) ); @@ -1073,12 +1105,15 @@ void Gia_ManVerifyTwoTruths( Gia_Man_t * p1, Gia_Man_t * p2 ) word2 = ~word2; if ( word1 != word2 ) { + //Dau_DsdPrintFromTruth( &word1, 6 ); + //Dau_DsdPrintFromTruth( &word2, 6 ); printf( "Verification failed for output %d (out of %d).\n", i, Gia_ManCoNum(p1) ); fFailed = 1; } } - if ( !fFailed ) - printf( "Verification succeeded for %d outputs.\n", Gia_ManCoNum(p1) ); +// if ( !fFailed ) +// printf( "Verification succeeded for %d outputs.\n", Gia_ManCoNum(p1) ); + return !fFailed; } @@ -1097,10 +1132,12 @@ void Gia_ManVerifyTwoTruths( Gia_Man_t * p1, Gia_Man_t * p2 ) void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax ) { int fVerbose = 0; - int i, nWins = 0, nWinSize = 0, nInsSize = 0, nOutSize = 0; + int fUseHash = 1; + int i, nWins = 0, nWinSize = 0, nInsSize = 0, nOutSize = 0, nNodeGain = 0; Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 ); Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) ); Vec_Int_t * vRefs = Vec_IntStart( Gia_ManObjNum(p) ); + Hsh_VecMan_t * pHash = Hsh_VecManStart( 1000 ); Gia_Obj_t * pObj; Gia_Man_t * pIn, * pOut; abctime clk = Abc_Clock(); @@ -1115,6 +1152,8 @@ void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax ) nWinSize += Vec_IntSize(vWin); nInsSize += Vec_IntSize(vIns); nOutSize += Vec_IntSize(vOuts); + + if ( fVerbose ) { printf( "\n\nObj %d\n", i ); @@ -1123,14 +1162,34 @@ void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax ) Vec_IntPrint( vOuts ); printf( "\n" ); } - else - printf( "\nObj %d. Window: Ins = %d. Ands = %d. Outs = %d.\n", + else if ( Vec_IntSize(vWin) > 1000 ) + printf( "Obj %d. Window: Ins = %d. Ands = %d. Outs = %d.\n", i, Vec_IntSize(vIns), Vec_IntSize(vWin)-Vec_IntSize(vIns), Vec_IntSize(vOuts) ); + if ( fUseHash ) + { + int nEntries = Hsh_VecSize(pHash); + Hsh_VecManAdd( pHash, vWin ); + if ( nEntries == Hsh_VecSize(pHash) ) + { + Vec_IntFree( vWin ); + Vec_IntFree( vIns ); + Vec_IntFree( vOuts ); + continue; + } + } + pIn = Gia_RsbDeriveGiaFromWindows( p, vWin, vIns, vOuts ); pOut = Gia_ManResub2Test( pIn ); - Gia_ManVerifyTwoTruths( pIn, pOut ); + //pOut = Gia_ManDup( pIn ); + if ( !Gia_ManVerifyTwoTruths( pIn, pOut ) ) + { + Gia_ManPrint( pIn ); + Gia_ManPrint( pOut ); + pOut = pOut; + } + nNodeGain += Gia_ManAndNum(pIn) - Gia_ManAndNum(pOut); Gia_ManStop( pIn ); Gia_ManStop( pOut ); @@ -1142,9 +1201,11 @@ void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax ) Vec_WecFree( vLevels ); Vec_IntFree( vPaths ); Vec_IntFree( vRefs ); - printf( "\nComputed windows for %d nodes (out of %d). Ave inputs = %.2f. Ave outputs = %.2f. Ave volume = %.2f. ", - nWins, Gia_ManAndNum(p), 1.0*nInsSize/Abc_MaxInt(1,nWins), 1.0*nOutSize/Abc_MaxInt(1,nWins), 1.0*nWinSize/Abc_MaxInt(1,nWins) ); + printf( "Computed windows for %d nodes (out of %d). Unique = %d. Ave inputs = %.2f. Ave outputs = %.2f. Ave volume = %.2f. Gain = %d. ", + nWins, Gia_ManAndNum(p), Hsh_VecSize(pHash), 1.0*nInsSize/Abc_MaxInt(1,nWins), + 1.0*nOutSize/Abc_MaxInt(1,nWins), 1.0*nWinSize/Abc_MaxInt(1,nWins), nNodeGain ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Hsh_VecManStop( pHash ); } //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 083c1218e5a1742e881d0ce9e90c8cd0b53748a7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 17 Sep 2020 13:04:09 -0700 Subject: Improving MFFC computation code. --- src/aig/gia/giaSim4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSim4.c b/src/aig/gia/giaSim4.c index 6ce89cf0..56dcb713 100644 --- a/src/aig/gia/giaSim4.c +++ b/src/aig/gia/giaSim4.c @@ -41,7 +41,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fVerbose ) +int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fSkipMffc, int fVerbose ) { return 0; } -- cgit v1.2.3 From 63fc01ccbda851b34647de6ee57b36a82e1e6d48 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 17 Sep 2020 13:07:14 -0700 Subject: Compiler warnings. --- src/aig/gia/giaResub2.c | 2 +- src/aig/gia/giaSimBase.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index ac086b68..23d73dd8 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -419,7 +419,7 @@ void Abc_ResubPrintDivs( void ** ppDivs, int nDivs ) for ( i = 0; i < nDivs; i++ ) { printf( "Div %2d : ", i ); - Dau_DsdPrintFromTruth( ppDivs[i], 6 ); + Dau_DsdPrintFromTruth( pDivs[i], 6 ); } } int Abc_ResubNodeToTry( Vec_Int_t * vTried, int iFirst, int iLast ) diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index db29bbed..2e61c1ff 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -2103,7 +2103,7 @@ void Gia_ManSimGen( Gia_Man_t * pGia ) fprintf( pFile, " unsigned long s%07d_%d = 0x%08x%08x;\n", 0, k, 0, 0 ); Gia_ManForEachCiId( pGia, Id, i ) { - word * pSim = Vec_WrdEntryP(vSim0, i*nWords); + //word * pSim = Vec_WrdEntryP(vSim0, i*nWords); //unsigned * pSimU = (unsigned *)pSim; for ( k = 0; k < nWords; k++ ) fprintf( pFile, " unsigned long s%07d_%d = ((unsigned long)rand() << 48) | ((unsigned long)rand() << 32) | ((unsigned long)rand() << 16) | (unsigned long)rand();\n", Id, k ); -- cgit v1.2.3 From 55f4751f7569bcdc4c7b24628a1404d31c43b375 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 17 Sep 2020 18:08:31 -0700 Subject: Experiment with using MUXes in k-resub engine. --- src/aig/gia/giaResub.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 6 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index a32d0094..b0b67c46 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -1068,6 +1068,99 @@ void Gia_ManSortBinate( word * pSets[2], Vec_Ptr_t * vDivs, int nWords, Vec_Int_ Vec_IntShrink( vBinateVars, 2000 ); } +/**Function************************************************************* + + Synopsis [Perform resubstitution.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManResubFindBestBinate( Gia_ResbMan_t * p ) +{ + int nMintsAll = Abc_TtCountOnesVec(p->pSets[0], p->nWords) + Abc_TtCountOnesVec(p->pSets[1], p->nWords); + int i, iDiv, iLitBest = -1, CostBest = -1; +//Vec_IntPrint( p->vBinateVars ); +//Dau_DsdPrintFromTruth( p->pSets[0], 6 ); +//Dau_DsdPrintFromTruth( p->pSets[1], 6 ); + Vec_IntForEachEntry( p->vBinateVars, iDiv, i ) + { + word * pDiv = (word *)Vec_PtrEntry(p->vDivs, iDiv); + int nMints0 = Abc_TtCountOnesVecMask( pDiv, p->pSets[0], p->nWords, 0 ); + int nMints1 = Abc_TtCountOnesVecMask( pDiv, p->pSets[1], p->nWords, 0 ); + if ( CostBest < nMints0 + nMints1 ) + { + CostBest = nMints0 + nMints1; + iLitBest = Abc_Var2Lit( iDiv, 0 ); + } + if ( CostBest < nMintsAll - nMints0 - nMints1 ) + { + CostBest = nMintsAll - nMints0 - nMints1; + iLitBest = Abc_Var2Lit( iDiv, 1 ); + } + } + return iLitBest; +} +int Gia_ManResubAddNode( Gia_ResbMan_t * p, int iLit0, int iLit1, int Type ) +{ + int iNode = Vec_PtrSize(p->vDivs) + Vec_IntSize(p->vGates)/2; + int fFlip = (Type == 2) ^ (iLit0 > iLit1); + int iFan0 = fFlip ? iLit1 : iLit0; + int iFan1 = fFlip ? iLit0 : iLit1; + assert( iLit0 != iLit1 ); + if ( Type == 2 ) + assert( iFan0 > iFan1 ); + else + assert( iFan0 < iFan1 ); + Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iFan0, Type==1), Abc_LitNotCond(iFan1, Type==1) ); + return Abc_Var2Lit( iNode, Type==1 ); +} +int Gia_ManResubPerformMux_rec( Gia_ResbMan_t * p, int nLimit ) +{ + extern int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ); + int iDivBest, iResLit0, iResLit1, nNodes; + word * pDiv, * pCopy[2]; + if ( nLimit < 3 ) + return -1; + iDivBest = Gia_ManResubFindBestBinate( p ); + if ( iDivBest == -1 ) + return -1; + pCopy[0] = ABC_CALLOC( word, p->nWords ); + pCopy[1] = ABC_CALLOC( word, p->nWords ); + Abc_TtCopy( pCopy[0], p->pSets[0], p->nWords, 0 ); + Abc_TtCopy( pCopy[1], p->pSets[1], p->nWords, 0 ); + pDiv = (word *)Vec_PtrEntry( p->vDivs, Abc_Lit2Var(iDivBest) ); + Abc_TtAndSharp( p->pSets[0], pCopy[0], pDiv, p->nWords, !Abc_LitIsCompl(iDivBest) ); + Abc_TtAndSharp( p->pSets[1], pCopy[1], pDiv, p->nWords, !Abc_LitIsCompl(iDivBest) ); + nNodes = Vec_IntSize(p->vGates)/2; + iResLit0 = Gia_ManResubPerform_rec( p, nLimit-3 ); + if ( iResLit0 == -1 ) + { + ABC_FREE( pCopy[0] ); + ABC_FREE( pCopy[1] ); + return -1; + } + Abc_TtAndSharp( p->pSets[0], pCopy[0], pDiv, p->nWords, Abc_LitIsCompl(iDivBest) ); + Abc_TtAndSharp( p->pSets[1], pCopy[1], pDiv, p->nWords, Abc_LitIsCompl(iDivBest) ); + ABC_FREE( pCopy[0] ); + ABC_FREE( pCopy[1] ); + nNodes = Vec_IntSize(p->vGates)/2 - nNodes; + if ( nLimit-nNodes < 3 ) + return -1; + iResLit1 = Gia_ManResubPerform_rec( p, nLimit-3-nNodes ); + if ( iResLit1 == -1 ) + return -1; + else + { + int iLit0 = Gia_ManResubAddNode( p, Abc_LitNot(iDivBest), iResLit0, 0 ); + int iLit1 = Gia_ManResubAddNode( p, iDivBest, iResLit1, 0 ); + return Gia_ManResubAddNode( p, iLit0, iLit1, 1 ); + } +} + /**Function************************************************************* Synopsis [Perform resubstitution.] @@ -1112,6 +1205,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) return Abc_Var2Lit( iNode, fComp ); } Vec_IntTwoFindCommon( p->vNotUnateVars[0], p->vNotUnateVars[1], p->vBinateVars ); + //return Gia_ManResubPerformMux_rec( p, nLimit ); if ( Vec_IntSize(p->vBinateVars) > p->nDivsMax ) Vec_IntShrink( p->vBinateVars, p->nDivsMax ); if ( p->fVerbose ) printf( " B = %3d", Vec_IntSize(p->vBinateVars) ); @@ -1290,7 +1384,10 @@ void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int int Res; Gia_ResbInit( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, fVerbose ); Res = Gia_ManResubPerform_rec( p, nLimit ); - if ( Res >= 0 ) Vec_IntPush( p->vGates, Res ); + if ( Res >= 0 ) + Vec_IntPush( p->vGates, Res ); + else + Vec_IntClear( p->vGates ); if ( fVerbose ) printf( "\n" ); } @@ -1398,7 +1495,7 @@ extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit ); void Gia_ManResubTest3() { - int nVars = 3; + int nVars = 4; int fVerbose = 1; word Divs[6] = { 0, 0, ABC_CONST(0xAAAAAAAAAAAAAAAA), @@ -1412,7 +1509,7 @@ void Gia_ManResubTest3() for ( i = 0; i < 6; i++ ) Vec_PtrPush( vDivs, Divs+i ); Abc_ResubPrepareManager( 1 ); - for ( i = 0; i < (1<<(1< Date: Fri, 18 Sep 2020 21:50:27 -0700 Subject: Performance bug in k-resub and faster windowing. --- src/aig/gia/giaResub.c | 52 ++++++------ src/aig/gia/giaResub2.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 236 insertions(+), 26 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index b0b67c46..a1343290 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -1248,34 +1248,37 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) Vec_IntPushTwo( p->vGates, iDiv0, Abc_Var2Lit(iNode, fComp1) ); return Abc_Var2Lit( iNode+1, fComp ); } - if ( nLimit == 2 ) - return -1; - iResLit = Gia_ManFindGateGate( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, p->pDivA, p->pDivB ); - if ( iResLit >= 0 ) // and(pair,pair) +// if ( nLimit == 2 ) +// return -1; + if ( nLimit >= 3 ) { - int iNode = nVars + Vec_IntSize(p->vGates)/2; + iResLit = Gia_ManFindGateGate( p->pSets, p->vDivs, p->nWords, p->vUnatePairs, p->vUnatePairsW, p->pDivA, p->pDivB ); + if ( iResLit >= 0 ) // and(pair,pair) + { + int iNode = nVars + Vec_IntSize(p->vGates)/2; - int fComp = Abc_LitIsCompl(iResLit); - int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; // pair - int iDiv1 = Abc_Lit2Var(iResLit) >> 15; // pair + int fComp = Abc_LitIsCompl(iResLit); + int iDiv0 = Abc_Lit2Var(iResLit) & 0x7FFF; // pair + int iDiv1 = Abc_Lit2Var(iResLit) >> 15; // pair - int Div0 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv0) ); - int fComp0 = Abc_LitIsCompl(Div0) ^ Abc_LitIsCompl(iDiv0); - int iDiv00 = Abc_Lit2Var(Div0) & 0x7FFF; - int iDiv01 = Abc_Lit2Var(Div0) >> 15; + int Div0 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv0) ); + int fComp0 = Abc_LitIsCompl(Div0) ^ Abc_LitIsCompl(iDiv0); + int iDiv00 = Abc_Lit2Var(Div0) & 0x7FFF; + int iDiv01 = Abc_Lit2Var(Div0) >> 15; - int Div1 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv1) ); - int fComp1 = Abc_LitIsCompl(Div1) ^ Abc_LitIsCompl(iDiv1); - int iDiv10 = Abc_Lit2Var(Div1) & 0x7FFF; - int iDiv11 = Abc_Lit2Var(Div1) >> 15; + int Div1 = Vec_IntEntry( p->vUnatePairs[!fComp], Abc_Lit2Var(iDiv1) ); + int fComp1 = Abc_LitIsCompl(Div1) ^ Abc_LitIsCompl(iDiv1); + int iDiv10 = Abc_Lit2Var(Div1) & 0x7FFF; + int iDiv11 = Abc_Lit2Var(Div1) >> 15; - Vec_IntPushTwo( p->vGates, iDiv00, iDiv01 ); - Vec_IntPushTwo( p->vGates, iDiv10, iDiv11 ); - Vec_IntPushTwo( p->vGates, Abc_Var2Lit(iNode, fComp0), Abc_Var2Lit(iNode+1, fComp1) ); - return Abc_Var2Lit( iNode+2, fComp ); + Vec_IntPushTwo( p->vGates, iDiv00, iDiv01 ); + Vec_IntPushTwo( p->vGates, iDiv10, iDiv11 ); + Vec_IntPushTwo( p->vGates, Abc_Var2Lit(iNode, fComp0), Abc_Var2Lit(iNode+1, fComp1) ); + return Abc_Var2Lit( iNode+2, fComp ); + } } - if ( nLimit == 3 ) - return -1; +// if ( nLimit == 3 ) +// return -1; if ( Vec_IntSize(p->vUnateLits[0]) + Vec_IntSize(p->vUnateLits[1]) + Vec_IntSize(p->vUnatePairs[0]) + Vec_IntSize(p->vUnatePairs[1]) == 0 ) return -1; @@ -1289,9 +1292,10 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) Max2 = Abc_MaxInt(TopTwoW[0], TopTwoW[1]); if ( Abc_MaxInt(Max1, Max2) == 0 ) return -1; + if ( Max1 > Max2/2 ) { - if ( Max1 == TopOneW[0] || Max1 == TopOneW[1] ) + if ( nLimit >= 2 && (Max1 == TopOneW[0] || Max1 == TopOneW[1]) ) { int fUseOr = Max1 == TopOneW[0]; int iDiv = Vec_IntEntry( p->vUnateLits[!fUseOr], 0 ); @@ -1335,7 +1339,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) } else { - if ( Max2 == TopTwoW[0] || Max2 == TopTwoW[1] ) + if ( nLimit >= 3 && (Max2 == TopTwoW[0] || Max2 == TopTwoW[1]) ) { int fUseOr = Max2 == TopTwoW[0]; int iDiv = Vec_IntEntry( p->vUnatePairs[!fUseOr], 0 ); diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index 23d73dd8..468730fe 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -540,7 +540,10 @@ Gia_Man_t * Gia_ManResub2Test( Gia_Man_t * p ) //printf( "Performed resub %d times. Reduced %d nodes.\n", nResubs, nObjsNew ? Gia_ManObjNum(p) - nObjsNew : 0 ); Abc_ResubPrepareManager( 0 ); if ( nObjsNew ) + { pNew = Gia_ManFromResub( pObjsNew, nObjsNew, Gia_ManCiNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + } else pNew = Gia_ManDup( p ); ABC_FREE( pObjs ); @@ -965,6 +968,193 @@ void Gia_RsbWindowGrow( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Ve } } +/**Function************************************************************* + + Synopsis [Grow window for the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// uses levelized structure (vLevels) to collect in array vWin divisors supported by the cut (vIn) +void Gia_WinCreateFromCut( Gia_Man_t * p, Vec_Int_t * vIn, Vec_Wec_t * vLevels, Vec_Int_t * vWin ) +{ + Vec_Int_t * vLevel; + Gia_Obj_t * pObj, * pFanout; + int k, i, f, iObj, Level; + Vec_Int_t * vUsed = Vec_IntAlloc( 100 ); + // precondition: the levelized structure is empty + assert( Vec_WecSizeSize(vLevels) == 0 ); + // clean the resulting array + Vec_IntClear( vWin ); + // start a new trav ID and add nodes to the levelized structure + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vIn, iObj, i ) + { + Gia_ObjSetTravIdCurrentId( p, iObj ); + Vec_WecPush( vLevels, Gia_ObjLevelId(p, iObj), iObj ); + Vec_IntPush( vWin, iObj ); + Vec_IntPushUniqueOrder( vUsed, Gia_ObjLevelId(p, iObj) ); + } + // iterate through all objects and explore their fanouts + //Vec_WecForEachLevel( vLevels, vLevel, k ) + Vec_IntForEachEntry( vUsed, Level, k ) + { + vLevel = Vec_WecEntry( vLevels, Level ); + Gia_ManForEachObjVec( vLevel, p, pObj, i ) + Gia_ObjForEachFanoutStatic( p, pObj, pFanout, f ) + { + if ( f == 5 ) // explore first 5 fanouts of the node + break; + if ( Gia_ObjIsAnd(pFanout) && // internal node + !Gia_ObjIsTravIdCurrent(p, pFanout) && // not in the window + Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pFanout)) && // but fanins are + Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pFanout)) ) // in the window + { + // add fanout to the window and to the levelized structure + Gia_ObjSetTravIdCurrent( p, pFanout ); + Vec_WecPush( vLevels, Gia_ObjLevel(p, pFanout), Gia_ObjId(p, pFanout) ); + Vec_IntPush( vWin, Gia_ObjId(p, pFanout) ); + Vec_IntPushUniqueOrder( vUsed, Gia_ObjLevel(p, pFanout) ); + } + } + Vec_IntClear( vLevel ); + } + Vec_IntSort( vWin, 0 ); + Vec_IntFree( vUsed ); +} +// update the cut until both fanins of AND nodes are not in the cut +int Gia_RsbExpandCut( Gia_Man_t * p, Vec_Int_t * vIns ) +{ + int fOnlyPis = 0, fChange = 1, nSize = Vec_IntSize(vIns); + while ( fChange ) + { + Gia_Obj_t * pObj; + int i, iFan0, iFan1, fHave0, fHave1; + fOnlyPis = 1; + fChange = 0; + // check if some nodes can be expanded without increasing cut size + Gia_ManForEachObjVec( vIns, p, pObj, i ) + { + assert( Gia_ObjIsTravIdCurrent(p, pObj) ); + if ( !Gia_ObjIsAnd(pObj) ) + continue; + fOnlyPis = 0; + iFan0 = Gia_ObjFaninId0p(p, pObj); + iFan1 = Gia_ObjFaninId1p(p, pObj); + fHave0 = Gia_ObjIsTravIdCurrentId(p, iFan0); + fHave1 = Gia_ObjIsTravIdCurrentId(p, iFan1); + if ( !fHave0 && !fHave1 ) + continue; + // can expand because one of the fanins is already in the cut + // remove current cut node + Vec_IntDrop( vIns, i ); + // add missing fanin + if ( !fHave0 ) + { + Vec_IntPush( vIns, iFan0 ); + Gia_ObjSetTravIdCurrentId( p, iFan0 ); + } + if ( !fHave1 ) + { + Vec_IntPush( vIns, iFan1 ); + Gia_ObjSetTravIdCurrentId( p, iFan1 ); + } + fChange = 1; + break; + } + } + assert( Vec_IntSize(vIns) <= nSize ); + return fOnlyPis; +} +int Gia_RsbFindFaninAdd( int iFan, int pFanins[32], int pFaninCounts[32], int nFanins ) +{ + int i; + for ( i = 0; i < nFanins; i++ ) + if ( pFanins[i] == iFan ) + break; + pFanins[i] = iFan; + pFaninCounts[i]++; + return nFanins + (i == nFanins); +} +int Gia_RsbFindFaninToAddToCut( Gia_Man_t * p, Vec_Int_t * vIns ) +{ + Gia_Obj_t * pObj; + int nFanins = 0, pFanins[64] = {0}, pFaninCounts[64] = {0}; + int i, iFan0, iFan1, iFanMax = -1, CountMax = 0; + Gia_ManForEachObjVec( vIns, p, pObj, i ) + { + if ( !Gia_ObjIsAnd(pObj) ) + continue; + iFan0 = Gia_ObjFaninId0p(p, pObj); + iFan1 = Gia_ObjFaninId1p(p, pObj); + assert( !Gia_ObjIsTravIdCurrentId(p, iFan0) ); + assert( !Gia_ObjIsTravIdCurrentId(p, iFan1) ); + nFanins = Gia_RsbFindFaninAdd( iFan0, pFanins, pFaninCounts, nFanins ); + nFanins = Gia_RsbFindFaninAdd( iFan1, pFanins, pFaninCounts, nFanins ); + assert( nFanins < 64 ); + } + // find fanin with the highest count + for ( i = 0; i < nFanins; i++ ) + if ( CountMax < pFaninCounts[i] ) + { + CountMax = pFaninCounts[i]; + iFanMax = pFanins[i]; + } + return iFanMax; +} +// precondition: nodes in vWin and in vIns are marked with the current ID +void Gia_RsbWindowGrow2( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vIns, int nInputsMax ) +{ + // window will be recomputed later + Vec_IntClear( vWin ); + // expand the cut without increasing its cost + if ( !Gia_RsbExpandCut( p, vIns ) ) + { + // save it as the best cut + Vec_Int_t * vBest = Vec_IntSize(vIns) <= nInputsMax ? Vec_IntDup(vIns) : NULL; + int fOnlyPis = 0, Iter = 0; + // iterate expansion until + // (1) the cut cannot be expanded because all leaves are PIs + // (2) the cut size exceeded the limit for 5 consecutive iterations + while ( !fOnlyPis && (Vec_IntSize(vIns) <= nInputsMax || Iter < 5) ) + { + int iFanBest = Gia_RsbFindFaninToAddToCut( p, vIns ); + Vec_IntPush( vIns, iFanBest ); + Gia_ObjSetTravIdCurrentId( p, iFanBest ); + fOnlyPis = Gia_RsbExpandCut( p, vIns ); + if ( Vec_IntSize(vIns) > nInputsMax ) + Iter++; + else + Iter = 0; + if ( Vec_IntSize(vIns) <= nInputsMax && (!vBest || Vec_IntSize(vBest) <= Vec_IntSize(vIns)) ) + { + if ( vBest ) + Vec_IntClear(vBest); + else + vBest = Vec_IntAlloc( 10 ); + Vec_IntAppend( vBest, vIns ); + } + } + if ( vBest ) + { + Vec_IntClear( vIns ); + Vec_IntAppend( vIns, vBest ); + Vec_IntFree( vBest ); + } + else + assert( Vec_IntSize(vIns) > nInputsMax ); + } + if ( Vec_IntSize(vIns) <= nInputsMax ) + { + Vec_IntSort( vIns, 0 ); + Gia_WinCreateFromCut( p, vIns, vLevels, vWin ); + } +} + /**Function************************************************************* Synopsis [Create window for the node.] @@ -987,8 +1177,8 @@ int Gia_RsbWindowCompute( Gia_Man_t * p, int iObj, int nInputsMax, int nLevelsMa // vWin and vIns are labeled with the current trav ID //Vec_IntPrint( vWin ); //Vec_IntPrint( vIns ); - if ( Vec_IntSize(vIns) <= nInputsMax + 2 ) // consider windows, which initially has a larger input space - Gia_RsbWindowGrow( p, vLevels, vWin, vIns, nInputsMax ); + if ( Vec_IntSize(vIns) <= nInputsMax + 3 ) // consider windows, which initially has a larger input space + Gia_RsbWindowGrow2( p, vLevels, vWin, vIns, nInputsMax ); if ( Vec_IntSize(vIns) <= nInputsMax ) { Vec_IntSort( vWin, 0 ); @@ -1208,6 +1398,22 @@ void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax ) Hsh_VecManStop( pHash ); } +/**Function************************************************************* + + Synopsis [Apply k-resub to one AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_RsbTryOneWindow( Gia_Man_t * p ) +{ + return Gia_ManResub2Test( p ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 55a67a115cb3d008594377cacec478fe33db4aee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 21 Sep 2020 09:00:30 -0700 Subject: Improvement to reconv-driven windowing. --- src/aig/gia/giaResub2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index 468730fe..2c55e0cb 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -1099,7 +1099,8 @@ int Gia_RsbFindFaninToAddToCut( Gia_Man_t * p, Vec_Int_t * vIns ) } // find fanin with the highest count for ( i = 0; i < nFanins; i++ ) - if ( CountMax < pFaninCounts[i] ) +// if ( CountMax < pFaninCounts[i] ) + if ( CountMax < pFaninCounts[i] || (CountMax == pFaninCounts[i] && (Gia_ObjFanoutNumId(p, iFanMax) < Gia_ObjFanoutNumId(p, pFanins[i]))) ) { CountMax = pFaninCounts[i]; iFanMax = pFanins[i]; @@ -1322,7 +1323,7 @@ int Gia_ManVerifyTwoTruths( Gia_Man_t * p1, Gia_Man_t * p2 ) void Gia_RsbEnumerateWindows( Gia_Man_t * p, int nInputsMax, int nLevelsMax ) { int fVerbose = 0; - int fUseHash = 1; + int fUseHash = 0; int i, nWins = 0, nWinSize = 0, nInsSize = 0, nOutSize = 0, nNodeGain = 0; Vec_Wec_t * vLevels = Vec_WecStart( Gia_ManLevelNum(p)+1 ); Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) ); -- cgit v1.2.3 From 41c937e4c8a25070a8b507d98a1ccd2ac26b0d28 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 25 Sep 2020 20:35:11 -0700 Subject: Memory leaks. --- src/aig/gia/giaAiger.c | 1 + src/aig/gia/giaIf.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index c9ad28db..bc2e25ad 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -636,6 +636,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi pCur++; if ( (*pCur >= 'a' && *pCur <= 'z') || (*pCur >= 'A' && *pCur <= 'Z') || (*pCur >= '0' && *pCur <= '9') ) { + ABC_FREE( pNew->pName ); pNew->pName = Abc_UtilStrsav( (char *)pCur ); pCur += strlen(pNew->pName) + 1; } else diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 37ca6d4b..6b6d9e04 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -2357,6 +2357,7 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars ) // transfer name assert( pNew->pName == NULL ); pNew->pName = Abc_UtilStrsav( p->pName ); + ABC_FREE( pNew->pSpec ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); // print delay trace -- cgit v1.2.3 From 947eeb9501d8f2ad9fdedba37b47125d6d03ebe1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 28 Sep 2020 23:02:26 -0700 Subject: Memory leaks. --- src/aig/gia/giaIf.c | 1 + src/aig/gia/giaScript.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 6b6d9e04..2c206292 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -1987,6 +1987,7 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan ) pFile = fopen( Buffer, "wb" ); if ( pFile == NULL ) { + Vec_StrFree( vConfigsStr ); printf( "Cannot open file \"%s\".\n", Buffer ); return pNew; } diff --git a/src/aig/gia/giaScript.c b/src/aig/gia/giaScript.c index 751f5000..f32b1658 100644 --- a/src/aig/gia/giaScript.c +++ b/src/aig/gia/giaScript.c @@ -91,6 +91,7 @@ Gia_Man_t * Gia_ManAigSyn2( Gia_Man_t * pInit, int fOldAlgo, int fCoarsen, int f { pNew = Gia_ManDup(p); Gia_ManTransferTiming( pNew, p ); + Gia_ManStop( p ); return pNew; } // delay optimization @@ -164,6 +165,7 @@ Gia_Man_t * Gia_ManAigSyn3( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) { pNew = Gia_ManDup(p); Gia_ManTransferTiming( pNew, p ); + Gia_ManStop( p ); return pNew; } // perform balancing @@ -200,6 +202,7 @@ Gia_Man_t * Gia_ManAigSyn4( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) { pNew = Gia_ManDup(p); Gia_ManTransferTiming( pNew, p ); + Gia_ManStop( p ); return pNew; } //Gia_ManAigPrintPiLevels( p ); -- cgit v1.2.3 From f1eb933992b23a54ec7d6c894152d0e581915450 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 30 Sep 2020 10:23:01 -0700 Subject: Bug fix in window output computation. --- src/aig/gia/giaResub2.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index 2c55e0cb..cbd3caa1 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -1211,19 +1211,20 @@ Vec_Int_t * Gia_RsbFindOutputs( Gia_Man_t * p, Vec_Int_t * vWin, Vec_Int_t * vIn { Vec_Int_t * vOuts = Vec_IntAlloc( 100 ); Gia_Obj_t * pObj; int i; + Gia_ManIncrementTravId( p ); + Gia_ManForEachObjVec( vIns, p, pObj, i ) + Gia_ObjSetTravIdCurrent( p, pObj ); Gia_ManForEachObjVec( vWin, p, pObj, i ) - if ( Gia_ObjIsAnd(pObj) ) + if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjIsAnd(pObj) ) { Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), 1 ); Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1p(p, pObj), 1 ); } - Gia_ManForEachObjVec( vIns, p, pObj, i ) - Vec_IntWriteEntry( vRefs, Gia_ObjId(p, pObj), Gia_ObjFanoutNum(p, pObj) ); Gia_ManForEachObjVec( vWin, p, pObj, i ) - if ( Gia_ObjFanoutNum(p, pObj) != Vec_IntEntry(vRefs, Gia_ObjId(p, pObj)) ) + if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjFanoutNum(p, pObj) != Vec_IntEntry(vRefs, Gia_ObjId(p, pObj)) ) Vec_IntPush( vOuts, Gia_ObjId(p, pObj) ); Gia_ManForEachObjVec( vWin, p, pObj, i ) - if ( Gia_ObjIsAnd(pObj) ) + if ( !Gia_ObjIsTravIdCurrent(p, pObj) && Gia_ObjIsAnd(pObj) ) { Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), -1 ); Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1p(p, pObj), -1 ); -- cgit v1.2.3 From 73f8b598ac0809f646007c84504ac6afb2a922e8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 29 Oct 2020 17:21:37 -0700 Subject: Rare bug fix in mapping with choices. --- src/aig/gia/giaAig.c | 36 ++++++++++++++++++++++++++++++++++++ src/aig/gia/giaIf.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index dfd4a467..91a9c600 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -100,6 +100,41 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Checks integrity of choice nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCheckChoices_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( !pObj || !Gia_ObjIsAnd(pObj) || pObj->fPhase ) + return; + pObj->fPhase = 1; + Gia_ManCheckChoices_rec( p, Gia_ObjFanin0(pObj) ); + Gia_ManCheckChoices_rec( p, Gia_ObjFanin1(pObj) ); + Gia_ManCheckChoices_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)) ); +} +void Gia_ManCheckChoices( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, fFound = 0; + Gia_ManCleanPhase( p ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManCheckChoices_rec( p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachAnd( p, pObj, i ) + if ( !pObj->fPhase ) + printf( "Object %d is dangling.\n", i ), fFound = 1; + if ( !fFound ) + printf( "There are no dangling objects.\n" ); + Gia_ManCleanPhase( p ); +} + /**Function************************************************************* Synopsis [Duplicates AIG in the DFS order.] @@ -155,6 +190,7 @@ Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p ) Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); //assert( Gia_ManObjNum(pNew) == Aig_ManObjNum(p) ); + //Gia_ManCheckChoices( pNew ); return pNew; } diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 2c206292..614f7b47 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -756,6 +756,43 @@ int Gia_ManChoiceLevel( Gia_Man_t * p ) } +/**Function************************************************************* + + Synopsis [Checks integrity of choice nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void If_ManCheckChoices_rec( If_Man_t * pIfMan, If_Obj_t * pIfObj ) +{ + if ( !pIfObj || pIfObj->Type != IF_AND || pIfObj->fDriver ) + return; + pIfObj->fDriver = 1; + If_ManCheckChoices_rec( pIfMan, If_ObjFanin0(pIfObj) ); + If_ManCheckChoices_rec( pIfMan, If_ObjFanin1(pIfObj) ); + If_ManCheckChoices_rec( pIfMan, pIfObj->pEquiv ); +} +void If_ManCheckChoices( If_Man_t * pIfMan ) +{ + If_Obj_t * pIfObj; + int i, fFound = 0; + If_ManForEachObj( pIfMan, pIfObj, i ) + pIfObj->fDriver = 0; + If_ManForEachCo( pIfMan, pIfObj, i ) + If_ManCheckChoices_rec( pIfMan, If_ObjFanin0(pIfObj) ); + If_ManForEachNode( pIfMan, pIfObj, i ) + if ( !pIfObj->fDriver ) + printf( "Object %d is dangling.\n", i ), fFound = 1; + if ( !fFound ) + printf( "There are no dangling objects.\n" ); + If_ManForEachObj( pIfMan, pIfObj, i ) + pIfObj->fDriver = 0; +} + /**Function************************************************************* @@ -824,6 +861,7 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars ) } if ( Gia_ManHasChoices(p) ) Gia_ManCleanMark0( p ); + //If_ManCheckChoices( pIfMan ); return pIfMan; } -- cgit v1.2.3 From 3a7b3d27f19e1d8b43cfe974b6c8c3ab5c79d351 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Nov 2020 09:56:01 -0800 Subject: Experimental cost function in technology mapping. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaMf.c | 37 ++++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 7f6bbea6..acabe8e0 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -339,6 +339,7 @@ struct Jf_Par_t_ int fCutMin; int fFuncDsd; int fGenCnf; + int fGenLit; int fCnfObjIds; int fAddOrCla; int fCnfMapping; diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 7e699d9b..4bd08dcf 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -24,6 +24,7 @@ #include "misc/extra/extra.h" #include "sat/cnf/cnf.h" #include "opt/dau/dau.h" +#include "bool/kit/kit.h" ABC_NAMESPACE_IMPL_START @@ -557,8 +558,8 @@ static inline int Mf_CutComputeTruth6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t assert( (int)(t & 1) == 0 ); truthId = Vec_MemHashInsert(p->vTtMem, &t); pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); - if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) ) - Vec_IntPush( &p->vCnfSizes, Abc_Tt6CnfSize(t, pCutR->nLeaves) ); + if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) ) + Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt6CnfSize(t, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)&t, pCutR->nLeaves, &p->vCnfMem) ); // p->nCutMux += Mf_ManTtIsMux( t ); assert( (int)pCutR->nLeaves <= nOldSupp ); // Mf_ManTruthCanonicize( &t, pCutR->nLeaves ); @@ -588,8 +589,8 @@ static inline int Mf_CutComputeTruth( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t * //Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" ); truthId = Vec_MemHashInsert(p->vTtMem, uTruth); pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); - if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 ) - Vec_IntPush( &p->vCnfSizes, Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) ); + if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 ) + Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)uTruth, pCutR->nLeaves, &p->vCnfMem) ); assert( (int)pCutR->nLeaves <= nOldSupp ); return (int)pCutR->nLeaves < nOldSupp; } @@ -612,8 +613,8 @@ static inline int Mf_CutComputeTruthMux6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut assert( (int)(t & 1) == 0 ); truthId = Vec_MemHashInsert(p->vTtMem, &t); pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); - if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) ) - Vec_IntPush( &p->vCnfSizes, Abc_Tt6CnfSize(t, pCutR->nLeaves) ); + if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) ) + Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt6CnfSize(t, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)&t, pCutR->nLeaves, &p->vCnfMem) ); assert( (int)pCutR->nLeaves <= nOldSupp ); return (int)pCutR->nLeaves < nOldSupp; } @@ -642,8 +643,8 @@ static inline int Mf_CutComputeTruthMux( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_ assert( (uTruth[0] & 1) == 0 ); truthId = Vec_MemHashInsert(p->vTtMem, uTruth); pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); - if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 ) - Vec_IntPush( &p->vCnfSizes, Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) ); + if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 ) + Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)uTruth, pCutR->nLeaves, &p->vCnfMem) ); assert( (int)pCutR->nLeaves <= nOldSupp ); return (int)pCutR->nLeaves < nOldSupp; } @@ -699,6 +700,8 @@ static inline void Mf_CutPrint( Mf_Man_t * p, Mf_Cut_t * pCut ) { if ( p->pPars->fGenCnf ) printf( "CNF = %2d ", Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(pCut->iFunc)) ); + if ( p->pPars->fGenLit ) + printf( "Lit = %2d ", Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(pCut->iFunc)) ); Dau_DsdPrintFromTruth( Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)), pCut->nLeaves ); } else @@ -998,7 +1001,7 @@ static inline int Mf_CutArea( Mf_Man_t * p, int nLeaves, int iFunc ) { if ( nLeaves < 2 ) return 0; - if ( p->pPars->fGenCnf ) + if ( p->pPars->fGenCnf || p->pPars->fGenLit ) return Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(iFunc)); if ( p->pPars->fOptEdge ) return nLeaves + p->pPars->nAreaTuner; @@ -1202,7 +1205,7 @@ int Mf_ManSetMapRefs( Mf_Man_t * p ) Mf_ObjMapRefInc( p, pCut[k] ); p->pPars->Edge += Mf_CutSize(pCut); p->pPars->Area++; - if ( p->pPars->fGenCnf ) + if ( p->pPars->fGenCnf || p->pPars->fGenLit ) p->pPars->Clause += Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut)); } // blend references @@ -1394,7 +1397,7 @@ Mf_Man_t * Mf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars ) p->pLfObjs = ABC_CALLOC( Mf_Obj_t, Gia_ManObjNum(pGia) ); p->iCur = 2; Vec_PtrGrow( &p->vPages, 256 ); - if ( pPars->fGenCnf ) + if ( pPars->fGenCnf || pPars->fGenLit ) { Vec_IntGrow( &p->vCnfSizes, 10000 ); Vec_IntPush( &p->vCnfSizes, 1 ); @@ -1410,7 +1413,7 @@ Mf_Man_t * Mf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars ) } void Mf_ManFree( Mf_Man_t * p ) { - assert( !p->pPars->fGenCnf || Vec_IntSize(&p->vCnfSizes) == Vec_MemEntryNum(p->vTtMem) ); + assert( !p->pPars->fGenCnf || !p->pPars->fGenLit || Vec_IntSize(&p->vCnfSizes) == Vec_MemEntryNum(p->vTtMem) ); if ( p->pPars->fCutMin ) Vec_MemHashFree( p->vTtMem ); if ( p->pPars->fCutMin ) @@ -1453,6 +1456,7 @@ void Mf_ManSetDefaultPars( Jf_Par_t * pPars ) pPars->fCoarsen = 1; pPars->fCutMin = 0; pPars->fGenCnf = 0; + pPars->fGenLit = 0; pPars->fPureAig = 0; pPars->fVerbose = 0; pPars->fVeryVerbose = 0; @@ -1469,6 +1473,8 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle ) printf( "Edge =%9lu ", (long)p->pPars->Edge ); if ( p->pPars->fGenCnf ) printf( "CNF =%9lu ", (long)p->pPars->Clause ); + if ( p->pPars->fGenLit ) + printf( "FFL =%9lu ", (long)p->pPars->Clause ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } @@ -1483,6 +1489,7 @@ void Mf_ManPrintInit( Mf_Man_t * p ) printf( "CutMin = %d ", p->pPars->fCutMin ); printf( "Coarse = %d ", p->pPars->fCoarsen ); printf( "CNF = %d ", p->pPars->fGenCnf ); + printf( "FFL = %d ", p->pPars->fGenLit ); printf( "\n" ); printf( "Computing cuts...\r" ); fflush( stdout ); @@ -1656,7 +1663,7 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) { Mf_Man_t * p; Gia_Man_t * pNew, * pCls; - if ( pPars->fGenCnf ) + if ( pPars->fGenCnf || pPars->fGenLit ) pPars->fCutMin = 1; if ( Gia_ManHasChoices(pGia) ) pPars->fCutMin = 1, pPars->fCoarsen = 0; @@ -1685,8 +1692,8 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) pNew = Mf_ManDeriveMapping( p ); if ( p->pPars->fGenCnf ) pGia->pData = Mf_ManDeriveCnf( p, p->pPars->fCnfObjIds, p->pPars->fAddOrCla ); -// if ( p->pPars->fGenCnf ) -// Mf_ManProfileTruths( p ); + //if ( p->pPars->fGenCnf || p->pPars->fGenLit ) + // Mf_ManProfileTruths( p ); Gia_ManMappingVerify( pNew ); Mf_ManPrintQuit( p, pNew ); Mf_ManFree( p ); -- cgit v1.2.3 From 6e6cc08becbe68734a3b38ae4dc0b56b020d0f39 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 3 Nov 2020 18:02:32 -0800 Subject: Improving resub window computation by always including the TFI of the pivot node. --- src/aig/gia/giaResub2.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index cbd3caa1..8877439c 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -979,8 +979,20 @@ void Gia_RsbWindowGrow( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Ve SeeAlso [] ***********************************************************************/ +void Gia_WinCreateFromCut_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vWin ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + assert( Gia_ObjIsAnd(pObj) ); + Gia_WinCreateFromCut_rec( p, Gia_ObjFaninId0(pObj, iObj), vWin ); + Gia_WinCreateFromCut_rec( p, Gia_ObjFaninId1(pObj, iObj), vWin ); + Vec_IntPush( vWin, iObj ); +} // uses levelized structure (vLevels) to collect in array vWin divisors supported by the cut (vIn) -void Gia_WinCreateFromCut( Gia_Man_t * p, Vec_Int_t * vIn, Vec_Wec_t * vLevels, Vec_Int_t * vWin ) +void Gia_WinCreateFromCut( Gia_Man_t * p, int iPivot, Vec_Int_t * vIn, Vec_Wec_t * vLevels, Vec_Int_t * vWin ) { Vec_Int_t * vLevel; Gia_Obj_t * pObj, * pFanout; @@ -990,13 +1002,19 @@ void Gia_WinCreateFromCut( Gia_Man_t * p, Vec_Int_t * vIn, Vec_Wec_t * vLevels, assert( Vec_WecSizeSize(vLevels) == 0 ); // clean the resulting array Vec_IntClear( vWin ); - // start a new trav ID and add nodes to the levelized structure + // collect leaves Gia_ManIncrementTravId( p ); Vec_IntForEachEntry( vIn, iObj, i ) { Gia_ObjSetTravIdCurrentId( p, iObj ); - Vec_WecPush( vLevels, Gia_ObjLevelId(p, iObj), iObj ); Vec_IntPush( vWin, iObj ); + } + // collect internal cone + Gia_WinCreateFromCut_rec( p, iPivot, vWin ); + // add nodes to the levelized structure + Vec_IntForEachEntry( vWin, iObj, i ) + { + Vec_WecPush( vLevels, Gia_ObjLevelId(p, iObj), iObj ); Vec_IntPushUniqueOrder( vUsed, Gia_ObjLevelId(p, iObj) ); } // iterate through all objects and explore their fanouts @@ -1108,7 +1126,7 @@ int Gia_RsbFindFaninToAddToCut( Gia_Man_t * p, Vec_Int_t * vIns ) return iFanMax; } // precondition: nodes in vWin and in vIns are marked with the current ID -void Gia_RsbWindowGrow2( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vIns, int nInputsMax ) +void Gia_RsbWindowGrow2( Gia_Man_t * p, int iObj, Vec_Wec_t * vLevels, Vec_Int_t * vWin, Vec_Int_t * vIns, int nInputsMax ) { // window will be recomputed later Vec_IntClear( vWin ); @@ -1152,7 +1170,7 @@ void Gia_RsbWindowGrow2( Gia_Man_t * p, Vec_Wec_t * vLevels, Vec_Int_t * vWin, V if ( Vec_IntSize(vIns) <= nInputsMax ) { Vec_IntSort( vIns, 0 ); - Gia_WinCreateFromCut( p, vIns, vLevels, vWin ); + Gia_WinCreateFromCut( p, iObj, vIns, vLevels, vWin ); } } @@ -1179,7 +1197,7 @@ int Gia_RsbWindowCompute( Gia_Man_t * p, int iObj, int nInputsMax, int nLevelsMa //Vec_IntPrint( vWin ); //Vec_IntPrint( vIns ); if ( Vec_IntSize(vIns) <= nInputsMax + 3 ) // consider windows, which initially has a larger input space - Gia_RsbWindowGrow2( p, vLevels, vWin, vIns, nInputsMax ); + Gia_RsbWindowGrow2( p, iObj, vLevels, vWin, vIns, nInputsMax ); if ( Vec_IntSize(vIns) <= nInputsMax ) { Vec_IntSort( vWin, 0 ); -- cgit v1.2.3 From 40bfe2fb88b4a4dc32fa280e66f66dcefb4a4b1d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Nov 2020 13:24:07 -0800 Subject: Experiments with SAT sweeping. --- src/aig/gia/gia.h | 4 +++- src/aig/gia/giaEquiv.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index acabe8e0..722abd72 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1069,9 +1069,11 @@ static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { a #define Gia_ManForEachClassReverse( p, i ) \ for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else #define Gia_ClassForEachObj( p, i, iObj ) \ - for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) ) + for ( assert(Gia_ObjIsHead(p, i) && i), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) ) #define Gia_ClassForEachObj1( p, i, iObj ) \ for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) +#define Gia_ClassForEachObjStart( p, i, iObj, Start ) \ + for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, Start); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) static inline int Gia_ObjFoffsetId( Gia_Man_t * p, int Id ) { return Vec_IntEntry( p->vFanout, Id ); } diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 03b9b819..0e9f5526 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -480,8 +480,10 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ) } CounterX -= Gia_ManCoNum(p); nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX; - Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d mem =%5.2f MB\n", - Counter0, Counter, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem ); +// Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d mem =%5.2f MB\n", +// Counter0, Counter, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem ); + Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d\n", + Counter0, Counter, nLits, CounterX, Proved ); assert( Gia_ManEquivCheckLits( p, nLits ) ); if ( fVerbose ) { -- cgit v1.2.3 From 83519c320c1d335675e97f144cff109200141770 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Nov 2020 20:17:20 -0800 Subject: Experiments with SAT sweeping. --- src/aig/gia/giaEquiv.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 0e9f5526..f7f873cd 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -269,6 +269,7 @@ int * Gia_ManDeriveNexts( Gia_Man_t * p ) pTails[i] = i; for ( i = 0; i < Gia_ManObjNum(p); i++ ) { + //if ( p->pReprs[i].iRepr == GIA_VOID ) if ( !p->pReprs[i].iRepr || p->pReprs[i].iRepr == GIA_VOID ) continue; pNexts[ pTails[p->pReprs[i].iRepr] ] = i; @@ -2589,6 +2590,123 @@ void Gia_ManFilterEquivsUsingLatches( Gia_Man_t * pGia, int fFlopsOnly, int fFlo Abc_Print( 1, "The number of literals: Before = %d. After = %d.\n", iLitsOld, iLitsNew ); } +/**Function************************************************************* + + Synopsis [Changing node order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManChangeOrder_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + if ( Gia_ObjIsCi(pObj) ) + return pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin0(pObj) ); + if ( Gia_ObjIsCo(pObj) ) + return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Gia_Man_t * Gia_ManChangeOrder( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i, k; + Gia_ManFillValue( p ); + 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); + Gia_ManForEachClass( p, i ) + Gia_ClassForEachObj( p, i, k ) + Gia_ManChangeOrder_rec( pNew, p, Gia_ManObj(p, k) ); + Gia_ManForEachConst( p, k ) + Gia_ManChangeOrder_rec( pNew, p, Gia_ManObj(p, k) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManChangeOrder_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) ); + assert( Gia_ManObjNum(pNew) == Gia_ManObjNum(p) ); + return pNew; +} +void Gia_ManTransferEquivs( Gia_Man_t * p, Gia_Man_t * pNew ) +{ + Vec_Int_t * vClass; + int i, k, iNode, iRepr; + assert( Gia_ManObjNum(p) == Gia_ManObjNum(pNew) ); + assert( p->pReprs != NULL ); + assert( p->pNexts != NULL ); + assert( pNew->pReprs == NULL ); + assert( pNew->pNexts == NULL ); + // start representatives + pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) ); + for ( i = 0; i < Gia_ManObjNum(pNew); i++ ) + Gia_ObjSetRepr( pNew, i, GIA_VOID ); + // iterate over constant candidates + Gia_ManForEachConst( p, i ) + Gia_ObjSetRepr( pNew, Abc_Lit2Var(Gia_ManObj(p, i)->Value), 0 ); + // iterate over class candidates + vClass = Vec_IntAlloc( 100 ); + Gia_ManForEachClass( p, i ) + { + Vec_IntClear( vClass ); + Gia_ClassForEachObj( p, i, k ) + Vec_IntPushUnique( vClass, Abc_Lit2Var(Gia_ManObj(p, k)->Value) ); + assert( Vec_IntSize( vClass ) > 1 ); + Vec_IntSort( vClass, 0 ); + iRepr = Vec_IntEntry( vClass, 0 ); + Vec_IntForEachEntryStart( vClass, iNode, k, 1 ) + Gia_ObjSetRepr( pNew, iNode, iRepr ); + } + Vec_IntFree( vClass ); + pNew->pNexts = Gia_ManDeriveNexts( pNew ); +} +void Gia_ManTransferTest( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; int i; + Gia_Rpr_t * pReprs = p->pReprs; // representatives (for CIs and ANDs) + int * pNexts = p->pNexts; // next nodes in the equivalence classes + Gia_Man_t * pNew = Gia_ManChangeOrder(p); + //Gia_ManEquivPrintClasses( p, 1, 0 ); + assert( Gia_ManObjNum(p) == Gia_ManObjNum(pNew) ); + Gia_ManTransferEquivs( p, pNew ); + p->pReprs = NULL; + p->pNexts = NULL; + // make new point to old + Gia_ManForEachObj( p, pObj, i ) + { + assert( !Abc_LitIsCompl(pObj->Value) ); + Gia_ManObj(pNew, Abc_Lit2Var(pObj->Value))->Value = Abc_Var2Lit(i, 0); + } + Gia_ManTransferEquivs( pNew, p ); + //Gia_ManEquivPrintClasses( p, 1, 0 ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + pReprs[i].fProved = 0; + //printf( "%5d : %5d %5d %5d %5d\n", i, *(int*)&p->pReprs[i], *(int*)&pReprs[i], (int)p->pNexts[i], (int)pNexts[i] ); + if ( memcmp(p->pReprs, pReprs, sizeof(int)*Gia_ManObjNum(p)) ) + printf( "Verification of reprs failed.\n" ); + else + printf( "Verification of reprs succeeded.\n" ); + if ( memcmp(p->pNexts, pNexts, sizeof(int)*Gia_ManObjNum(p)) ) + printf( "Verification of nexts failed.\n" ); + else + printf( "Verification of nexts succeeded.\n" ); + ABC_FREE( pNew->pReprs ); + ABC_FREE( pNew->pNexts ); + ABC_FREE( pReprs ); + ABC_FREE( pNexts ); + Gia_ManStop( pNew ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From fef0c368bc64bb9e8109c4d2adcdde9fed0f7399 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Nov 2020 17:17:26 -0800 Subject: Improvements to the SAT sweeper. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaMan.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 722abd72..4203329e 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -235,6 +235,7 @@ struct Gia_Man_t_ Vec_Wrd_t * vSuppWords; // support information Vec_Int_t vCopiesTwo; // intermediate copies Vec_Int_t vSuppVars; // used variables + Vec_Int_t vVarMap; // used variables Gia_Dat_t * pUData; }; diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 4ca9bfa4..51dd4250 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -129,6 +129,7 @@ void Gia_ManStop( Gia_Man_t * p ) Vec_IntFreeP( &p->vVar2Obj ); Vec_IntErase( &p->vCopiesTwo ); Vec_IntErase( &p->vSuppVars ); + Vec_IntErase( &p->vVarMap ); Vec_WrdFreeP( &p->vSuppWords ); Vec_IntFreeP( &p->vTtNums ); Vec_IntFreeP( &p->vTtNodes ); -- cgit v1.2.3 From b28c4b5c17e0e3d390edab32c9346be8267e0627 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 15 Nov 2020 21:06:58 -0800 Subject: Experiments with MFFC computation. --- src/aig/gia/gia.h | 2 + src/aig/gia/giaFanout.c | 83 ++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaMf.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++- src/aig/gia/giaUtil.c | 47 ++++++++++++++++++++++++ 4 files changed, 228 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 4203329e..3616e10c 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1403,6 +1403,7 @@ extern void Gia_ManFanoutStart( Gia_Man_t * p ); extern void Gia_ManFanoutStop( Gia_Man_t * p ); extern void Gia_ManStaticFanoutStart( Gia_Man_t * p ); extern void Gia_ManStaticFanoutStop( Gia_Man_t * p ); +extern void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p ); /*=== giaForce.c =========================================================*/ extern void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose ); /*=== giaFrames.c =========================================================*/ @@ -1693,6 +1694,7 @@ extern int Gia_ObjRecognizeMuxLits( Gia_Man_t * p, Gia_Obj_t * p extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode ); extern int Gia_NodeMffcSizeMark( Gia_Man_t * p, Gia_Obj_t * pNode ); extern int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp ); +extern int Gia_NodeMffcMapping( Gia_Man_t * p ); extern int Gia_ManHasDangling( Gia_Man_t * p ); extern int Gia_ManMarkDangling( Gia_Man_t * p ); extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p ); diff --git a/src/aig/gia/giaFanout.c b/src/aig/gia/giaFanout.c index 44e79ba2..8b104e9b 100644 --- a/src/aig/gia/giaFanout.c +++ b/src/aig/gia/giaFanout.c @@ -283,6 +283,89 @@ void Gia_ManStaticFanoutStart( Gia_Man_t * p ) Vec_IntFree( vCounts ); } + +/**Function************************************************************* + + Synopsis [Compute the map of all edges.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManStartMappingFanoutMap( Gia_Man_t * p, Vec_Int_t * vFanoutNums ) +{ + Gia_Obj_t * pObj; + int i, iOffset = Gia_ManObjNum(p); + Vec_Int_t * vEdgeMap = Vec_IntAlloc( 2 * iOffset ); + Vec_IntFill( vEdgeMap, iOffset, 0 ); + Gia_ManForEachObj( p, pObj, i ) + { + if ( Vec_IntEntry(vFanoutNums, i) == 0 ) + continue; + Vec_IntWriteEntry( vEdgeMap, i, iOffset ); + iOffset += Vec_IntEntry( vFanoutNums, i ); + Vec_IntFillExtra( vEdgeMap, iOffset, 0 ); + } + //printf( "Fanout map is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vEdgeMap)/Gia_ManObjNum(p) ); + return vEdgeMap; +} + +/**Function************************************************************* + + Synopsis [Allocates static fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p ) +{ + Vec_Int_t * vCounts; + int * pRefsOld; + Gia_Obj_t * pObj, * pFanin; + int i, k, iFan, iFanout; + assert( p->vFanoutNums == NULL ); + assert( p->vFanout == NULL ); + // recompute reference counters + pRefsOld = p->pLutRefs; p->pLutRefs = NULL; + Gia_ManSetLutRefs(p); + p->vFanoutNums = Vec_IntAllocArray( p->pLutRefs, Gia_ManObjNum(p) ); + p->pLutRefs = pRefsOld; + // start the fanout maps + p->vFanout = Gia_ManStartMappingFanoutMap( p, p->vFanoutNums ); + // incrementally add fanouts + vCounts = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_ManForEachLut( p, i ) + { + pObj = Gia_ManObj( p, i ); + Gia_LutForEachFanin( p, i, iFan, k ) + { + pFanin = Gia_ManObj( p, iFan ); + iFanout = Vec_IntEntry( vCounts, iFan ); + Gia_ObjSetFanout( p, pFanin, iFanout, pObj ); + Vec_IntAddToEntry( vCounts, iFan, 1 ); + } + } + Gia_ManForEachCo( p, pObj, i ) + { + iFan = Gia_ObjFaninId0p(p, pObj); + pFanin = Gia_ManObj( p, iFan ); + iFanout = Vec_IntEntry( vCounts, iFan ); + Gia_ObjSetFanout( p, pFanin, iFanout, pObj ); + Vec_IntAddToEntry( vCounts, iFan, 1 ); + } + // double-check the current number of fanouts added + Gia_ManForEachObj( p, pObj, i ) + assert( Vec_IntEntry(vCounts, i) == Gia_ObjFanoutNum(p, pObj) ); + Vec_IntFree( vCounts ); +} + /**Function************************************************************* Synopsis [Deallocates static fanout.] diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 4bd08dcf..7c67fb88 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -1569,6 +1569,16 @@ static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut ) Mf_ObjMapRefDec( p, iObj ); return Ela1; } +static inline int Mf_CutAreaDerefed2Multi( Mf_Man_t * p, int ** ppCuts, int nCuts ) +{ + int Ela1 = 0, iObj, i; + Vec_IntClear( &p->vTemp ); + for ( i = 0; i < nCuts; i++ ) + Ela1 += Mf_CutRef2_rec( p, ppCuts[i], &p->vTemp, ABC_INFINITY ); + Vec_IntForEachEntry( &p->vTemp, iObj, i ) + Mf_ObjMapRefDec( p, iObj ); + return Ela1; +} int Mf_CutRef_rec( Mf_Man_t * p, int * pCut ) { @@ -1586,11 +1596,18 @@ int Mf_CutDeref_rec( Mf_Man_t * p, int * pCut ) Count += Mf_CutDeref_rec( p, Mf_ObjCutBest(p, pCut[i]) ); return Count; } +static inline int Mf_CutAreaRefed( Mf_Man_t * p, int * pCut ) +{ + int Ela1 = Mf_CutDeref_rec( p, pCut ); + int Ela2 = Mf_CutRef_rec( p, pCut ); + //assert( Ela1 == Ela2 ); + return Ela1; +} static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut ) { int Ela1 = Mf_CutRef_rec( p, pCut ); int Ela2 = Mf_CutDeref_rec( p, pCut ); - assert( Ela1 == Ela2 ); + //assert( Ela1 == Ela2 ); return Ela1; } static inline float Mf_CutFlow( Mf_Man_t * p, int * pCut, int * pTime ) @@ -1640,6 +1657,83 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mf_ManPrintFanoutProfile( Mf_Man_t * p, Vec_Int_t * vFanCounts ) +{ + Gia_Man_t * pGia = p->pGia0; + int i, Count, nMax = Vec_IntFindMax( vFanCounts ); + Vec_Int_t * vCounts = Vec_IntStart( nMax + 1 ); + Vec_IntForEachEntry( vFanCounts, Count, i ) + if ( Count && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) ) + Vec_IntAddToEntry( vCounts, Count, 1 ); + printf( "\nFanout distribution for internal nodes:\n" ); + Vec_IntForEachEntry( vCounts, Count, i ) + if ( Count ) printf( "Fanout = %5d : Nodes = %5d.\n", i, Count ); + printf( "Total nodes with fanout = %d. Max fanout = %d.\n\n", Vec_IntCountPositive(vCounts), nMax ); + Vec_IntFree( vCounts ); +} +int Mf_ManPrintMfccStats( Mf_Man_t * p, int iObj ) +{ + Gia_Man_t * pGia = p->pGia0; + int Area = Mf_ObjMapRefNum(p, iObj) > 0 ? + Mf_CutAreaRefed (p, Mf_ObjCutBest(p, iObj)) : + Mf_CutAreaDerefed(p, Mf_ObjCutBest(p, iObj)); + printf( "%5d : Level = %5d Refs = %5d Mffc = %5d\n", + iObj, Gia_ObjLevelId(pGia, iObj), Mf_ObjMapRefNum(p, iObj), Area ); + return Area; +} +void Mf_ManOptimizationOne( Mf_Man_t * p, int iObj ) +{ + Gia_Man_t * pGia = p->pGia0; + int * ppCuts[32], nCuts = 0; + int iFanout, i, nAreaSum = 0, nAreaBest = 0; + // skip pivots whose MFFC fanouts are not used in the mapping or pointed to by COs + Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) + if ( Mf_ObjMapRefNum(p, iFanout) == 0 || Gia_ObjIsCo(Gia_ManObj(pGia, iFanout)) ) + return; + // print this pivot and its fanouts + printf( "\nPivot node = %d\n", iObj ); + printf( "Pivot " ), Mf_ManPrintMfccStats( p, iObj ); + Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) + printf( "Node " ), nAreaSum += Mf_ManPrintMfccStats( p, iFanout ); + // calculate the shared MFFC + Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) + Mf_ObjMapRefInc( p, iFanout ); + Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) + ppCuts[nCuts++] = Mf_ObjCutBest( p, iFanout ); + nAreaBest = Mf_CutAreaDerefed2Multi( p, ppCuts, nCuts ); + Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) + Mf_ObjMapRefDec( p, iFanout ); + printf( "Sum of MFFC size = %d\n", nAreaSum ); + printf( "Shared MFFC size = %d\n", nAreaBest ); +} +void Mf_ManOptimization( Mf_Man_t * p ) +{ + int nOutMax = 3; + Gia_Man_t * pGia = p->pGia0; + int i, Count, nNodes = Gia_NodeMffcMapping( pGia ); + Gia_ManLevelNum( pGia ); + Gia_ManStaticMappingFanoutStart( pGia ); + Mf_ManPrintFanoutProfile( p, pGia->vFanoutNums ); + printf( "\nIndividual logic cones:\n" ); + Vec_IntForEachEntry( pGia->vFanoutNums, Count, i ) + if ( Count >= 2 && Count <= nOutMax && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) ) + Mf_ManOptimizationOne( p, i ); + printf( "\nFinished printing individual logic cones.\n" ); + Gia_ManStaticFanoutStop( pGia ); + Vec_IntFreeP( &pGia->vMapping ); +} + /**Function************************************************************* Synopsis [Technology mappping.] @@ -1682,6 +1776,7 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) p->fUseEla = 1; for ( ; p->Iter < p->pPars->nRounds + pPars->nRoundsEla; p->Iter++ ) Mf_ManComputeMapping( p ); + //Mf_ManOptimization( p ); if ( pPars->fVeryVerbose && pPars->fCutMin ) Vec_MemDumpTruthTables( p->vTtMem, Gia_ManName(p->pGia), pPars->nLutSize ); if ( pPars->fCutMin ) diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 2e1830c5..b8f33b69 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -1234,6 +1234,53 @@ int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp ) return ConeSize1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_NodeMffcMapping_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vMapping, Vec_Int_t * vSupp ) +{ + Gia_Obj_t * pObj; int i, iNode, Count = 1; + if ( !iObj || Vec_IntEntry(vMapping, iObj) ) + return 0; + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + Gia_NodeMffcSizeSupp( p, pObj, vSupp ); + Vec_IntSort( vSupp, 0 ); + Vec_IntWriteEntry( vMapping, iObj, Vec_IntSize(vMapping) ); + Vec_IntPush( vMapping, Vec_IntSize(vSupp) ); + Vec_IntAppend( vMapping, vSupp ); + Vec_IntPush( vMapping, iObj ); + Vec_IntForEachEntry( vSupp, iNode, i ) + Count += Gia_NodeMffcMapping_rec( p, iNode, vMapping, vSupp ); + return Count; +} +int Gia_NodeMffcMapping( Gia_Man_t * p ) +{ + int i, Id, Count = 0; + int * pRefsOld; + Vec_Int_t * vMapping, * vSupp = Vec_IntAlloc( 100 ); + vMapping = Vec_IntAlloc( 2 * Gia_ManObjNum(p) ); + Vec_IntFill( vMapping, Gia_ManObjNum(p), 0 ); + pRefsOld = p->pRefs; p->pRefs = NULL; + Gia_ManCreateRefs( p ); + p->pRefs = pRefsOld; + Gia_ManForEachCoDriverId( p, Id, i ) + Count += Gia_NodeMffcMapping_rec( p, Id, vMapping, vSupp ); + Vec_IntFree( vSupp ); + p->vMapping = vMapping; + //printf( "Mapping is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vMapping)/Gia_ManObjNum(p) ); + return Count; +} + /**Function************************************************************* Synopsis [Returns 1 if AIG has dangling nodes.] -- cgit v1.2.3 From ecafca53d8ec0d8ad779ec187b758837e379847a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 15 Nov 2020 21:30:01 -0800 Subject: Experiments with MFFC computation (bug fix). --- src/aig/gia/giaMf.c | 4 ++-- src/aig/gia/giaUtil.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 7c67fb88..ecea3955 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -1600,14 +1600,14 @@ static inline int Mf_CutAreaRefed( Mf_Man_t * p, int * pCut ) { int Ela1 = Mf_CutDeref_rec( p, pCut ); int Ela2 = Mf_CutRef_rec( p, pCut ); - //assert( Ela1 == Ela2 ); + assert( Ela1 == Ela2 ); return Ela1; } static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut ) { int Ela1 = Mf_CutRef_rec( p, pCut ); int Ela2 = Mf_CutDeref_rec( p, pCut ); - //assert( Ela1 == Ela2 ); + assert( Ela1 == Ela2 ); return Ela1; } static inline float Mf_CutFlow( Mf_Man_t * p, int * pCut, int * pTime ) diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index b8f33b69..2409df2e 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -1272,9 +1272,9 @@ int Gia_NodeMffcMapping( Gia_Man_t * p ) Vec_IntFill( vMapping, Gia_ManObjNum(p), 0 ); pRefsOld = p->pRefs; p->pRefs = NULL; Gia_ManCreateRefs( p ); - p->pRefs = pRefsOld; Gia_ManForEachCoDriverId( p, Id, i ) Count += Gia_NodeMffcMapping_rec( p, Id, vMapping, vSupp ); + p->pRefs = pRefsOld; Vec_IntFree( vSupp ); p->vMapping = vMapping; //printf( "Mapping is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vMapping)/Gia_ManObjNum(p) ); -- cgit v1.2.3 From d350b1a82f6a6ae698c9d88098c9a0f39f062207 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 16 Nov 2020 07:12:26 -0800 Subject: Experiments with MFFC computation. --- src/aig/gia/giaMf.c | 150 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 108 insertions(+), 42 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index ecea3955..e732f25e 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -1548,68 +1548,97 @@ void Mf_ManComputeCuts( Mf_Man_t * p ) SeeAlso [] ***********************************************************************/ -int Mf_CutRef2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit ) +int Mf_CutRef_rec( Mf_Man_t * p, int * pCut ) { int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut)); - if ( Limit == 0 ) return Count; for ( i = 1; i <= Mf_CutSize(pCut); i++ ) - { - Vec_IntPush( vTemp, pCut[i] ); if ( !Mf_ObjMapRefInc(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet ) - Count += Mf_CutRef2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 ); - } + Count += Mf_CutRef_rec( p, Mf_ObjCutBest(p, pCut[i]) ); return Count; } -static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut ) +int Mf_CutDeref_rec( Mf_Man_t * p, int * pCut ) { - int Ela1, iObj, i; - Vec_IntClear( &p->vTemp ); - Ela1 = Mf_CutRef2_rec( p, pCut, &p->vTemp, 8 ); - Vec_IntForEachEntry( &p->vTemp, iObj, i ) - Mf_ObjMapRefDec( p, iObj ); + int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut)); + for ( i = 1; i <= Mf_CutSize(pCut); i++ ) + if ( !Mf_ObjMapRefDec(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet ) + Count += Mf_CutDeref_rec( p, Mf_ObjCutBest(p, pCut[i]) ); + return Count; +} +static inline int Mf_CutAreaRefed( Mf_Man_t * p, int * pCut ) +{ + int Ela1 = Mf_CutDeref_rec( p, pCut ); + int Ela2 = Mf_CutRef_rec( p, pCut ); + assert( Ela1 == Ela2 ); return Ela1; } -static inline int Mf_CutAreaDerefed2Multi( Mf_Man_t * p, int ** ppCuts, int nCuts ) +static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut ) { - int Ela1 = 0, iObj, i; - Vec_IntClear( &p->vTemp ); - for ( i = 0; i < nCuts; i++ ) - Ela1 += Mf_CutRef2_rec( p, ppCuts[i], &p->vTemp, ABC_INFINITY ); - Vec_IntForEachEntry( &p->vTemp, iObj, i ) - Mf_ObjMapRefDec( p, iObj ); + int Ela1 = Mf_CutRef_rec( p, pCut ); + int Ela2 = Mf_CutDeref_rec( p, pCut ); + assert( Ela1 == Ela2 ); return Ela1; } +static inline int Mf_CutAreaMffc( Mf_Man_t * p, int iObj ) +{ + return Mf_ObjMapRefNum(p, iObj) ? + Mf_CutAreaRefed (p, Mf_ObjCutBest(p, iObj)) : + Mf_CutAreaDerefed(p, Mf_ObjCutBest(p, iObj)); +} -int Mf_CutRef_rec( Mf_Man_t * p, int * pCut ) +int Mf_CutRef2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit ) { int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut)); + if ( Limit == 0 ) return Count; for ( i = 1; i <= Mf_CutSize(pCut); i++ ) + { + Vec_IntPush( vTemp, pCut[i] ); if ( !Mf_ObjMapRefInc(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet ) - Count += Mf_CutRef_rec( p, Mf_ObjCutBest(p, pCut[i]) ); + Count += Mf_CutRef2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 ); + } return Count; } -int Mf_CutDeref_rec( Mf_Man_t * p, int * pCut ) +int Mf_CutDeref2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit ) { int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut)); + if ( Limit == 0 ) return Count; for ( i = 1; i <= Mf_CutSize(pCut); i++ ) + { + Vec_IntPush( vTemp, pCut[i] ); if ( !Mf_ObjMapRefDec(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet ) - Count += Mf_CutDeref_rec( p, Mf_ObjCutBest(p, pCut[i]) ); + Count += Mf_CutDeref2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 ); + } return Count; } -static inline int Mf_CutAreaRefed( Mf_Man_t * p, int * pCut ) +static inline int Mf_CutAreaRefed2( Mf_Man_t * p, int * pCut ) { - int Ela1 = Mf_CutDeref_rec( p, pCut ); - int Ela2 = Mf_CutRef_rec( p, pCut ); - assert( Ela1 == Ela2 ); + int Ela1, iObj, i; + Vec_IntClear( &p->vTemp ); + Ela1 = Mf_CutDeref2_rec( p, pCut, &p->vTemp, 8 ); + Vec_IntForEachEntry( &p->vTemp, iObj, i ) + Mf_ObjMapRefInc( p, iObj ); return Ela1; } -static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut ) +static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut ) { - int Ela1 = Mf_CutRef_rec( p, pCut ); - int Ela2 = Mf_CutDeref_rec( p, pCut ); - assert( Ela1 == Ela2 ); + int Ela1, iObj, i; + Vec_IntClear( &p->vTemp ); + Ela1 = Mf_CutRef2_rec( p, pCut, &p->vTemp, 8 ); + Vec_IntForEachEntry( &p->vTemp, iObj, i ) + Mf_ObjMapRefDec( p, iObj ); + return Ela1; +} +static inline int Mf_CutAreaRefed2Multi( Mf_Man_t * p, int iObj, int ** ppCuts, int nCuts ) +{ + int Ela1 = 0, iTemp, i; + Vec_IntClear( &p->vTemp ); + for ( i = 0; i < nCuts; i++ ) + Ela1 += Mf_CutDeref2_rec( p, ppCuts[i], &p->vTemp, ABC_INFINITY ); + assert( Mf_ObjMapRefNum(p, iObj) == 0 ); + Vec_IntForEachEntry( &p->vTemp, iTemp, i ) + Mf_ObjMapRefInc( p, iTemp ); return Ela1; } + static inline float Mf_CutFlow( Mf_Man_t * p, int * pCut, int * pTime ) { Mf_Obj_t * pObj; @@ -1657,6 +1686,41 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mf_ManMappingFromMapping( Mf_Man_t * p ) +{ + Gia_Man_t * pGia = p->pGia0; + Gia_Obj_t * pObj; + int i, iObj, Count = 0; + Vec_Int_t * vMapping = Vec_IntAlloc( 3 * Gia_ManObjNum(pGia) ); + Vec_IntFill( vMapping, Gia_ManObjNum(pGia), 0 ); + Gia_ManForEachAnd( pGia, pObj, iObj ) + if ( Mf_ObjMapRefNum(p, iObj) ) + { + int * pCut = Mf_ObjCutBest(p, iObj); + Vec_IntWriteEntry( vMapping, iObj, Vec_IntSize(vMapping) ); + Vec_IntPush( vMapping, Mf_CutSize(pCut) ); + for ( i = 1; i <= Mf_CutSize(pCut); i++ ) + Vec_IntPush( vMapping, pCut[i] ); + Vec_IntPush( vMapping, iObj ); + Count++; + } + assert( pGia->vMapping == NULL ); + pGia->vMapping = vMapping; + printf( "Mapping is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vMapping)/Gia_ManObjNum(pGia) ); + return Count; +} + /**Function************************************************************* Synopsis [] @@ -1685,11 +1749,9 @@ void Mf_ManPrintFanoutProfile( Mf_Man_t * p, Vec_Int_t * vFanCounts ) int Mf_ManPrintMfccStats( Mf_Man_t * p, int iObj ) { Gia_Man_t * pGia = p->pGia0; - int Area = Mf_ObjMapRefNum(p, iObj) > 0 ? - Mf_CutAreaRefed (p, Mf_ObjCutBest(p, iObj)) : - Mf_CutAreaDerefed(p, Mf_ObjCutBest(p, iObj)); + int Area; printf( "%5d : Level = %5d Refs = %5d Mffc = %5d\n", - iObj, Gia_ObjLevelId(pGia, iObj), Mf_ObjMapRefNum(p, iObj), Area ); + iObj, Gia_ObjLevelId(pGia, iObj), Mf_ObjMapRefNum(p, iObj), (Area = Mf_CutAreaMffc(p, iObj)) ); return Area; } void Mf_ManOptimizationOne( Mf_Man_t * p, int iObj ) @@ -1697,10 +1759,14 @@ void Mf_ManOptimizationOne( Mf_Man_t * p, int iObj ) Gia_Man_t * pGia = p->pGia0; int * ppCuts[32], nCuts = 0; int iFanout, i, nAreaSum = 0, nAreaBest = 0; - // skip pivots whose MFFC fanouts are not used in the mapping or pointed to by COs + // skip pivots whose MFFC fanouts are pointed to by COs Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) - if ( Mf_ObjMapRefNum(p, iFanout) == 0 || Gia_ObjIsCo(Gia_ManObj(pGia, iFanout)) ) + if ( Gia_ObjIsCo(Gia_ManObj(pGia, iFanout)) ) return; + // the pivot is used in the mapping as well as all of its fanouts + assert( Mf_ObjMapRefNum(p, iObj) > 1 ); + Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) + assert( Mf_ObjMapRefNum(p, iFanout) > 0 ); // print this pivot and its fanouts printf( "\nPivot node = %d\n", iObj ); printf( "Pivot " ), Mf_ManPrintMfccStats( p, iObj ); @@ -1711,21 +1777,21 @@ void Mf_ManOptimizationOne( Mf_Man_t * p, int iObj ) Mf_ObjMapRefInc( p, iFanout ); Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) ppCuts[nCuts++] = Mf_ObjCutBest( p, iFanout ); - nAreaBest = Mf_CutAreaDerefed2Multi( p, ppCuts, nCuts ); + nAreaBest = Mf_CutAreaRefed2Multi( p, iObj, ppCuts, nCuts ); Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i ) Mf_ObjMapRefDec( p, iFanout ); - printf( "Sum of MFFC size = %d\n", nAreaSum ); - printf( "Shared MFFC size = %d\n", nAreaBest ); + printf( "Sum of MFFC sizes = %d\n", nAreaSum ); + printf( "Shared MFFC size = %d\n", nAreaBest ); } void Mf_ManOptimization( Mf_Man_t * p ) { int nOutMax = 3; Gia_Man_t * pGia = p->pGia0; - int i, Count, nNodes = Gia_NodeMffcMapping( pGia ); + int i, Count, nNodes = Mf_ManMappingFromMapping( p ); Gia_ManLevelNum( pGia ); Gia_ManStaticMappingFanoutStart( pGia ); Mf_ManPrintFanoutProfile( p, pGia->vFanoutNums ); - printf( "\nIndividual logic cones:\n" ); + printf( "\nIndividual logic cones for mapping with %d nodes:\n", nNodes ); Vec_IntForEachEntry( pGia->vFanoutNums, Count, i ) if ( Count >= 2 && Count <= nOutMax && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) ) Mf_ManOptimizationOne( p, i ); -- cgit v1.2.3 From 48f71adacd7727280498f414ad992257c23d76d7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 19 Nov 2020 19:22:27 -0800 Subject: Integration with several commands. --- src/aig/gia/giaDup.c | 2 +- src/aig/gia/giaEquiv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 4f448c40..ed4b7109 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -1327,7 +1327,7 @@ Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p ) { Gia_Obj_t * pRepr; pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) ); - for ( i = 0; i < Gia_ManObjNum(p); i++ ) + for ( i = 0; i < Gia_ManObjNum(pNew); i++ ) Gia_ObjSetRepr( pNew, i, GIA_VOID ); Gia_ManForEachObj1( p, pObj, i ) { diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index f7f873cd..c987453f 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -1988,7 +1988,7 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots ) pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) ); for ( i = 0; i < Gia_ManObjNum(p); i++ ) - Gia_ObjSetRepr( pNew, i, GIA_VOID ); + pNew->pReprs[i].iRepr = GIA_VOID; Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) -- cgit v1.2.3 From 0e5af861e09d94b9c1acd6bf0ab8b013a9544d24 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Nov 2020 09:52:08 -1000 Subject: Fixing a memory corruption problem accidentally introduced by fixing memory leaks on Sep 28. --- src/aig/gia/giaScript.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaScript.c b/src/aig/gia/giaScript.c index f32b1658..b52288a9 100644 --- a/src/aig/gia/giaScript.c +++ b/src/aig/gia/giaScript.c @@ -165,7 +165,7 @@ Gia_Man_t * Gia_ManAigSyn3( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) { pNew = Gia_ManDup(p); Gia_ManTransferTiming( pNew, p ); - Gia_ManStop( p ); + //Gia_ManStop( p ); return pNew; } // perform balancing @@ -202,7 +202,7 @@ Gia_Man_t * Gia_ManAigSyn4( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) { pNew = Gia_ManDup(p); Gia_ManTransferTiming( pNew, p ); - Gia_ManStop( p ); + //Gia_ManStop( p ); return pNew; } //Gia_ManAigPrintPiLevels( p ); -- cgit v1.2.3 From fa87d16b971438d5f1bc369a28c69eb4435d040a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 29 Nov 2020 12:23:17 -1000 Subject: Window resub testing. --- src/aig/gia/giaResub2.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index 8877439c..89ddaf33 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -1434,6 +1434,70 @@ Gia_Man_t * Gia_RsbTryOneWindow( Gia_Man_t * p ) return Gia_ManResub2Test( p ); } +/**Function************************************************************* + + Synopsis [Apply k-resub to one AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_RsbTestArray() +{ + int Array[1000] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 3, 7, 15, 17, 8, 19, + 5, 20, 5, 12, 8, 24, 4, 12, 9, 28, 27, 31, 23, 32, 4, 13, 8, 36, 5, + 13, 18, 40, 9, 18, 5, 44, 19, 36, 9, 48, 47, 51, 10, 18, 40, 54, 8, + 56, 25, 37, 44, 61, 59, 63, 8, 28, 8, 18, 25, 68, 66, 70, 64, 73, 11, + 19, 8, 13, 76, 78, 10, 19, 40, 82, 9, 84, 81, 87, 20, 61, 19, 28, 30, + 92, 91, 95, 88, 96, 74, 98, 9, 40, 49, 103, 27, 104, 10, 107, 8, 40, + 9, 24, 111, 113, 11, 115, 109, 117, 11, 66, 51, 121, 118, 122, 18, 36, + 18, 110, 93, 127, 10, 131, 129, 133, 11, 38, 32, 137, 103, 138, 19, 141, + 134, 143, 28, 76, 9, 146, 11, 110, 19, 150, 149, 153, 87, 95, 9, 19, 10, + 159, 61, 160, 18, 30, 61, 158, 9, 12, 25, 169, 19, 171, 111, 173, 10, 175, + 167, 177, 18, 102, 4, 20, 18, 171, 183, 185, 11, 187, 181, 189, 178, 190, + 24, 44, 11, 194, 8, 54, 4, 198, 197, 201, 45, 49, 10, 39, 9, 126, 73, 209, + 11, 211, 54, 168, 213, 215, 43, 167, 67, 218, 10, 221, 26, 54, 18, 18, 34, + 34, 38, 38, 40, 40, 42, 42, 52, 52, 100, 100, 124, 124, 126, 126, 144, 144, + 148, 148, 154, 154, 156, 156, 162, 162, 164, 164, 192, 192, 70, 70, 202, + 202, 204, 204, 206, 206, 216, 216, 222, 222, 224, 224 + }; + int i, iFan0, iFan1, nResubs; + int * pRes; + // create the internal array + Vec_Int_t * vArray = Vec_IntAlloc( 100 ); + for ( i = 0; i < 50 || Array[i] > 0; i++ ) + Vec_IntPush( vArray, Array[i] ); + Vec_IntPrint( vArray ); + // check the nodes + printf( "Constant0 and primary inputs:\n" ); + Vec_IntForEachEntryDouble( vArray, iFan0, iFan1, i ) + { + if ( iFan0 != iFan1 ) + break; + printf( "%2d = %c%2d & %c%2d;\n", i, + Abc_LitIsCompl(iFan0) ? '!' : ' ', Abc_Lit2Var(iFan0), + Abc_LitIsCompl(iFan1) ? '!' : ' ', Abc_Lit2Var(iFan1) ); + } + printf( "Primary outputs:\n" ); + Vec_IntForEachEntryDoubleStart( vArray, iFan0, iFan1, i, 14 ) + { + if ( iFan0 != iFan1 ) + continue; + printf( "%2d = %c%2d & %c%2d;\n", i, + Abc_LitIsCompl(iFan0) ? '!' : ' ', Abc_Lit2Var(iFan0), + Abc_LitIsCompl(iFan1) ? '!' : ' ', Abc_Lit2Var(iFan1) ); + } + // run the resub + Abc_ResubPrepareManager( 1 ); + Abc_ResubComputeWindow( Vec_IntArray(vArray), Vec_IntSize(vArray)/2, 10, -1, 0, 0, 1, 1, &pRes, &nResubs ); + Abc_ResubPrepareManager( 0 ); + Vec_IntFree( vArray ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 206527045e3ce4bb1b1adb683b0f471865648ffb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 7 Dec 2020 16:28:14 -1000 Subject: Deriving structural choices from proved equivalences. --- src/aig/gia/giaEquiv.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index c987453f..224d9c4d 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -2707,6 +2707,117 @@ void Gia_ManTransferTest( Gia_Man_t * p ) Gia_ManStop( pNew ); } + +/**Function************************************************************* + + Synopsis [Converting AIG after SAT sweeping into AIG with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec4_ManMarkIndependentClasses_rec( Gia_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj; + assert( iObj > 0 ); + if ( Gia_ObjIsTravIdPreviousId(p, iObj) ) // failed + return 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) // passed + return 1; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return 1; + assert( Gia_ObjIsAnd(pObj) ); + if ( Cec4_ManMarkIndependentClasses_rec( p, Gia_ObjFaninId0(pObj, iObj) ) && + Cec4_ManMarkIndependentClasses_rec( p, Gia_ObjFaninId1(pObj, iObj) ) ) + return 1; + Gia_ObjSetTravIdPreviousId(p, iObj); + return 0; +} +int Cec4_ManMarkIndependentClasses( Gia_Man_t * p, Gia_Man_t * pNew ) +{ + int iObjNew, iRepr, iObj, Res, fHaveChoices = 0; + Gia_ManCleanMark01(p); + Gia_ManForEachClass( p, iRepr ) + { + Gia_ManIncrementTravId( pNew ); + Gia_ManIncrementTravId( pNew ); + iObjNew = Abc_Lit2Var( Gia_ManObj(p, iRepr)->Value ); + Res = Cec4_ManMarkIndependentClasses_rec( pNew, iObjNew ); + assert( Res == 1 ); + Gia_ObjSetTravIdPreviousId( pNew, iObjNew ); + p->pReprs[iRepr].fColorA = 1; + Gia_ClassForEachObj1( p, iRepr, iObj ) + { + assert( p->pReprs[iObj].iRepr == (unsigned)iRepr ); + iObjNew = Abc_Lit2Var( Gia_ManObj(p, iObj)->Value ); + if ( Cec4_ManMarkIndependentClasses_rec( pNew, iObjNew ) ) + { + p->pReprs[iObj].fColorA = 1; + fHaveChoices = 1; + } + Gia_ObjSetTravIdPreviousId( pNew, iObjNew ); + } + } + return fHaveChoices; +} +int Cec4_ManSatSolverAnd_rec( Gia_Man_t * pCho, Gia_Man_t * p, Gia_Man_t * pNew, int iObj ) +{ + return 0; +} +int Cec4_ManSatSolverChoices_rec( Gia_Man_t * pCho, Gia_Man_t * p, Gia_Man_t * pNew, int iObj ) +{ + if ( !Gia_ObjIsClass(p, iObj) ) + return Cec4_ManSatSolverAnd_rec( pCho, p, pNew, iObj ); + else + { + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + int i, iHead, iNext, iRepr = Gia_ObjIsHead(p, iObj) ? iObj : Gia_ObjRepr(p, iObj); + Gia_ClassForEachObj( p, iRepr, iObj ) + if ( p->pReprs[iObj].fColorA ) + Vec_IntPush( vLits, Cec4_ManSatSolverAnd_rec( pCho, p, pNew, iObj ) ); + Vec_IntSort( vLits, 1 ); + iHead = Abc_Lit2Var( Vec_IntEntry(vLits, 0) ); + if ( Vec_IntSize(vLits) > 1 ) + { + Vec_IntForEachEntryStart( vLits, iNext, i, 1 ) + { + pCho->pSibls[iHead] = Abc_Lit2Var(iNext); + iHead = Abc_Lit2Var(iNext); + } + } + return Abc_LitNotCond( Vec_IntEntry(vLits, 0), Gia_ManObj(p, iHead)->fPhase ); + } +} +Gia_Man_t * Cec4_ManSatSolverChoices( Gia_Man_t * p, Gia_Man_t * pNew ) +{ + Gia_Man_t * pCho; + Gia_Obj_t * pObj; + int i, DriverId; + // mark topologically dependent equivalent nodes + if ( !Cec4_ManMarkIndependentClasses( p, pNew ) ) + return Gia_ManDup( pNew ); + // rebuild AIG in a different order with choices + pCho = Gia_ManStart( Gia_ManObjNum(pNew) ); + pCho->pName = Abc_UtilStrsav( p->pName ); + pCho->pSpec = Abc_UtilStrsav( p->pSpec ); + pCho->pSibls = ABC_CALLOC( int, Gia_ManObjNum(pNew) ); + Gia_ManFillValue(pNew); + Gia_ManConst0(pNew)->Value = 0; + for ( i = 0; i < Gia_ManCiNum(pNew); i++ ) + Gia_ManCi(pNew, i)->Value = Gia_ManAppendCi( pCho ); + Gia_ManForEachCoDriverId( p, DriverId, i ) + Cec4_ManSatSolverChoices_rec( pCho, p, pNew, DriverId ); + Gia_ManForEachCo( pNew, pObj, i ) + pObj->Value = Gia_ManAppendCo( pCho, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pCho, Gia_ManRegNum(p) ); + return pCho; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 5b8e56b2e51ea01a54f668d9ec139f37f7fec10f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 7 Dec 2020 17:15:31 -1000 Subject: Adding timeout to several commands. --- src/aig/gia/giaSim4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSim4.c b/src/aig/gia/giaSim4.c index 56dcb713..886807d5 100644 --- a/src/aig/gia/giaSim4.c +++ b/src/aig/gia/giaSim4.c @@ -41,7 +41,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fSkipMffc, int fVerbose ) +int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nTimeout, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fSkipMffc, int fVerbose ) { return 0; } -- cgit v1.2.3 From 06094ade87fbec6000619bf007aaad596e8bc0a2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 16 Dec 2020 00:06:31 -0800 Subject: Adding switch to replace proved outputs by const0. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaCSat.c | 4 +++- src/aig/gia/giaEquiv.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 3616e10c..3c16600e 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1250,7 +1250,7 @@ extern Cbs_Man_t * Cbs_ManAlloc( Gia_Man_t * pGia ); extern void Cbs_ManStop( Cbs_Man_t * p ); extern int Cbs_ManSolve( Cbs_Man_t * p, Gia_Obj_t * pObj ); extern int Cbs_ManSolve2( Cbs_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 ); -extern Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose ); +extern Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose ); extern void Cbs_ManSetConflictNum( Cbs_Man_t * p, int Num ); extern Vec_Int_t * Cbs_ReadModel( Cbs_Man_t * p ); /*=== giaCTas.c ============================================================*/ diff --git a/src/aig/gia/giaCSat.c b/src/aig/gia/giaCSat.c index 503961d4..67b62655 100644 --- a/src/aig/gia/giaCSat.c +++ b/src/aig/gia/giaCSat.c @@ -1034,7 +1034,7 @@ void Cbs_ManSatPrintStats( Cbs_Man_t * p ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose ) +Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose ) { extern void Gia_ManCollectTest( Gia_Man_t * pAig ); extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); @@ -1105,6 +1105,8 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt } if ( status == 1 ) { + if ( f0Proved ) + Gia_ManPatchCoDriver( pAig, i, 0 ); p->nSatUnsat++; p->nConfUnsat += p->Pars.nBTThis; p->timeSatUnsat += Abc_Clock() - clk; diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 224d9c4d..5c82b260 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -2818,6 +2818,66 @@ Gia_Man_t * Cec4_ManSatSolverChoices( Gia_Man_t * p, Gia_Man_t * pNew ) return pCho; } +/**Function************************************************************* + + Synopsis [Converting AIG after SAT sweeping into AIG with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCombSpecReduce( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pRepr; int i, iLit; + Vec_Int_t * vXors = Vec_IntAlloc( 100 ); + Gia_Man_t * pTemp, * pNew = Gia_ManStart( Gia_ManObjNum(p) ); + assert( p->pReprs && p->pNexts ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManLevelNum(p); + Gia_ManSetPhase(p); + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + { + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + pRepr = Gia_ObjReprObj( p, i ); + if ( pRepr && Abc_Lit2Var(pObj->Value) != Abc_Lit2Var(pRepr->Value) ) + { + //if ( Gia_ObjLevel(p, pRepr) > Gia_ObjLevel(p, pObj) + 50 ) + //printf( "%d %d ", Gia_ObjLevel(p, pRepr), Gia_ObjLevel(p, pObj) ); + iLit = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase ); + Vec_IntPush( vXors, Gia_ManHashXor( pNew, pObj->Value, iLit ) ); + pObj->Value = iLit; + } + } + Gia_ManHashStop( pNew ); + if ( Vec_IntSize(vXors) == 0 ) + Vec_IntPush( vXors, 0 ); + Vec_IntForEachEntry( vXors, iLit, i ) + Gia_ManAppendCo( pNew, iLit ); + Vec_IntFree( vXors ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} +void Gia_ManCombSpecReduceTest( Gia_Man_t * p, char * pFileName ) +{ + Gia_Man_t * pSrm = Gia_ManCombSpecReduce( p ); + if ( pFileName == NULL ) + pFileName = "test.aig"; + Gia_AigerWrite( pSrm, pFileName, 0, 0, 0 ); + Abc_Print( 1, "Speculatively reduced model was written into file \"%s\".\n", pFileName ); + Gia_ManStop( pSrm ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From f06217e25a9905e5ebb9bce27ac06c456b9cf5f8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 21 Dec 2020 12:45:50 -0800 Subject: Compiler warnings. --- src/aig/gia/giaUtil.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 2409df2e..2762dbac 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2460,6 +2460,40 @@ Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ComputeTest() +{ + char * pStart, Line [1000]; float Total = 0; + char * pFileName = "data.txt"; + FILE * pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { printf( "Input file \"%s\" cannot be opened.\n", pFileName ); return; } + while ( fgets( Line, 1000, pFile ) != NULL ) + { + if ( !strstr(Line, "xxx") ) + continue; + if ( !strstr(Line, "yyy") ) + continue; + //printf( "%s", Line ); + pStart = strstr(Line, "zzz"); + if ( pStart == NULL ) + continue; + //printf( "%s", pStart + 4 ); + Total += -atof( pStart + 4 ); + } + printf( "Total = %.2f\n", Total ); + fclose( pFile ); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -- cgit v1.2.3 From d0efef2fe958ca093b06ad4be739ffdcb44c4d28 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 30 Dec 2020 11:24:35 -0800 Subject: Experiments with simulation. --- src/aig/gia/gia.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 3c16600e..1fa7e368 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -479,6 +479,7 @@ static inline int Gia_ObjValue( Gia_Obj_t * pObj ) { static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { pObj->Value = i; } static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; } static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); } +static inline int Gia_ObjPhaseDiff( Gia_Man_t * p, int i, int k ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, k)->fPhase; } static inline int Gia_ObjIsTerm( Gia_Obj_t * pObj ) { return pObj->fTerm; } static inline int Gia_ObjIsAndOrConst0( Gia_Obj_t * pObj ) { return!pObj->fTerm; } -- cgit v1.2.3 From cd8843c06ce2a37067edb5116f0c735ce3e3b7c7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 9 Jan 2021 13:06:45 -0800 Subject: Preventing command history from being overwritten by internal scripts. --- src/aig/gia/giaDeep.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaDeep.c b/src/aig/gia/giaDeep.c index aa9e9cb2..eecc598a 100644 --- a/src/aig/gia/giaDeep.c +++ b/src/aig/gia/giaDeep.c @@ -74,10 +74,23 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in pComp = "; &dc2"; sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s", fDch ? " -f" : "", KLut, fFx ? "; &fx" : "", pComp ); - if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) ) + if ( Abc_FrameIsBatchMode() ) { - Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command ); - return NULL; + if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) ) + { + Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command ); + return NULL; + } + } + else + { + Abc_FrameSetBatchMode( 1 ); + if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) ) + { + Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command ); + return NULL; + } + Abc_FrameSetBatchMode( 0 ); } pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame()); if ( Gia_ManAndNum(pNew) > Gia_ManAndNum(pTemp) ) -- cgit v1.2.3 From 6a03ece98d0da3f6ec14d86f0bff36e6f36ba8bd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 28 Mar 2021 14:49:27 -1000 Subject: Command &iwls21test for evaluating the results of 2021 IWLS Contest. --- src/aig/gia/gia.c | 1 + src/aig/gia/giaGen.c | 428 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 429 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c index cf7c0ddd..ed6e276a 100644 --- a/src/aig/gia/gia.c +++ b/src/aig/gia/gia.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "gia.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c index 94d561cc..c33e9dbe 100644 --- a/src/aig/gia/giaGen.c +++ b/src/aig/gia/giaGen.c @@ -20,6 +20,7 @@ #include "gia.h" #include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -33,6 +34,63 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_DeriveAig( Vec_Wrd_t * vSims, Vec_Str_t * vSimsOut ) +{ + int nInputs = 32*32*24; + int nWords = nInputs/64; + int nExamps = 64; + int i, e, iLitOut[10] = {0}; + Gia_Man_t * pNew; + assert( Vec_WrdSize(vSims) % nInputs == 0 ); + pNew = Gia_ManStart( nInputs * nExamps + 10000 ); + for ( i = 0; i < nInputs; i++ ) + Gia_ManAppendCi( pNew ); + Gia_ManHashStart( pNew ); + for ( e = 0; e < nExamps; e++ ) + { + int Class = Vec_StrEntry( vSimsOut, e ); + int This = 1; + word * pSim = Vec_WrdEntryP( vSims, e*nWords ); + for ( i = 0; i < nInputs; i++ ) + This = Gia_ManHashAnd( pNew, This, Abc_Var2Lit(i+1, !Abc_TtGetBit(pSim, i)) ); + assert( Class >= 0 && Class <= 9 ); + iLitOut[Class] = Gia_ManHashOr( pNew, iLitOut[Class], This ); + //printf( "Finished example %d\n", e ); + } + for ( i = 0; i < 10; i++ ) + Gia_ManAppendCo( pNew, iLitOut[i] ); + //pNew = Gia_ManCleanup( pTemp = pNew ); + //Gia_ManStop( pTemp ); + return pNew; +} +void Gia_DeriveAigTest() +{ + extern int Gia_ManReadCifar10File( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut, int * pnExamples ); + char pFileName[100] = "test"; + Vec_Wrd_t * vSimsIn; + Vec_Str_t * vSimsOut; + int nExamples = 0; + int nInputs = Gia_ManReadCifar10File( pFileName, &vSimsIn, &vSimsOut, &nExamples ); + Gia_Man_t * pThis = Gia_DeriveAig( vSimsIn, vSimsOut ); + Gia_AigerWrite( pThis, "examples64.aig", 0, 0, 0 ); + printf( "Dumped file \"%s\".\n", "examples64.aig" ); + Gia_ManStop( pThis ); + Vec_WrdFree( vSimsIn ); + Vec_StrFree( vSimsOut ); +} + + /**Function************************************************************* Synopsis [Populate internal simulation info.] @@ -432,6 +490,224 @@ void Gia_ManCompareValues( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Int_t * vValu printf( "Finished dumping statistics into file \"%s\".\n", pDumpFile ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManReadSimFile( char * pFileName, int * pnIns, int * pnOuts, int * pnPats, Vec_Wrd_t ** pvSimsIn, Vec_Wrd_t ** pvSimsOut ) +{ + char * pTemp, pBuffer[1000]; + Vec_Wrd_t * vSimsIn = NULL, * vSimsOut = NULL; + int i, iPat = 0, nWordsI, nWordsO, nIns = -1, nOuts = -1, nPats = -1; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return; + } + while ( fgets( pBuffer, 1000, pFile ) != NULL ) + { + pTemp = pBuffer; + if ( pTemp[0] == '\0' || pTemp[0] == '#' || pTemp[0] == ' ' ) + continue; + if ( pTemp[0] != '.' ) + break; + if ( pTemp[1] = 'i' ) + nIns = atoi(pTemp+2); + else if ( pTemp[1] = 'o' ) + nOuts = atoi(pTemp+2); + else if ( pTemp[1] = 'p' ) + { + if ( atoi(pTemp+2) % 64 == 0 ) + printf( "Expecting the number of patterns divisible by 64.\n" ); + nPats = atoi(pTemp+2) / 64; + } + } + if ( nIns == -1 || nOuts == -1 || nPats == -1 ) + { + printf( "Some of the parameters (inputs, outputs, patterns) is not specified.\n" ); + fclose( pFile ); + return; + } + nWordsI = (nIns + 63) / 64; + nWordsO = (nOuts + 63) / 64; + + vSimsIn = Vec_WrdStart( nPats * nWordsI ); + vSimsOut = Vec_WrdStart( nPats * nWordsO ); + rewind(pFile); + while ( fgets( pBuffer, 1000, pFile ) != NULL ) + { + if ( pTemp[0] == '\0' || pTemp[0] == '.' ) + continue; + for ( i = 0, pTemp = pBuffer; *pTemp != '\n'; pTemp++ ) + if ( *pTemp == '0' || *pTemp == '1' ) + { + if ( *pTemp == '1' ) + { + if ( i < nIns ) + Abc_TtSetBit( Vec_WrdEntryP(vSimsIn, nWordsI*iPat), i ); + else + Abc_TtSetBit( Vec_WrdEntryP(vSimsOut, nWordsO*iPat), i-nIns ); + } + i++; + } + iPat++; + } + if ( iPat != nPats ) + printf( "The number of patterns does not match.\n" ); + fclose( pFile ); + *pnIns = nIns; + *pnOuts = nOuts; + *pnPats = nPats; + *pvSimsIn = vSimsIn; + *pvSimsOut = vSimsOut; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManReadBinaryFile( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut ) +{ + extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ); + int nFileSize = Extra_FileSize( pFileName ); + int nExamples = 1 << 16; + int nInputs = nFileSize / nExamples - 1; + int nWords = (8*nInputs + 63)/64, i; + char * pContents = Extra_FileReadContents( pFileName ); + Vec_Wrd_t * vSimsIn = Vec_WrdStart( nExamples * nWords ); + Vec_Wrd_t * vSimsIn2 = Vec_WrdStart( nExamples * nWords ); + Vec_Str_t * vSimsOut = Vec_StrAlloc( nExamples ); + assert( nFileSize % nExamples == 0 ); + for ( i = 0; i < nExamples; i++ ) + { + memcpy( (void *)Vec_WrdEntryP(vSimsIn, i*nWords), (void *)(pContents + i*(nInputs+1)), nInputs ); + Vec_StrPush( vSimsOut, pContents[i*(nInputs+1) + nInputs] ); + } + Extra_BitMatrixTransposeP( vSimsIn, nWords, vSimsIn2, nExamples/64 ); + Vec_WrdShrink( vSimsIn2, 8*nInputs * nExamples/64 ); + Vec_WrdFree( vSimsIn ); + *pvSimsIn = vSimsIn2; + *pvSimsOut = vSimsOut; + ABC_FREE( pContents ); + return nInputs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimLogStats2( Gia_Man_t * p, char * pDumpFile, int Total, int nPositives, float ErrorTotal, float GuessTotal ) +{ + FILE * pTable = fopen( pDumpFile, "wb" ); + fprintf( pTable, "{\n" ); + fprintf( pTable, " \"name\" : \"%s\",\n", p->pName ); + fprintf( pTable, " \"input\" : %d,\n", Gia_ManCiNum(p) ); + fprintf( pTable, " \"output\" : %d,\n", Gia_ManCoNum(p) ); + fprintf( pTable, " \"and\" : %d,\n", Gia_ManAndNum(p) ); + fprintf( pTable, " \"level\" : %d,\n", Gia_ManLevelNum(p) ); + fprintf( pTable, " \"total\" : %d,\n", Total ); + fprintf( pTable, " \"positive\" : %d,\n", nPositives ); + fprintf( pTable, " \"error\" : %e,\n", ErrorTotal ); + fprintf( pTable, " \"guess\" : %e\n", GuessTotal ); + fprintf( pTable, "}\n" ); + fclose( pTable ); +} +int Gia_ManGetExampleValue( word ** ppSims, int nSims, int iExample ) +{ + int o, Sign = 0, ValueSim = 0; + for ( o = 0; o < nSims; o++ ) + if ( (Sign = Abc_TtGetBit(ppSims[o], iExample)) ) + ValueSim |= (1 << o); + if ( Sign ) + ValueSim |= ~0 << nSims; + return ValueSim; +} +void Gia_ManCompareValues2( int nInputs, Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vValues, char * pDumpFile ) +{ + float Error1, ErrorTotal = 0, Guess1, GuessTotal = 0; + int i, o, nPositives = 0, nWords = Vec_WrdSize(vSimsIn) / Gia_ManCiNum(p); + word ** ppSims = ABC_CALLOC( word *, Gia_ManCoNum(p) ); + Gia_Obj_t * pObj; + assert( nWords == (1<<10) ); + assert( Vec_WrdSize(vSimsIn) % Gia_ManCiNum(p) == 0 ); + assert( Vec_StrSize(vValues) == (1 << 16) ); + assert( nWords*64 == (1 << 16) ); + // simulate examples given in vSimsIn + Gia_ManSimulateWordsInit( p, vSimsIn ); + // collect simulation info for the outputs + assert( p->nSimWords == nWords ); + Gia_ManForEachCo( p, pObj, o ) + ppSims[o] = Gia_ManObjSim( p, Gia_ObjId(p, pObj) ); + // compare the output for each example + for ( i = 0; i < nWords*64; i++ ) + { + int ValueGold = (int)Vec_StrEntry( vValues, i ); + int ValueImpl = Gia_ManGetExampleValue( ppSims, Gia_ManCoNum(p), i ); + // compute error for this example + Error1 = (float)(ValueGold - ValueImpl)/256; + ErrorTotal += Error1 * Error1; + // compute error of zero-output + Guess1 = ValueGold > 0 ? Abc_AbsInt(ValueImpl) : 0; + GuessTotal += Guess1 * Guess1; + // count positive values (disregard negative values due to Leaky ReLU) + nPositives += (int)(ValueGold > 0); + } + ABC_FREE( ppSims ); + printf( "Total = %6d. Positive = %6d. (%6.2f %%) Errors = %e. Guess = %e. (%6.2f %%)\n", + Vec_StrSize(vValues), nPositives, 100.0*nPositives/Vec_StrSize(vValues), + ErrorTotal, GuessTotal, 100.0*ErrorTotal/GuessTotal ); + if ( pDumpFile == NULL ) + return; + Gia_ManSimLogStats2( p, pDumpFile, Vec_StrSize(vValues), nPositives, ErrorTotal, GuessTotal ); + printf( "Finished dumping statistics into file \"%s\".\n", pDumpFile ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTestWordFileUnused( Gia_Man_t * p, char * pFileName, char * pDumpFile ) +{ + Vec_Wrd_t * vSimsIn; + Vec_Str_t * vSimsOut; + int nInputs = Gia_ManReadBinaryFile( pFileName, &vSimsIn, &vSimsOut ); + if ( Gia_ManCiNum(p) == 8*nInputs ) + Gia_ManCompareValues2( nInputs, p, vSimsIn, vSimsOut, pDumpFile ); + else + printf( "The number of inputs in the AIG (%d) and in the file (%d) does not match.\n", Gia_ManCiNum(p), 8*nInputs ); + Vec_WrdFree( vSimsIn ); + Vec_StrFree( vSimsOut ); +} + /**Function************************************************************* Synopsis [] @@ -463,6 +739,158 @@ void Gia_ManTestOneFile( Gia_Man_t * p, char * pFileName, char * pDumpFile ) Vec_IntFree( vValues ); } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManReadCifar10File( char * pFileName, Vec_Wrd_t ** pvSimsIn, Vec_Str_t ** pvSimsOut, int * pnExamples ) +{ + int nPixels = 32*32*3; + int nFileSize = Extra_FileSize( pFileName ); + int nExamples = nFileSize / (nPixels + 1); + int nWordsIn = nPixels / 8; + int nWordsOut = (nExamples + 63) / 64; int e; + if ( nFileSize % (nPixels + 1) ) + { + printf( "The input file \"%s\" with image data does not appear to be in CIFAR10 format.\n", pFileName ); + return 0; + } + else + { + Vec_Wrd_t * vSimsIn = Vec_WrdStart( 64 * nWordsOut * nWordsIn ); + Vec_Str_t * vSimsOut = Vec_StrAlloc( 64 * nWordsOut ); + unsigned char * pBuffer = ABC_ALLOC( unsigned char, nFileSize ); + FILE * pFile = fopen( pFileName, "rb" ); + int Value = fread( pBuffer, 1, nFileSize, pFile ); + fclose( pFile ); + assert( Value == nFileSize ); + printf( "Successfully read %5.2f MB (%d images) from file \"%s\".\n", (float)nFileSize/(1<<20), nExamples, pFileName ); + for ( e = 0; e < nExamples; e++ ) + { + Vec_StrPush( vSimsOut, (char)pBuffer[e*(nPixels + 1)] ); + memcpy( Vec_WrdEntryP(vSimsIn, e*nWordsIn), pBuffer + e*(nPixels + 1) + 1, nPixels ); + } + ABC_FREE( pBuffer ); + for ( ; e < 64 * nWordsOut; e++ ) + Vec_StrPush( vSimsOut, (char)0 ); + memset( Vec_WrdEntryP(vSimsIn, nExamples*nWordsIn), 0, (64*nWordsOut - nExamples)*nWordsIn ); + *pvSimsIn = vSimsIn; + *pvSimsOut = vSimsOut; + *pnExamples = nExamples; + return 8*nPixels; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSimulateBatch( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vSimsOut, Vec_Str_t * vSimsOut2, int b, int Limit ) +{ + Gia_Obj_t * pObj; + word * ppSims[10]; + int i, o, Count = 0; + assert( Gia_ManCiNum(p) == Vec_WrdSize(vSimsIn) ); + assert( Gia_ManCoNum(p) == 10 ); + Gia_ManSimulateWordsInit( p, vSimsIn ); + Gia_ManForEachCo( p, pObj, o ) + ppSims[o] = Gia_ManObjSim( p, Gia_ObjId(p, pObj) ); + for ( i = 0; i < Limit; i++ ) + { + int Value = 0; + for ( o = 0; o < 10; o++ ) + if ( Abc_TtGetBit(ppSims[o], i) ) + { + Value = o; + break; + } + Vec_StrPush( vSimsOut, (char)Value ); + Count += Value == (int)Vec_StrEntry( vSimsOut2, 64*b+i ); + } + return Count; +} +Vec_Str_t * Gia_ManSimulateAll( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Str_t * vSimsOut, int nExamples, int fVerbose ) +{ + extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ); + Vec_Str_t * vRes = Vec_StrAlloc( 100 ); int b, Count; + int nWordsIn = 32*32*24/64; // one image + int nWordsOut = Vec_WrdSize(vSimsIn)/(nWordsIn*64); + assert( Vec_WrdSize(vSimsIn) % nWordsIn == 0 ); + for ( b = 0; b < nWordsOut; b++ ) + { + int Limit = b == nWordsOut-1 ? nExamples-b*64 : 64; + Vec_Wrd_t * vSimsIn1 = Vec_WrdStart( nWordsIn*64 ); + Vec_Wrd_t * vSimsIn2 = Vec_WrdStart( nWordsIn*64 ); + memcpy( Vec_WrdArray(vSimsIn1), Vec_WrdEntryP(vSimsIn, b*nWordsIn*64), sizeof(word)*nWordsIn*64 ); + Extra_BitMatrixTransposeP( vSimsIn1, nWordsIn, vSimsIn2, 1 ); + Vec_WrdFree( vSimsIn1 ); + Count = Gia_ManSimulateBatch( p, vSimsIn2, vRes, vSimsOut, b, Limit ); + Vec_WrdFree( vSimsIn2 ); + if ( fVerbose ) + printf( "Finished simulating word %4d (out of %4d). Correct = %2d. (Limit = %2d.)\n", b, nWordsOut, Count, Limit ); + } + assert( Vec_StrSize(vRes) == nExamples ); + return vRes; +} +void Gia_ManCompareCifar10Values( Gia_Man_t * p, Vec_Str_t * vRes, Vec_Str_t * vSimsOut, char * pDumpFile, int nExamples ) +{ + int i, Guess = (nExamples+9)/10, Count = 0; + for ( i = 0; i < nExamples; i++ ) + { + char ValueReal = Vec_StrEntry(vRes, i); + char ValueGold = Vec_StrEntry(vSimsOut, i); + if ( ValueReal == ValueGold ) + Count++; + } + printf( "Summary: Total = %6d. Errors = %6d. Correct = %6d. (%6.2f %%) Naive guess = %6d. (%6.2f %%)\n", + nExamples, nExamples - Count, + Count, 100.0*Count/nExamples, + Guess, 100.0*Guess/nExamples); + if ( pDumpFile == NULL ) + return; + Gia_ManSimLogStats( p, pDumpFile, nExamples, Count, Guess ); + printf( "Finished dumping statistics into file \"%s\".\n", pDumpFile ); +} +void Gia_ManTestWordFile( Gia_Man_t * p, char * pFileName, char * pDumpFile, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Vec_Wrd_t * vSimsIn; + Vec_Str_t * vSimsOut; + int i, nExamples = 0; + int nInputs = Gia_ManReadCifar10File( pFileName, &vSimsIn, &vSimsOut, &nExamples ); + char * pKnownFileNames[3] = {"small.aig", "medium.aig", "large.aig"}; + int pLimitFileSizes[3] = {10000, 100000, 1000000}; + for ( i = 0; i < 3; i++ ) + if ( !strncmp(p->pSpec, pKnownFileNames[i], 5) && Gia_ManAndNum(p) > pLimitFileSizes[i] ) + printf( "Warning: The input file \"%s\" contains more than %d internal and-nodes.\n", pKnownFileNames[i], pLimitFileSizes[i] ); + if ( nInputs == Gia_ManCiNum(p) ) + { + Vec_Str_t * vRes = Gia_ManSimulateAll( p, vSimsIn, vSimsOut, nExamples, fVerbose ); + Gia_ManCompareCifar10Values( p, vRes, vSimsOut, pDumpFile, nExamples ); + Vec_StrFree( vRes ); + } + else + printf( "The primary input counts in the AIG (%d) and in the image data (%d) do not match.\n", Gia_ManCiNum(p), nInputs ); + Vec_WrdFree( vSimsIn ); + Vec_StrFree( vSimsOut ); + Abc_PrintTime( 1, "Total checking time", Abc_Clock() - clk ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 35a4ce557cb84ef8f92ace363c92b264cda59ac7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 28 Mar 2021 14:52:11 -1000 Subject: Compiler warnings. --- src/aig/gia/giaGen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c index c33e9dbe..5857080b 100644 --- a/src/aig/gia/giaGen.c +++ b/src/aig/gia/giaGen.c @@ -88,6 +88,7 @@ void Gia_DeriveAigTest() Gia_ManStop( pThis ); Vec_WrdFree( vSimsIn ); Vec_StrFree( vSimsOut ); + nInputs = 0; } @@ -519,11 +520,11 @@ void Gia_ManReadSimFile( char * pFileName, int * pnIns, int * pnOuts, int * pnPa continue; if ( pTemp[0] != '.' ) break; - if ( pTemp[1] = 'i' ) + if ( pTemp[1] == 'i' ) nIns = atoi(pTemp+2); - else if ( pTemp[1] = 'o' ) + else if ( pTemp[1] == 'o' ) nOuts = atoi(pTemp+2); - else if ( pTemp[1] = 'p' ) + else if ( pTemp[1] == 'p' ) { if ( atoi(pTemp+2) % 64 == 0 ) printf( "Expecting the number of patterns divisible by 64.\n" ); -- cgit v1.2.3 From 9145a5c20d5fe85523364d7fe2727b8d83c90aaa Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 28 Mar 2021 15:40:27 -1000 Subject: An option to extend the number of primary inputs. --- src/aig/gia/giaDup.c | 32 ++++++++++++++++++++++++++++++++ src/aig/gia/giaGen.c | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index ed4b7109..9de9e735 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -4899,6 +4899,38 @@ Gia_Man_t * Gia_ManDupReplaceCut( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Duplicate AIG by creating a cut between logic fed by PIs] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupAddPis( Gia_Man_t * p, int nMulti ) +{ + Gia_Man_t * pNew; int i, k; + Gia_Obj_t * pObj; + pNew = Gia_ManStart( Gia_ManObjNum(p) + Gia_ManCiNum(p) * nMulti ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + { + pObj->Value = Gia_ManAppendCi(pNew); + for ( k = 1; k < nMulti; k++ ) + Gia_ManAppendCi(pNew); + } + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + assert( Gia_ManCiNum(pNew) == nMulti * Gia_ManCiNum(p) ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c index 5857080b..3c0d2235 100644 --- a/src/aig/gia/giaGen.c +++ b/src/aig/gia/giaGen.c @@ -877,7 +877,7 @@ void Gia_ManTestWordFile( Gia_Man_t * p, char * pFileName, char * pDumpFile, int char * pKnownFileNames[3] = {"small.aig", "medium.aig", "large.aig"}; int pLimitFileSizes[3] = {10000, 100000, 1000000}; for ( i = 0; i < 3; i++ ) - if ( !strncmp(p->pSpec, pKnownFileNames[i], 5) && Gia_ManAndNum(p) > pLimitFileSizes[i] ) + if ( p->pSpec && !strncmp(p->pSpec, pKnownFileNames[i], 5) && Gia_ManAndNum(p) > pLimitFileSizes[i] ) printf( "Warning: The input file \"%s\" contains more than %d internal and-nodes.\n", pKnownFileNames[i], pLimitFileSizes[i] ); if ( nInputs == Gia_ManCiNum(p) ) { -- cgit v1.2.3 From 75981f7feebc4065980f99551654ac101edb4afa Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 9 Apr 2021 13:46:52 -0700 Subject: Computing sum of PO support sizes. --- src/aig/gia/giaUtil.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 2762dbac..3dcefcec 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2495,6 +2495,65 @@ void Gia_ComputeTest() fclose( pFile ); } + +/**Function************************************************************* + + Synopsis [Computes sum total of support size of primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSumTotalOfSupportSizes( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) ); + int i, nResult = 0; + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + Vec_IntPush( Vec_WecEntry(vSupps, 1+i), i ); + Gia_ManForEachAnd( p, pObj, i ) + Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, i)), Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, i)), Vec_WecEntry(vSupps, i) ); + Gia_ManForEachCo( p, pObj, i ) + nResult += Vec_IntSize( Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) ); + Vec_WecFree( vSupps ); + return nResult; +} + +/**Function************************************************************* + + Synopsis [Computes sum total of support size of primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSumTotalOfSupportSizes2( Gia_Man_t * p ) +{ + Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(p) ); + int r, nResult = 0, nRounds = (Gia_ManCiNum(p) + 63)/64; + for ( r = 0; r < nRounds; r++ ) + { + Gia_Obj_t * pObj; + int i, Limit = r == nRounds-1 ? Gia_ManCiNum(p) % 64 : 64; + for ( i = 0; i < Limit; i++ ) + Vec_WrdWriteEntry( vSims, 1+64*r+i, (word)1 << i ); + Gia_ManForEachAnd( p, pObj, i ) + Vec_WrdWriteEntry( vSims, i, Vec_WrdEntry(vSims, Gia_ObjFaninId0(pObj, i)) | Vec_WrdEntry(vSims, Gia_ObjFaninId1(pObj, i)) ); + Gia_ManForEachCo( p, pObj, i ) + nResult += Abc_TtCountOnes( Vec_WrdEntry(vSims, Gia_ObjFaninId0p(p, pObj)) ); + for ( i = 0; i < Limit; i++ ) + Vec_WrdWriteEntry( vSims, 1+64*r+i, 0 ); + } + Vec_WrdFree( vSims ); + return nResult; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 7d90895dcf97c726deab121bb042e68abda301e9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 1 May 2021 22:44:29 -0700 Subject: Experiments with LUT mapping for small functions. --- src/aig/gia/giaMinLut.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 1 + 2 files changed, 153 insertions(+) create mode 100644 src/aig/gia/giaMinLut.c (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c new file mode 100644 index 00000000..660b3c8f --- /dev/null +++ b/src/aig/gia/giaMinLut.c @@ -0,0 +1,152 @@ +/**CFile**************************************************************** + + FileName [giaMinLut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Collapsing AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaMinLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaAig.h" +#include "base/main/mainInt.h" +#include "opt/sfm/sfm.h" + +#ifdef ABC_USE_CUDD +#include "bdd/extrab/extraBdd.h" +#include "bdd/dsd/dsd.h" +#endif + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#ifdef ABC_USE_CUDD + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDoMuxMapping( Gia_Man_t * p ) +{ + extern Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars ); + Gia_Man_t * pTemp, * pNew = Gia_ManDup( p ); + Jf_Par_t Pars, * pPars = &Pars; int c, nIters = 2; + Sfm_Par_t Pars2, * pPars2 = &Pars2; + Lf_ManSetDefaultPars( pPars ); + Sfm_ParSetDefault( pPars2 ); + pPars2->nTfoLevMax = 5; + pPars2->nDepthMax = 100; + pPars2->nWinSizeMax = 2000; + for ( c = 0; c < nIters; c++ ) + { + pNew = Lf_ManPerformMapping( pTemp = pNew, pPars ); + Gia_ManStop( pTemp ); + pNew = Gia_ManPerformMfs( pTemp = pNew, pPars2 ); + Gia_ManStop( pTemp ); + if ( c == nIters-1 ) + break; + pNew = (Gia_Man_t *)Dsm_ManDeriveGia( pTemp = pNew, 0 ); + Gia_ManStop( pTemp ); + } + return pNew; +} +Gia_Man_t * Gia_ManDoMuxTransform( Gia_Man_t * p, int fReorder ) +{ + extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk ); + extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); + extern int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder ); + Gia_Man_t * pRes = NULL; + Aig_Man_t * pMan = Gia_ManToAig( p, 0 ); + Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan ); + Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + pNtk->pName = Extra_UtilStrsav( pMan->pName ); + Aig_ManStop( pMan ); + if ( Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, 1000000, fReorder ) ) + { + Abc_Ntk_t * pStrash = Abc_NtkStrash( pNtkNew, 1, 1, 0 ); + pRes = Abc_NtkStrashToGia( pStrash ); + Abc_NtkDelete( pStrash ); + } + Abc_NtkDelete( pNtkNew ); + Abc_NtkDelete( pNtk ); + return pRes; +} +int Gia_ManDoTest1( Gia_Man_t * p, int fReorder ) +{ + Gia_Man_t * pTemp, * pNew; int Res; + pNew = Gia_ManDoMuxTransform( p, fReorder ); + pNew = Gia_ManDoMuxMapping( pTemp = pNew ); + Gia_ManStop( pTemp ); + Res = Gia_ManLutNum( pNew ); + Gia_ManStop( pNew ); + return Res; +} +Gia_Man_t * Gia_ManPerformMinLut( Gia_Man_t * p, int GroupSize, int LutSize, int fVerbose ) +{ + Gia_Man_t * pNew = NULL; + int Res1, Res2, Result = 0; + int g, nGroups = Gia_ManCoNum(p) / GroupSize; + assert( Gia_ManCoNum(p) % GroupSize == 0 ); + assert( GroupSize <= 64 ); + for ( g = 0; g < nGroups; g++ ) + { + Gia_Man_t * pNew;//, * pTemp; + int fTrimPis = 0; + int o, pPos[64]; + for ( o = 0; o < GroupSize; o++ ) + pPos[o] = g*GroupSize+o; + pNew = Gia_ManDupCones( p, pPos, GroupSize, fTrimPis ); + printf( "%3d / %3d : ", g, nGroups ); + printf( "Test1 = %4d ", Res1 = Gia_ManDoTest1(pNew, 0) ); + printf( "Test2 = %4d ", Res2 = Gia_ManDoTest1(pNew, 1) ); + printf( "Test = %4d ", Abc_MinInt(Res1, Res2) ); + printf( "\n" ); + Result += Abc_MinInt(Res1, Res2); + //Gia_ManPrintStats( pNew, NULL ); + Gia_ManStop( pNew ); + } + printf( "Total LUT count = %d.\n", Result ); + return pNew; +} + +#else + +Gia_Man_t * Gia_ManPerformMinLut( Gia_Man_t * p, int GroupSize, int LutSize, int fVerbose ) +{ + return NULL; +} + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index e092765f..a84a25e5 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -51,6 +51,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaMem.c \ src/aig/gia/giaMfs.c \ src/aig/gia/giaMini.c \ + src/aig/gia/giaMinLut.c \ src/aig/gia/giaMuxes.c \ src/aig/gia/giaNf.c \ src/aig/gia/giaOf.c \ -- cgit v1.2.3 From 174f27d9813dede18e5c06fe8c98d6819ce49835 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 8 May 2021 13:28:27 -0700 Subject: Bug fix in &blut. --- src/aig/gia/giaStr.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaStr.c b/src/aig/gia/giaStr.c index 085738c3..2233d0fc 100644 --- a/src/aig/gia/giaStr.c +++ b/src/aig/gia/giaStr.c @@ -859,21 +859,23 @@ static inline void transpose64( word A[64] ) static inline int Str_ManNum( Gia_Man_t * p, int iObj ) { return Vec_IntEntry(&p->vCopies, iObj); } static inline void Str_ManSetNum( Gia_Man_t * p, int iObj, int Num ) { Vec_IntWriteEntry(&p->vCopies, iObj, Num); } -int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word Matrix[256], int nLimit ) +int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word * Matrix, int nLimit ) { int fVerbose = 0; - int Levels[256]; + int * Levels = NULL; int nSize = Vec_IntSize(vSuper); int Prev = nSize, nLevels = 1; int i, k, iLit, iFanin, nSizeNew; word Mask; assert( nSize > 2 ); + assert( nSize <= nLimit ); if ( nSize > 64 ) { for ( i = 0; i < 64; i++ ) Matrix[i] = 0; return 0; } + Levels = ABC_ALLOC( int, nLimit+256 ); // mark current nodes Gia_ManIncrementTravId( p ); Vec_IntForEachEntry( vSuper, iLit, i ) @@ -948,6 +950,7 @@ int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay if ( nSizeNew == 0 ) { Vec_IntShrink( vSuper, nSize ); + ABC_FREE( Levels ); return 0; } /* @@ -979,6 +982,7 @@ int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay } i = 0; } + ABC_FREE( Levels ); Vec_IntShrink( vSuper, nSize ); return nSizeNew; } @@ -1088,15 +1092,14 @@ int Str_NtkBalanceTwo( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, int i, void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec_Int_t * vDelay, int nLutSize ) { - word pMatrix[256]; - int Limit = 256; + word * pMatrix = ABC_ALLOC( word, pObj->nFanins+256 ); Vec_Int_t * vSuper = pNew->vSuper; Vec_Int_t * vCosts = pNew->vStore; int * pSuper = Vec_IntArray(vSuper); int * pCost = Vec_IntArray(vCosts); int k, iLit, MatrixSize = 0; - assert( Limit <= Vec_IntCap(vSuper) ); - assert( Limit <= Vec_IntCap(vCosts) ); + assert( (int)pObj->nFanins <= Vec_IntCap(vSuper) ); + assert( (int)pObj->nFanins <= Vec_IntCap(vCosts) ); // collect nodes Vec_IntClear( vSuper ); @@ -1111,11 +1114,13 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec if ( Vec_IntSize(vSuper) == 1 ) { pObj->iCopy = Vec_IntEntry(vSuper, 0); + ABC_FREE( pMatrix ); return; } if ( Vec_IntSize(vSuper) == 2 ) { pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 ); + ABC_FREE( pMatrix ); return; } @@ -1127,7 +1132,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec // compute affinity if ( Vec_IntSize(vSuper) < 64 ) - MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, Limit ); + MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins ); // start the new product while ( Vec_IntSize(vSuper) > 2 ) @@ -1147,7 +1152,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec // compute affinity if ( Vec_IntSize(vSuper) == 64 ) - MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, Limit ); + MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins ); assert( Vec_IntSize(vSuper) <= 64 ); // Str_PrintState( pCost, pSuper, pMatrix, Vec_IntSize(vSuper) ); @@ -1236,6 +1241,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec continue; } pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 ); + ABC_FREE( pMatrix ); /* // simple -- cgit v1.2.3 From 13a0bb97b5d1f2d67088317655737e726a07cf04 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 8 May 2021 14:00:32 -0700 Subject: Updating cost function in &save/&load. --- src/aig/gia/giaIf.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 614f7b47..50101bdf 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -39,6 +39,8 @@ ABC_NAMESPACE_IMPL_START extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); extern int Abc_RecToGia3( Gia_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, Vec_Int_t * vLeaves, int fHash ); +extern void Gia_ManPrintGetMuxFanins( Gia_Man_t * p, Gia_Obj_t * pObj, int * pFanins ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -219,20 +221,37 @@ void Gia_ManLutParams( Gia_Man_t * p, int * pnCurLuts, int * pnCurEdges, int * p int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); *pnCurLuts = 0; *pnCurEdges = 0; + *pnCurLevels = 0; Gia_ManForEachLut( p, i ) { - int Level = 0; + if ( Gia_ObjLutIsMux(p, i) ) + { + int pFanins[3]; + if ( Gia_ObjLutSize(p, i) == 3 ) + { + Gia_ManPrintGetMuxFanins( p, Gia_ManObj(p, i), pFanins ); + pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[0]]+1 ); + pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[1]] ); + pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[pFanins[2]] ); + } + else if ( Gia_ObjLutSize(p, i) == 2 ) + { + pObj = Gia_ManObj( p, i ); + pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Gia_ObjFaninId0(pObj, i)] ); + pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Gia_ObjFaninId1(pObj, i)] ); + } + *pnCurLevels = Abc_MaxInt( *pnCurLevels, pLevels[i] ); + *pnCurEdges++; + //nMuxF++; + continue; + } (*pnCurLuts)++; (*pnCurEdges) += Gia_ObjLutSize(p, i); Gia_LutForEachFanin( p, i, iFan, k ) - if ( Level < pLevels[iFan] ) - Level = pLevels[iFan]; - pLevels[i] = Level + 1; + pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[iFan] ); + pLevels[i]++; + *pnCurLevels = Abc_MaxInt( *pnCurLevels, pLevels[i] ); } - *pnCurLevels = 0; - Gia_ManForEachCo( p, pObj, k ) - if ( *pnCurLevels < pLevels[Gia_ObjFaninId0p(p, pObj)] ) - *pnCurLevels = pLevels[Gia_ObjFaninId0p(p, pObj)]; ABC_FREE( pLevels ); } } -- cgit v1.2.3 From 45acbef88233a5863d03a03203b9c5ffaa07d301 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 8 May 2021 14:02:51 -0700 Subject: Updating cost function in &save/&load. --- src/aig/gia/giaIf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 50101bdf..7056e310 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -241,7 +241,7 @@ void Gia_ManLutParams( Gia_Man_t * p, int * pnCurLuts, int * pnCurEdges, int * p pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[Gia_ObjFaninId1(pObj, i)] ); } *pnCurLevels = Abc_MaxInt( *pnCurLevels, pLevels[i] ); - *pnCurEdges++; + (*pnCurEdges)++; //nMuxF++; continue; } -- cgit v1.2.3 From 76bed2055cc171109a86bf56c6da00aa4d251a30 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 8 May 2021 20:10:44 -0700 Subject: Updating LUT synthesis code. --- src/aig/gia/giaGen.c | 30 +++++++++++ src/aig/gia/giaMinLut.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c index 3c0d2235..3c813d5c 100644 --- a/src/aig/gia/giaGen.c +++ b/src/aig/gia/giaGen.c @@ -195,6 +195,36 @@ int Gia_ManSimulateWordsInit( Gia_Man_t * p, Vec_Wrd_t * vSimsIn ) return 1; } +Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn ) +{ + Gia_Obj_t * pObj; int i, Id; + int nWords = Vec_WrdSize(vSimsIn) / Gia_ManCiNum(p); + Vec_Wrd_t * vSimsOut = Vec_WrdStart( nWords * Gia_ManCoNum(p) ); + assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) ); + // allocate simulation info for one timeframe + Vec_WrdFreeP( &p->vSims ); + p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); + p->nSimWords = nWords; + // set input sim info + Gia_ManForEachCiId( p, Id, i ) + memcpy( Vec_WrdEntryP(p->vSims, Id*nWords), Vec_WrdEntryP(vSimsIn, i*nWords), sizeof(word)*nWords ); + // perform simulation + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + Gia_ManObjSimAnd( p, i ); + else if ( Gia_ObjIsCi(pObj) ) + continue; + else if ( Gia_ObjIsCo(pObj) ) + Gia_ManObjSimPo( p, i ); + else assert( 0 ); + } + // set output sim info + Gia_ManForEachCoId( p, Id, i ) + memcpy( Vec_WrdEntryP(vSimsOut, i*nWords), Vec_WrdEntryP(p->vSims, Id*nWords), sizeof(word)*nWords ); + return vSimsOut; +} + /**Function************************************************************* Synopsis [Dump data files.] diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 660b3c8f..7d0ac8e1 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -40,6 +40,136 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO, int nIns, int nOuts ) +{ + int i, nSize, iLine, nLines, nWords; + char pLine[1000]; + Vec_Wrd_t * vSimI, * vSimO; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return; + } + fseek( pFile, 0, SEEK_END ); + nSize = ftell( pFile ); + if ( nSize % (nIns + nOuts + 1) > 0 ) + { + printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % (nIns + nOuts + 1) ); + fclose( pFile ); + return; + } + rewind( pFile ); + nLines = nSize / (nIns + nOuts + 1); + nWords = (nLines + 63)/64; + vSimI = Vec_WrdStart( nIns *nWords ); + vSimO = Vec_WrdStart( nOuts*nWords ); + for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ ) + { + for ( i = 0; i < nIns; i++ ) + if ( pLine[i] == '1' ) + Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine ); + else assert( pLine[i] == '0' ); + for ( i = 0; i < nOuts; i++ ) + if ( pLine[nIns+i] == '1' ) + Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine ); + else assert( pLine[nIns+i] == '0' ); + } + fclose( pFile ); + *pvSimI = vSimI; + *pvSimO = vSimO; + printf( "Read %d words of simulation data for %d inputs and %d outputs.\n", nWords, nIns, nOuts ); +} +void Gia_ManSimInfoTransform( int fSmall ) +{ + int nIns = fSmall ? 32 : 64; + int nOuts = fSmall ? 10 : 35; + char * pFileName = fSmall ? "io_s.txt" : "io_l.txt"; + Vec_Wrd_t * vSimI, * vSimO; + Vec_WrdReadText( pFileName, &vSimI, &vSimO, nIns, nOuts ); + Vec_WrdDumpBin( Extra_FileNameGenericAppend(pFileName, ".simi"), vSimI, 1 ); + Vec_WrdDumpBin( Extra_FileNameGenericAppend(pFileName, ".simo"), vSimO, 1 ); + Vec_WrdFree( vSimI ); + Vec_WrdFree( vSimO ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Wrd_t * vSimO ) +{ + extern Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn ); + Vec_Wrd_t * vSimsOut = Gia_ManSimulateWordsOut( p, vSimI ); + word * pSim0 = Vec_WrdArray(p->vSims); + int i, Count, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p); + Gia_Obj_t * pObj; + assert( Vec_WrdSize(vSimI) / Gia_ManCiNum(p) == nWords ); + assert( Vec_WrdSize(vSimI) % Gia_ManCiNum(p) == 0 ); + assert( Vec_WrdSize(vSimO) % Gia_ManCoNum(p) == 0 ); + Abc_TtClear( pSim0, nWords ); + Gia_ManForEachCo( p, pObj, i ) + { + word * pSimImpl = Vec_WrdEntryP( vSimsOut, i * nWords ); + word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords ); + Abc_TtOrXor( pSim0, pSimImpl, pSimGold, nWords ); + } + Count = Abc_TtCountOnesVec( pSim0, nWords ); + printf( "Number of failed patterns is %d (out of %d). The first one is %d\n", + Count, 64*nWords, Abc_TtFindFirstBit2(pSim0, nWords) ); + Vec_WrdFreeP( &p->vSims ); + Vec_WrdFreeP( &vSimsOut ); + p->nSimWords = -1; + return Count; +} +void Gia_ManSimInfoTryTest( Gia_Man_t * p, int fSmall ) +{ + abctime clk = Abc_Clock(); + int nIns = fSmall ? 32 : 64; + int nOuts = fSmall ? 10 : 35; + char * pFileNameI = fSmall ? "s.simi" : "l.simi"; + char * pFileNameO = fSmall ? "s.simo" : "l.simo"; + Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileNameI, 1 ); + Vec_Wrd_t * vSimO = Vec_WrdReadBin( pFileNameO, 1 ); + Gia_ManSimInfoTry( p, vSimI, vSimO ); + Vec_WrdFree( vSimI ); + Vec_WrdFree( vSimO ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimInfoPassTest( Gia_Man_t * p, int fSmall ) +{ +} + /**Function************************************************************* Synopsis [] -- cgit v1.2.3 From aa9fe1f24094d0423cc32cbd6e9682ea2a3935cb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 11 May 2021 15:04:15 -0700 Subject: Updating LUT synthesis code. --- src/aig/gia/giaGen.c | 2 + src/aig/gia/giaMinLut.c | 218 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 195 insertions(+), 25 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c index 3c813d5c..cb56ef64 100644 --- a/src/aig/gia/giaGen.c +++ b/src/aig/gia/giaGen.c @@ -222,6 +222,8 @@ Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn ) // set output sim info Gia_ManForEachCoId( p, Id, i ) memcpy( Vec_WrdEntryP(vSimsOut, i*nWords), Vec_WrdEntryP(p->vSims, Id*nWords), sizeof(word)*nWords ); + Vec_WrdFreeP( &p->vSims ); + p->nSimWords = -1; return vSimsOut; } diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 7d0ac8e1..a33f9710 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -78,18 +78,18 @@ void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ ) { for ( i = 0; i < nIns; i++ ) - if ( pLine[i] == '1' ) + if ( pLine[nIns-1-i] == '1' ) Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine ); - else assert( pLine[i] == '0' ); + else assert( pLine[nIns-1-i] == '0' ); for ( i = 0; i < nOuts; i++ ) - if ( pLine[nIns+i] == '1' ) + if ( pLine[nIns+nOuts-1-i] == '1' ) Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine ); - else assert( pLine[nIns+i] == '0' ); + else assert( pLine[nIns+nOuts-1-i] == '0' ); } fclose( pFile ); *pvSimI = vSimI; *pvSimO = vSimO; - printf( "Read %d words of simulation data for %d inputs and %d outputs.\n", nWords, nIns, nOuts ); + printf( "Read %d words of simulation data for %d inputs and %d outputs (padded %d zero-patterns).\n", nWords, nIns, nOuts, nWords*64-nLines ); } void Gia_ManSimInfoTransform( int fSmall ) { @@ -115,43 +115,143 @@ void Gia_ManSimInfoTransform( int fSmall ) SeeAlso [] ***********************************************************************/ -int Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Wrd_t * vSimO ) +Vec_Wrd_t * Vec_WrdZoneExtract( int ZoneSize, Vec_Wrd_t * p, int iWord, int nWords ) +{ + int z, nZones = Vec_WrdSize(p)/ZoneSize; + int w, Limit = Abc_MinInt( nWords, ZoneSize-iWord ); + Vec_Wrd_t * pNew = Vec_WrdStart( nZones*nWords ); + for ( z = 0; z < nZones; z++ ) + for ( w = 0; w < Limit; w++ ) + Vec_WrdWriteEntry( pNew, z*nWords + w, Vec_WrdEntry(p, z*ZoneSize + iWord + w) ); + return pNew; +} +void Vec_WrdZoneInsert( Vec_Wrd_t * pNew, int ZoneSize, Vec_Wrd_t * p, int iWord, int nWords ) +{ + int z, nZones = Vec_WrdSize(pNew)/ZoneSize; + int w, Limit = Abc_MinInt( nWords, ZoneSize-iWord ); + for ( z = 0; z < nZones; z++ ) + for ( w = 0; w < Limit; w++ ) + Vec_WrdWriteEntry( pNew, z*ZoneSize + iWord + w, Vec_WrdEntry(p, z*nWords + w) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimInfoPrintOne( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSimsOut, int nWords, int nPats ) +{ + int Id, i, k; + for ( k = 0; k < nPats; k++ ) + { + Gia_ManForEachCiId( p, Id, i ) + // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 ); + printf( "%d", (Vec_WrdEntry(vSimsIn, nWords*i) >> k) & 1 ); + printf( " " ); + Gia_ManForEachCoId( p, Id, i ) + // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 ); + printf( "%d", (Vec_WrdEntry(vSimsOut, nWords*i) >> k) & 1 ); + printf( "\n" ); + } +} +Vec_Wrd_t * Gia_ManSimInfoTryOne( Gia_Man_t * p, Vec_Wrd_t * vSimI, int fPrint ) { extern Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn ); Vec_Wrd_t * vSimsOut = Gia_ManSimulateWordsOut( p, vSimI ); - word * pSim0 = Vec_WrdArray(p->vSims); - int i, Count, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p); - Gia_Obj_t * pObj; - assert( Vec_WrdSize(vSimI) / Gia_ManCiNum(p) == nWords ); + int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p); assert( Vec_WrdSize(vSimI) % Gia_ManCiNum(p) == 0 ); - assert( Vec_WrdSize(vSimO) % Gia_ManCoNum(p) == 0 ); - Abc_TtClear( pSim0, nWords ); - Gia_ManForEachCo( p, pObj, i ) + if ( fPrint ) + Gia_ManSimInfoPrintOne( p, vSimI, vSimsOut, nWords, 6 ); + return vSimsOut; +} +int Gia_ManSimEvalOne( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new ) +{ + int i, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p); + word * pSim0 = ABC_CALLOC( word, nWords ); + assert( Vec_WrdSize(vSimO) == Vec_WrdSize(vSimO_new) ); + for ( i = 0; i < Gia_ManCoNum(p); i++ ) { - word * pSimImpl = Vec_WrdEntryP( vSimsOut, i * nWords ); - word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords ); + word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords ); + word * pSimImpl = Vec_WrdEntryP( vSimO_new, i * nWords ); Abc_TtOrXor( pSim0, pSimImpl, pSimGold, nWords ); } Count = Abc_TtCountOnesVec( pSim0, nWords ); - printf( "Number of failed patterns is %d (out of %d). The first one is %d\n", + printf( "Number of failed patterns is %d (out of %d). The first one is %d.\n", Count, 64*nWords, Abc_TtFindFirstBit2(pSim0, nWords) ); - Vec_WrdFreeP( &p->vSims ); - Vec_WrdFreeP( &vSimsOut ); - p->nSimWords = -1; + ABC_FREE( pSim0 ); return Count; } +Vec_Wrd_t * Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI ) +{ + int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p); + int w, nWordsOne = 200, nWordBatches = (nWords + nWordsOne - 1)/nWordsOne; + Vec_Wrd_t * vSimO_new = Vec_WrdStart( nWords * Gia_ManCoNum(p) ); + for ( w = 0; w < nWordBatches; w++ ) + { + //int Value = printf( "%3d / %3d : ", w, nWordBatches ); + Vec_Wrd_t * vSimI_ = Vec_WrdZoneExtract( nWords, vSimI, w*nWordsOne, nWordsOne ); + Vec_Wrd_t * vSimO_ = Gia_ManSimInfoTryOne( p, vSimI_, 0 ); + Vec_WrdZoneInsert( vSimO_new, nWords, vSimO_, w*nWordsOne, nWordsOne ); + Vec_WrdFree( vSimI_ ); + Vec_WrdFree( vSimO_ ); + //Value = 0; + } + return vSimO_new; +} +int Gia_ManSimInfoEval( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new ) +{ + int nResult = Gia_ManSimEvalOne(p, vSimO, vSimO_new); + Vec_WrdDumpBin( "temp.simo", vSimO_new, 1 ); + printf( "Total errors = %d. ", nResult ); + printf( "Density of output patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO_new), Vec_WrdSize(vSimO_new))/(64*Vec_WrdSize(vSimO_new)) ); + return nResult; +} void Gia_ManSimInfoTryTest( Gia_Man_t * p, int fSmall ) { abctime clk = Abc_Clock(); - int nIns = fSmall ? 32 : 64; - int nOuts = fSmall ? 10 : 35; - char * pFileNameI = fSmall ? "s.simi" : "l.simi"; - char * pFileNameO = fSmall ? "s.simo" : "l.simo"; + char * pFileNameI = fSmall ? "io_s.simi" : "io_l.simi"; + char * pFileNameO = fSmall ? "io_s.simo" : "io_l.simo"; Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileNameI, 1 ); Vec_Wrd_t * vSimO = Vec_WrdReadBin( pFileNameO, 1 ); - Gia_ManSimInfoTry( p, vSimI, vSimO ); + Vec_Wrd_t * vSimO_new; + printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); + printf( "Density of output patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) ); + vSimO_new = Gia_ManSimInfoTry( p, vSimI ); + Gia_ManSimInfoEval( p, vSimO, vSimO_new ); Vec_WrdFree( vSimI ); Vec_WrdFree( vSimO ); + Vec_WrdFree( vSimO_new ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} +void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, int fCompare ) +{ + abctime clk = Abc_Clock(); + if ( fCompare ) + { + Vec_Wrd_t * vSim1 = Vec_WrdReadBin( pFileName, 1 ); + Vec_Wrd_t * vSim2 = Vec_WrdReadBin( pFileName2, 1 ); + printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim1), Vec_WrdSize(vSim1))/(64*Vec_WrdSize(vSim1)) ); + printf( "Density of output patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim2), Vec_WrdSize(vSim2))/(64*Vec_WrdSize(vSim2)) ); + Gia_ManSimInfoEval( p, vSim1, vSim2 ); + Vec_WrdFree( vSim1 ); + Vec_WrdFree( vSim2 ); + } + else + { + Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, 1 ); + Vec_Wrd_t * vSimO = Gia_ManSimInfoTry( p, vSimI ); + printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); + printf( "Density of output patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) ); + Vec_WrdDumpBin( pFileName2, vSimO, 1 ); + Vec_WrdFree( vSimI ); + Vec_WrdFree( vSimO ); + } Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } @@ -166,8 +266,76 @@ void Gia_ManSimInfoTryTest( Gia_Man_t * p, int fSmall ) SeeAlso [] ***********************************************************************/ -void Gia_ManSimInfoPassTest( Gia_Man_t * p, int fSmall ) +int Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh ) +{ + int i, k, Id, nUsed = 0, nGood = 0; + int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p); + int nMints = 1 << Vec_IntSize(vSupp); + word ** pSims = ABC_ALLOC( word *, Vec_IntSize(vSupp) ); + int * pCounts = ABC_CALLOC( int, nMints ); + Vec_IntForEachEntry( vSupp, Id, i ) + pSims[i] = Vec_WrdEntryP( vSimI, Id * nWords ); + for ( k = 0; k < 64*nWords; k++ ) + { + int iMint = 0; + for ( i = 0; i < Vec_IntSize(vSupp); i++ ) + if ( Abc_TtGetBit(pSims[i], k) ) + iMint |= 1 << i; + assert( iMint < nMints ); + pCounts[iMint]++; + } + for ( k = 0; k < nMints; k++ ) + { + nUsed += (pCounts[k] > 0); + nGood += (pCounts[k] > Thresh); + //printf( "%d ", pCounts[k] ); + } + //printf( "\n" ); + printf( "Total used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints ); + ABC_FREE( pSims ); + ABC_FREE( pCounts ); + return nUsed; +} +void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp ) +{ + Gia_Obj_t * pObj; + if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vSupp, Gia_ObjCioId(pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vSupp ); + Gia_ManCollectSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vSupp ); +} +Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts ) +{ + Vec_Int_t * vSupp = Vec_IntAlloc( 16 ); int i; + Gia_ManIncrementTravId( p ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp ); + return vSupp; +} +void Gia_ManSimInfoSynthOne( Gia_Man_t * p, Vec_Wrd_t * vSimI, int iOut, int nOuts, int Thresh ) { + Vec_Int_t * vSupp = Gia_ManCollectSupp( p, iOut, nOuts ); + printf( "Group %3d / %3d / %3d : Supp = %3d ", iOut, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp) ); + Gia_ManCountFraction( p, vSimI, vSupp, Thresh ); + Vec_IntFree( vSupp ); +} +void Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int GroupSize, int Thresh ) +{ + Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, 1 ); + int g, nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); + printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); + printf( "The number of patterns %d with threshold %d (%6.2f %%).\n", nPats, Thresh, 100.0*Thresh/nPats ); + for ( g = 0; g < Gia_ManCoNum(p); g += GroupSize ) + Gia_ManSimInfoSynthOne( p, vSimI, g, GroupSize, Thresh ); + Vec_WrdFree( vSimI ); } /**Function************************************************************* -- cgit v1.2.3 From e6a47c3e41486f238be6d798fbf68a83cd11810a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 11 May 2021 15:54:43 -0700 Subject: Disable cube-sort when deriving SOPs. --- src/aig/gia/giaMinLut.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index a33f9710..1972c175 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -152,11 +152,11 @@ void Gia_ManSimInfoPrintOne( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSi { Gia_ManForEachCiId( p, Id, i ) // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 ); - printf( "%d", (Vec_WrdEntry(vSimsIn, nWords*i) >> k) & 1 ); + printf( "%d", (int)(Vec_WrdEntry(vSimsIn, nWords*i) >> k) & 1 ); printf( " " ); Gia_ManForEachCoId( p, Id, i ) // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 ); - printf( "%d", (Vec_WrdEntry(vSimsOut, nWords*i) >> k) & 1 ); + printf( "%d", (int)(Vec_WrdEntry(vSimsOut, nWords*i) >> k) & 1 ); printf( "\n" ); } } -- cgit v1.2.3 From ed13c6d4d26460b0ffa2c72b1d2decc11f8ebf0d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 11 May 2021 17:45:20 -0700 Subject: Updating LUT synthesis code. --- src/aig/gia/giaMinLut.c | 101 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 24 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 1972c175..79bd32fd 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -34,8 +34,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#ifdef ABC_USE_CUDD - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -266,15 +264,17 @@ void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, SeeAlso [] ***********************************************************************/ -int Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh ) +word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh, int fVerbose ) { - int i, k, Id, nUsed = 0, nGood = 0; + Gia_Obj_t * pObj; + int i, k, nUsed = 0, nGood = 0; int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p); int nMints = 1 << Vec_IntSize(vSupp); word ** pSims = ABC_ALLOC( word *, Vec_IntSize(vSupp) ); + word * pRes = ABC_CALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) ); int * pCounts = ABC_CALLOC( int, nMints ); - Vec_IntForEachEntry( vSupp, Id, i ) - pSims[i] = Vec_WrdEntryP( vSimI, Id * nWords ); + Gia_ManForEachObjVec( vSupp, p, pObj, i ) + pSims[i] = Vec_WrdEntryP( vSimI, Gia_ObjCioId(pObj) * nWords ); for ( k = 0; k < 64*nWords; k++ ) { int iMint = 0; @@ -288,13 +288,16 @@ int Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, i { nUsed += (pCounts[k] > 0); nGood += (pCounts[k] > Thresh); + if ( pCounts[k] > Thresh ) + Abc_TtXorBit( pRes, k ); //printf( "%d ", pCounts[k] ); } //printf( "\n" ); - printf( "Total used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints ); + if ( fVerbose ) + printf( "Used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints ); ABC_FREE( pSims ); ABC_FREE( pCounts ); - return nUsed; + return pRes; } void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp ) { @@ -305,7 +308,8 @@ void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp ) pObj = Gia_ManObj( p, iObj ); if ( Gia_ObjIsCi(pObj) ) { - Vec_IntPush( vSupp, Gia_ObjCioId(pObj) ); + //Vec_IntPush( vSupp, Gia_ObjCioId(pObj) ); + Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); return; } assert( Gia_ObjIsAnd(pObj) ); @@ -320,24 +324,73 @@ Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts ) Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp ); return vSupp; } -void Gia_ManSimInfoSynthOne( Gia_Man_t * p, Vec_Wrd_t * vSimI, int iOut, int nOuts, int Thresh ) +Gia_Man_t * Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int LutSize, int Thresh, int fVerbose ) { - Vec_Int_t * vSupp = Gia_ManCollectSupp( p, iOut, nOuts ); - printf( "Group %3d / %3d / %3d : Supp = %3d ", iOut, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp) ); - Gia_ManCountFraction( p, vSimI, vSupp, Thresh ); - Vec_IntFree( vSupp ); -} -void Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int GroupSize, int Thresh ) -{ - Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, 1 ); - int g, nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); - printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); - printf( "The number of patterns %d with threshold %d (%6.2f %%).\n", nPats, Thresh, 100.0*Thresh/nPats ); - for ( g = 0; g < Gia_ManCoNum(p); g += GroupSize ) - Gia_ManSimInfoSynthOne( p, vSimI, g, GroupSize, Thresh ); - Vec_WrdFree( vSimI ); + extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + Gia_Man_t * pNew; Gia_Obj_t * pObj; + Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 18 ); + Vec_Int_t * vLeaves = Vec_IntAlloc( nIns ); + Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, 1 ) : NULL; + word * pTruth0 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); + word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; + if ( vSimI ) + { + int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); + printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); + printf( "The number of patterns %d with threshold %d (%6.2f %%).\n", nPats, Thresh, 100.0*Thresh/nPats ); + } + Gia_ManFillValue( p ); + 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, k ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ObjComputeTruthTableStart( p, nIns ); + Gia_ManHashStart( pNew ); + for ( g = 0; g < Gia_ManCoNum(p); g += nOuts ) + { + Vec_Int_t * vSupp = Gia_ManCollectSupp( p, g, nOuts ); + int Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0; + word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) ); + int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) ); + assert( Vec_IntSize(vSupp) <= nIns ); + Vec_IntClear( vLeaves ); + Gia_ManForEachObjVec( vSupp, p, pObj, k ) + Vec_IntPush( vLeaves, pObj->Value ); + for ( k = 0; k < nOuts; k++ ) + { + Gia_Obj_t * pObj = Gia_ManCo( p, g+k ); + if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) ) + { + word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp ); + Abc_TtSharp( pTruth0, pCare, pTruth, nWords ); + Abc_TtAnd( pTruth1, pCare, pTruth, nWords, 0 ); + pObj->Value = Kit_TruthToGia2( pNew, (unsigned *)pTruth0, (unsigned *)pTruth1, Vec_IntSize(vLeaves), vMemory, vLeaves, 1 ); + } + else + pObj->Value = Gia_ObjFanin0(pObj)->Value; + pObj->Value ^= Gia_ObjFaninC0(pObj); + } + ABC_FREE( pCare ); + Vec_IntFree( vSupp ); + Temp = 0; + } + Gia_ManHashStop( pNew ); + Gia_ManForEachCo( p, pObj, k ) + pObj->Value = Gia_ManAppendCo( pNew, pObj->Value ); + Gia_ObjComputeTruthTableStop( p ); + ABC_FREE( pTruth0 ); + ABC_FREE( pTruth1 ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vMemory ); + Vec_WrdFreeP( &vSimI ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; } +#ifdef ABC_USE_CUDD + /**Function************************************************************* Synopsis [] -- cgit v1.2.3 From 0ce11851bcb364abfd5d65685ab779faed4398ec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 16 May 2021 20:33:53 -0700 Subject: Updating LUT synthesis code. --- src/aig/gia/giaDup.c | 2 + src/aig/gia/giaMinLut.c | 226 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 165 insertions(+), 63 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 9de9e735..0f200bfc 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3460,6 +3460,8 @@ Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis ) // create PIs if ( fTrimPis ) { + Gia_ManForEachPi( p, pObj, i ) + pObj->Value = ~0; Vec_PtrForEachEntry( Gia_Obj_t *, vLeaves, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); } diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 79bd32fd..9ac9e770 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -89,15 +89,12 @@ void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO *pvSimO = vSimO; printf( "Read %d words of simulation data for %d inputs and %d outputs (padded %d zero-patterns).\n", nWords, nIns, nOuts, nWords*64-nLines ); } -void Gia_ManSimInfoTransform( int fSmall ) +void Gia_ManSimInfoTransform( char * pFileName, char * pFileOut1, char * pFileOut2, int nIns, int nOuts ) { - int nIns = fSmall ? 32 : 64; - int nOuts = fSmall ? 10 : 35; - char * pFileName = fSmall ? "io_s.txt" : "io_l.txt"; Vec_Wrd_t * vSimI, * vSimO; Vec_WrdReadText( pFileName, &vSimI, &vSimO, nIns, nOuts ); - Vec_WrdDumpBin( Extra_FileNameGenericAppend(pFileName, ".simi"), vSimI, 1 ); - Vec_WrdDumpBin( Extra_FileNameGenericAppend(pFileName, ".simo"), vSimO, 1 ); + Vec_WrdDumpBin( pFileOut1 ? pFileOut1 : Extra_FileNameGenericAppend(pFileName, ".simi"), vSimI, 1 ); + Vec_WrdDumpBin( pFileOut2 ? pFileOut2 : Extra_FileNameGenericAppend(pFileName, ".simo"), vSimO, 1 ); Vec_WrdFree( vSimI ); Vec_WrdFree( vSimO ); } @@ -180,8 +177,25 @@ int Gia_ManSimEvalOne( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new ) Abc_TtOrXor( pSim0, pSimImpl, pSimGold, nWords ); } Count = Abc_TtCountOnesVec( pSim0, nWords ); - printf( "Number of failed patterns is %d (out of %d). The first one is %d.\n", - Count, 64*nWords, Abc_TtFindFirstBit2(pSim0, nWords) ); + printf( "Number of failed patterns is %d (%8.4f %% of %d). The first one is %d.\n", + Count, 100.0*Count/(64*nWords), 64*nWords, Abc_TtFindFirstBit2(pSim0, nWords) ); + ABC_FREE( pSim0 ); + return Count; +} +int Gia_ManSimEvalOne2( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new ) +{ + int i, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p); + word * pSim0 = ABC_CALLOC( word, nWords ); + assert( Vec_WrdSize(vSimO) == Vec_WrdSize(vSimO_new) ); + for ( i = 0; i < Gia_ManCoNum(p); i++ ) + { + word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords ); + word * pSimImpl = Vec_WrdEntryP( vSimO_new, i * nWords ); + Abc_TtXor( pSim0, pSimImpl, pSimGold, nWords, 0 ); + Count += Abc_TtCountOnesVec( pSim0, nWords ); + } + printf( "Number of failed patterns is %d (%8.4f %% of %d). The first one is %d.\n", + Count, 100.0*Count/(64*nWords*Gia_ManCoNum(p)), 64*nWords*Gia_ManCoNum(p), Abc_TtFindFirstBit2(pSim0, nWords) ); ABC_FREE( pSim0 ); return Count; } @@ -204,29 +218,12 @@ Vec_Wrd_t * Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI ) } int Gia_ManSimInfoEval( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new ) { - int nResult = Gia_ManSimEvalOne(p, vSimO, vSimO_new); - Vec_WrdDumpBin( "temp.simo", vSimO_new, 1 ); + int nResult = Gia_ManSimEvalOne2(p, vSimO, vSimO_new); + //Vec_WrdDumpBin( "temp.simo", vSimO_new, 1 ); printf( "Total errors = %d. ", nResult ); - printf( "Density of output patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO_new), Vec_WrdSize(vSimO_new))/(64*Vec_WrdSize(vSimO_new)) ); + printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO_new), Vec_WrdSize(vSimO_new))/(64*Vec_WrdSize(vSimO_new)) ); return nResult; } -void Gia_ManSimInfoTryTest( Gia_Man_t * p, int fSmall ) -{ - abctime clk = Abc_Clock(); - char * pFileNameI = fSmall ? "io_s.simi" : "io_l.simi"; - char * pFileNameO = fSmall ? "io_s.simo" : "io_l.simo"; - Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileNameI, 1 ); - Vec_Wrd_t * vSimO = Vec_WrdReadBin( pFileNameO, 1 ); - Vec_Wrd_t * vSimO_new; - printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); - printf( "Density of output patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) ); - vSimO_new = Gia_ManSimInfoTry( p, vSimI ); - Gia_ManSimInfoEval( p, vSimO, vSimO_new ); - Vec_WrdFree( vSimI ); - Vec_WrdFree( vSimO ); - Vec_WrdFree( vSimO_new ); - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); -} void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, int fCompare ) { abctime clk = Abc_Clock(); @@ -234,8 +231,8 @@ void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, { Vec_Wrd_t * vSim1 = Vec_WrdReadBin( pFileName, 1 ); Vec_Wrd_t * vSim2 = Vec_WrdReadBin( pFileName2, 1 ); - printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim1), Vec_WrdSize(vSim1))/(64*Vec_WrdSize(vSim1)) ); - printf( "Density of output patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim2), Vec_WrdSize(vSim2))/(64*Vec_WrdSize(vSim2)) ); + printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim1), Vec_WrdSize(vSim1))/(64*Vec_WrdSize(vSim1)) ); + printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim2), Vec_WrdSize(vSim2))/(64*Vec_WrdSize(vSim2)) ); Gia_ManSimInfoEval( p, vSim1, vSim2 ); Vec_WrdFree( vSim1 ); Vec_WrdFree( vSim2 ); @@ -244,8 +241,8 @@ void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, { Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, 1 ); Vec_Wrd_t * vSimO = Gia_ManSimInfoTry( p, vSimI ); - printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); - printf( "Density of output patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) ); + printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); + printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) ); Vec_WrdDumpBin( pFileName2, vSimO, 1 ); Vec_WrdFree( vSimI ); Vec_WrdFree( vSimO ); @@ -264,7 +261,7 @@ void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, SeeAlso [] ***********************************************************************/ -word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh, int fVerbose ) +word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh, int fVerbose, int * pCare ) { Gia_Obj_t * pObj; int i, k, nUsed = 0, nGood = 0; @@ -287,8 +284,8 @@ word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp for ( k = 0; k < nMints; k++ ) { nUsed += (pCounts[k] > 0); - nGood += (pCounts[k] > Thresh); - if ( pCounts[k] > Thresh ) + nGood += (pCounts[k] >= Thresh); + if ( pCounts[k] >= Thresh ) Abc_TtXorBit( pRes, k ); //printf( "%d ", pCounts[k] ); } @@ -297,6 +294,7 @@ word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp printf( "Used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints ); ABC_FREE( pSims ); ABC_FREE( pCounts ); + *pCare = nGood; return pRes; } void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp ) @@ -324,7 +322,7 @@ Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts ) Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp ); return vSupp; } -Gia_Man_t * Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int LutSize, int Thresh, int fVerbose ) +Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int Thresh, int fVerbose ) { extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); Gia_Man_t * pNew; Gia_Obj_t * pObj; @@ -332,12 +330,12 @@ Gia_Man_t * Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int nIns, int Vec_Int_t * vLeaves = Vec_IntAlloc( nIns ); Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, 1 ) : NULL; word * pTruth0 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); - word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; + word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; float CareAve = 0; if ( vSimI ) { int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); - printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); - printf( "The number of patterns %d with threshold %d (%6.2f %%).\n", nPats, Thresh, 100.0*Thresh/nPats ); + printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); + printf( "Using patterns with count %d and higher as cares (%8.4f %% of all patterns).\n", Thresh, 100.0*Thresh/nPats ); } Gia_ManFillValue( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); @@ -351,9 +349,10 @@ Gia_Man_t * Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int nIns, int for ( g = 0; g < Gia_ManCoNum(p); g += nOuts ) { Vec_Int_t * vSupp = Gia_ManCollectSupp( p, g, nOuts ); - int Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0; - word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) ); + int Care, Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0; + word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) ); int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) ); + CareAve += 100.0*Care/(1 << nIns); assert( Vec_IntSize(vSupp) <= nIns ); Vec_IntClear( vLeaves ); Gia_ManForEachObjVec( vSupp, p, pObj, k ) @@ -376,6 +375,8 @@ Gia_Man_t * Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int nIns, int Vec_IntFree( vSupp ); Temp = 0; } + CareAve /= Gia_ManCoNum(p)/nOuts; + printf( "Average size of the care set = %8.4f %%.\n", CareAve ); Gia_ManHashStop( pNew ); Gia_ManForEachCo( p, pObj, k ) pObj->Value = Gia_ManAppendCo( pNew, pObj->Value ); @@ -430,14 +431,15 @@ Gia_Man_t * Gia_ManDoMuxTransform( Gia_Man_t * p, int fReorder ) { extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk ); extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); - extern int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder ); + extern int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder, int fUseAdd ); Gia_Man_t * pRes = NULL; Aig_Man_t * pMan = Gia_ManToAig( p, 0 ); Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan ); Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); pNtk->pName = Extra_UtilStrsav( pMan->pName ); Aig_ManStop( pMan ); - if ( Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, 1000000, fReorder ) ) + //pNtkNew = Abc_NtkBddToMuxes( pNtk, 1, 1000000, 1 ); + if ( Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, 1000000, fReorder, 0 ) ) { Abc_Ntk_t * pStrash = Abc_NtkStrash( pNtkNew, 1, 1, 0 ); pRes = Abc_NtkStrashToGia( pStrash ); @@ -457,37 +459,135 @@ int Gia_ManDoTest1( Gia_Man_t * p, int fReorder ) Gia_ManStop( pNew ); return Res; } -Gia_Man_t * Gia_ManPerformMinLut( Gia_Man_t * p, int GroupSize, int LutSize, int fVerbose ) +Abc_Ntk_t * Gia_ManDoTest2( Gia_Man_t * p, int fReorder ) { - Gia_Man_t * pNew = NULL; + extern Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs ); + Abc_Ntk_t * pNtkNew; + Gia_Man_t * pTemp, * pNew; + pNew = Gia_ManDoMuxTransform( p, fReorder ); + pNew = Gia_ManDoMuxMapping( pTemp = pNew ); + Gia_ManStop( pTemp ); + pNtkNew = Abc_NtkFromMappedGia( pNew, 0, 0 ); + pNtkNew->pName = Extra_UtilStrsav(p->pName); + Gia_ManStop( pNew ); + Abc_NtkToSop( pNtkNew, 1, ABC_INFINITY ); + return pNtkNew; +} +Abc_Ntk_t * Abc_NtkMapTransform( Gia_Man_t * p, int nOuts, int fUseFixed, int fVerbose ) +{ + extern Abc_Ntk_t * Abc_NtkSpecialMapping( Abc_Ntk_t * pNtk, int fVerbose ); + int i, k, g, nGroups = Gia_ManCoNum(p) / nOuts, CountsAll[3] = {0}; + Abc_Obj_t * pObjNew, * pFaninNew; Gia_Obj_t * pObj; + Abc_Ntk_t * pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); + assert( Gia_ManCoNum(p) % nOuts == 0 ); + pNtkNew->pName = Extra_UtilStrsav(p->pName); + pNtkNew->pSpec = Extra_UtilStrsav(p->pSpec); + Gia_ManFillValue( p ); + Gia_ManForEachPi( p, pObj, i ) + Abc_NtkCreatePi( pNtkNew ); + Gia_ManForEachPo( p, pObj, i ) + Abc_NtkCreatePo( pNtkNew ); + assert( nOuts <= 64 ); + for ( g = 0; g < nGroups; g++ ) + { + Gia_Man_t * pNew; Aig_Man_t * pMan; + Abc_Ntk_t * pNtk, * pNtkRes, * pNtkMap; + int pPos[64], Counter = 0, Counts[3] = {0}; + for ( i = 0; i < nOuts; i++ ) + pPos[i] = g*nOuts+i; + pNew = Gia_ManDupCones( p, pPos, nOuts, 1 ); + if ( !fUseFixed ) + pNtkMap = Gia_ManDoTest2( pNew, 1 ); + else + { + pMan = Gia_ManToAig( pNew, 0 ); + pNtk = Abc_NtkFromAigPhase( pMan ); + Aig_ManStop( pMan ); + pNtkRes = Abc_NtkBddToMuxes( pNtk, 1, 1000000, 1 ); + Abc_NtkDelete( pNtk ); + pNtkMap = Abc_NtkSpecialMapping( pNtkRes, 0 ); + Abc_NtkDelete( pNtkRes ); + } + Gia_ManStop( pNew ); + Gia_ManForEachCi( p, pObj, i ) + if ( ~pObj->Value ) + Abc_NtkCi(pNtkMap, Counter++)->pCopy = Abc_NtkCi(pNtkNew, i); + assert( Counter == Abc_NtkCiNum(pNtkMap) ); + Abc_NtkForEachNode( pNtkMap, pObjNew, i ) + { + pObjNew->pCopy = Abc_NtkDupObj( pNtkNew, pObjNew, 0 ); + pObjNew->pCopy->fPersist = pObjNew->fPersist; + if ( pObjNew->fPersist ) + Counts[1]++; + else + Counts[0]++; + Abc_ObjForEachFanin( pObjNew, pFaninNew, k ) + Abc_ObjAddFanin( pObjNew->pCopy, pFaninNew->pCopy ); + } + Abc_NtkForEachCo( pNtkMap, pObjNew, i ) + Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, g*nOuts+i), Abc_ObjFanin0(pObjNew)->pCopy ); + Abc_NtkDelete( pNtkMap ); + + if ( fVerbose ) + { + printf( "%3d / %3d : ", g, nGroups ); + printf( "Test = %4d ", Counts[0] ); + printf( "MarkA = %4d ", Counts[1] ); + printf( "MarkB = %4d ", Counts[2] ); + printf( "\n" ); + } + + CountsAll[0] += Counts[0]; + CountsAll[1] += Counts[1]; + CountsAll[2] += Counts[2]; + } + if ( fVerbose ) + printf( "Total LUT count = %5d. MarkA = %5d. MarkB = %5d.\n", CountsAll[0], CountsAll[1], CountsAll[2] ); + // create names + Abc_NtkAddDummyPiNames( pNtkNew ); + Abc_NtkAddDummyPoNames( pNtkNew ); + Abc_NtkAddDummyBoxNames( pNtkNew ); + // check the resulting AIG + if ( !Abc_NtkCheck( pNtkNew ) ) + Abc_Print( 1, "Abc_NtkFromMappedGia(): Network check has failed.\n" ); + return pNtkNew; +} + +Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fVerbose ) +{ + int fPrintOnly = 0; int Res1, Res2, Result = 0; int g, nGroups = Gia_ManCoNum(p) / GroupSize; assert( Gia_ManCoNum(p) % GroupSize == 0 ); assert( GroupSize <= 64 ); - for ( g = 0; g < nGroups; g++ ) + if ( fPrintOnly ) { - Gia_Man_t * pNew;//, * pTemp; - int fTrimPis = 0; - int o, pPos[64]; - for ( o = 0; o < GroupSize; o++ ) - pPos[o] = g*GroupSize+o; - pNew = Gia_ManDupCones( p, pPos, GroupSize, fTrimPis ); - printf( "%3d / %3d : ", g, nGroups ); - printf( "Test1 = %4d ", Res1 = Gia_ManDoTest1(pNew, 0) ); - printf( "Test2 = %4d ", Res2 = Gia_ManDoTest1(pNew, 1) ); - printf( "Test = %4d ", Abc_MinInt(Res1, Res2) ); - printf( "\n" ); - Result += Abc_MinInt(Res1, Res2); - //Gia_ManPrintStats( pNew, NULL ); - Gia_ManStop( pNew ); + for ( g = 0; g < nGroups; g++ ) + { + Gia_Man_t * pNew; + int o, pPos[64]; + for ( o = 0; o < GroupSize; o++ ) + pPos[o] = g*GroupSize+o; + pNew = Gia_ManDupCones( p, pPos, GroupSize, 0 ); + printf( "%3d / %3d : ", g, nGroups ); + printf( "Test1 = %4d ", Res1 = Gia_ManDoTest1(pNew, 0) ); + printf( "Test2 = %4d ", Res2 = Gia_ManDoTest1(pNew, 1) ); + printf( "Test = %4d ", Abc_MinInt(Res1, Res2) ); + printf( "\n" ); + Result += Abc_MinInt(Res1, Res2); + //Gia_ManPrintStats( pNew, NULL ); + Gia_ManStop( pNew ); + } + printf( "Total LUT count = %d.\n", Result ); + return NULL; + } - printf( "Total LUT count = %d.\n", Result ); - return pNew; + return Abc_NtkMapTransform( p, GroupSize, fUseFixed, fVerbose ); } #else -Gia_Man_t * Gia_ManPerformMinLut( Gia_Man_t * p, int GroupSize, int LutSize, int fVerbose ) +Gia_Man_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fVerbose ) { return NULL; } -- cgit v1.2.3 From 93849685b3dadc878bab3dd266a80ad9cfa74a5e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 16 May 2021 20:35:55 -0700 Subject: Updating LUT synthesis code. --- src/aig/gia/giaMinLut.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 9ac9e770..082ad900 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -34,6 +34,8 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -430,7 +432,6 @@ Gia_Man_t * Gia_ManDoMuxMapping( Gia_Man_t * p ) Gia_Man_t * Gia_ManDoMuxTransform( Gia_Man_t * p, int fReorder ) { extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk ); - extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); extern int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder, int fUseAdd ); Gia_Man_t * pRes = NULL; Aig_Man_t * pMan = Gia_ManToAig( p, 0 ); -- cgit v1.2.3 From 49078ffebf4d87165c625a0dad249e039adeb952 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 25 May 2021 23:12:30 -0700 Subject: Updating LUT synthesis code. --- src/aig/gia/giaMinLut.c | 198 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 167 insertions(+), 31 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 082ad900..442c6d66 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -91,13 +91,94 @@ void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO *pvSimO = vSimO; printf( "Read %d words of simulation data for %d inputs and %d outputs (padded %d zero-patterns).\n", nWords, nIns, nOuts, nWords*64-nLines ); } -void Gia_ManSimInfoTransform( char * pFileName, char * pFileOut1, char * pFileOut2, int nIns, int nOuts ) +int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI ) { - Vec_Wrd_t * vSimI, * vSimO; - Vec_WrdReadText( pFileName, &vSimI, &vSimO, nIns, nOuts ); - Vec_WrdDumpBin( pFileOut1 ? pFileOut1 : Extra_FileNameGenericAppend(pFileName, ".simi"), vSimI, 1 ); - Vec_WrdDumpBin( pFileOut2 ? pFileOut2 : Extra_FileNameGenericAppend(pFileName, ".simo"), vSimO, 1 ); + int i, nSize, iLine, nLines, nWords, nIns; + char pLine[1000]; + Vec_Wrd_t * vSimI; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return 0; + } + fgets( pLine, 1000, pFile ); + nIns = strlen(pLine)-1; + if ( nIns < 1 ) + { + printf( "Cannot find the number of inputs in file \"%s\".\n", pFileName ); + fclose( pFile ); + return 0; + } + fseek( pFile, 0, SEEK_END ); + nSize = ftell( pFile ); + if ( nSize % (nIns + 1) > 0 ) + { + printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % (nIns + 1) ); + fclose( pFile ); + return 0; + } + rewind( pFile ); + nLines = nSize / (nIns + 1); + nWords = (nLines + 63)/64; + vSimI = Vec_WrdStart( nIns *nWords ); + for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ ) + { + for ( i = 0; i < nIns; i++ ) + if ( pLine[nIns-1-i] == '1' ) + Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine ); + else assert( pLine[nIns-1-i] == '0' ); + } + fclose( pFile ); + *pvSimI = vSimI; + printf( "Read %d words of simulation data for %d inputs (padded to 64-bit boundary with %d zero-patterns).\n", nWords, nIns, nWords*64-nLines ); + return nIns; +} +Vec_Int_t * Vec_WrdReadNumsOut( char * pFileName, int fVerbose ) +{ + char pLine[1000]; + Vec_Int_t * vNums; int iLine; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return NULL; + } + vNums = Vec_IntAlloc( 1000 ); + for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ ) + Vec_IntPush( vNums, atoi(pLine) ); + fclose( pFile ); + if ( fVerbose ) + printf( "Finished reading %d output values from file \"%s\".\n", Vec_IntSize(vNums), pFileName ); + return vNums; +} +Vec_Wrd_t * Vec_WrdReadTextOut( char * pFileName, int nOuts ) +{ + int i, iLine, nLines, nWords; + Vec_Wrd_t * vSimO; + Vec_Int_t * vNums = Vec_WrdReadNumsOut( pFileName, 1 ); + if ( vNums == NULL ) + return NULL; + nLines = Vec_IntSize(vNums); + nWords = (nLines + 63)/64; + vSimO = Vec_WrdStart( nOuts*nWords ); + Vec_IntForEachEntry( vNums, i, iLine ) + Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine ); + Vec_IntFree( vNums ); + printf( "Read %d words of simulation data for %d outputs (padded %d zero-patterns).\n", nWords, nOuts, nWords*64-nLines ); + return vSimO; +} +void Gia_ManReadSimInfoInputs( char * pFileName, char * pFileOut1, int fVerbose ) +{ + Vec_Wrd_t * vSimI; + Vec_WrdReadText2( pFileName, &vSimI ); + Vec_WrdDumpBin( pFileOut1, vSimI, fVerbose ); Vec_WrdFree( vSimI ); +} +void Gia_ManReadSimInfoOutputs( char * pFileName, char * pFileOut, int nOuts ) +{ + Vec_Wrd_t * vSimO = Vec_WrdReadTextOut( pFileName, nOuts ); + Vec_WrdDumpBin( pFileOut, vSimO, 1 ); Vec_WrdFree( vSimO ); } @@ -201,6 +282,49 @@ int Gia_ManSimEvalOne2( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new ABC_FREE( pSim0 ); return Count; } +int Gia_ManSimEvalMaxValue( Vec_Wrd_t * vSimO, int nWords, int nOuts, int nBits, int iPat ) +{ + int o, ValueMax = -1, OutMax = -1; + for ( o = 0; o < nOuts; o++ ) + { + int i, Value = 0; + for ( i = 0; i < nBits; i++ ) + { + word * pSim = Vec_WrdEntryP( vSimO, (o*nBits+i) * nWords ); + if ( Abc_TtGetBit(pSim, iPat) ) + Value |= 1 << i; + } + if ( ValueMax <= Value ) + { + ValueMax = Value; + OutMax = o; + } + } + return OutMax; +} +int Gia_ManSimEvalOne3( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Int_t * vValues, int nBits ) +{ + int i, Value, nOuts = Gia_ManCoNum(p) / nBits; + int First = -1, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p); + assert( Gia_ManCoNum(p) % nBits == 0 ); + assert( 64*(nWords-1) < Vec_IntSize(vValues) && Vec_IntSize(vValues) <= 64*nWords ); + Vec_IntForEachEntry( vValues, Value, i ) + if ( Value == Gia_ManSimEvalMaxValue(vSimO, nWords, nOuts, nBits, i) ) + { + Count++; + if ( First == -1 ) + First = i; + } + printf( "The accuracy is %8.4f %% (%d out of %d output are correct, for example, output number %d).\n", + 100.0*Count/Vec_IntSize(vValues), Count, Vec_IntSize(vValues), First ); + if ( 0 ) + { + FILE * pTable = fopen( "stats.txt", "a+" ); + fprintf( pTable, "%0.2f \n", 100.0*Count/Vec_IntSize(vValues) ); + fclose( pTable ); + } + return Count; +} Vec_Wrd_t * Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI ) { int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p); @@ -218,7 +342,7 @@ Vec_Wrd_t * Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI ) } return vSimO_new; } -int Gia_ManSimInfoEval( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new ) +int Gia_ManSimInfoEval_old( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new ) { int nResult = Gia_ManSimEvalOne2(p, vSimO, vSimO_new); //Vec_WrdDumpBin( "temp.simo", vSimO_new, 1 ); @@ -226,29 +350,33 @@ int Gia_ManSimInfoEval( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO_new), Vec_WrdSize(vSimO_new))/(64*Vec_WrdSize(vSimO_new)) ); return nResult; } -void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, int fCompare ) +void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, int fVerbose ) { abctime clk = Abc_Clock(); - if ( fCompare ) - { - Vec_Wrd_t * vSim1 = Vec_WrdReadBin( pFileName, 1 ); - Vec_Wrd_t * vSim2 = Vec_WrdReadBin( pFileName2, 1 ); - printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim1), Vec_WrdSize(vSim1))/(64*Vec_WrdSize(vSim1)) ); - printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim2), Vec_WrdSize(vSim2))/(64*Vec_WrdSize(vSim2)) ); - Gia_ManSimInfoEval( p, vSim1, vSim2 ); - Vec_WrdFree( vSim1 ); - Vec_WrdFree( vSim2 ); - } - else - { - Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, 1 ); - Vec_Wrd_t * vSimO = Gia_ManSimInfoTry( p, vSimI ); - printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); - printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) ); - Vec_WrdDumpBin( pFileName2, vSimO, 1 ); - Vec_WrdFree( vSimI ); - Vec_WrdFree( vSimO ); - } + Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, fVerbose ); + Vec_Wrd_t * vSimO = Gia_ManSimInfoTry( p, vSimI ); + if ( fVerbose ) + printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); + if ( fVerbose ) + printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) ); + Vec_WrdDumpBin( pFileName2, vSimO, fVerbose ); + Vec_WrdFree( vSimI ); + Vec_WrdFree( vSimO ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} +void Gia_ManSimInfoEval( Gia_Man_t * p, char * pFileName, char * pFileName2, int nOuts, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Vec_Wrd_t * vSim1 = Vec_WrdReadBin( pFileName, fVerbose ); + Vec_Int_t * vNums = Vec_WrdReadNumsOut( pFileName2, fVerbose ); + assert( nOuts > 0 ); + if ( fVerbose ) + printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim1), Vec_WrdSize(vSim1))/(64*Vec_WrdSize(vSim1)) ); + Gia_ManSimEvalOne3( p, vSim1, vNums, nOuts ); + Vec_WrdFree( vSim1 ); + Vec_IntFree( vNums ); + if ( fVerbose ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } @@ -326,18 +454,19 @@ Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts ) } Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int Thresh, int fVerbose ) { + abctime clk = Abc_Clock(); extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); Gia_Man_t * pNew; Gia_Obj_t * pObj; Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 18 ); Vec_Int_t * vLeaves = Vec_IntAlloc( nIns ); - Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, 1 ) : NULL; + Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL; word * pTruth0 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; float CareAve = 0; - if ( vSimI ) + if ( vSimI && fVerbose ) { int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); - printf( "Using patterns with count %d and higher as cares (%8.4f %% of all patterns).\n", Thresh, 100.0*Thresh/nPats ); + printf( "Using patterns with count %d and higher as cares.\n", Thresh ); } Gia_ManFillValue( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); @@ -378,7 +507,6 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, in Temp = 0; } CareAve /= Gia_ManCoNum(p)/nOuts; - printf( "Average size of the care set = %8.4f %%.\n", CareAve ); Gia_ManHashStop( pNew ); Gia_ManForEachCo( p, pObj, k ) pObj->Value = Gia_ManAppendCo( pNew, pObj->Value ); @@ -389,6 +517,14 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, in Vec_IntFree( vMemory ); Vec_WrdFreeP( &vSimI ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + printf( "Using patterns with count %d and higher as cares. Average care set is %8.4f %%. ", Thresh, CareAve ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( 0 ) + { + FILE * pTable = fopen( "stats.txt", "a+" ); + fprintf( pTable, "%0.2f ", CareAve ); + fclose( pTable ); + } return pNew; } -- cgit v1.2.3 From 8889ccb18c8da84fcb36abc226ff30702e2db215 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 26 May 2021 23:25:08 -0700 Subject: Updating LUT synthesis code. --- src/aig/gia/giaMan.c | 2 +- src/aig/gia/giaMinLut.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 51dd4250..b5748401 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -583,7 +583,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars ) Gia_ManPrintMappingStats( p, pPars ? pPars->pDumpFile : NULL ); else if ( pPars && pPars->pDumpFile ) Gia_ManLogAigStats( p, pPars->pDumpFile ); - if ( pPars && pPars->fNpn && Gia_ManHasMapping(p) && Gia_ManLutSizeMax(p) <= 4 ) + if ( pPars && pPars->fNpn && Gia_ManHasMapping(p) ) Gia_ManPrintNpnClasses( p ); if ( p->vPacking ) Gia_ManPrintPackingStats( p ); diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 442c6d66..8cd66253 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -102,9 +102,7 @@ int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI ) printf( "Cannot open file \"%s\" for reading.\n", pFileName ); return 0; } - fgets( pLine, 1000, pFile ); - nIns = strlen(pLine)-1; - if ( nIns < 1 ) + if ( !fgets(pLine, 1000, pFile) || (nIns = strlen(pLine)-1) < 1 ) { printf( "Cannot find the number of inputs in file \"%s\".\n", pFileName ); fclose( pFile ); @@ -464,7 +462,7 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, in word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; float CareAve = 0; if ( vSimI && fVerbose ) { - int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); + //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); printf( "Using patterns with count %d and higher as cares.\n", Thresh ); } @@ -724,7 +722,7 @@ Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, #else -Gia_Man_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fVerbose ) +Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fVerbose ) { return NULL; } -- cgit v1.2.3 From 7fcbffd2af448d405689465d2da4c81582f2ff98 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 2 Jun 2021 18:57:22 -0700 Subject: Disabled special handling of 2-input LUTs. --- src/aig/gia/giaIf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 7056e310..2f2566d1 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -202,6 +202,7 @@ int Gia_ManLutLevel( Gia_Man_t * p, int ** ppLevels ) ***********************************************************************/ void Gia_ManLutParams( Gia_Man_t * p, int * pnCurLuts, int * pnCurEdges, int * pnCurLevels ) { + int fDisable2Lut = 1; if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t *)p->pManTime) ) { int i; @@ -224,7 +225,7 @@ void Gia_ManLutParams( Gia_Man_t * p, int * pnCurLuts, int * pnCurEdges, int * p *pnCurLevels = 0; Gia_ManForEachLut( p, i ) { - if ( Gia_ObjLutIsMux(p, i) ) + if ( Gia_ObjLutIsMux(p, i) && !(fDisable2Lut && Gia_ObjLutSize(p, i) == 2) ) { int pFanins[3]; if ( Gia_ObjLutSize(p, i) == 3 ) @@ -471,6 +472,7 @@ int Gia_ManCountDupLut( Gia_Man_t * p ) void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) { + int fDisable2Lut = 1; Gia_Obj_t * pObj; int * pLevels; int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0, Ave = 0, nMuxF = 0; @@ -479,7 +481,7 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); Gia_ManForEachLut( p, i ) { - if ( Gia_ObjLutIsMux(p, i) ) + if ( Gia_ObjLutIsMux(p, i) && !(fDisable2Lut && Gia_ObjLutSize(p, i) == 2) ) { int pFanins[3]; if ( Gia_ObjLutSize(p, i) == 3 ) -- cgit v1.2.3 From 7d18d6b7aad526ba73b761f3c2f9292f7546b611 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 5 Jun 2021 17:48:12 -0700 Subject: Experiments with cut computation. --- src/aig/gia/giaCut.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 4 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaCut.c b/src/aig/gia/giaCut.c index f70f0fc0..fc5396c9 100644 --- a/src/aig/gia/giaCut.c +++ b/src/aig/gia/giaCut.c @@ -602,10 +602,10 @@ void Gia_StoRefObj( Gia_Sto_t * p, int iObj ) } void Gia_StoComputeCuts( Gia_Man_t * pGia ) { - int nCutSize = 6; - int nCutNum = 25; - int fCutMin = 1; - int fTruthMin = 1; + int nCutSize = 8; + int nCutNum = 6; + int fCutMin = 0; + int fTruthMin = 0; int fVerbose = 1; Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose ); Gia_Obj_t * pObj; int i, iObj; @@ -637,6 +637,145 @@ void Gia_StoComputeCuts( Gia_Man_t * pGia ) Gia_StoFree( p ); } + +/**Function************************************************************* + + Synopsis [Extract a given number of cuts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_StoSelectOneCut( Vec_Wec_t * vCuts, int iObj, Vec_Int_t * vCut, int nCutSizeMin ) +{ + Vec_Int_t * vThis = Vec_WecEntry( vCuts, iObj ); + int i, v, * pCut, * pList = Vec_IntArray( vThis ); + if ( pList == NULL ) + return 0; + Vec_IntClear( vCut ); + Sdb_ForEachCut( pList, pCut, i ) + { + if ( pCut[0] < nCutSizeMin ) + continue; + for ( v = 0; v <= pCut[0]; v++ ) + Vec_IntPush( vCut, pCut[v] ); + return 1; + } + return 0; +} +Vec_Wec_t * Gia_ManSelectCuts( Vec_Wec_t * vCuts, int nCuts, int nCutSizeMin ) +{ + Vec_Wec_t * vCutsSel = Vec_WecStart( nCuts ); + int i; srand( time(NULL) ); + for ( i = 0; i < nCuts; i++ ) + while ( !Gia_StoSelectOneCut(vCuts, (rand() | (rand() << 15)) % Vec_WecSize(vCuts), Vec_WecEntry(vCutsSel, i), nCutSizeMin) ); + return vCutsSel; +} +Vec_Wec_t * Gia_ManExtractCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 ) +{ + int nCutSize = nCutSize0; + int nCutNum = 6; + int fCutMin = 0; + int fTruthMin = 0; + int fVerbose = fVerbose0; + Vec_Wec_t * vCutsSel; + Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose ); + Gia_Obj_t * pObj; int i, iObj; + assert( nCutSize <= GIA_MAX_CUTSIZE ); + assert( nCutNum < GIA_MAX_CUTNUM ); + // prepare references + Gia_ManForEachObj( p->pGia, pObj, iObj ) + Gia_StoRefObj( p, iObj ); + // compute cuts + Gia_StoComputeCutsConst0( p, 0 ); + Gia_ManForEachCiId( p->pGia, iObj, i ) + Gia_StoComputeCutsCi( p, iObj ); + Gia_ManForEachAnd( p->pGia, pObj, iObj ) + Gia_StoComputeCutsNode( p, iObj ); + if ( p->fVerbose ) + { + printf( "Running cut computation with CutSize = %d CutNum = %d CutMin = %s TruthMin = %s\n", + p->nCutSize, p->nCutNum, p->fCutMin ? "yes":"no", p->fTruthMin ? "yes":"no" ); + 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( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ", + p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) ); + Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart ); + } + vCutsSel = Gia_ManSelectCuts( p->vCuts, nCuts0, nCutSize0-1 ); + Gia_StoFree( p ); + return vCutsSel; +} +void Gia_ManCreateWins( Gia_Man_t * pGia, Vec_Wec_t * vCuts ) +{ + Gia_Obj_t * pObj; + Vec_Wec_t * vWins = Vec_WecStart( Gia_ManObjNum(pGia) ); + Vec_Int_t * vTemp = Vec_IntAlloc( 100 ); + Vec_Int_t * vCut; int i, k, Obj, Cut; + Vec_WecForEachLevel( vCuts, vCut, i ) + Vec_IntForEachEntryStart( vCut, Obj, k, 1 ) + Vec_IntPush( Vec_WecEntry(vWins, Obj), i ); + Gia_ManForEachAnd( pGia, pObj, Obj ) + { + Vec_Int_t * vWin = Vec_WecEntry(vWins, Obj); + Vec_Int_t * vWin0 = Vec_WecEntry(vWins, Gia_ObjFaninId0(pObj, Obj)); + Vec_Int_t * vWin1 = Vec_WecEntry(vWins, Gia_ObjFaninId1(pObj, Obj)); + Vec_IntTwoFindCommon( vWin0, vWin1, vTemp ); + Vec_IntForEachEntry( vTemp, Cut, k ) + { + Vec_IntPushUniqueOrder( vWin, Cut ); + Vec_IntPush( Vec_WecEntry(vCuts, Cut), Obj ); + } + } + Vec_WecFree( vWins ); + Vec_IntFree( vTemp ); +} +void Gia_ManPrintWins( Vec_Wec_t * vCuts ) +{ + Vec_Int_t * vCut; int i, k, Obj; + Vec_WecForEachLevel( vCuts, vCut, i ) + { + int nInputs = Vec_IntEntry(vCut, 0); + printf( "Cut %5d : ", i ); + printf( "Supp = %d ", nInputs ); + printf( "Nodes = %d ", Vec_IntSize(vCut) - 1 - nInputs ); + Vec_IntForEachEntryStartStop( vCut, Obj, k, 1, nInputs+1 ) + printf( "%d ", Obj ); + printf( " " ); + Vec_IntForEachEntryStart( vCut, Obj, k, nInputs+1 ) + printf( "%d ", Obj ); + printf( "\n" ); + } +} +void Gia_ManPrintWinStats( Vec_Wec_t * vCuts ) +{ + Vec_Int_t * vCut; int i, nInputs = 0, nNodes = 0; + Vec_WecForEachLevel( vCuts, vCut, i ) + { + nInputs += Vec_IntEntry(vCut, 0); + nNodes += Vec_IntSize(vCut) - 1 - Vec_IntEntry(vCut, 0); + } + printf( "Computed %d windows with average support %.3f and average volume %.3f.\n", + Vec_WecSize(vCuts), 1.0*nInputs/Vec_WecSize(vCuts), 1.0*nNodes/Vec_WecSize(vCuts) ); +} +void Gia_ManExtractTest( Gia_Man_t * pGia ) +{ + Vec_Wec_t * vCutsSel = Gia_ManExtractCuts( pGia, 8, 10000, 1 ); + abctime clk = Abc_Clock(); + Gia_ManCreateWins( pGia, vCutsSel ); + //Gia_ManPrintWins( vCutsSel ); + Gia_ManPrintWinStats( vCutsSel ); + Vec_WecFree( vCutsSel ); + Abc_PrintTime( 0, "Creating windows", Abc_Clock() - clk ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From db3f5b6d0bac98b9123681a1189acf738cae83d6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 8 Jun 2021 11:39:42 -0700 Subject: Experiments with cut computation. --- src/aig/gia/giaCut.c | 4 +++- src/aig/gia/giaResub2.c | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaCut.c b/src/aig/gia/giaCut.c index fc5396c9..7ee795b6 100644 --- a/src/aig/gia/giaCut.c +++ b/src/aig/gia/giaCut.c @@ -767,7 +767,9 @@ void Gia_ManPrintWinStats( Vec_Wec_t * vCuts ) } void Gia_ManExtractTest( Gia_Man_t * pGia ) { - Vec_Wec_t * vCutsSel = Gia_ManExtractCuts( pGia, 8, 10000, 1 ); + extern Vec_Wec_t * Gia_ManExtractCuts2( Gia_Man_t * p, int nCutSize, int nCuts, int fVerbose ); + Vec_Wec_t * vCutsSel = Gia_ManExtractCuts2( pGia, 8, 10000, 1 ); + //Vec_Wec_t * vCutsSel = Gia_ManExtractCuts( pGia, 8, 10000, 1 ); abctime clk = Abc_Clock(); Gia_ManCreateWins( pGia, vCutsSel ); //Gia_ManPrintWins( vCutsSel ); diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index 89ddaf33..be527d4f 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -1498,10 +1498,50 @@ void Gia_RsbTestArray() Vec_IntFree( vArray ); } +/**Function************************************************************* + + Synopsis [Computing cuts of the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Gia_ManExtractCuts2( Gia_Man_t * p, int nCutSize, int nCuts, int fVerbose ) +{ + int c, nLevelMax = 8; + abctime clk = Abc_Clock(); + Vec_Wec_t * vCuts = Vec_WecStart( nCuts ); + Vec_Int_t * vPaths = Vec_IntStart( Gia_ManObjNum(p) ); + srand( time(NULL) ); + for ( c = 0; c < nCuts; ) + { + Vec_Int_t * vCut, * vWin = NULL; + while ( vWin == NULL ) + { + int iPivot = 1 + Gia_ManCiNum(p) + rand() % Gia_ManAndNum(p); + assert( Gia_ObjIsAnd(Gia_ManObj(p, iPivot)) ); + vWin = Gia_RsbWindowInit( p, vPaths, iPivot, nLevelMax ); + } + vCut = Gia_RsbCreateWindowInputs( p, vWin ); + if ( Vec_IntSize(vCut) >= nCutSize - 2 && Vec_IntSize(vCut) <= nCutSize ) + { + Vec_IntPush( Vec_WecEntry(vCuts, c), Vec_IntSize(vCut) ); + Vec_IntAppend( Vec_WecEntry(vCuts, c++), vCut ); + } + Vec_IntFree( vCut ); + Vec_IntFree( vWin ); + } + Vec_IntFree( vPaths ); + Abc_PrintTime( 0, "Computing cuts ", Abc_Clock() - clk ); + return vCuts; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// - ABC_NAMESPACE_IMPL_END -- cgit v1.2.3 From b4f099c511f66dfe6624ac26194abb90e9615cfd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 19 Jun 2021 19:26:41 -0700 Subject: Experiments with LUT mapping for small functions. --- src/aig/gia/giaMinLut.c | 76 ++++- src/aig/gia/giaMinLut2.c | 797 +++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaTruth.c | 32 +- src/aig/gia/module.make | 1 + 4 files changed, 867 insertions(+), 39 deletions(-) create mode 100644 src/aig/gia/giaMinLut2.c (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 8cd66253..13c9a3ce 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -417,6 +417,8 @@ word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp Abc_TtXorBit( pRes, k ); //printf( "%d ", pCounts[k] ); } + if ( Vec_IntSize(vSupp) < 6 ) + pRes[0] = Abc_Tt6Stretch( pRes[0], Vec_IntSize(vSupp) ); //printf( "\n" ); if ( fVerbose ) printf( "Used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints ); @@ -450,16 +452,29 @@ Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts ) Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp ); return vSupp; } -Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int Thresh, int fVerbose ) +int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) { - abctime clk = Abc_Clock(); + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManPerformLNetOpt_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManPerformLNetOpt_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose ) +{ + extern int Gia_ManDupOrderDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ); + extern Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ); + extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ); extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + abctime clk = Abc_Clock(); Gia_Man_t * pNew; Gia_Obj_t * pObj; Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 18 ); Vec_Int_t * vLeaves = Vec_IntAlloc( nIns ); Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL; word * pTruth0 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; float CareAve = 0; + word * pTruthsTry = ABC_CALLOC( word, 2*nOuts*Abc_Truth6WordNum(nIns) ); if ( vSimI && fVerbose ) { //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); @@ -478,10 +493,10 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, in for ( g = 0; g < Gia_ManCoNum(p); g += nOuts ) { Vec_Int_t * vSupp = Gia_ManCollectSupp( p, g, nOuts ); - int Care, Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0; + int Care = 1 << Vec_IntSize(vSupp), Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0; word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) ); int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) ); - CareAve += 100.0*Care/(1 << nIns); + CareAve += 100.0*Care/(1 << Vec_IntSize(vSupp)); assert( Vec_IntSize(vSupp) <= nIns ); Vec_IntClear( vLeaves ); Gia_ManForEachObjVec( vSupp, p, pObj, k ) @@ -489,16 +504,42 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, in for ( k = 0; k < nOuts; k++ ) { Gia_Obj_t * pObj = Gia_ManCo( p, g+k ); - if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) ) + word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp ); + Abc_TtSharp( pTruth0, pCare, pTruth, nWords ); + Abc_TtAnd( pTruth1, pCare, pTruth, nWords, 0 ); + if ( vSimI ) + { + Abc_TtCopy( pTruthsTry + (2*k+0)*nWords, pTruth1, nWords, 0 ); + Abc_TtCopy( pTruthsTry + (2*k+1)*nWords, pTruth0, nWords, 0 ); + } + else + Abc_TtCopy( pTruthsTry + k*nWords, pTruth1, nWords, 0 ); + if ( !fTryNew ) { - word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp ); - Abc_TtSharp( pTruth0, pCare, pTruth, nWords ); - Abc_TtAnd( pTruth1, pCare, pTruth, nWords, 0 ); pObj->Value = Kit_TruthToGia2( pNew, (unsigned *)pTruth0, (unsigned *)pTruth1, Vec_IntSize(vLeaves), vMemory, vLeaves, 1 ); + pObj->Value ^= Gia_ObjFaninC0(pObj); } + } + if ( fTryNew ) + { + Gia_Man_t * pMin; + if ( vSimI ) + pMin = Gia_TryPermOpt( pTruthsTry, Vec_IntSize(vSupp), 2*nOuts, nWords, nRounds, fVerbose ); else - pObj->Value = Gia_ObjFanin0(pObj)->Value; - pObj->Value ^= Gia_ObjFaninC0(pObj); + pMin = Gia_TryPermOptCare( pTruthsTry, Vec_IntSize(vSupp), nOuts, nWords, nRounds, fVerbose ); + Gia_ManFillValue( pMin ); + Gia_ManConst0(pMin)->Value = 0; + Gia_ManForEachCi( pMin, pObj, k ) + pObj->Value = Vec_IntEntry( vLeaves, k ); + for ( k = 0; k < nOuts; k++ ) + { + Gia_Obj_t * pObj = Gia_ManCo( p, g+k ); + Gia_Obj_t * pObj2 = Gia_ManCo( pMin, k ); + pObj->Value = Gia_ManPerformLNetOpt_rec( pNew, pMin, Gia_ObjFanin0(pObj2) ); + pObj->Value ^= Gia_ObjFaninC0(pObj2); + pObj->Value ^= Gia_ObjFaninC0(pObj); + } + Gia_ManStop( pMin ); } ABC_FREE( pCare ); Vec_IntFree( vSupp ); @@ -523,6 +564,7 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, char * pFileName, int nIns, in fprintf( pTable, "%0.2f ", CareAve ); fclose( pTable ); } + ABC_FREE( pTruthsTry ); return pNew; } @@ -594,12 +636,12 @@ int Gia_ManDoTest1( Gia_Man_t * p, int fReorder ) Gia_ManStop( pNew ); return Res; } -Abc_Ntk_t * Gia_ManDoTest2( Gia_Man_t * p, int fReorder ) +Abc_Ntk_t * Gia_ManDoTest2( Gia_Man_t * p, int fReorder, int fTryNew ) { extern Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs ); Abc_Ntk_t * pNtkNew; Gia_Man_t * pTemp, * pNew; - pNew = Gia_ManDoMuxTransform( p, fReorder ); + pNew = fTryNew ? Gia_ManDup(p) : Gia_ManDoMuxTransform( p, fReorder ); pNew = Gia_ManDoMuxMapping( pTemp = pNew ); Gia_ManStop( pTemp ); pNtkNew = Abc_NtkFromMappedGia( pNew, 0, 0 ); @@ -608,7 +650,7 @@ Abc_Ntk_t * Gia_ManDoTest2( Gia_Man_t * p, int fReorder ) Abc_NtkToSop( pNtkNew, 1, ABC_INFINITY ); return pNtkNew; } -Abc_Ntk_t * Abc_NtkMapTransform( Gia_Man_t * p, int nOuts, int fUseFixed, int fVerbose ) +Abc_Ntk_t * Abc_NtkMapTransform( Gia_Man_t * p, int nOuts, int fUseFixed, int fTryNew, int fVerbose ) { extern Abc_Ntk_t * Abc_NtkSpecialMapping( Abc_Ntk_t * pNtk, int fVerbose ); int i, k, g, nGroups = Gia_ManCoNum(p) / nOuts, CountsAll[3] = {0}; @@ -632,7 +674,7 @@ Abc_Ntk_t * Abc_NtkMapTransform( Gia_Man_t * p, int nOuts, int fUseFixed, int fV pPos[i] = g*nOuts+i; pNew = Gia_ManDupCones( p, pPos, nOuts, 1 ); if ( !fUseFixed ) - pNtkMap = Gia_ManDoTest2( pNew, 1 ); + pNtkMap = Gia_ManDoTest2( pNew, 1, fTryNew ); else { pMan = Gia_ManToAig( pNew, 0 ); @@ -688,7 +730,7 @@ Abc_Ntk_t * Abc_NtkMapTransform( Gia_Man_t * p, int nOuts, int fUseFixed, int fV return pNtkNew; } -Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fVerbose ) +Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose ) { int fPrintOnly = 0; int Res1, Res2, Result = 0; @@ -717,12 +759,12 @@ Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, return NULL; } - return Abc_NtkMapTransform( p, GroupSize, fUseFixed, fVerbose ); + return Abc_NtkMapTransform( p, GroupSize, fUseFixed, fTryNew, fVerbose ); } #else -Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fVerbose ) +Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose ) { return NULL; } diff --git a/src/aig/gia/giaMinLut2.c b/src/aig/gia/giaMinLut2.c new file mode 100644 index 00000000..a53e7be5 --- /dev/null +++ b/src/aig/gia/giaMinLut2.c @@ -0,0 +1,797 @@ +/**CFile**************************************************************** + + FileName [giaMinLut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Collapsing AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaMinLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaAig.h" +#include "base/main/mainInt.h" +#include "opt/sfm/sfm.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define TREE_MAX_VARS 16 + +typedef struct Tree_Sto_t_ Tree_Sto_t; +struct Tree_Sto_t_ +{ + int nIns; + int nOuts; + int pTried[TREE_MAX_VARS]; + int pPerm[TREE_MAX_VARS]; + int pIPerm[TREE_MAX_VARS]; + int nNodes[TREE_MAX_VARS]; + Vec_Int_t vCofs[TREE_MAX_VARS]; + word * pMem; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Tree_Sto_t * Gia_ManTreeDup( Tree_Sto_t * p ) +{ + Tree_Sto_t * pSto = ABC_CALLOC( Tree_Sto_t, 1 ); + int i, k, Obj; + *pSto = *p; + pSto->pMem = Abc_TtDup( pSto->pMem, p->nOuts*Abc_TtWordNum(p->nIns), 0 ); + memset( pSto->vCofs, 0, sizeof(Vec_Int_t)*TREE_MAX_VARS ); + for ( i = 0; i < TREE_MAX_VARS; i++ ) + Vec_IntForEachEntry( p->vCofs+i, Obj, k ) + Vec_IntPush( pSto->vCofs+i, Obj ); + return pSto; +} +void Gia_ManTreeFree( Tree_Sto_t * p ) +{ + int i; + for ( i = 0; i < TREE_MAX_VARS; i++ ) + ABC_FREE( p->vCofs[i].pArray ); + ABC_FREE( p->pMem ); + ABC_FREE( p ); +} +int Gia_ManTreeCountNodes( Tree_Sto_t * p ) +{ + int i, nNodes = 0; + for ( i = 0; i < TREE_MAX_VARS; i++ ) + nNodes += p->nNodes[i]; + return nNodes; +} +void Gia_ManTreePrint( Tree_Sto_t * p ) +{ + int i; + printf( "Tree with %d nodes:\n", Gia_ManTreeCountNodes(p) ); + for ( i = p->nIns-1; i >= 0; i-- ) + printf( "Level %2d Var %2d : %s Nodes = %3d Cofs = %3d\n", + i, p->pIPerm[i], p->pTried[i]?"*":" ", p->nNodes[i], Vec_IntSize(p->vCofs+i) ); +// for ( i = p->nIns-1; i >= 0; i-- ) +// printf( "Var %2d Level %2d\n", i, p->pPerm[i] ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManFindOrAddNode( Tree_Sto_t * pSto, int iVar, int Truth, word * pCof ) +{ + int k, Obj; + if ( iVar > 5 ) + { + int nWords = Abc_TtWordNum(iVar); + Vec_IntForEachEntry( pSto->vCofs+iVar, Obj, k ) + if ( Abc_TtEqual( pSto->pMem + Obj, pCof, nWords ) ) + return 1; + Vec_IntPush( pSto->vCofs+iVar, pCof - pSto->pMem ); + } + else + { + Vec_IntForEachEntry( pSto->vCofs+iVar, Obj, k ) + if ( Obj == Truth ) + return 1; + Vec_IntPush( pSto->vCofs+iVar, Truth ); + } + return 0; +} +int Gia_ManProcessLevel( Tree_Sto_t * pSto, int iVar ) +{ + int k, Obj, nNodes = 0; + //Vec_IntPrint( pSto->vCofs+iVar ); + Vec_IntClear( pSto->vCofs+iVar ); + if ( iVar > 5 ) + { + int nWords = Abc_TtWordNum(iVar); + Vec_IntForEachEntry( pSto->vCofs+iVar+1, Obj, k ) + { + word * pCof0 = pSto->pMem + Obj; + word * pCof1 = pCof0 + nWords; + Gia_ManFindOrAddNode( pSto, iVar, -1, pCof0 ); + if ( Abc_TtEqual( pCof0, pCof1, nWords ) ) + continue; + Gia_ManFindOrAddNode( pSto, iVar, -1, pCof1 ); + nNodes++; + } + } + else + { + Vec_IntForEachEntry( pSto->vCofs+iVar+1, Obj, k ) + { + unsigned Cof0 = iVar < 5 ? Abc_Tt5Cofactor0( Obj, iVar ) : (unsigned) pSto->pMem[Obj]; + unsigned Cof1 = iVar < 5 ? Abc_Tt5Cofactor1( Obj, iVar ) : (unsigned)(pSto->pMem[Obj] >> 32); + Gia_ManFindOrAddNode( pSto, iVar, Cof0, NULL ); + if ( Cof0 == Cof1 ) + continue; + Gia_ManFindOrAddNode( pSto, iVar, Cof1, NULL ); + nNodes++; + } + } + //printf( "Level %2d : Nodes = %3d Cofs = %3d\n", iVar, nNodes, Vec_IntSize(pSto->vCofs+iVar) ); + //Vec_IntPrint( pSto->vCofs+iVar ); + //printf( "\n" ); + return nNodes; +} +Tree_Sto_t * Gia_ManContructTree( word * pTruths, int nIns, int nOuts, int nWords ) +{ + Tree_Sto_t * pSto = ABC_CALLOC( Tree_Sto_t, 1 ); int i; + assert( Abc_TtWordNum(nIns) == nWords ); + assert( nIns+1 <= TREE_MAX_VARS ); + pSto->pMem = Abc_TtDup(pTruths, nOuts*nWords, 0); + pSto->nIns = nIns; + pSto->nOuts = nOuts; + for ( i = 0; i < nIns; i++ ) + pSto->pPerm[i] = pSto->pIPerm[i] = i; + for ( i = 0; i < nOuts; i++ ) + Gia_ManFindOrAddNode( pSto, nIns, (unsigned)pSto->pMem[i], pSto->pMem + i*nWords ); + for ( i = nIns-1; i >= 0; i-- ) + pSto->nNodes[i] = Gia_ManProcessLevel( pSto, i ); + return pSto; +} +void Gia_ManContructTreeTest( word * pTruths, int nIns, int nOuts, int nWords ) +{ + Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords ); + printf( "Total nodes = %d.\n", Gia_ManTreeCountNodes(pSto) ); + Gia_ManTreeFree( pSto ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSwapTree( Tree_Sto_t * pSto, int i ) +{ + int nNodes = pSto->nNodes[i+1] + pSto->nNodes[i]; + int v, o, nWords = Abc_TtWordNum(pSto->nIns); + //printf( "Swapping %2d and %2d ", i, i+1 ); + assert( i >= 0 && i < pSto->nIns-1 ); + for ( o = 0; o < pSto->nOuts; o++ ) + Abc_TtSwapAdjacent( pSto->pMem + o*nWords, nWords, i ); + for ( v = 5; v > i+1; v-- ) + pSto->nNodes[v] = Gia_ManProcessLevel( pSto, v ); + pSto->nNodes[i+1] = Gia_ManProcessLevel( pSto, i+1 ); + pSto->nNodes[i] = Gia_ManProcessLevel( pSto, i ); + ABC_SWAP( int, pSto->pTried[i], pSto->pTried[i+1] ); + ABC_SWAP( int, pSto->pIPerm[i], pSto->pIPerm[i+1] ); + pSto->pPerm[pSto->pIPerm[i+1]] = i+1; + pSto->pPerm[pSto->pIPerm[i]] = i; + return pSto->nNodes[i+1] + pSto->nNodes[i] - nNodes; +} +int Gia_ManFindBestPosition( word * pTruths, int nIns, int nOuts, int nWords, word * pStore, int fMoveMore, int * pnNodesMin, int fVerbose ) +{ + Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords ); + //int v, vBest = nIns-1, nNodesCur = Gia_ManTreeCountNodes(pSto), nNodesMin = nNodesCur; + int v, vBest = -1, nNodesCur = Gia_ManTreeCountNodes(pSto), nNodesMin = ABC_INFINITY; + if ( fVerbose ) + Gia_ManTreePrint( pSto ); + Abc_TtCopy( pStore+(nIns-1)*nOuts*nWords, pSto->pMem, nOuts*nWords, 0 ); + for ( v = nIns-2; v >= 0; v-- ) + { + nNodesCur += Gia_ManSwapTree( pSto, v ); + if ( fMoveMore ? nNodesMin >= nNodesCur : nNodesMin > nNodesCur ) + { + nNodesMin = nNodesCur; + vBest = v; + } + if ( fVerbose ) + printf( "Level %2d -> %2d : Nodes = %4d. ", v+1, v, nNodesCur ); + Abc_TtCopy( pStore+v*nOuts*nWords, pSto->pMem, nOuts*nWords, 0 ); + if ( fVerbose ) + Gia_ManContructTreeTest( pSto->pMem, nIns, nOuts, nWords ); + } + assert( vBest != nIns-1 ); + Gia_ManTreeFree( pSto ); + if ( fVerbose ) + printf( "Best level = %d. Best nodes = %d.\n", vBest, nNodesMin ); + if ( pnNodesMin ) + *pnNodesMin = nNodesMin; + return vBest; +} +void Gia_ManPermStats( int nIns, int * pIPerm, int * pTried ) +{ + int v; + for ( v = nIns-1; v >= 0; v-- ) + printf( "Level = %2d : Var = %2d Tried = %2d\n", v, pIPerm[v], pTried[v] ); + printf( "\n" ); +} +int Gia_ManPermuteTreeOne( word * pTruths, int nIns, int nOuts, int nWords, int fRandom, int * pIPermOut, int fVeryVerbose, int fVerbose ) +{ + extern void Gia_ManDumpMuxes( Tree_Sto_t * p, char * pFileName, int * pIPerm ); + word * pStore = ABC_ALLOC( word, nIns*nOuts*nWords ); + int pTried[TREE_MAX_VARS] = {0}; + int pIPerm[TREE_MAX_VARS] = {0}; + int v, r, Pos, nNodesPrev = -1, nNodesMin = 0, nNoChange = 0; + int nNodesBeg, nNodesEnd; + Tree_Sto_t * pSto; + for ( v = 0; v < nIns; v++ ) + pIPerm[v] = v; + pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords ); + nNodesBeg = Gia_ManTreeCountNodes(pSto); + //Gia_ManDumpMuxes( pSto, "from_tt1.aig", pIPerm ); + Gia_ManTreeFree( pSto ); + if ( fRandom ) + for ( v = 0; v < nIns; v++ ) + { + //int o, vRand = rand() % nIns; + int o, vRand = Gia_ManRandom(0) % nIns; + for ( o = 0; o < nOuts; o++ ) + Abc_TtSwapVars( pTruths + o*nWords, nIns, v, vRand ); + ABC_SWAP( int, pIPerm[vRand], pIPerm[v] ); + } + for ( r = 0; r < 10*nIns; r++ ) + { + nNodesPrev = nNodesMin; + if ( fVeryVerbose ) + printf( "\nRound %d:\n", r ); + Pos = Gia_ManFindBestPosition( pTruths, nIns, nOuts, nWords, pStore, r&1, &nNodesMin, fVeryVerbose ); + Abc_TtCopy( pTruths, pStore+Pos*nOuts*nWords, nOuts*nWords, 0 ); + pTried[nIns-1]++; + for ( v = nIns-2; v >= Pos; v-- ) + { + ABC_SWAP( int, pTried[v+1], pTried[v] ); + ABC_SWAP( int, pIPerm[v+1], pIPerm[v] ); + } + if ( fVeryVerbose ) + Gia_ManPermStats( nIns, pIPerm, pTried ); + nNoChange = nNodesPrev == nNodesMin ? nNoChange + 1 : 0; + if ( nNoChange == 4 ) + break; + } + pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords ); + nNodesEnd = Gia_ManTreeCountNodes(pSto); + //Gia_ManDumpMuxes( pSto, "from_tt2.aig", pIPerm ); + if ( fVerbose ) + printf( "Nodes %5d -> %5d. ", nNodesBeg, nNodesEnd ); + Gia_ManTreeFree( pSto ); + ABC_FREE( pStore ); + if ( pIPermOut ) + memcpy( pIPermOut, pIPerm, sizeof(int)*nIns ); + return nNodesEnd; +} +void Gia_ManPermuteTree( word * pTruths, int nIns, int nOuts, int nWords, int fRandom, int fVerbose ) +{ + abctime clk = Abc_Clock(); + word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 ); + int r; + //srand( time(NULL) ); + Gia_ManRandom(1); + for ( r = 0; r < 100; r++ ) + { + Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, fRandom, NULL, 0, fVerbose ); + Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 ); + } + ABC_FREE( pTruthDup ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#define TT_UNDEF ABC_CONST(0x1234567887654321) + +static inline word Abc_Tt6Min_rec( word uF, word uR, int nVars, Vec_Wrd_t * vNodes ) +{ + word uF0, uF1, uR0, uR1, uRes0, uRes1, uRes2; int i, Var; + assert( nVars <= 6 ); + assert( (uF & uR) == 0 ); + if ( !uF && !uR ) + return TT_UNDEF; + if ( !uF && !~uR ) + return 0; + if ( !~uF && !uR ) + return ~(word)0; + assert( nVars > 0 ); + for ( Var = nVars-1; Var >= 0; Var-- ) + if ( Abc_Tt6HasVar( uF, Var ) || Abc_Tt6HasVar( uR, Var ) ) + break; + assert( Var >= 0 ); + if ( 1 && vNodes ) + Vec_WrdForEachEntry( vNodes, uRes2, i ) + if ( !(uF & ~uRes2) && !(uRes2 & uR) ) + return uRes2; +// else if ( !(uF & uRes2) && !(~uRes2 & uR) ) +// return ~uRes2; + uF0 = Abc_Tt6Cofactor0( uF, Var ); + uF1 = Abc_Tt6Cofactor1( uF, Var ); + uR0 = Abc_Tt6Cofactor0( uR, Var ); + uR1 = Abc_Tt6Cofactor1( uR, Var ); + uRes0 = Abc_Tt6Min_rec( uF0, uR0, Var, vNodes ); + uRes1 = Abc_Tt6Min_rec( uF1, uR1, Var, vNodes ); + if ( uRes0 == TT_UNDEF && uRes1 == TT_UNDEF ) + return TT_UNDEF; + if ( uRes0 == TT_UNDEF ) + return uRes1; + if ( uRes1 == TT_UNDEF ) + return uRes0; + if ( uRes0 == uRes1 ) + return uRes0; +// if ( (uRes0 & ~uRes1) == 0 ) +// printf( "0" ); +// else if ( (~uRes0 & uRes1) == 0 ) +// printf( "1" ); +// else +// printf( "*" ); + uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]); + assert( !(uF & ~uRes2) ); + assert( !(uRes2 & uR) ); + if ( vNodes ) + Vec_WrdPush( vNodes, uRes2 ); + return uRes2; +} +word * Abc_TtMin_rec( word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2 ) +{ + int i, Entry, nWords = Abc_TtWordNum(nVars); + word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords ); + if ( nVars <= 6 ) + { + pRes2[0] = Abc_Tt6Min_rec( pF[0], pR[0], nVars, vNodes ); + return pRes2; + } + assert( !Abc_TtIntersect(pF, pR, nWords, 0) ); + if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst0(pR, nWords) ) + return NULL; + if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst1(pR, nWords) ) + { + Abc_TtClear( pRes2, nWords ); + return pRes2; + } + if ( Abc_TtIsConst1(pF, nWords) && Abc_TtIsConst0(pR, nWords) ) + { + Abc_TtFill( pRes2, nWords ); + return pRes2; + } + nWords >>= 1; + if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) && !Abc_TtHasVar( pR, nVars, nVars-1 ) ) + { + pRes0 = Abc_TtMin_rec( pF, pR, nVars-1, vMemory, vNodes, vNodes2 ); + Abc_TtCopy( pRes2, pRes0, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 ); + return pRes2; + } + if ( 1 && vNodes2 ) + { + Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); + Vec_IntForEachEntry( vLayer, Entry, i ) + { + word * pTemp = Vec_WrdEntryP( vMemory, Entry ); + if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) ) + return pTemp; +/* + if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) ) + { + Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 ); + return pRes2; + } +*/ + } + } + assert( nVars > 6 ); + pRes0 = Abc_TtMin_rec( pF, pR, nVars-1, vMemory, vNodes, vNodes2 ); + pRes1 = Abc_TtMin_rec( pF + nWords, pR + nWords, nVars-1, vMemory, vNodes, vNodes2 ); + if ( pRes0 == NULL && pRes1 == NULL ) + return NULL; + if ( pRes0 == NULL || pRes1 == NULL || Abc_TtEqual(pRes0, pRes1, nWords) ) + { + Abc_TtCopy( pRes2, pRes0 ? pRes0 : pRes1, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes0 ? pRes0 : pRes1, nWords, 0 ); + return pRes2; + } + Abc_TtCopy( pRes2, pRes0, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 ); + assert( !Abc_TtIntersect(pRes2, pF, 2*nWords, 1) ); // assert( !(uF & ~uRes2) ); + assert( !Abc_TtIntersect(pRes2, pR, 2*nWords, 0) ); // assert( !(uRes2 & uR) ); + if ( vNodes2 ) + Vec_WecPush( vNodes2, nVars, pRes2 - Vec_WrdArray(vMemory) ); + return pRes2; +} +word * Abc_TtMin( word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2 ) +{ + word * pResult; + int i, nWords = Abc_TtWordNum(nVars); + assert( nVars >= 0 && nVars <= 16 ); + for ( i = nVars; i < 6; i++ ) + assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) ); + Vec_WrdClear( vMemory ); + Vec_WrdGrow( vMemory, 1 << 20 ); + pResult = Abc_TtMin_rec( pF, pR, nVars, vMemory, vNodes, vNodes2 ); + if ( pResult == NULL ) + { + Vec_WrdFill( vMemory, nWords, 0 ); + return Vec_WrdArray( vMemory ); + } + //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords ); + Abc_TtCopy( Vec_WrdArray(vMemory), pResult, nWords, 0 ); + Vec_WrdShrink( vMemory, nWords ); + return Vec_WrdArray(vMemory); +} +word * Abc_TtMinArray( word * p, int nOuts, int nVars, int * pnNodes, int fVerbose ) +{ + int o, i, nWords = Abc_TtWordNum(nVars); + word * pRes, * pResult = ABC_ALLOC( word, nOuts*nWords/2 ); + Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 ); + Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 ); + Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 ); + Vec_WrdGrow( vMemory, 1 << 20 ); + for ( o = 0; o < nOuts/2; o++ ) + { + word * pF = p + (2*o+0)*nWords; + word * pR = p + (2*o+1)*nWords; + for ( i = nVars; i < 6; i++ ) + assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) ); + pRes = Abc_TtMin_rec( pF, pR, nVars, vMemory, vNodes, vNodes2 ); + if ( pResult == NULL ) + Abc_TtClear( pResult + o*nWords, nWords ); + else + Abc_TtCopy( pResult + o*nWords, pRes, nWords, 0 ); + } + if ( fVerbose ) + printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ", + Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) ); + //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords ); + if ( pnNodes ) + *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2); + Vec_WrdFree( vMemory ); + Vec_WrdFree( vNodes ); + Vec_WecFree( vNodes2 ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManBuildMuxes6_rec( Gia_Man_t * p, word t, int nVars, int * pPerm ) +{ + int iLit0, iLit1, Var; + assert( nVars <= 6 ); + if ( t == 0 ) + return 0; + if ( ~t == 0 ) + return 1; + assert( nVars > 0 ); + for ( Var = nVars-1; Var >= 0; Var-- ) + if ( Abc_Tt6HasVar( t, Var ) ) + break; + assert( Var >= 0 ); + iLit0 = Gia_ManBuildMuxes6_rec( p, Abc_Tt6Cofactor0(t, Var), Var, pPerm ); + iLit1 = Gia_ManBuildMuxes6_rec( p, Abc_Tt6Cofactor1(t, Var), Var, pPerm ); + Var = pPerm ? pPerm[Var] : Var; + return Gia_ManAppendMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 ); +} +int Gia_ManBuildMuxes_rec( Gia_Man_t * p, word * pTruth, int nVars, int * pPerm ) +{ + int iLit0, iLit1, Var, nWords = Abc_TtWordNum(nVars); + if ( nVars <= 6 ) + return Gia_ManBuildMuxes6_rec( p, pTruth[0], nVars, pPerm ); + if ( Abc_TtIsConst0(pTruth, nWords) ) + return 0; + if ( Abc_TtIsConst1(pTruth, nWords) ) + return 1; +/* + assert( nVars > 0 ); + if ( !Abc_TtHasVar( pTruth, nVars, nVars-1 ) ) + return Gia_ManBuildMuxes_rec( p, pTruth, nVars-1 ); + assert( nVars > 6 ); + iLit0 = Gia_ManBuildMuxes_rec( p, pTruth, nVars-1 ); + iLit1 = Gia_ManBuildMuxes_rec( p, pTruth+nWords/2, nVars-1 ); +*/ + assert( nVars > 0 ); + for ( Var = nVars-1; Var >= 0; Var-- ) + if ( Abc_TtHasVar( pTruth, nVars, Var ) ) + break; + assert( Var >= 0 ); + if ( Var < 6 ) + return Gia_ManBuildMuxes6_rec( p, pTruth[0], Var+1, pPerm ); + iLit0 = Gia_ManBuildMuxes_rec( p, pTruth, Var, pPerm ); + iLit1 = Gia_ManBuildMuxes_rec( p, pTruth+Abc_TtWordNum(Var), Var, pPerm ); + Var = pPerm ? pPerm[Var] : Var; + return Gia_ManAppendMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 ); +} +Gia_Man_t * Gia_ManBuildMuxesTest( word * pTruth, int nIns, int nOuts, int * pPerm ) +{ + Gia_Man_t * pNew, * pTemp; + int i, nWords = Abc_TtWordNum(nIns); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "muxes" ); + for ( i = 0; i < nIns; i++ ) + Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManAppendCo( pNew, Gia_ManBuildMuxes_rec( pNew, pTruth+i*nWords, nIns, pPerm ) ); + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} +Gia_Man_t * Gia_ManBuildMuxes( Tree_Sto_t * p, int * pIPerm ) +{ + return Gia_ManBuildMuxesTest( p->pMem, p->nIns, p->nOuts, pIPerm ? pIPerm : p->pIPerm ); +} +void Gia_ManDumpMuxes( Tree_Sto_t * p, char * pFileName, int * pIPerm ) +{ + Gia_Man_t * pNew = Gia_ManBuildMuxes( p, pIPerm ); + Gia_AigerWrite( pNew, pFileName, 0, 0, 0 ); + Gia_ManStop( pNew ); + printf( "Finished dumping tree into AIG file \"%s\".\n", pFileName ); +} +Gia_Man_t * Gia_ManCreateMuxGia( word * pTruths, int nIns, int nOuts, int nWords, int * pIPerm ) +{ + Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords ); + Gia_Man_t * pNew = Gia_ManBuildMuxes( pSto, pIPerm ); + //printf( "Internal nodes = %5d.\n", Gia_ManTreeCountNodes(pSto) ); + Gia_ManTreeFree( pSto ); + return pNew; +} +void Gia_ManDumpMuxGia( word * pTruths, int nIns, int nOuts, int nWords, int * pIPerm, char * pFileName ) +{ + Tree_Sto_t * pSto = Gia_ManContructTree( pTruths, nIns, nOuts, nWords ); + Gia_ManDumpMuxes( pSto, pFileName, pIPerm ); + Gia_ManTreeFree( pSto ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gia_Man_t * pNew; + word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 ); + word * pTruthBest = ABC_ALLOC( word, nOuts*nWords ); + int pIPermBest[TREE_MAX_VARS] = {0}; + int pIPerm[TREE_MAX_VARS] = {0}; + int r, rBest = -1, nNodes = -1, nNodesBest = ABC_INFINITY; + //Gia_ManDumpMuxGia( pTruths, nIns, nOuts, nWords, NULL, "tt_beg.aig" ); + //srand( time(NULL) ); + Gia_ManRandom(1); + for ( r = 0; r < nRounds; r++ ) + { + nNodes = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose ); + if ( nNodesBest > nNodes ) + { + nNodesBest = nNodes; + memcpy( pIPermBest, pIPerm, sizeof(int)*nIns ); + Abc_TtCopy( pTruthBest, pTruthDup, nOuts*nWords, 0 ); + rBest = r; + } + Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 ); + if ( fVerbose ) + printf( "\n" ); + } + if ( fVerbose ) + printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest ); + ABC_FREE( pTruthDup ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + pNew = Gia_ManCreateMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest ); + //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest, "tt_end.aig" ); + ABC_FREE( pTruthBest ); + return pNew; +} +Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gia_Man_t * pNew; + word * pRes, * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 ); + word * pTruthBest = ABC_ALLOC( word, nOuts*nWords/2 ); + int pIPermBest[TREE_MAX_VARS] = {0}; + int pIPerm[TREE_MAX_VARS] = {0}; + int r, rBest = -1, nNodes = -1, nNodesBest = ABC_INFINITY; + assert( nOuts % 2 == 0 ); + // collect onsets + //for ( r = 0; r < nOuts/2; r++ ) + // Abc_TtCopy( pTruthBest+r*nWords, pTruths+2*r*nWords, nWords, 0 ); + //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts/2, nWords, NULL, "tt_beg.aig" ); + //srand( time(NULL) ); + Gia_ManRandom(1); + for ( r = 0; r < nRounds; r++ ) + { + int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose ); + pRes = Abc_TtMinArray( pTruthDup, nOuts, nIns, &nNodes, fVerbose ); + if ( nNodesBest > nNodes ) + { + nNodesBest = nNodes; + memcpy( pIPermBest, pIPerm, sizeof(int)*nIns ); + Abc_TtCopy( pTruthBest, pRes, nOuts*nWords/2, 0 ); + rBest = r; + } + ABC_FREE( pRes ); + Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 ); + if ( fVerbose ) + printf( "\n" ); + } + if ( fVerbose ) + printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest ); + ABC_FREE( pTruthDup ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + pNew = Gia_ManCreateMuxGia( pTruthBest, nIns, nOuts/2, nWords, pIPermBest ); + //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts/2, nWords, pIPermBest, "tt_end.aig" ); + ABC_FREE( pTruthBest ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_Tt6MinTest3( Gia_Man_t * p ) +{ + word f = ABC_CONST(0x513B00000819050F); + //word r = ABC_CONST(0xA000571507200000); + word r = ~f; + Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 ); + word Res = Abc_Tt6Min_rec( f, r, 6, vNodes ); + printf( "Nodes = %d.\n", Vec_WrdSize(vNodes) ); + if ( Res == f ) + printf( "Verification successful.\n" ); + else + printf( "Verification FAILED.\n" ); + Vec_WrdFree( vNodes ); +} +void Abc_Tt6MinTest2( Gia_Man_t * p ) +{ + int fVerbose = 0; + int i, nWords = Abc_TtWordNum(Gia_ManCiNum(p)); + word * pTruth = ABC_ALLOC( word, 3*nWords ); + word * pRes = NULL, * pTruths[3] = { pTruth, pTruth+nWords, pTruth+2*nWords }; + + Gia_Man_t * pNew = NULL; + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 ); + Vec_Wec_t * vNodes2 = Vec_WecAlloc( 100 ); + Vec_Wrd_t * vMemory = Vec_WrdAlloc( 0 ); + + Gia_Obj_t * pObj; + Gia_ManForEachCi( p, pObj, i ) + Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); + + Gia_ObjComputeTruthTableStart( p, Gia_ManCiNum(p) ); + assert( Gia_ManCoNum(p) == 3 ); + Gia_ManForEachCo( p, pObj, i ) + { + word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp ); + Abc_TtCopy( pTruths[i], pTruth, nWords, Gia_ObjFaninC0(pObj) ); + } + Gia_ObjComputeTruthTableStop( p ); + + + //Abc_TtSharp( pTruths[0], pTruths[0], pTruths[1], nWords ); + Abc_TtReverseVars( pTruths[0], Gia_ManCiNum(p) ); + Abc_TtCopy( pTruths[1], pTruths[0], nWords, 1 ); + + pRes = Abc_TtMin( pTruths[0], pTruths[1], Gia_ManCiNum(p), vMemory, vNodes, vNodes2 ); + printf( "Nodes = %d.\n", Vec_WrdSize(vNodes) ); + printf( "Nodes2 = %d.\n", Vec_WecSizeSize(vNodes2) ); + if ( Abc_TtEqual(pRes, pTruths[0], nWords) ) + printf( "Verification successful.\n" ); + else + printf( "Verification FAILED.\n" ); + + //printf( "Printing the tree:\n" ); +// Gia_ManPermuteTree( pTruths[0], Gia_ManCiNum(p), 1, nWords, fVerbose ); + Gia_ManPermuteTree( pTruth, Gia_ManCiNum(p), 3, nWords, 0, fVerbose ); + + +/* + Abc_TtReverseVars( pTruths[0], Gia_ManCiNum(p) ); + Abc_TtReverseVars( pTruths[1], Gia_ManCiNum(p) ); + Abc_TtReverseVars( pTruths[2], Gia_ManCiNum(p) ); + printf( "Printing the tree:\n" ); + Gia_ManContructTree( pTruth, Gia_ManCiNum(p), 3, nWords ); +*/ + +/* + pNew = Gia_ManBuildMuxesTest( pTruth, Gia_ManCiNum(p), Gia_ManCoNum(p), NULL ); + Gia_AigerWrite( pNew, "from_tt.aig", 0, 0, 0 ); + printf( "Dumping file \"%s\".\n", "from_tt.aig" ); + Gia_ManStop( pNew ); +*/ + + Vec_WrdFree( vMemory ); + Vec_WrdFree( vNodes ); + Vec_WecFree( vNodes2 ); + Vec_IntFree( vSupp ); + ABC_FREE( pTruth ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c index 91c4fa24..c24748ed 100644 --- a/src/aig/gia/giaTruth.c +++ b/src/aig/gia/giaTruth.c @@ -118,27 +118,6 @@ word Gia_LutComputeTruth6Map( Gia_Man_t * p, int iPo, Vec_Int_t * vMap ) SeeAlso [] ***********************************************************************/ -static unsigned s_Truths5[5] = { - 0xAAAAAAAA, - 0xCCCCCCCC, - 0xF0F0F0F0, - 0xFF00FF00, - 0xFFFF0000, -}; -static inline int Abc_Tt5HasVar( unsigned t, int iVar ) -{ - return ((t << (1<= 0 && iVar < 6 ); - return (t & ~s_Truths5[iVar]) | ((t & ~s_Truths5[iVar]) << (1<= 0 && iVar < 6 ); - return (t & s_Truths5[iVar]) | ((t & s_Truths5[iVar]) >> (1<vTtMemory != NULL ); assert( Vec_IntSize(vLeaves) <= p->nTtVars ); + if ( Index >= 0 ) + return Gla_ObjTruthElem( p, Index ); + if ( Gia_ObjIsConst0(pRoot) ) + { + if ( Vec_WrdSize(p->vTtMemory) < p->nTtWords ) + Vec_WrdFillExtra( p->vTtMemory, p->nTtWords, 0 ); + return Gla_ObjTruthConst0( p, Gla_ObjTruthFree1(p) ); + } + assert( Gia_ObjIsAnd(pRoot) ); // extend ID numbers if ( Vec_IntSize(p->vTtNums) < Gia_ManObjNum(p) ) Vec_IntFillExtra( p->vTtNums, Gia_ManObjNum(p), -ABC_INFINITY ); diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index a84a25e5..ed6a9052 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -52,6 +52,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaMfs.c \ src/aig/gia/giaMini.c \ src/aig/gia/giaMinLut.c \ + src/aig/gia/giaMinLut2.c \ src/aig/gia/giaMuxes.c \ src/aig/gia/giaNf.c \ src/aig/gia/giaOf.c \ -- cgit v1.2.3 From 28ba2c52137883b4acc46b2d31edf717822e543f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 24 Jun 2021 19:18:28 -0700 Subject: Adding place holder file for resub experiments. --- src/aig/gia/giaMinLut2.c | 2 +- src/aig/gia/giaResub3.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 1 + 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/aig/gia/giaResub3.c (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut2.c b/src/aig/gia/giaMinLut2.c index a53e7be5..69ed6f3b 100644 --- a/src/aig/gia/giaMinLut2.c +++ b/src/aig/gia/giaMinLut2.c @@ -683,6 +683,7 @@ Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 ); if ( fVerbose ) printf( "\n" ); + nNodesAll = 0; } if ( fVerbose ) printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest ); @@ -728,7 +729,6 @@ void Abc_Tt6MinTest2( Gia_Man_t * p ) word * pTruth = ABC_ALLOC( word, 3*nWords ); word * pRes = NULL, * pTruths[3] = { pTruth, pTruth+nWords, pTruth+2*nWords }; - Gia_Man_t * pNew = NULL; Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 ); Vec_Wec_t * vNodes2 = Vec_WecAlloc( 100 ); diff --git a/src/aig/gia/giaResub3.c b/src/aig/gia/giaResub3.c new file mode 100644 index 00000000..71e182d1 --- /dev/null +++ b/src/aig/gia/giaResub3.c @@ -0,0 +1,54 @@ +/**CFile**************************************************************** + + FileName [giaResub3.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Resubstitution computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaResub3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPerformNewResub( Gia_Man_t * p, int nWinCount, int nCutSize, int nProcs, int fVerbose ) +{ + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index ed6a9052..843d721b 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -62,6 +62,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaQbf.c \ src/aig/gia/giaResub.c \ src/aig/gia/giaResub2.c \ + src/aig/gia/giaResub3.c \ src/aig/gia/giaRetime.c \ src/aig/gia/giaRex.c \ src/aig/gia/giaSatEdge.c \ -- cgit v1.2.3 From 5a135c8799d439ad85ac9a0d105721ed80f355be Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 8 Jul 2021 21:42:15 -0700 Subject: Experiments with MUX decomposition. --- src/aig/gia/giaSimBase.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 2e61c1ff..9e7033ab 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -149,6 +149,85 @@ void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ) Vec_WrdDumpHex( pFileName, vSimsIn, nWords, 0 ); } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word * Gia_ManDeriveFuncs( Gia_Man_t * p ) +{ + int nVars2 = (Gia_ManCiNum(p) + 6)/2; + int nVars3 = Gia_ManCiNum(p) - nVars2; + int nWords = Abc_Truth6WordNum( Gia_ManCiNum(p) ); + int nWords2 = Abc_Truth6WordNum( nVars2 ); + word * pRes = ABC_ALLOC( word, Gia_ManCoNum(p) * nWords ); + Vec_Wrd_t * vSims = Vec_WrdStart( nWords2 * Gia_ManObjNum(p) ); + Vec_Ptr_t * vTruths = Vec_PtrAllocTruthTables( nVars2 ); + Gia_Obj_t * pObj; int i, v, m; + Gia_ManForEachCi( p, pObj, i ) + assert( Gia_ObjId(p, pObj) == i+1 ); + for ( i = 0; i < nVars2; i++ ) + Abc_TtCopy( Vec_WrdEntryP(vSims, nWords2*(i+1)), (word *)Vec_PtrEntry(vTruths, i), nWords2, 0 ); + Vec_PtrFree( vTruths ); + for ( m = 0; m < (1 << nVars3); m++ ) + { + for ( v = 0; v < nVars3; v++ ) + Abc_TtConst( Vec_WrdEntryP(vSims, nWords2*(nVars2+v+1)), nWords2, (m >> v) & 1 ); + Gia_ManForEachAnd( p, pObj, i ) + Gia_ManSimPatSimAnd( p, i, pObj, nWords2, vSims ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj), pObj, nWords2, vSims ); + Gia_ManForEachCo( p, pObj, i ) + Abc_TtCopy( pRes + i*nWords + m*nWords2, Vec_WrdEntryP(vSims, nWords2*Gia_ObjId(p, pObj)), nWords2, 0 ); + } + Vec_WrdFree( vSims ); + return pRes; +} +Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p ) +{ + extern int Gia_ManFindMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, int Shift ); + extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + int nWords = Abc_Truth6WordNum( Gia_ManCiNum(p) ); + int nCofs = 1 << (Gia_ManCiNum(p) - 6); + word * pRes = Gia_ManDeriveFuncs( p ); + Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 16 ); + Vec_Int_t * vLeaves = Vec_IntAlloc( 6 ); + Vec_Int_t * vCtrls = Vec_IntAlloc( nCofs ); + Vec_Int_t * vDatas = Vec_IntAlloc( Gia_ManCoNum(p) ); + Gia_Man_t * pNew, * pTemp; int i, o; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + Vec_IntPush( i < 6 ? vLeaves : vCtrls, Gia_ManAppendCi(pNew) ); + Gia_ManHashAlloc( pNew ); + for ( o = 0; o < Gia_ManCoNum(p); o++ ) + { + Vec_IntClear( vDatas ); + for ( i = 0; i < nWords; i++ ) + Vec_IntPush( vDatas, Kit_TruthToGia(pNew, (unsigned *)(pRes+o*nWords+i), 6, vMemory, vLeaves, 1) ); + Gia_ManAppendCo( pNew, Gia_ManFindMuxTree_rec(pNew, Vec_IntArray(vCtrls), Vec_IntSize(vCtrls), vDatas, 0) ); + } + Gia_ManHashStop( pNew ); + ABC_FREE( pRes ); + Vec_IntFree( vMemory ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vCtrls ); + Vec_IntFree( vDatas ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + /**Function************************************************************* Synopsis [] -- cgit v1.2.3 From 96b9192c783de58f723966358337d26728611c84 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 8 Jul 2021 21:54:07 -0700 Subject: Experiments with MUX decomposition. --- src/aig/gia/giaSimBase.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 9e7033ab..23b2eb31 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -211,6 +211,7 @@ Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p ) Gia_ManHashAlloc( pNew ); for ( o = 0; o < Gia_ManCoNum(p); o++ ) { + Abc_TtReverseVars( pRes+o*nWords, nWords ); Vec_IntClear( vDatas ); for ( i = 0; i < nWords; i++ ) Vec_IntPush( vDatas, Kit_TruthToGia(pNew, (unsigned *)(pRes+o*nWords+i), 6, vMemory, vLeaves, 1) ); -- cgit v1.2.3 From 4116e13b5e70ae334acddb88c8bec869f6c9af75 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 8 Jul 2021 21:54:46 -0700 Subject: Experiments with MUX decomposition. --- src/aig/gia/giaSimBase.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 23b2eb31..9e7033ab 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -211,7 +211,6 @@ Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p ) Gia_ManHashAlloc( pNew ); for ( o = 0; o < Gia_ManCoNum(p); o++ ) { - Abc_TtReverseVars( pRes+o*nWords, nWords ); Vec_IntClear( vDatas ); for ( i = 0; i < nWords; i++ ) Vec_IntPush( vDatas, Kit_TruthToGia(pNew, (unsigned *)(pRes+o*nWords+i), 6, vMemory, vLeaves, 1) ); -- cgit v1.2.3 From fdc9e89d6643743c0d03b8c6c9cbf480f585c7ee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 9 Jul 2021 11:53:50 -0700 Subject: Simple AIGER reader/writer. --- src/aig/gia/giaAiger.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index bc2e25ad..fef5b6e4 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -1478,6 +1478,147 @@ void Gia_AigerWriteSimple( Gia_Man_t * pInit, char * pFileName ) fclose( pFile ); } + + +/**Function************************************************************* + + Synopsis [Simple AIGER reader/writer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Aiger_ReadUnsigned( FILE * pFile ) +{ + unsigned x = 0, i = 0; + unsigned char ch; + while ((ch = fgetc(pFile)) & 0x80) + x |= (ch & 0x7f) << (7 * i++); + return x | (ch << (7 * i)); +} +static inline void Aiger_WriteUnsigned( FILE * pFile, unsigned x ) +{ + unsigned char ch; + while (x & ~0x7f) + { + ch = (x & 0x7f) | 0x80; + fputc( ch, pFile ); + x >>= 7; + } + ch = x; + fputc( ch, pFile ); +} +int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int * pnOuts, int * pnAnds ) +{ + int i, Temp, nTotal, nObjs, nIns, nLats, nOuts, nAnds, * pObjs; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Aiger_Read(): Cannot open the output file \"%s\".\n", pFileName ); + return NULL; + } + if ( fgetc(pFile) != 'a' || fgetc(pFile) != 'i' || fgetc(pFile) != 'g' ) + { + fprintf( stdout, "Aiger_Read(): Can only read binary AIGER.\n" ); + fclose( pFile ); + return NULL; + } + if ( fscanf(pFile, "%d %d %d %d %d", &nTotal, &nIns, &nLats, &nOuts, &nAnds) != 5 ) + { + fprintf( stdout, "Aiger_Read(): Cannot read the header line.\n" ); + fclose( pFile ); + return NULL; + } + if ( nTotal != nIns + nLats + nAnds ) + { + fprintf( stdout, "The number of objects does not match.\n" ); + fclose( pFile ); + return NULL; + } + nObjs = 1 + nIns + 2*nLats + nOuts + nAnds; + pObjs = ABC_CALLOC( int, nObjs * 2 ); + // read flop input literals + for ( i = 0; i < nLats; i++ ) + { + while ( fgetc(pFile) != '\n' ); + fscanf( pFile, "%d", &Temp ); + pObjs[2*(nObjs-nLats+i)+0] = Temp; + pObjs[2*(nObjs-nLats+i)+1] = Temp; + } + // read output literals + for ( i = 0; i < nOuts; i++ ) + { + while ( fgetc(pFile) != '\n' ); + fscanf( pFile, "%d", &Temp ); + pObjs[2*(nObjs-nOuts-nLats+i)+0] = Temp; + pObjs[2*(nObjs-nOuts-nLats+i)+1] = Temp; + } + // read the binary part + while ( fgetc(pFile) != '\n' ); + for ( i = 0; i < nAnds; i++ ) + { + int uLit = 2*(1 + nIns + nLats + i); + int uLit1 = uLit - Aiger_ReadUnsigned( pFile ); + int uLit0 = uLit1 - Aiger_ReadUnsigned( pFile ); + pObjs[2*(1+nIns+i)+0] = uLit0; + pObjs[2*(1+nIns+i)+1] = uLit1; + } + fclose( pFile ); + if ( pnObjs ) *pnObjs = nObjs; + if ( pnIns ) *pnIns = nIns; + if ( pnLats ) *pnLats = nLats; + if ( pnOuts ) *pnOuts = nOuts; + if ( pnAnds ) *pnAnds = nAnds; + return pObjs; +} +void Aiger_Write( char * pFileName, int * pObjs, int nObjs, int nIns, int nLats, int nOuts, int nAnds ) +{ + FILE * pFile = fopen( pFileName, "wb" ); int i; + if ( pFile == NULL ) + { + fprintf( stdout, "Aiger_Write(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "aig %d %d %d %d %d\n", nIns + nLats + nAnds, nIns, nLats, nOuts, nAnds ); + for ( i = 0; i < nLats; i++ ) + fprintf( pFile, "%d\n", pObjs[2*(nObjs-nLats+i)+0] ); + for ( i = 0; i < nOuts; i++ ) + fprintf( pFile, "%d\n", pObjs[2*(nObjs-nOuts-nLats+i)+0] ); + for ( i = 0; i < nAnds; i++ ) + { + int uLit = 2*(1 + nIns + nLats + i); + int uLit0 = pObjs[2*(1+nIns+i)+0]; + int uLit1 = pObjs[2*(1+nIns+i)+1]; + Aiger_WriteUnsigned( pFile, uLit - uLit1 ); + Aiger_WriteUnsigned( pFile, uLit1 - uLit0 ); + } + fprintf( pFile, "c\n" ); + fclose( pFile ); +} +void Aiger_Test( char * pFileNameIn, char * pFileNameOut ) +{ + int nObjs, nIns, nLats, nOuts, nAnds, * pObjs = Aiger_Read( pFileNameIn, &nObjs, &nIns, &nLats, &nOuts, &nAnds ); + if ( pObjs == NULL ) + return; + printf( "Read input file \"%s\".\n", pFileNameIn ); + Aiger_Write( pFileNameOut, pObjs, nObjs, nIns, nLats, nOuts, nAnds ); + printf( "Written output file \"%s\".\n", pFileNameOut ); + ABC_FREE( pObjs ); +} + +/* +int main( int argc, char ** argv ) +{ + if ( argc != 3 ) + return 0; + Aiger_Test( argv[1], argv[2] ); + return 1; +} +*/ + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 9fac6c7a8b150792b67c3daabf672137942103ee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 10 Jul 2021 10:50:33 -0700 Subject: Experiments with CEC. --- src/aig/gia/giaAiger.c | 7 ++- src/aig/gia/giaSimBase.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 3 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index fef5b6e4..593743d5 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -1513,7 +1513,7 @@ static inline void Aiger_WriteUnsigned( FILE * pFile, unsigned x ) } int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int * pnOuts, int * pnAnds ) { - int i, Temp, nTotal, nObjs, nIns, nLats, nOuts, nAnds, * pObjs; + int i, Temp, Value = 0, nTotal, nObjs, nIns, nLats, nOuts, nAnds, * pObjs; FILE * pFile = fopen( pFileName, "rb" ); if ( pFile == NULL ) { @@ -1544,7 +1544,7 @@ int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int for ( i = 0; i < nLats; i++ ) { while ( fgetc(pFile) != '\n' ); - fscanf( pFile, "%d", &Temp ); + Value += fscanf( pFile, "%d", &Temp ); pObjs[2*(nObjs-nLats+i)+0] = Temp; pObjs[2*(nObjs-nLats+i)+1] = Temp; } @@ -1552,10 +1552,11 @@ int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int for ( i = 0; i < nOuts; i++ ) { while ( fgetc(pFile) != '\n' ); - fscanf( pFile, "%d", &Temp ); + Value += fscanf( pFile, "%d", &Temp ); pObjs[2*(nObjs-nOuts-nLats+i)+0] = Temp; pObjs[2*(nObjs-nOuts-nLats+i)+1] = Temp; } + assert( Value == nLats + nOuts ); // read the binary part while ( fgetc(pFile) != '\n' ); for ( i = 0; i < nAnds; i++ ) diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 9e7033ab..18176305 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -228,6 +228,145 @@ Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManComputeTfos_rec( Gia_Man_t * p, int iObj, int iRoot, Vec_Int_t * vNode ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjIsTravIdPreviousId(p, iObj) ) + return 1; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 0; + pObj = Gia_ManObj( p, iObj ); + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( Gia_ManComputeTfos_rec( p, Gia_ObjFaninId0(pObj, iObj), iRoot, vNode ) | + Gia_ManComputeTfos_rec( p, Gia_ObjFaninId1(pObj, iObj), iRoot, vNode ) ) + { + Gia_ObjSetTravIdPreviousId(p, iObj); + Vec_IntPush( vNode, iObj ); + return 1; + } + Gia_ObjSetTravIdCurrentId(p, iObj); + return 0; +} +Vec_Wec_t * Gia_ManComputeTfos( Gia_Man_t * p ) +{ + Vec_Wec_t * vNodes = Vec_WecStart( Gia_ManCiNum(p) ); + Vec_Int_t * vTemp = Vec_IntAlloc( 100 ); + int i, o, IdCi, IdCo; + Gia_ManForEachCiId( p, IdCi, i ) + { + Vec_Int_t * vNode = Vec_WecEntry( vNodes, i ); + Gia_ManIncrementTravId( p ); + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdPreviousId(p, IdCi); + Vec_IntPush( vNode, IdCi ); + Vec_IntClear( vTemp ); + Gia_ManForEachCoId( p, IdCo, o ) + if ( Gia_ManComputeTfos_rec( p, Gia_ObjFaninId0(Gia_ManObj(p, IdCo), IdCo), IdCi, vNode ) ) + Vec_IntPush( vTemp, Gia_ManObjNum(p) + (o >> 1) ); + Vec_IntUniqify( vTemp ); + Vec_IntAppend( vNode, vTemp ); + } + Vec_IntFree( vTemp ); + Vec_WecSort( vNodes, 1 ); + //Vec_WecPrint( vNodes, 0 ); + //Gia_AigerWrite( p, "dump.aig", 0, 0, 0 ); + return vNodes; +} +int Gia_ManFindDividerVar( Gia_Man_t * p, int fVerbose ) +{ + int iVar, Target = 1 << 28; + for ( iVar = 6; iVar < Gia_ManCiNum(p); iVar++ ) + if ( (1 << (iVar-3)) * Gia_ManObjNum(p) > Target ) + break; + if ( iVar == Gia_ManCiNum(p) ) + iVar = Gia_ManCiNum(p) - 1; + if ( fVerbose ) + printf( "Split var = %d. Rounds = %d. Bytes per node = %d. Total = %.2f MB.\n", iVar, 1 << (Gia_ManCiNum(p) - iVar), 1 << (iVar-3), 1.0*(1 << (iVar-3)) * Gia_ManObjNum(p)/(1<<20) ); + return iVar; +} +int Gia_ManComparePair( Gia_Man_t * p, Vec_Wrd_t * vSims, int iOut, int nWords2 ) +{ + Gia_Obj_t * pObj0 = Gia_ManCo( p, 2*iOut+0 ); + Gia_Obj_t * pObj1 = Gia_ManCo( p, 2*iOut+1 ); + word * pSim0 = Vec_WrdEntryP( vSims, nWords2*Gia_ObjId(p, pObj0) ); + word * pSim1 = Vec_WrdEntryP( vSims, nWords2*Gia_ObjId(p, pObj1) ); + Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj0), pObj0, nWords2, vSims ); + Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj1), pObj1, nWords2, vSims ); + return Abc_TtEqual( pSim0, pSim1, nWords2 ); +} +int Gia_ManCheckSimEquiv( Gia_Man_t * p, int fVerbose ) +{ + int Status = -1; + abctime clk = Abc_Clock(); int fWarning = 0; + //int nVars2 = (Gia_ManCiNum(p) + 6)/2; + int nVars2 = Gia_ManFindDividerVar( p, fVerbose ); + int nVars3 = Gia_ManCiNum(p) - nVars2; + int nWords2 = Abc_Truth6WordNum( nVars2 ); + Vec_Wrd_t * vSims = Vec_WrdStart( nWords2 * Gia_ManObjNum(p) ); + Vec_Wec_t * vNodes = Gia_ManComputeTfos( p ); + Vec_Ptr_t * vTruths = Vec_PtrAllocTruthTables( nVars2 ); + Gia_Obj_t * pObj; Vec_Int_t * vNode; int i, m, iObj; + Vec_WecForEachLevelStop( vNodes, vNode, i, nVars2 ) + Abc_TtCopy( Vec_WrdEntryP(vSims, nWords2*Vec_IntEntry(vNode,0)), (word *)Vec_PtrEntry(vTruths, i), nWords2, 0 ); + Vec_PtrFree( vTruths ); + Gia_ManForEachAnd( p, pObj, i ) + Gia_ManSimPatSimAnd( p, i, pObj, nWords2, vSims ); + for ( i = 0; i < Gia_ManCoNum(p)/2; i++ ) + { + if ( !Gia_ManComparePair( p, vSims, i, nWords2 ) ) + { + printf( "Miter is asserted for output %d.\n", i ); + Vec_WecFree( vNodes ); + Vec_WrdFree( vSims ); + return 0; + } + } + for ( m = 0; m < (1 << nVars3); m++ ) + { + int iVar = m ? Abc_TtSuppFindFirst( m ^ (m >> 1) ^ (m-1) ^ ((m-1) >> 1) ) : 0; + vNode = Vec_WecEntry( vNodes, nVars2+iVar ); + Abc_TtNot( Vec_WrdEntryP(vSims, nWords2*Vec_IntEntry(vNode,0)), nWords2 ); + Vec_IntForEachEntryStart( vNode, iObj, i, 1 ) + { + if ( iObj < Gia_ManObjNum(p) ) + { + pObj = Gia_ManObj( p, iObj ); + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManSimPatSimAnd( p, iObj, pObj, nWords2, vSims ); + } + else if ( !Gia_ManComparePair( p, vSims, iObj - Gia_ManObjNum(p), nWords2 ) ) + { + printf( "Miter is asserted for output %d.\n", iObj - Gia_ManObjNum(p) ); + Vec_WecFree( vNodes ); + Vec_WrdFree( vSims ); + return 0; + } + } + //for ( i = 0; i < Gia_ManObjNum(p); i++ ) + // printf( "%3d : ", i), Extra_PrintHex2( stdout, (unsigned *)Vec_WrdEntryP(vSims, i), 6 ), printf( "\n" ); + if ( !fWarning && Abc_Clock() > clk + 5*CLOCKS_PER_SEC ) + printf( "The computation is expected to take about %.2f sec.\n", 5.0*(1 << nVars3)/m ), fWarning = 1; + //if ( (m & 0x3F) == 0x3F ) + if ( fVerbose && (m & 0xFF) == 0xFF ) + printf( "Finished %6d (out of %6d)...\n", m, 1 << nVars3 ); + } + Vec_WecFree( vNodes ); + Vec_WrdFree( vSims ); + return 1; +} + /**Function************************************************************* Synopsis [] -- cgit v1.2.3 From be14c397409d5d95c066444f9f19aac7c0d5de0e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 11 Jul 2021 00:04:59 -0700 Subject: Experiments with MUX decomposition. --- src/aig/gia/giaSimBase.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 18176305..ee6b1ff0 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -225,6 +225,7 @@ Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p ) Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); + Gia_ManTransferTiming( pNew, p ); return pNew; } @@ -308,7 +309,6 @@ int Gia_ManComparePair( Gia_Man_t * p, Vec_Wrd_t * vSims, int iOut, int nWords2 } int Gia_ManCheckSimEquiv( Gia_Man_t * p, int fVerbose ) { - int Status = -1; abctime clk = Abc_Clock(); int fWarning = 0; //int nVars2 = (Gia_ManCiNum(p) + 6)/2; int nVars2 = Gia_ManFindDividerVar( p, fVerbose ); -- cgit v1.2.3 From 3e67d167f5c07315f3d1bb7d8ae6c079cb451ded Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 13 Jul 2021 19:05:02 -0700 Subject: Experiments with LUT mapping for small functions. --- src/aig/gia/giaMinLut.c | 139 +++++++++++++++++++++++ src/aig/gia/giaMinLut2.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 420 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 13c9a3ce..72f3570b 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -40,6 +40,145 @@ extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Vec_WrdReadLayerText( char * pFileName, int * pnIns, int * pnOuts ) +{ + char * pThis, pLine[1000]; + Vec_Wec_t * vRes; int iLine; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return NULL; + } + vRes = Vec_WecAlloc(100); + for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ ) + { + if ( iLine == 0 ) + { + pThis = strstr( pLine, "[" ); + *pnIns = atoi( pThis+1 ) + 1; + pThis = strstr( pThis+1, "[" ); + *pnOuts = atoi( pThis+1 ) + 1; + } + else + { + Vec_Int_t * vLevel = NULL; + for ( pThis = pLine; (pThis = strstr(pThis, "M0[")); pThis++ ) + { + if ( vLevel == NULL ) + vLevel = Vec_WecPushLevel( vRes ); + Vec_IntPush( vLevel, atoi( pThis+3 ) ); + } + if ( vLevel ) + Vec_IntReverseOrder( vLevel ); + } + } + fclose( pFile ); + //Vec_WecPrint( vRes, 0 ); + return vRes; +} +int Vec_WrdReadTruthTextOne( char * pFileName, int nIns, int nOuts, word * pRes ) +{ + int i, nWords = Abc_TtWordNum( nIns ); + char * pStart, * pBuffer = Extra_FileReadContents( pFileName ); + if ( pBuffer == NULL ) + { + printf( "Cannot read file \"%s\".\n", pFileName ); + return 0; + } + pStart = pBuffer; + for ( i = 0; i < nOuts; i++ ) + { + pStart = strstr( pStart + 1, "0x" ); + if ( !Extra_ReadHex( (unsigned *)(pRes + i*nWords), pStart + 2, nWords*16 ) ) + { + printf( "Cannot read truth table %d (out of %d) in file \"%s\".\n", i, nOuts, pFileName ); + ABC_FREE( pBuffer ); + return 0; + } + } + ABC_FREE( pBuffer ); + return 1; +} +word * Vec_WrdReadTruthText( char * pFileName, int nIns, int nOuts, int nFiles ) +{ + char FileName[1000]; + int i, nWords = Abc_TtWordNum( nIns ); + word * pRes = ABC_CALLOC( word, nOuts*nFiles*nWords ); + for ( i = 0; i < nFiles; i++ ) + { + assert( strlen(pFileName) < 900 ); + strcpy( FileName, pFileName ); + sprintf( FileName + strlen(FileName) - 2, "_N%d.bench", i ); + if ( !Vec_WrdReadTruthTextOne( FileName, nIns, nOuts, pRes + i*nOuts*nWords ) ) + { + ABC_FREE( pRes ); + return NULL; + } + } + return pRes; +} +Gia_Man_t * Vec_WrdReadTest( char * pFileName ) +{ + extern int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ); + extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ); + Gia_Man_t * pPart, * pNew = NULL; Gia_Obj_t * pObj; + int i, k, nIns, nOuts, iLit; + Vec_Wec_t * vRes = Vec_WrdReadLayerText( pFileName, &nIns, &nOuts ); + int nFiles = vRes ? Vec_WecSize(vRes) : 0; + int nBitsI = vRes ? Vec_WecMaxLevelSize(vRes) : 0; + int nBitsO = vRes ? nOuts / Vec_WecSize(vRes) : 0; + word * pFuncs = vRes ? Vec_WrdReadTruthText( pFileName, nBitsI, nBitsO, Vec_WecSize(vRes) ) : NULL; + Vec_Int_t * vPart, * vLits = Vec_IntAlloc( nOuts ); + if ( vRes == NULL || pFuncs == NULL ) + { + Vec_WecFreeP( &vRes ); + Vec_IntFreeP( &vLits ); + ABC_FREE( pFuncs ); + return NULL; + } + assert( nOuts % Vec_WecSize(vRes) == 0 ); + pNew = Gia_ManStart( 10000 ); + pNew->pName = Abc_UtilStrsav( pFileName ); + pNew->pSpec = NULL; + for ( i = 0; i < nIns; i++ ) + Gia_ManAppendCi(pNew); + Gia_ManHashStart( pNew ); + Vec_WecForEachLevel( vRes, vPart, i ) + { + assert( Vec_IntSize(vPart) <= nBitsI ); + pPart = Gia_TryPermOptCare( pFuncs + i * nBitsO, nBitsI, nBitsO, Abc_TtWordNum(nBitsI), 10, 0 ); + Gia_ManFillValue( pPart ); + Gia_ManConst0(pPart)->Value = 0; + Gia_ManForEachCi( pPart, pObj, k ) + pObj->Value = Abc_Var2Lit( 1+Vec_IntEntry(vPart, k), 0 ); + Gia_ManForEachCo( pPart, pObj, k ) + { + Gia_ManPerformLNetOpt_rec( pNew, pPart, Gia_ObjFanin0(pObj) ); + Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManStop( pPart ); + } + Gia_ManHashStop( pNew ); + Vec_IntForEachEntry( vLits, iLit, i ) + Gia_ManAppendCo( pNew, iLit ); + ABC_FREE( pFuncs ); + Vec_WecFree( vRes ); + Vec_IntFree( vLits ); + return pNew; +} + /**Function************************************************************* Synopsis [] diff --git a/src/aig/gia/giaMinLut2.c b/src/aig/gia/giaMinLut2.c index 69ed6f3b..425d9718 100644 --- a/src/aig/gia/giaMinLut2.c +++ b/src/aig/gia/giaMinLut2.c @@ -504,6 +504,247 @@ word * Abc_TtMinArray( word * p, int nOuts, int nVars, int * pnNodes, int fVerbo return pResult; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Abc_TtGia6Min_rec( Gia_Man_t * p, word uF, word uR, int nVars, Vec_Wrd_t * vNodes, int * piLit, int * pPerm ) +{ + word uF0, uF1, uR0, uR1, uRes0, uRes1, uRes2; int i, Var, iLit0, iLit1; + assert( nVars <= 6 ); + assert( (uF & uR) == 0 ); + *piLit = -1; + if ( !uF && !uR ) + return TT_UNDEF; + if ( !uF && !~uR ) + { + *piLit = 0; + return 0; + } + if ( !~uF && !uR ) + { + *piLit = 1; + return ~(word)0; + } + assert( nVars > 0 ); + for ( Var = nVars-1; Var >= 0; Var-- ) + if ( Abc_Tt6HasVar( uF, Var ) || Abc_Tt6HasVar( uR, Var ) ) + break; + assert( Var >= 0 ); + if ( 1 && vNodes ) + { + int iLit; + Vec_WrdForEachEntryDouble( vNodes, uRes2, iLit, i ) + if ( !(uF & ~uRes2) && !(uRes2 & uR) ) + { + *piLit = (unsigned)iLit; + return uRes2; + } + else if ( !(uF & uRes2) && !(~uRes2 & uR) ) + { + *piLit = Abc_LitNot( (unsigned)iLit ); + return ~uRes2; + } + } + uF0 = Abc_Tt6Cofactor0( uF, Var ); + uF1 = Abc_Tt6Cofactor1( uF, Var ); + uR0 = Abc_Tt6Cofactor0( uR, Var ); + uR1 = Abc_Tt6Cofactor1( uR, Var ); + uRes0 = Abc_TtGia6Min_rec( p, uF0, uR0, Var, vNodes, &iLit0, pPerm ); + uRes1 = Abc_TtGia6Min_rec( p, uF1, uR1, Var, vNodes, &iLit1, pPerm ); + if ( uRes0 == TT_UNDEF && uRes1 == TT_UNDEF ) + return TT_UNDEF; + if ( uRes0 == TT_UNDEF ) + { + *piLit = iLit1; + return uRes1; + } + if ( uRes1 == TT_UNDEF || uRes0 == uRes1 ) + { + *piLit = iLit0; + return uRes0; + } +// if ( (uRes0 & ~uRes1) == 0 ) +// printf( "0" ); +// else if ( (~uRes0 & uRes1) == 0 ) +// printf( "1" ); +// else +// printf( "*" ); + uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]); + Var = pPerm ? pPerm[Var] : Var; + if ( !(uRes0 & ~uRes1) ) + *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 ); + else if ( !(uRes1 & ~uRes0) ) + *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 ); + else + *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 ); + assert( !(uF & ~uRes2) ); + assert( !(uRes2 & uR) ); + if ( vNodes ) + Vec_WrdPushTwo( vNodes, uRes2, (word)*piLit ); + return uRes2; +} +word * Abc_TtGiaMin_rec( Gia_Man_t * p, word * pF, word * pR, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2, int * piLit, int * pPerm ) +{ + int i, Entry, Var, iLit0, iLit1, nWords = Abc_TtWordNum(nVars); + word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords ); + *piLit = -1; + if ( nVars <= 6 ) + { + pRes2[0] = Abc_TtGia6Min_rec( p, pF[0], pR[0], nVars, vNodes, piLit, pPerm ); + return pRes2; + } + assert( !Abc_TtIntersect(pF, pR, nWords, 0) ); + if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst0(pR, nWords) ) + return NULL; + if ( Abc_TtIsConst0(pF, nWords) && Abc_TtIsConst1(pR, nWords) ) + { + *piLit = 0; + Abc_TtClear( pRes2, nWords ); + return pRes2; + } + if ( Abc_TtIsConst1(pF, nWords) && Abc_TtIsConst0(pR, nWords) ) + { + *piLit = 1; + Abc_TtFill( pRes2, nWords ); + return pRes2; + } + nWords >>= 1; + if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) && !Abc_TtHasVar( pR, nVars, nVars-1 ) ) + { + pRes0 = Abc_TtGiaMin_rec( p, pF, pR, nVars-1, vMemory, vNodes, vNodes2, piLit, pPerm ); + Abc_TtCopy( pRes2, pRes0, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 ); + return pRes2; + } + if ( 1 && vNodes2 ) + { + Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); int iLit; + Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i ) + { + word * pTemp = Vec_WrdEntryP( vMemory, Entry ); + if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) ) + { + *piLit = iLit; + return pTemp; + } + else if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) ) + { + *piLit = Abc_LitNot(iLit); + Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 ); + return pRes2; + } + } +/* + if ( nVars > 7 ) + { + vLayer = Vec_WecEntry( vNodes2, nVars-1 ); + Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i ) + { + word * pTemp = Vec_WrdEntryP( vMemory, Entry ); + if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 1) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 0) ) + { + *piLit = iLit; + return pTemp; + } + else if ( !Abc_TtIntersect(pTemp, pF, 2*nWords, 0) && !Abc_TtIntersect(pTemp, pR, 2*nWords, 1) ) + { + *piLit = Abc_LitNot(iLit); + Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 ); + return pRes2; + } + } + } +*/ + } + assert( nVars > 6 ); + pRes0 = Abc_TtGiaMin_rec( p, pF, pR, nVars-1, vMemory, vNodes, vNodes2, &iLit0, pPerm ); + pRes1 = Abc_TtGiaMin_rec( p, pF + nWords, pR + nWords, nVars-1, vMemory, vNodes, vNodes2, &iLit1, pPerm ); + if ( pRes0 == NULL && pRes1 == NULL ) + return NULL; + if ( pRes0 == NULL || pRes1 == NULL || Abc_TtEqual(pRes0, pRes1, nWords) ) + { + *piLit = pRes0 ? iLit0 : iLit1; + Abc_TtCopy( pRes2, pRes0 ? pRes0 : pRes1, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes0 ? pRes0 : pRes1, nWords, 0 ); + return pRes2; + } + Abc_TtCopy( pRes2, pRes0, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 ); + Var = pPerm ? pPerm[nVars-1] : nVars-1; + if ( !Abc_TtIntersect(pRes1, pRes0, nWords, 1) ) + *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 ); + else if ( !Abc_TtIntersect(pRes0, pRes1, nWords, 1) ) + *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 ); + else + *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 ); + assert( !Abc_TtIntersect(pRes2, pF, 2*nWords, 1) ); // assert( !(uF & ~uRes2) ); + assert( !Abc_TtIntersect(pRes2, pR, 2*nWords, 0) ); // assert( !(uRes2 & uR) ); + if ( vNodes2 ) + { + Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); + Vec_IntPushTwo( vLayer, pRes2 - Vec_WrdArray(vMemory), *piLit ); + } + return pRes2; +} +Gia_Man_t * Abc_TtGiaMinArray( word * p, int nOuts, int nVars, int * pnNodes, int fVerbose, int * pIPerm ) +{ + Gia_Man_t * pNew, * pTemp; + int o, i, iLit, nWords = Abc_TtWordNum(nVars); + word * pRes, * pResult = ABC_ALLOC( word, nOuts*nWords/2 ); + Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 ); + Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 ); + Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 ); + Vec_WrdGrow( vMemory, 1 << 20 ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "muxes" ); + for ( i = 0; i < nVars; i++ ) + Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + + for ( o = 0; o < nOuts/2; o++ ) + { + word * pF = p + (2*o+0)*nWords; + word * pR = p + (2*o+1)*nWords; + for ( i = nVars; i < 6; i++ ) + assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) ); + pRes = Abc_TtGiaMin_rec( pNew, pF, pR, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm ); + if ( pResult == NULL ) + { + Abc_TtClear( pResult + o*nWords, nWords ); + Gia_ManAppendCo( pNew, 0 ); + } + else + { + Abc_TtCopy( pResult + o*nWords, pRes, nWords, 0 ); + Gia_ManAppendCo( pNew, iLit ); + } + } + if ( fVerbose ) + printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ", + Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) ); + //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords ); + if ( pnNodes ) + *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2); + Vec_WrdFree( vMemory ); + Vec_WrdFree( vNodes ); + Vec_WecFree( vNodes2 ); + ABC_FREE( pResult ); + + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + + /**Function************************************************************* Synopsis [] @@ -652,7 +893,7 @@ Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, ABC_FREE( pTruthBest ); return pNew; } -Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ) +Gia_Man_t * Gia_TryPermOpt2( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ) { abctime clk = Abc_Clock(); Gia_Man_t * pNew; @@ -695,6 +936,45 @@ Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int ABC_FREE( pTruthBest ); return pNew; } +Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gia_Man_t * pBest = NULL; + word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 ); + int pIPermBest[TREE_MAX_VARS] = {0}; + int pIPerm[TREE_MAX_VARS] = {0}; + int r, rBest = -1, nNodes2 = -1, nNodesBest = ABC_INFINITY; + assert( nOuts % 2 == 0 ); + //srand( time(NULL) ); + Gia_ManRandom(1); + for ( r = 0; r < nRounds; r++ ) + { + int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose ); + Gia_Man_t * pTemp = Abc_TtGiaMinArray( pTruthDup, nOuts, nIns, NULL, 0, pIPerm ); + nNodes2 = Gia_ManAndNum(pTemp); + if ( nNodesBest > nNodes2 ) + { + nNodesBest = nNodes2; + memcpy( pIPermBest, pIPerm, sizeof(int)*nIns ); + rBest = r; + + Gia_ManStopP( &pBest ); + pBest = pTemp; + pTemp = NULL; + } + Gia_ManStopP( &pTemp ); + Abc_TtCopy( pTruthDup, pTruths, nOuts*nWords, 0 ); + if ( fVerbose ) + printf( "Permuted = %5d. AIG = %5d.\n", nNodesAll, nNodes2 ); + nNodesAll = 0; + } + if ( fVerbose ) + printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest ); + ABC_FREE( pTruthDup ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return pBest; +} /**Function************************************************************* -- cgit v1.2.3 From d9aeaade3b29360c65b54f6df734359b3fb452f0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 15 Jul 2021 18:23:04 -0700 Subject: Several unrelated changes. --- src/aig/gia/giaMinLut.c | 1 - src/aig/gia/giaResub2.c | 27 +++++++++---- src/aig/gia/giaSim.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 9 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 72f3570b..6b71fdef 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -136,7 +136,6 @@ Gia_Man_t * Vec_WrdReadTest( char * pFileName ) Gia_Man_t * pPart, * pNew = NULL; Gia_Obj_t * pObj; int i, k, nIns, nOuts, iLit; Vec_Wec_t * vRes = Vec_WrdReadLayerText( pFileName, &nIns, &nOuts ); - int nFiles = vRes ? Vec_WecSize(vRes) : 0; int nBitsI = vRes ? Vec_WecMaxLevelSize(vRes) : 0; int nBitsO = vRes ? nOuts / Vec_WecSize(vRes) : 0; word * pFuncs = vRes ? Vec_WrdReadTruthText( pFileName, nBitsI, nBitsO, Vec_WecSize(vRes) ) : NULL; diff --git a/src/aig/gia/giaResub2.c b/src/aig/gia/giaResub2.c index be527d4f..1219526f 100644 --- a/src/aig/gia/giaResub2.c +++ b/src/aig/gia/giaResub2.c @@ -1116,13 +1116,24 @@ int Gia_RsbFindFaninToAddToCut( Gia_Man_t * p, Vec_Int_t * vIns ) assert( nFanins < 64 ); } // find fanin with the highest count - for ( i = 0; i < nFanins; i++ ) -// if ( CountMax < pFaninCounts[i] ) - if ( CountMax < pFaninCounts[i] || (CountMax == pFaninCounts[i] && (Gia_ObjFanoutNumId(p, iFanMax) < Gia_ObjFanoutNumId(p, pFanins[i]))) ) - { - CountMax = pFaninCounts[i]; - iFanMax = pFanins[i]; - } + if ( p->vFanoutNums != NULL ) + { + for ( i = 0; i < nFanins; i++ ) + if ( CountMax < pFaninCounts[i] || (CountMax == pFaninCounts[i] && (Gia_ObjFanoutNumId(p, iFanMax) < Gia_ObjFanoutNumId(p, pFanins[i]))) ) + { + CountMax = pFaninCounts[i]; + iFanMax = pFanins[i]; + } + } + else + { + for ( i = 0; i < nFanins; i++ ) + if ( CountMax < pFaninCounts[i] || (CountMax == pFaninCounts[i] && (Gia_ObjRefNumId(p, iFanMax) < Gia_ObjRefNumId(p, pFanins[i]))) ) + { + CountMax = pFaninCounts[i]; + iFanMax = pFanins[i]; + } + } return iFanMax; } // precondition: nodes in vWin and in vIns are marked with the current ID @@ -1167,7 +1178,7 @@ void Gia_RsbWindowGrow2( Gia_Man_t * p, int iObj, Vec_Wec_t * vLevels, Vec_Int_t else assert( Vec_IntSize(vIns) > nInputsMax ); } - if ( Vec_IntSize(vIns) <= nInputsMax ) + if ( vLevels && Vec_IntSize(vIns) <= nInputsMax ) { Vec_IntSort( vIns, 0 ); Gia_WinCreateFromCut( p, iObj, vIns, vLevels, vWin ); diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c index 001bd8ac..a0a65112 100644 --- a/src/aig/gia/giaSim.c +++ b/src/aig/gia/giaSim.c @@ -1222,6 +1222,106 @@ int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimOneBit( Gia_Man_t * p, Vec_Int_t * vValues ) +{ + Gia_Obj_t * pObj; int k; + assert( Vec_IntSize(vValues) == Gia_ManCiNum(p) ); + + Gia_ManConst0(p)->fMark0 = 0; + Gia_ManForEachCi( p, pObj, k ) + pObj->fMark0 = Vec_IntEntry(vValues, k); + Gia_ManForEachAnd( p, pObj, k ) + pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); + Gia_ManForEachCo( p, pObj, k ) + pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); + + Gia_ManForEachCo( p, pObj, k ) + printf( "%d", k % 10 ); + printf( "\n" ); + + Gia_ManForEachCo( p, pObj, k ) + printf( "%d", pObj->fMark0 ); + printf( "\n" ); + printf( "\n" ); +} +void Gia_ManSimOneBitTest2( Gia_Man_t * p ) +{ + Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); + + Vec_IntWriteEntry( vValues, 0, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, 0, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, 0, 1 ); + Vec_IntWriteEntry( vValues, 1, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2+2, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, 0, 1 ); + Vec_IntWriteEntry( vValues, 1, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntFill( vValues, Vec_IntSize(vValues)/2, 1 ); + Vec_IntFillExtra( vValues, Gia_ManCiNum(p), 0 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Gia_ManCiNum(p), 0 ); + + Vec_IntFill( vValues, Gia_ManCiNum(p), 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Gia_ManCiNum(p), 0 ); + + Vec_IntFill( vValues, Gia_ManCiNum(p), 1 ); + Vec_IntWriteEntry( vValues, 127, 1 ); + Vec_IntWriteEntry( vValues, 255, 0 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Gia_ManCiNum(p), 0 ); + + Vec_IntFill( vValues, Gia_ManCiNum(p), 1 ); + Vec_IntWriteEntry( vValues, 127, 0 ); + Vec_IntWriteEntry( vValues, 255, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Gia_ManCiNum(p), 0 ); + + Vec_IntFill( vValues, Gia_ManCiNum(p), 1 ); + Vec_IntWriteEntry( vValues, 127, 0 ); + Vec_IntWriteEntry( vValues, 255, 0 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Gia_ManCiNum(p), 0 ); + + Vec_IntFree( vValues ); +} +void Gia_ManSimOneBitTest( Gia_Man_t * p ) +{ + Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); + int i, k; + for ( i = 0; i < 10; i++ ) + { + for ( k = 0; k < Vec_IntSize(vValues); k++ ) + Vec_IntWriteEntry( vValues, k, Vec_IntEntry(vValues, k) ^ (rand()&1) ); + + printf( "Values = %d ", Vec_IntSum(vValues) ); + Gia_ManSimOneBit( p, vValues ); + } +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -- cgit v1.2.3 From 6e5a797a6d7551af06c0a0ebf721161ba2b6f44d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 16 Jul 2021 13:44:38 -0700 Subject: Command to move CI/CO names. --- src/aig/gia/giaMinLut.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 6b71fdef..832d5e79 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -138,6 +138,7 @@ Gia_Man_t * Vec_WrdReadTest( char * pFileName ) Vec_Wec_t * vRes = Vec_WrdReadLayerText( pFileName, &nIns, &nOuts ); int nBitsI = vRes ? Vec_WecMaxLevelSize(vRes) : 0; int nBitsO = vRes ? nOuts / Vec_WecSize(vRes) : 0; + int nWords = Abc_TtWordNum(nBitsI); word * pFuncs = vRes ? Vec_WrdReadTruthText( pFileName, nBitsI, nBitsO, Vec_WecSize(vRes) ) : NULL; Vec_Int_t * vPart, * vLits = Vec_IntAlloc( nOuts ); if ( vRes == NULL || pFuncs == NULL ) @@ -157,7 +158,7 @@ Gia_Man_t * Vec_WrdReadTest( char * pFileName ) Vec_WecForEachLevel( vRes, vPart, i ) { assert( Vec_IntSize(vPart) <= nBitsI ); - pPart = Gia_TryPermOptCare( pFuncs + i * nBitsO, nBitsI, nBitsO, Abc_TtWordNum(nBitsI), 10, 0 ); + pPart = Gia_TryPermOptCare( pFuncs + i * nBitsO * nWords, nBitsI, nBitsO, nWords, 10, 0 ); Gia_ManFillValue( pPart ); Gia_ManConst0(pPart)->Value = 0; Gia_ManForEachCi( pPart, pObj, k ) -- cgit v1.2.3 From a162b1f47aa4d3c38439d779c7ad943102c63bc5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 25 Jul 2021 14:11:34 -0700 Subject: Experimental simulation commands. --- src/aig/gia/giaSim.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++- src/aig/gia/giaSimBase.c | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c index a0a65112..ecad182f 100644 --- a/src/aig/gia/giaSim.c +++ b/src/aig/gia/giaSim.c @@ -1246,10 +1246,16 @@ void Gia_ManSimOneBit( Gia_Man_t * p, Vec_Int_t * vValues ) Gia_ManForEachCo( p, pObj, k ) pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); - Gia_ManForEachCo( p, pObj, k ) + Gia_ManForEachCi( p, pObj, k ) printf( "%d", k % 10 ); printf( "\n" ); + Gia_ManForEachCi( p, pObj, k ) + printf( "%d", Vec_IntEntry(vValues, k) ); + printf( "\n" ); + Gia_ManForEachCo( p, pObj, k ) + printf( "%d", k % 10 ); + printf( "\n" ); Gia_ManForEachCo( p, pObj, k ) printf( "%d", pObj->fMark0 ); printf( "\n" ); @@ -1309,6 +1315,66 @@ void Gia_ManSimOneBitTest2( Gia_Man_t * p ) Vec_IntFree( vValues ); } +void Gia_ManSimOneBitTest3( Gia_Man_t * p ) +{ + Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); + + Vec_IntWriteEntry( vValues, 0, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, 0, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, 0, 1 ); + Vec_IntWriteEntry( vValues, 1, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2+2, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-3, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -3, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-3, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 ); + Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -3, 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntFill( vValues, Vec_IntSize(vValues), 1 ); + Gia_ManSimOneBit( p, vValues ); + Vec_IntFill( vValues, Vec_IntSize(vValues), 0 ); + + Vec_IntFree( vValues ); +} + + void Gia_ManSimOneBitTest( Gia_Man_t * p ) { Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index ee6b1ff0..79377310 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -2348,6 +2348,55 @@ void Gia_ManSimGen( Gia_Man_t * pGia ) fclose( pFile ); } + +/**Function************************************************************* + + Synopsis [Trying vectorized simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose ) +{ + Vec_Wrd_t * vSim0, * vSim1, * vSim2; + abctime clk = Abc_Clock(); + int n, i, RetValue = 1; + printf( "Simulating %d round with %d machine words.\n", nRounds, nWords ); + Abc_RandomW(0); + for ( n = 0; RetValue && n < nRounds; n++ ) + { + vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(p0) * nWords ); + p0->vSimsPi = vSim0; + p1->vSimsPi = vSim0; + vSim1 = Gia_ManSimPatSim( p0 ); + vSim2 = Gia_ManSimPatSim( p1 ); + for ( i = 0; i < Gia_ManCoNum(p0); i++ ) + { + word * pSim1 = Vec_WrdEntryP(vSim1, Gia_ObjId(p0, Gia_ManCo(p0, i))*nWords); + word * pSim2 = Vec_WrdEntryP(vSim2, Gia_ObjId(p1, Gia_ManCo(p1, i))*nWords); + if ( memcmp(pSim1, pSim2, sizeof(word)*nWords) ) + { + printf( "Output %d failed simulation at round %d. ", i, n ); + RetValue = 0; + break; + } + } + Vec_WrdFree( vSim1 ); + Vec_WrdFree( vSim2 ); + Vec_WrdFree( vSim0 ); + p0->vSimsPi = NULL; + p1->vSimsPi = NULL; + } + if ( RetValue == 1 ) + printf( "Simulation did not detect a bug. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From d925e4802cdbd89b1c7cee4fa1041b08cf0d32f7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Jul 2021 11:30:19 -0700 Subject: Experiments with cofactoring. --- src/aig/gia/giaUtil.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 3dcefcec..f04c0bc3 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2554,6 +2554,271 @@ int Gia_ManSumTotalOfSupportSizes2( Gia_Man_t * p ) return nResult; } +/**Function************************************************************* + + Synopsis [Compute dependency.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManComputeCofs( Gia_Man_t * p, int nVars ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; int i, m; + Gia_Obj_t * pSink = Gia_ManCo(p, 0); + Vec_Int_t * vRoots = Vec_IntAlloc( 1 ); + Vec_Int_t * vNodes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, pSink) ); + Gia_ManCollectTfi( p, vRoots, vNodes ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + for ( m = 0; m < (1 << nVars); m++ ) + { + for ( i = 0; i < nVars; i++ ) + Gia_ManCi(p, Gia_ManCiNum(p)-nVars+i)->Value = (m >> i) & 1; + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pSink) ); + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Vec_IntFree( vRoots ); + Vec_IntFree( vNodes ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Compute dependency.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManComputeCofs2( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pSink; int i, o, m; + Vec_Int_t * vSupp = Vec_IntAlloc( 1000 ); + Vec_Int_t * vAnds = Vec_IntAlloc( 1000 ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManForEachCi( p, pObj, i ) + { + pObj->Value = Gia_ManAppendCi(pNew); + assert( pObj->Value = Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 ) ); + } + Gia_ManHashAlloc( pNew ); + Gia_ManForEachRi( p, pSink, o ) + { + int Fanin = Gia_ObjFaninId0p( p, pSink ); + Vec_Int_t * vNodes = Gia_ManCollectNodesCis( p, &Fanin, 1 ); + Vec_IntClear( vSupp ); + Vec_IntClear( vAnds ); + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Vec_IntPush( Gia_ObjIsAnd(pObj) ? vAnds : vSupp, Gia_ObjId(p, pObj) ); + Vec_IntFree( vNodes ); + Vec_IntSort( vSupp, 0 ); + for ( m = 0; m < 5; m++ ) + { + Gia_ManForEachObjVec( vSupp, p, pObj, i ) + if ( i >= Vec_IntSize(vSupp)-5 ) + pObj->Value = (i == Vec_IntSize(vSupp)-5+m) ? 1 : 0; + Gia_ManForEachObjVec( vAnds, p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //if ( m == 4 ) + // Gia_ManAppendCo( pNew, 0 ); + //else + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pSink) ); + Gia_ManAppendCo( pNew, Abc_Var2Lit( Vec_IntEntry(vSupp, Vec_IntSize(vSupp)-5+m), 0 ) ); + Gia_ManForEachObjVec( vSupp, p, pObj, i ) + if ( i >= Vec_IntSize(vSupp)-5 ) + pObj->Value = Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 ); + } + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Vec_IntFree( vSupp ); + Vec_IntFree( vAnds ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Compute dependency.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManComputeDepAig( Gia_Man_t * p, int iIn, int iOut ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; int i, n, iLits[2]; + Gia_Obj_t * pPivot = Gia_ManCi(p, iIn); + Gia_Obj_t * pSink = Gia_ManCo(p, iOut); + Vec_Int_t * vRoots = Vec_IntAlloc( 1 ); + Vec_Int_t * vNodes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, pSink) ); + Gia_ManCollectTfi( p, vRoots, vNodes ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + for ( n = 0; n < 2; n++ ) + { + pPivot->Value = n; + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + iLits[n] = Gia_ObjFanin0Copy(pSink); + } + Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, iLits[1], Abc_LitNot(iLits[0])) ); + Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, iLits[0], Abc_LitNot(iLits[1])) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Vec_IntFree( vRoots ); + Vec_IntFree( vNodes ); + return pNew; +} +int Gia_ManComputeDep( Gia_Man_t * p, int iIn, int iOut ) +{ + extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); + Gia_Man_t * pNew = Gia_ManComputeDepAig( p, iIn, iOut ); + Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pNew, 100000, 0 ); + int iLit[2] = { Gia_ObjFaninId0p( pSwp, Gia_ManCo(pSwp, 0) ), Gia_ObjFaninId0p( pSwp, Gia_ManCo(pSwp, 1) ) }; + Gia_ManStop( pNew ); + Gia_ManStop( pSwp ); + if ( iLit[0] == 0 && iLit[1] == 0 ) + return 2; + if ( iLit[1] == 0 ) + return 1; + if ( iLit[0] == 0 ) + return 0; + return -1; +} +Gia_Man_t * Gia_ManComputeDepTest( Gia_Man_t * p ) +{ + abctime clk = Abc_Clock(); + int i; + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + printf( "%3d : %3d\n", i, Gia_ManComputeDep(p, i, 0) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return Gia_ManDup(p); +} + +/**Function************************************************************* + + Synopsis [Compute support diffs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Gia_ManComputeSupports( Gia_Man_t * p ) +{ + Vec_Wec_t * vRes = Vec_WecStart( Gia_ManCoNum(p) ); + Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj; int i; + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + Vec_IntPush( Vec_WecEntry(vSupps, 1+i), i ); + Gia_ManForEachAnd( p, pObj, i ) + Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, i)), Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, i)), Vec_WecEntry(vSupps, i) ); + Gia_ManForEachCo( p, pObj, i ) + Vec_IntAppend( Vec_WecEntry(vRes, i), Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) ); + Vec_WecFree( vSupps ); + return vRes; +} +Vec_Wec_t * Gia_ManComputeSharing( Vec_Wec_t * vSupps ) +{ + Vec_Wec_t * vDiffs = Vec_WecStart( Vec_WecSize(vSupps) ); + Vec_Int_t * vNew, * vOld; int i; + Vec_WecForEachLevelTwo( vDiffs, vSupps, vNew, vOld, i ) if ( i ) + Vec_IntTwoFindCommon( Vec_WecEntry(vSupps, i-1), vOld, vNew ); + return vDiffs; +} +Vec_Str_t * Gia_ManConvertDump( Gia_Man_t * p, Vec_Wec_t * vSupps ) +{ + int fPrintDep = 1; + int nSize = Gia_ManCoNum(p) * (Gia_ManCiNum(p) + 1) + 1; + Vec_Str_t * vRes = Vec_StrAlloc( nSize ); + Vec_Int_t * vLevel; int i, k, Obj; + assert( Gia_ManCoNum(p) == Vec_WecSize(vSupps) ); + Vec_StrFill( vRes, nSize-1, '_' ); + Vec_StrPush( vRes, '\0' ); + Vec_WecForEachLevel( vSupps, vLevel, i ) + { + Vec_IntForEachEntry( vLevel, Obj, k ) + { + if ( !fPrintDep ) + Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, '*' ); + else + { + int Value = Gia_ManComputeDep( p, Obj, i ); + if ( Value == -1 ) + Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, '*' ); + else + Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Obj, (char)('0'+Value) ); + } + } + Vec_StrWriteEntry( vRes, i * (Gia_ManCiNum(p) + 1) + Gia_ManCiNum(p), '\n' ); + //printf( "Output %d\n", i ); + } + return vRes; +} +void Gia_ManDumpSuppFile( Vec_Str_t * p, char * pFileName ) +{ + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + else + { + int nOuts = Vec_StrCountEntry(p, '\n'); + int nIns = Vec_StrSize(p)/Vec_StrCountEntry(p, '\n') - 1; + int nSize1 = Vec_StrSize(p) - 1; + int nSize2 = fwrite( Vec_StrArray(p), 1, nSize1, pFile ); + assert( nSize1 == nSize2 ); + printf( "Successfully dumped file \"%s\" with support data for %d outputs and %d inputs.\n", pFileName, nOuts, nIns ); + } + fclose( pFile ); +} +void Gia_ManDumpSuppFileTest3( Gia_Man_t * p, char * pFileName ) +{ + Vec_Wec_t * vSupps = Gia_ManComputeSupports( p ); + Vec_Wec_t * vDiffs = Gia_ManComputeSharing( vSupps ); + Vec_Wec_t * vDiffs2 = Gia_ManComputeSharing( vDiffs ); + Vec_Str_t * vRes = Gia_ManConvertDump( p, vDiffs2 ); + Gia_ManDumpSuppFile( vRes, pFileName ); + Vec_WecFree( vDiffs2 ); + Vec_WecFree( vDiffs ); + Vec_WecFree( vSupps ); + Vec_StrFree( vRes ); +} +void Gia_ManDumpSuppFileTest( Gia_Man_t * p, char * pFileName ) +{ + Vec_Wec_t * vSupps = Gia_ManComputeSupports( p ); + Vec_Str_t * vRes = Gia_ManConvertDump( p, vSupps ); + Gia_ManDumpSuppFile( vRes, pFileName ); + Vec_WecFree( vSupps ); + Vec_StrFree( vRes ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 4cf906d2fc64f5f27fd1f01580b89a60c4ee7e61 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Aug 2021 12:13:27 -0700 Subject: Experiments with LUT mapping for small functions. --- src/aig/gia/giaMinLut.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++- src/aig/gia/giaMinLut2.c | 91 ++++++++++++++++++++++++++++++++-- 2 files changed, 211 insertions(+), 6 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 832d5e79..80d4476e 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -566,6 +566,44 @@ word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp *pCare = nGood; return pRes; } +void Gia_ManPermuteSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vLevels, Vec_Int_t * vCounts ) +{ + Gia_Obj_t * pObj; int n; + if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vLevels, vCounts ); + Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vLevels, vCounts ); + for ( n = 0; n < 2; n++ ) + { + Gia_Obj_t * pFanin = n ? Gia_ObjFanin1(pObj) : Gia_ObjFanin0(pObj); + if ( !Gia_ObjIsCi(pFanin) ) + continue; + Vec_IntAddToEntry( vLevels, Gia_ObjCioId(pFanin), Gia_ObjLevel(p, pObj) ); + Vec_IntAddToEntry( vCounts, Gia_ObjCioId(pFanin), 1 ); + } +} +void Gia_ManPermuteSupp( Gia_Man_t * p, int iOut, int nOuts, Vec_Int_t * vSupp ) +{ + Vec_Int_t * vLevels = Vec_IntStart( Gia_ManCiNum(p) ); + Vec_Int_t * vCounts = Vec_IntStart( Gia_ManCiNum(p) ); + int i, * pCost = ABC_CALLOC( int, Gia_ManCiNum(p) ); + Gia_Obj_t * pObj; + Gia_ManIncrementTravId( p ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vLevels, vCounts ); + Gia_ManForEachObjVec( vSupp, p, pObj, i ) + pCost[i] = 10000 * Vec_IntEntry(vLevels, Gia_ObjCioId(pObj)) / Vec_IntEntry(vCounts, Gia_ObjCioId(pObj)); + Vec_IntFree( vCounts ); + Vec_IntFree( vLevels ); + Vec_IntSelectSortCost2( Vec_IntArray(vSupp), Vec_IntSize(vSupp), pCost ); + assert( Vec_IntSize(vSupp) < 2 || pCost[0] <= pCost[1] ); + ABC_FREE( pCost ); +} void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp ) { Gia_Obj_t * pObj; @@ -591,6 +629,12 @@ Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts ) Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp ); return vSupp; } +Vec_Int_t * Gia_ManCollectSuppNew( Gia_Man_t * p, int iOut, int nOuts ) +{ + Vec_Int_t * vRes = Gia_ManCollectSupp( p, iOut, nOuts ); + Gia_ManPermuteSupp( p, iOut, nOuts, vRes ); + return vRes; +} int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( ~pObj->Value ) @@ -602,7 +646,6 @@ int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj } Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose ) { - extern int Gia_ManDupOrderDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ); extern Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ); extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ); extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); @@ -620,6 +663,7 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); printf( "Using patterns with count %d and higher as cares.\n", Thresh ); } + Gia_ManLevelNum( p ); Gia_ManFillValue( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); @@ -631,7 +675,7 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, Gia_ManHashStart( pNew ); for ( g = 0; g < Gia_ManCoNum(p); g += nOuts ) { - Vec_Int_t * vSupp = Gia_ManCollectSupp( p, g, nOuts ); + Vec_Int_t * vSupp = Gia_ManCollectSuppNew( p, g, nOuts ); int Care = 1 << Vec_IntSize(vSupp), Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0; word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) ); int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) ); @@ -706,6 +750,84 @@ Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, ABC_FREE( pTruthsTry ); return pNew; } +Gia_Man_t * Gia_ManPerformLNetOptNew( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose ) +{ + extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ); + abctime clk = Abc_Clock(); + Gia_Man_t * pNew, * pMin; Gia_Obj_t * pObj; + Vec_Int_t * vLeaves = Vec_IntAlloc( nIns ); + Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL; + word * pTruthsTry = ABC_CALLOC( word, (nOuts+1)*Abc_Truth6WordNum(nIns) ); + int k, g; float CareAve = 0; + if ( vSimI && fVerbose ) + { + //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p); + printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) ); + printf( "Using patterns with count %d and higher as cares.\n", Thresh ); + } + Gia_ManLevelNum( p ); + Gia_ManFillValue( p ); + 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, k ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ObjComputeTruthTableStart( p, nIns ); + Gia_ManHashStart( pNew ); + for ( g = 0; g < Gia_ManCoNum(p); g += nOuts ) + { + Vec_Int_t * vSupp = Gia_ManCollectSuppNew( p, g, nOuts ); + int Care = 1 << Vec_IntSize(vSupp), Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0; + word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) ); + int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) ); + CareAve += 100.0*Care/(1 << Vec_IntSize(vSupp)); + assert( Vec_IntSize(vSupp) <= nIns ); + Vec_IntClear( vLeaves ); + Gia_ManForEachObjVec( vSupp, p, pObj, k ) + Vec_IntPush( vLeaves, pObj->Value ); + for ( k = 0; k < nOuts; k++ ) + { + Gia_Obj_t * pObj = Gia_ManCo( p, g+k ); + word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp ); + Abc_TtCopy( pTruthsTry + k*nWords, pTruth, nWords, Gia_ObjFaninC0(pObj) ); + } + Abc_TtCopy( pTruthsTry + nOuts*nWords, pCare, nWords, 0 ); + ABC_FREE( pCare ); + pMin = Gia_TryPermOptNew( pTruthsTry, Vec_IntSize(vSupp), nOuts, nWords, nRounds, fVerbose ); + Gia_ManFillValue( pMin ); + Gia_ManConst0(pMin)->Value = 0; + Gia_ManForEachCi( pMin, pObj, k ) + pObj->Value = Vec_IntEntry( vLeaves, k ); + Gia_ManForEachCo( pMin, pObj, k ) + { + Gia_Obj_t * pObj0 = Gia_ManCo( p, g+k ); + pObj0->Value = Gia_ManPerformLNetOpt_rec( pNew, pMin, Gia_ObjFanin0(pObj) ); + pObj0->Value ^= Gia_ObjFaninC0(pObj); + } + Gia_ManStop( pMin ); + Vec_IntFree( vSupp ); + Temp = 0; + } + CareAve /= Gia_ManCoNum(p)/nOuts; + Gia_ManHashStop( pNew ); + Gia_ManForEachCo( p, pObj, k ) + pObj->Value = Gia_ManAppendCo( pNew, pObj->Value ); + Gia_ObjComputeTruthTableStop( p ); + Vec_IntFree( vLeaves ); + Vec_WrdFreeP( &vSimI ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + printf( "Using patterns with count %d and higher as cares. Average care set is %8.4f %%. ", Thresh, CareAve ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( 0 ) + { + FILE * pTable = fopen( "stats.txt", "a+" ); + fprintf( pTable, "%0.2f ", CareAve ); + fclose( pTable ); + } + ABC_FREE( pTruthsTry ); + return pNew; +} #ifdef ABC_USE_CUDD diff --git a/src/aig/gia/giaMinLut2.c b/src/aig/gia/giaMinLut2.c index 425d9718..26310d34 100644 --- a/src/aig/gia/giaMinLut2.c +++ b/src/aig/gia/giaMinLut2.c @@ -520,7 +520,7 @@ static inline word Abc_TtGia6Min_rec( Gia_Man_t * p, word uF, word uR, int nVars word uF0, uF1, uR0, uR1, uRes0, uRes1, uRes2; int i, Var, iLit0, iLit1; assert( nVars <= 6 ); assert( (uF & uR) == 0 ); - *piLit = -1; + *piLit = 0; if ( !uF && !uR ) return TT_UNDEF; if ( !uF && !~uR ) @@ -595,7 +595,7 @@ word * Abc_TtGiaMin_rec( Gia_Man_t * p, word * pF, word * pR, int nVars, Vec_Wrd { int i, Entry, Var, iLit0, iLit1, nWords = Abc_TtWordNum(nVars); word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords ); - *piLit = -1; + *piLit = 0; if ( nVars <= 6 ) { pRes2[0] = Abc_TtGia6Min_rec( p, pF[0], pR[0], nVars, vNodes, piLit, pPerm ); @@ -694,7 +694,7 @@ word * Abc_TtGiaMin_rec( Gia_Man_t * p, word * pF, word * pR, int nVars, Vec_Wrd } return pRes2; } -Gia_Man_t * Abc_TtGiaMinArray( word * p, int nOuts, int nVars, int * pnNodes, int fVerbose, int * pIPerm ) +Gia_Man_t * Abc_TtGiaMinArray( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm ) { Gia_Man_t * pNew, * pTemp; int o, i, iLit, nWords = Abc_TtWordNum(nVars); @@ -743,6 +743,50 @@ Gia_Man_t * Abc_TtGiaMinArray( word * p, int nOuts, int nVars, int * pnNodes, in Gia_ManStop( pTemp ); return pNew; } +Gia_Man_t * Abc_TtGiaMinArrayNew( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm ) +{ + Gia_Man_t * pNew, * pTemp; + int o, i, iLit, nWords = Abc_TtWordNum(nVars); + word * pF = ABC_ALLOC( word, nWords ); + word * pR = ABC_ALLOC( word, nWords ); + Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 ); + Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 ); + Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 ); + Vec_WrdGrow( vMemory, 1 << 20 ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "muxes" ); + for ( i = 0; i < nVars; i++ ) + Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + + for ( o = 0; o < nOuts; o++ ) + { + word * pCare = p + nOuts*nWords; + word * pTruth = p + o*nWords; + Abc_TtAnd( pF, pCare, pTruth, nWords, 0 ); + Abc_TtSharp( pR, pCare, pTruth, nWords ); + for ( i = nVars; i < 6; i++ ) + assert( !Abc_Tt6HasVar(pF[0], i) && !Abc_Tt6HasVar(pR[0], i) ); + Abc_TtGiaMin_rec( pNew, pF, pR, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm ); + Gia_ManAppendCo( pNew, iLit ); + } + if ( fVerbose ) + printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ", + Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) ); + //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords ); + if ( pnNodes ) + *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2); + Vec_WrdFree( vMemory ); + Vec_WrdFree( vNodes ); + Vec_WecFree( vNodes2 ); + ABC_FREE( pF ); + ABC_FREE( pR ); + + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} /**Function************************************************************* @@ -950,7 +994,7 @@ Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int for ( r = 0; r < nRounds; r++ ) { int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose ); - Gia_Man_t * pTemp = Abc_TtGiaMinArray( pTruthDup, nOuts, nIns, NULL, 0, pIPerm ); + Gia_Man_t * pTemp = Abc_TtGiaMinArray( pTruthDup, nIns, nOuts, NULL, 0, pIPerm ); nNodes2 = Gia_ManAndNum(pTemp); if ( nNodesBest > nNodes2 ) { @@ -975,6 +1019,45 @@ Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return pBest; } +Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gia_Man_t * pTemp, * pBest = NULL; + word * pTruthDup = Abc_TtDup( pTruths, (nOuts+1)*nWords, 0 ); + int pIPermBest[TREE_MAX_VARS] = {0}; + int pIPerm[TREE_MAX_VARS] = {0}; + int r, rBest = -1, nNodes2 = -1, nNodesBest = ABC_INFINITY; + //srand( time(NULL) ); + Gia_ManRandom(1); + for ( r = 0; r < nRounds; r++ ) + { + int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose ); + Abc_TtPermute( pTruthDup + nOuts*nWords, pIPerm, nIns ); + pTemp = Abc_TtGiaMinArrayNew( pTruthDup, nIns, nOuts, NULL, 0, pIPerm ); + nNodes2 = Gia_ManAndNum(pTemp); + if ( nNodesBest > nNodes2 ) + { + nNodesBest = nNodes2; + memcpy( pIPermBest, pIPerm, sizeof(int)*nIns ); + rBest = r; + + Gia_ManStopP( &pBest ); + pBest = pTemp; + pTemp = NULL; + } + Gia_ManStopP( &pTemp ); + Abc_TtCopy( pTruthDup, pTruths, (nOuts+1)*nWords, 0 ); + if ( fVerbose ) + printf( "Permuted = %5d. AIG = %5d.\n", nNodesAll, nNodes2 ); + nNodesAll = 0; + } + if ( fVerbose ) + printf( "Best round %3d. Best nodes %5d. ", rBest, nNodesBest ); + ABC_FREE( pTruthDup ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return pBest; +} /**Function************************************************************* -- cgit v1.2.3 From 5f8d4e72d1d99539d100ca5c190c56c5901976e6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Aug 2021 16:46:56 -0700 Subject: Experiments with LUT mapping for small functions. --- src/aig/gia/giaMinLut.c | 2 +- src/aig/gia/giaMinLut2.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 217 insertions(+), 4 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 80d4476e..957ee2c0 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -158,7 +158,7 @@ Gia_Man_t * Vec_WrdReadTest( char * pFileName ) Vec_WecForEachLevel( vRes, vPart, i ) { assert( Vec_IntSize(vPart) <= nBitsI ); - pPart = Gia_TryPermOptCare( pFuncs + i * nBitsO * nWords, nBitsI, nBitsO, nWords, 10, 0 ); + pPart = Gia_TryPermOptCare( pFuncs + i * nBitsO * nWords, nBitsI, nBitsO, nWords, 20, 0 ); Gia_ManFillValue( pPart ); Gia_ManConst0(pPart)->Value = 0; Gia_ManForEachCi( pPart, pObj, k ) diff --git a/src/aig/gia/giaMinLut2.c b/src/aig/gia/giaMinLut2.c index 26310d34..277ce949 100644 --- a/src/aig/gia/giaMinLut2.c +++ b/src/aig/gia/giaMinLut2.c @@ -504,6 +504,209 @@ word * Abc_TtMinArray( word * p, int nOuts, int nVars, int * pnNodes, int fVerbo return pResult; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Abc_TtSimple6Min_rec( Gia_Man_t * p, word uF, word uC, int nVars, Vec_Wrd_t * vNodes, int * piLit, int * pPerm ) +{ + word uF0, uF1, uC0, uC1, uRes0, uRes1, uRes2; int i, Var, iLit0, iLit1; + word uFC = uF & uC; + word uRC = ~uF & uC; + assert( nVars <= 6 ); + *piLit = 0; + if ( !uFC ) + { + *piLit = 0; + return 0; + } + if ( !uRC ) + { + *piLit = 1; + return ~(word)0; + } + assert( nVars > 0 ); + if ( 1 && vNodes ) + { + int iLit; + int s = 0; + Vec_WrdForEachEntryDouble( vNodes, uRes2, iLit, i ) + if ( !((uF ^ uRes2) & uC) ) + { + *piLit = (unsigned)iLit; + return uRes2; + } + else if ( !((uF ^ ~uRes2) & uC) ) + { + *piLit = Abc_LitNot( (unsigned)iLit ); + return ~uRes2; + } + } + for ( Var = nVars-1; Var >= 0; Var-- ) + if ( Abc_Tt6HasVar( uF, Var ) ) + break; + else + uC = Abc_Tt6Cofactor0(uC, Var) | Abc_Tt6Cofactor1(uC, Var); + assert( Var >= 0 ); + uF0 = Abc_Tt6Cofactor0( uF, Var ); + uF1 = Abc_Tt6Cofactor1( uF, Var ); + uC0 = Abc_Tt6Cofactor0( uC, Var ); + uC1 = Abc_Tt6Cofactor1( uC, Var ); + uRes0 = Abc_TtSimple6Min_rec( p, uF0, uC0, Var, vNodes, &iLit0, pPerm ); + uRes1 = Abc_TtSimple6Min_rec( p, uF1, uC1, Var, vNodes, &iLit1, pPerm ); + if ( uRes0 == uRes1 ) + { + *piLit = iLit0; + return uRes0; + } + uRes2 = (uRes0 & s_Truths6Neg[Var]) | (uRes1 & s_Truths6[Var]); + Var = pPerm ? pPerm[Var] : Var; + //if ( !(uRes0 & ~uRes1 & uC1) ) + if ( !(uRes0 & ~uRes1) ) + *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 ); + //else if ( !(uRes1 & ~uRes0 & uC0) ) + else if ( !(uRes1 & ~uRes0) ) + *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 ); + else + *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 ); + assert( !(uFC & ~uRes2) ); + assert( !(uRes2 & uRC) ); + if ( vNodes ) + Vec_WrdPushTwo( vNodes, uRes2, (word)*piLit ); + return uRes2; +} +word * Abc_TtSimpleMin_rec( Gia_Man_t * p, word * pF, word * pC, int nVars, Vec_Wrd_t * vMemory, Vec_Wrd_t * vNodes, Vec_Wec_t * vNodes2, int * piLit, int * pPerm ) +{ + int i, Entry, Var, iLit0, iLit1, nWords = Abc_TtWordNum(nVars); + word * pRes0, * pRes1, * pRes2 = Vec_WrdFetch( vMemory, nWords ); + *piLit = 0; + if ( nVars <= 6 ) + { + pRes2[0] = Abc_TtSimple6Min_rec( p, pF[0], pC[0], nVars, vNodes, piLit, pPerm ); + return pRes2; + } + if ( !Abc_TtIntersect(pF, pC, nWords, 0) ) + { + *piLit = 0; + Abc_TtClear( pRes2, nWords ); + return pRes2; + } + if ( !Abc_TtIntersect(pF, pC, nWords, 1) ) + { + *piLit = 1; + Abc_TtFill( pRes2, nWords ); + return pRes2; + } + nWords >>= 1; + if ( !Abc_TtHasVar( pF, nVars, nVars-1 ) ) + { + word * pCn = Vec_WrdFetch( vMemory, nWords ); + Abc_TtOr( pCn, pC, pC + nWords, nWords ); + pRes0 = Abc_TtSimpleMin_rec( p, pF, pCn, nVars-1, vMemory, vNodes, vNodes2, piLit, pPerm ); + Abc_TtCopy( pRes2, pRes0, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 ); + return pRes2; + } + if ( 1 && vNodes2 ) + { + Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); int iLit; + Vec_IntForEachEntryDouble( vLayer, Entry, iLit, i ) + { + word * pTemp = Vec_WrdEntryP( vMemory, Entry ); + if ( Abc_TtEqualCare(pTemp, pF, pC, 0, 2*nWords) ) + { + *piLit = iLit; + return pTemp; + } + else if ( Abc_TtEqualCare(pTemp, pF, pC, 1, 2*nWords) ) + { + *piLit = Abc_LitNot(iLit); + Abc_TtCopy( pRes2, pTemp, 2*nWords, 1 ); + return pRes2; + } + } + } + assert( nVars > 6 ); + pRes0 = Abc_TtSimpleMin_rec( p, pF, pC, nVars-1, vMemory, vNodes, vNodes2, &iLit0, pPerm ); + pRes1 = Abc_TtSimpleMin_rec( p, pF + nWords, pC + nWords, nVars-1, vMemory, vNodes, vNodes2, &iLit1, pPerm ); + if ( Abc_TtEqual(pRes0, pRes1, nWords) ) + { + *piLit = iLit0; + Abc_TtCopy( pRes2, pRes0, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes0, nWords, 0 ); + return pRes2; + } + Abc_TtCopy( pRes2, pRes0, nWords, 0 ); + Abc_TtCopy( pRes2 + nWords, pRes1, nWords, 0 ); + Var = pPerm ? pPerm[nVars-1] : nVars-1; + //if ( !Abc_TtIntersectCare(pRes1, pRes0, pC + nWords, nWords, 1) ) + if ( !Abc_TtIntersect(pRes1, pRes0, nWords, 1) ) + *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 0), iLit1), iLit0 ); + //else if ( !Abc_TtIntersectCare(pRes0, pRes1, pC, nWords, 1) ) + else if ( !Abc_TtIntersect(pRes0, pRes1, nWords, 1) ) + *piLit = Gia_ManHashOr( p, Gia_ManHashAnd(p, Abc_Var2Lit(1+Var, 1), iLit0), iLit1 ); + else + *piLit = Gia_ManHashMux( p, Abc_Var2Lit(1+Var, 0), iLit1, iLit0 ); + assert( Abc_TtEqualCare(pRes2, pF, pC, 0, 2*nWords) ); + if ( vNodes2 ) + { + Vec_Int_t * vLayer = Vec_WecEntry( vNodes2, nVars ); + Vec_IntPushTwo( vLayer, pRes2 - Vec_WrdArray(vMemory), *piLit ); + } + return pRes2; +} +Gia_Man_t * Abc_TtSimpleMinArrayNew( word * p, int nVars, int nOuts, int * pnNodes, int fVerbose, int * pIPerm ) +{ + Gia_Man_t * pNew, * pTemp; + int o, i, iLit, nWords = Abc_TtWordNum(nVars); + word * pF = ABC_ALLOC( word, nWords ); + word * pR = ABC_ALLOC( word, nWords ); + Vec_Wrd_t * vMemory = Vec_WrdAlloc( 100 ); + Vec_Wrd_t * vNodes = Vec_WrdAlloc( 100 ); + Vec_Wec_t * vNodes2 = Vec_WecStart( nVars+1 ); + Vec_WrdGrow( vMemory, 1 << 20 ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "muxes" ); + for ( i = 0; i < nVars; i++ ) + Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + + for ( o = 0; o < nOuts; o++ ) + { + word * pCare = p + nOuts*nWords; + word * pTruth = p + o*nWords; + for ( i = nVars; i < 6; i++ ) + assert( !Abc_Tt6HasVar(pTruth[0], i) && !Abc_Tt6HasVar(pCare[0], i) ); + Abc_TtSimpleMin_rec( pNew, pTruth, pCare, nVars, vMemory, vNodes, vNodes2, &iLit, pIPerm ); + Gia_ManAppendCo( pNew, iLit ); + } + if ( fVerbose ) + printf( "Nodes = %5d. Nodes2 = %5d. Total = %5d. ", + Vec_WrdSize(vNodes), Vec_WecSizeSize(vNodes2), Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2) ); + //printf( "Memory %d (Truth table %d)\n", Vec_WrdSize(vMemory), nWords ); + if ( pnNodes ) + *pnNodes = Vec_WrdSize(vNodes) + Vec_WecSizeSize(vNodes2); + Vec_WrdFree( vMemory ); + Vec_WrdFree( vNodes ); + Vec_WecFree( vNodes2 ); + ABC_FREE( pF ); + ABC_FREE( pR ); + + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + + + /**Function************************************************************* Synopsis [] @@ -906,7 +1109,7 @@ Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, abctime clk = Abc_Clock(); Gia_Man_t * pNew; word * pTruthDup = Abc_TtDup( pTruths, nOuts*nWords, 0 ); - word * pTruthBest = ABC_ALLOC( word, nOuts*nWords ); + word * pTruthBest = ABC_FALLOC( word, (nOuts+1)*nWords ); int pIPermBest[TREE_MAX_VARS] = {0}; int pIPerm[TREE_MAX_VARS] = {0}; int r, rBest = -1, nNodes = -1, nNodesBest = ABC_INFINITY; @@ -932,7 +1135,8 @@ Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, ABC_FREE( pTruthDup ); if ( fVerbose ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); - pNew = Gia_ManCreateMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest ); + //pNew = Gia_ManCreateMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest ); + pNew = Abc_TtSimpleMinArrayNew( pTruthBest, nIns, nOuts, NULL, 0, pIPermBest ); //Gia_ManDumpMuxGia( pTruthBest, nIns, nOuts, nWords, pIPermBest, "tt_end.aig" ); ABC_FREE( pTruthBest ); return pNew; @@ -1033,7 +1237,8 @@ Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, { int nNodesAll = Gia_ManPermuteTreeOne( pTruthDup, nIns, nOuts, nWords, r>0, pIPerm, 0, fVerbose ); Abc_TtPermute( pTruthDup + nOuts*nWords, pIPerm, nIns ); - pTemp = Abc_TtGiaMinArrayNew( pTruthDup, nIns, nOuts, NULL, 0, pIPerm ); + //pTemp = Abc_TtGiaMinArrayNew( pTruthDup, nIns, nOuts, NULL, 0, pIPerm ); + pTemp = Abc_TtSimpleMinArrayNew( pTruthDup, nIns, nOuts, NULL, 0, pIPerm ); nNodes2 = Gia_ManAndNum(pTemp); if ( nNodesBest > nNodes2 ) { @@ -1046,6 +1251,14 @@ Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, pTemp = NULL; } Gia_ManStopP( &pTemp ); +/* + for ( i = 0; i <= nOuts; i++ ) + { + Abc_TtUnpermute( pTruthDup + i*nWords, pIPerm, nIns ); + if ( !Abc_TtEqual(pTruthDup + i*nWords, pTruths + i*nWords, nWords) ) + printf( "Verification failed for output %d (out of %d).\n", i, nOuts ); + } +*/ Abc_TtCopy( pTruthDup, pTruths, (nOuts+1)*nWords, 0 ); if ( fVerbose ) printf( "Permuted = %5d. AIG = %5d.\n", nNodesAll, nNodes2 ); -- cgit v1.2.3 From dd87461ac9c0876c4b8f085e973db5449e379b73 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Aug 2021 16:48:52 -0700 Subject: Experiments with LUT mapping for small functions. --- src/aig/gia/giaMinLut2.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut2.c b/src/aig/gia/giaMinLut2.c index 277ce949..85cae0d2 100644 --- a/src/aig/gia/giaMinLut2.c +++ b/src/aig/gia/giaMinLut2.c @@ -536,7 +536,6 @@ static inline word Abc_TtSimple6Min_rec( Gia_Man_t * p, word uF, word uC, int nV if ( 1 && vNodes ) { int iLit; - int s = 0; Vec_WrdForEachEntryDouble( vNodes, uRes2, iLit, i ) if ( !((uF ^ uRes2) & uC) ) { -- cgit v1.2.3 From ab29dad7f4cfc1163e9004bc5b71320f50130acc Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 5 Aug 2021 11:07:16 -0700 Subject: Adding node ordering options to command &dfs. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaDup.c | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 7 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 1fa7e368..3517502d 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1279,7 +1279,7 @@ extern void Gia_ManDupRemapLiterals( Vec_Int_t * vLits, Gia_Man_t extern void Gia_ManDupRemapEquiv( Gia_Man_t * pNew, Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p ); -extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p, int fRevFans, int fRevOuts ); extern Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop ); extern Gia_Man_t * Gia_ManDupOutputVec( Gia_Man_t * p, Vec_Int_t * vOutPres ); extern Gia_Man_t * Gia_ManDupSelectedOutputs( Gia_Man_t * p, Vec_Int_t * vOutsLeft ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 0f200bfc..326bbedb 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -466,7 +466,16 @@ Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ) +int Gia_ManDupOrderDfs2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin1(pObj) ); + Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) ); + return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p, int fRevFans, int fRevOuts ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; @@ -476,12 +485,28 @@ Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p ) pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManConst0(p)->Value = 0; - Gia_ManForEachCoReverse( p, pObj, i ) - Gia_ManDupOrderDfs_rec( pNew, p, pObj ); Gia_ManForEachCi( p, pObj, i ) - if ( !~pObj->Value ) - pObj->Value = Gia_ManAppendCi(pNew); - assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); + pObj->Value = Gia_ManAppendCi(pNew); + if ( fRevOuts ) + { + if ( fRevFans ) + Gia_ManForEachCoReverse( p, pObj, i ) + Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) ); + else + Gia_ManForEachCoReverse( p, pObj, i ) + Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); + } + else + { + if ( fRevFans ) + Gia_ManForEachCo( p, pObj, i ) + Gia_ManDupOrderDfs2_rec( pNew, p, Gia_ObjFanin0(pObj) ); + else + Gia_ManForEachCo( p, pObj, i ) + Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); + } + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManDupRemapCis( pNew, p ); Gia_ManDupRemapCos( pNew, p ); Gia_ManDupRemapEquiv( pNew, p ); -- cgit v1.2.3 From ddc574a95406d2f86b82d4fcdfd2e66b216eaf0a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 5 Aug 2021 14:01:55 -0700 Subject: Supporting simple operators in NDR. --- src/aig/miniaig/abcOper.h | 20 ++++++++++++++++++++ src/aig/miniaig/ndr.h | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 9 deletions(-) (limited to 'src/aig') diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h index 2fd7ab24..881810fd 100644 --- a/src/aig/miniaig/abcOper.h +++ b/src/aig/miniaig/abcOper.h @@ -232,6 +232,26 @@ static inline const char * Abc_OperName( int Type ) return NULL; } +// printing operator types +static inline const char * Abc_OperNameSimple( int Type ) +{ + if ( Type == ABC_OPER_NONE ) return NULL; + if ( Type == ABC_OPER_CONST_F ) return "buf"; + if ( Type == ABC_OPER_CONST_T ) return "buf"; + if ( Type == ABC_OPER_CONST_X ) return "buf"; + if ( Type == ABC_OPER_CONST_Z ) return "buf"; + if ( Type == ABC_OPER_BIT_BUF ) return "buf"; + if ( Type == ABC_OPER_BIT_INV ) return "not"; + if ( Type == ABC_OPER_BIT_AND ) return "and"; + if ( Type == ABC_OPER_BIT_OR ) return "or"; + if ( Type == ABC_OPER_BIT_XOR ) return "xor"; + if ( Type == ABC_OPER_BIT_NAND ) return "nand"; + if ( Type == ABC_OPER_BIT_NOR ) return "nor"; + if ( Type == ABC_OPER_BIT_NXOR ) return "xnor"; + assert( 0 ); + return NULL; +} + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/miniaig/ndr.h b/src/aig/miniaig/ndr.h index 8d630159..78e5cd23 100644 --- a/src/aig/miniaig/ndr.h +++ b/src/aig/miniaig/ndr.h @@ -334,7 +334,7 @@ static inline int Ndr_DataObjNum( Ndr_Data_t * p, int Mod ) } // to write signal names, this procedure takes a mapping of name IDs into actual char-strings (pNames) -static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod, char ** pNames ) +static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod, char ** pNames, int fSimple ) { Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int * pOuts = NDR_ALLOC( int, Ndr_DataCoNum(p, Mod) ); @@ -377,6 +377,8 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod break; if ( k < i ) continue; + if ( Ndr_ObjReadOutName(p, Obj, pNames)[0] == '1' ) + continue; fprintf( pFile, " wire " ); Ndr_ObjWriteRange( p, Obj, pFile, 1 ); fprintf( pFile, " %s;\n", Ndr_ObjReadOutName(p, Obj, pNames) ); @@ -459,6 +461,24 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod fprintf( pFile, ");\n" ); continue; } + if ( fSimple ) + { + if ( Ndr_ObjReadOutName(p, Obj, pNames)[0] == '1' ) + continue; + nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray ); + fprintf( pFile, " %s ( %s", Abc_OperNameSimple(Type), Ndr_ObjReadOutName(p, Obj, pNames) ); + if ( nArray == 0 ) + fprintf( pFile, ", %s );\n", (char *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION) ); + else if ( nArray == 1 && Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE) == ABC_OPER_BIT_BUF ) + fprintf( pFile, ", %s );\n", pNames[pArray[0]] ); + else + { + for ( i = 0; i < nArray; i++ ) + fprintf( pFile, ", %s", pNames[pArray[i]] ); + fprintf( pFile, " );\n" ); + } + continue; + } fprintf( pFile, " assign %s = ", Ndr_ObjReadOutName(p, Obj, pNames) ); nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray ); if ( nArray == 0 ) @@ -492,7 +512,7 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod } // to write signal names, this procedure takes a mapping of name IDs into actual char-strings (pNames) -static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** pNames ) +static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** pNames, int fSimple ) { Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int Mod; @@ -500,7 +520,7 @@ static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** p if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; } Ndr_DesForEachMod( p, Mod ) - Ndr_WriteVerilogModule( pFile, p, Mod, pNames ); + Ndr_WriteVerilogModule( pFile, p, Mod, pNames, fSimple ); if ( pFileName ) fclose( pFile ); } @@ -656,7 +676,7 @@ static inline void Ndr_ModuleTest() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdS, 0, NULL, NULL ); // fanin is a // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames ); + Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); Ndr_Write( "add4.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -744,7 +764,7 @@ static inline void Ndr_ModuleTestAdder() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &FaninCO, 0, NULL, NULL ); // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames ); + Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); Ndr_Write( "add8.ndr", pDesign ); Ndr_Delete( pDesign ); @@ -830,7 +850,7 @@ static inline void Ndr_ModuleTestHierarchy() Ndr_AddObject( pDesign, Module41, ABC_OPER_CO, 0, 3, 0, 0, 1, &FaninOut, 0, NULL, NULL ); // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames ); + Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); Ndr_Write( "mux41w.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -919,7 +939,7 @@ static inline void Ndr_ModuleTestMemory() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_COMP_NOTEQU, 0, 0, 0, 0, 2, FaninsComp, 1, &NameIdComp, NULL ); // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames ); + Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); Ndr_Write( "memtest.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -968,7 +988,7 @@ static inline void Ndr_ModuleTestFlop() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdQ, 0, NULL, NULL ); // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames ); + Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); Ndr_Write( "flop.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -1022,7 +1042,7 @@ static inline void Ndr_ModuleTestSelSel() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 2, 0, 0, 1, &NameIdOut,0, NULL, NULL ); // write Verilog for verification - //Ndr_WriteVerilog( NULL, pDesign, ppNames ); + //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); Ndr_Write( "sel.ndr", pDesign ); Ndr_Delete( pDesign ); } -- cgit v1.2.3 From c312e416017f4abf856a184279f5ce3a7198601a Mon Sep 17 00:00:00 2001 From: Jerry James Date: Mon, 9 Aug 2021 16:24:04 -0600 Subject: Fix violation of C strict aliasing rules. --- src/aig/gia/giaUtil.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index f04c0bc3..d5a39f79 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2109,11 +2109,13 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName ) Gia_ManForEachObj( p, pObj, i ) if ( i && Gia_ObjIsLut(p, i) ) { + word truth; pLuts[iLut].Type = 3; Gia_LutForEachFanin( p, i, iFan, k ) pLuts[iLut].pFans[k] = Gia_ManObj(p, iFan)->Value; pLuts[iLut].nFans = k; - *(word *)pLuts[iLut].pTruth = Gia_LutComputeTruth6(p, i, vTruths); + truth = Gia_LutComputeTruth6(p, i, vTruths); + memcpy( pLuts[iLut].pTruth, &truth, sizeof(word) ); pObj->Value = pLuts[iLut].Out = Abc_Var2Lit( iLut, 0 ); iLut++; } -- cgit v1.2.3 From 4da6cc890433e8d782f8a1805fa9ec617955464d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 17 Aug 2021 16:52:29 -0700 Subject: Improving AIG to Verilog converter. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaMan.c | 89 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 67 insertions(+), 24 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 3517502d..8a5137fe 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1488,7 +1488,7 @@ extern void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose ) extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew ); extern void Gia_ManPrintNpnClasses( Gia_Man_t * p ); -extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs ); +extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs ); /*=== giaMem.c ===========================================================*/ extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax ); extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose ); diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index b5748401..e4c9afd0 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -1270,13 +1270,14 @@ void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Sta fFirst = 0; } } -void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs ) +void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs ) { FILE * pFile; Gia_Obj_t * pObj; Vec_Bit_t * vInvs, * vUsed; - int nDigits = Abc_Base10Log( Gia_ManObjNum(p) ); - int nDigits2 = Abc_Base10Log( Gia_ManPiNum(p) ); + int nDigits = Abc_Base10Log( Gia_ManObjNum(p) ); + int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) ); + int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) ); int i, k, iObj; if ( Gia_ManRegNum(p) ) { @@ -1301,20 +1302,63 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs ) fprintf( pFile, "%c", p->pName[i] ); else fprintf( pFile, "_" ); - fprintf( pFile, " (\n " ); - Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL ); - fprintf( pFile, ",\n " ); - Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL ); - fprintf( pFile, "\n );\n\n" ); + if ( fVerBufs ) + { + fprintf( pFile, " (\n " ); + Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 4, 4, NULL ); + fprintf( pFile, ",\n " ); + + Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 4, 4, NULL ); + fprintf( pFile, "\n );\n\n" ); + + fprintf( pFile, " input " ); + Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 8, 4, NULL ); + fprintf( pFile, ";\n\n" ); + + fprintf( pFile, " output " ); + Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 9, 4, NULL ); + fprintf( pFile, ";\n\n" ); + + fprintf( pFile, " wire " ); + Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL ); + fprintf( pFile, ";\n\n" ); - fprintf( pFile, " input " ); - Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL ); - fprintf( pFile, ";\n\n" ); + fprintf( pFile, " wire " ); + Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL ); + fprintf( pFile, ";\n\n" ); - fprintf( pFile, " output " ); - Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL ); - fprintf( pFile, ";\n\n" ); + Gia_ManForEachPi( p, pObj, i ) + { + fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) ); + fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, 'a', i, nDigitsI) ); + } + fprintf( pFile, "\n" ); + + Gia_ManForEachPo( p, pObj, i ) + { + fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'y', i, nDigitsO) ); + fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) ); + } + fprintf( pFile, "\n" ); + } + else + { + fprintf( pFile, " (\n " ); + Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL ); + fprintf( pFile, ",\n " ); + + Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL ); + fprintf( pFile, "\n );\n\n" ); + + fprintf( pFile, " input " ); + Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL ); + fprintf( pFile, ";\n\n" ); + + fprintf( pFile, " output " ); + Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL ); + fprintf( pFile, ";\n\n" ); + } if ( Vec_BitCount(vUsed) ) { @@ -1338,7 +1382,7 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs ) fprintf( pFile, ";\n\n" ); Vec_IntForEachEntry( vObjs, iObj, i ) { - fprintf( pFile, " buf( %s,", Gia_ObjGetDumpName(NULL, 'n', iObj, nDigits) ); + fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'n', iObj, nDigits) ); fprintf( pFile, " t_%d );\n", i ); } fprintf( pFile, "\n" ); @@ -1349,13 +1393,13 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs ) { if ( Vec_BitEntry(vUsed, Gia_ObjId(p, pObj)) ) { - fprintf( pFile, " buf( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) ); - fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigits2) ); + fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) ); + fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) ); } if ( Vec_BitEntry(vInvs, Gia_ObjId(p, pObj)) ) { - fprintf( pFile, " not( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) ); - fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigits2) ); + fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) ); + fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) ); } } @@ -1374,20 +1418,19 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs ) } if ( !fSkip ) { - fprintf( pFile, " and( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) ); + fprintf( pFile, " and ( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) ); fprintf( pFile, " %s,", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0(pObj, i), nDigits) ); fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC1(pObj)? 'i':'n'), Gia_ObjFaninId1(pObj, i), nDigits) ); } if ( Vec_BitEntry(vInvs, i) ) { - fprintf( pFile, " not( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) ); + fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) ); fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) ); } } // output drivers fprintf( pFile, "\n" ); - nDigits2 = Abc_Base10Log( Gia_ManPoNum(p) ); Gia_ManForEachPo( p, pObj, i ) { /* @@ -1397,7 +1440,7 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs ) else fprintf( pFile, "%s;\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) ); */ - fprintf( pFile, " buf( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigits2) ); + fprintf( pFile, " buf ( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) ); if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) ) fprintf( pFile, "1\'b%d );\n", Gia_ObjFaninC0(pObj) ); else -- cgit v1.2.3 From 77760dd8ac0d9ed1c0c909f28415204074074e78 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 19 Aug 2021 09:48:46 -0700 Subject: Extending &trim to trim structurally equivalent primary outputs. --- src/aig/gia/giaDup.c | 25 +++++++++++++ src/aig/gia/giaUtil.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 326bbedb..a2ed4942 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -2320,6 +2320,31 @@ Gia_Man_t * Gia_ManDupTrimmed2( Gia_Man_t * p ) assert( !Gia_ManHasDangling( pNew ) ); return pNew; } +Gia_Man_t * Gia_ManDupTrimmed3( Gia_Man_t * p ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_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) ); + // mark duplicated POs + Gia_ManForEachPo( p, pObj, i ) + Vec_IntWriteEntry( vMap, Gia_ObjFaninId0p(p, pObj), i ); + Gia_ManForEachPo( p, pObj, i ) + if ( Vec_IntEntry(vMap, Gia_ObjFaninId0p(p, pObj)) == i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Vec_IntFree( vMap ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} /**Function************************************************************* diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index f04c0bc3..371cda62 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2819,6 +2819,108 @@ void Gia_ManDumpSuppFileTest( Gia_Man_t * p, char * pFileName ) Vec_StrFree( vRes ); } + +/**Function************************************************************* + + Synopsis [Compute support diffs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManConvertSupp_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( !Gia_ObjIsAnd(pObj) ) + return; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Gia_Man_t * Gia_ManConvertSupp( Gia_Man_t * p ) +{ + int fOnly1 = 0; + int fVerbose = 1; + abctime clk = Abc_Clock(); + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObjPi, * pObjRi, * pObjRo; + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Int_t * vAnds = Vec_IntAlloc( 100 ); + int i, n, iLits[2]; + assert( Gia_ManRegNum(p) && Gia_ManRegNum(p) % 8 == 0 ); + 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_ManForEachPi( p, pObjPi, i ) + pObjPi->Value = Gia_ManAppendCi( pNew ); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachRi( p, pObjRi, i ) + { + pObjRo = Gia_ObjRiToRo(p, pObjRi); + if ( (i - Gia_ManPoNum(p)) % 8 != 0 ) + continue; + if ( fOnly1 ) + { + assert( pObjRo->Value == ~0 ); + for ( n = 0; n < 2; n++ ) + { + pObjRo->Value = n; + Gia_ManIncrementTravId( p ); + Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObjRi) ); + iLits[n] = Gia_ObjFanin0Copy(pObjRi); + } + pObjRo->Value = ~0; + Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[1], Abc_LitNot(iLits[0]) )) ); + } + else + { + int Fanin = Gia_ObjFaninId0p( p, pObjRi ); + Vec_Int_t * vNodes = Gia_ManCollectNodesCis( p, &Fanin, 1 ); + Gia_Obj_t * pObj; int i, m; + Vec_IntClear( vSupp ); + Vec_IntClear( vAnds ); + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Vec_IntPush( Gia_ObjIsAnd(pObj) ? vAnds : vSupp, Gia_ObjId(p, pObj) ); + Vec_IntFree( vNodes ); + Vec_IntSort( vSupp, 0 ); + for ( m = 0; m < 4; m++ ) + { + Gia_ManForEachObjVec( vSupp, p, pObj, i ) + if ( i >= Vec_IntSize(vSupp)-5 ) + pObj->Value = (i == Vec_IntSize(vSupp)-5+m) ? 1 : 0; + Gia_ManForEachObjVec( vAnds, p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //if ( m == 4 ) + // Gia_ManAppendCo( pNew, 0 ); + //else + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObjRi) ); + //Gia_ManAppendCo( pNew, Abc_Var2Lit( Vec_IntEntry(vSupp, Vec_IntSize(vSupp)-5+m), 0 ) ); + Gia_ManForEachObjVec( vSupp, p, pObj, i ) + if ( i >= Vec_IntSize(vSupp)-5 ) + pObj->Value = Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 ); + } + } + } + Vec_IntFree( vSupp ); + Vec_IntFree( vAnds ); + Gia_ManHashStop( pNew ); + //Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + if ( fVerbose ) + printf( "Transformed %d outputs, ", Gia_ManPoNum(pNew) ); + if ( fVerbose ) + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 625ccde611da6eecf3bfdefc7632cd7a801767df Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 22 Aug 2021 13:05:28 -0700 Subject: Support of pair-wise miter and other changes. --- src/aig/gia/giaDup.c | 38 ++++++ src/aig/gia/giaHash.c | 322 +++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaResub.c | 41 +++++++ src/aig/gia/giaUtil.c | 160 ++++++++++++++++++++++++ 4 files changed, 561 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index a2ed4942..c1da11da 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -2964,6 +2964,44 @@ Vec_Ptr_t * Gia_ManMiterNames( Vec_Ptr_t * p, int nOuts ) return pNew; } +/**Function************************************************************* + + Synopsis [Pair-wise miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPairWiseMiter( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj, * pObj2; + int i, k, iLit; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Gia_ManForEachPo( p, pObj2, k ) + { + if ( i >= k ) + continue; + iLit = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin0Copy(pObj2) ); + Gia_ManAppendCo( pNew, iLit ); + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + /**Function************************************************************* Synopsis [Transforms the circuit into a regular miter.] diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c index 64e39613..063cfd31 100644 --- a/src/aig/gia/giaHash.c +++ b/src/aig/gia/giaHash.c @@ -814,6 +814,328 @@ int Gia_ManHashDualMiter( Gia_Man_t * p, Vec_Int_t * vOuts ) return iRes; } + + +/**Function************************************************************* + + Synopsis [Create multi-input tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManCollectLiterals( int nVars ) +{ + int i, * pRes = ABC_CALLOC( int, nVars ); + for ( i = 0; i < nVars; i++ ) + pRes[i] = Abc_Var2Lit( i+1, 0 ); + return pRes; +} +int * Gia_ManGenZero( int nBits ) +{ + return ABC_CALLOC( int, nBits ); +} +int * Gia_ManGenPerm( int nBits ) +{ + int i, * pRes = ABC_CALLOC( int, nBits ); + srand( time(NULL) ); + for ( i = 0; i < nBits; i++ ) + pRes[i] = i; + for ( i = 0; i < nBits; i++ ) + { + int iPerm = rand() % nBits; + ABC_SWAP( int, pRes[i], pRes[iPerm] ); + } + return pRes; +} +int * Gia_ManGenPerm2( int nBits ) +{ + int i, * pRes = ABC_CALLOC( int, nBits ); + srand( time(NULL) ); + for ( i = 0; i < nBits; i++ ) + pRes[i] = rand() % nBits; + return pRes; +} +int Gia_ManMultiCheck( int * pPerm, int nPerm ) +{ + int i; + for ( i = 1; i < nPerm; i++ ) + if ( pPerm[i-1] <= pPerm[i] ) + return 0; + return 1; +} +int Gia_ManMultiInputPerm( Gia_Man_t * pNew, int * pVars, int nVars, int * pPerm, int fOr, int fXor ) +{ + int fPrint = 1; + int i, iLit; + if ( fPrint ) + { + for ( i = 0; i < nVars; i++ ) + printf( "%d ", pPerm[i] ); + printf( "\n" ); + } + while ( 1 ) + { + for ( i = 1; i < nVars; i++ ) + if ( pPerm[i-1] >= pPerm[i] ) + break; + if ( i == nVars ) + break; + assert( pPerm[i-1] >= pPerm[i] ); + if ( pPerm[i-1] > pPerm[i] ) + { + ABC_SWAP( int, pPerm[i-1], pPerm[i] ); + ABC_SWAP( int, pVars[i-1], pVars[i] ); + } + else + { + assert( pPerm[i-1] == pPerm[i] ); + pPerm[i-1]++; + if ( fXor ) + pVars[i-1] = Gia_ManHashXor( pNew, pVars[i-1], pVars[i] ); + else if ( fOr ) + pVars[i-1] = Gia_ManHashOr( pNew, pVars[i-1], pVars[i] ); + else + pVars[i-1] = Gia_ManHashAnd( pNew, pVars[i-1], pVars[i] ); + for ( i = i+1; i < nVars; i++ ) + { + pPerm[i-1] = pPerm[i]; + pVars[i-1] = pVars[i]; + } + nVars--; + } + if ( fPrint ) + { + for ( i = 0; i < nVars; i++ ) + printf( "%d ", pPerm[i] ); + printf( "\n" ); + } + } + iLit = pVars[0]; + for ( i = 1; i < nVars; i++ ) + if ( fXor ) + iLit = Gia_ManHashXor( pNew, iLit, pVars[i] ); + else if ( fOr ) + iLit = Gia_ManHashOr( pNew, iLit, pVars[i] ); + else + iLit = Gia_ManHashAnd( pNew, iLit, pVars[i] ); + return iLit; +} +Gia_Man_t * Gia_ManMultiInputTest( int nBits ) +{ + Gia_Man_t * pNew; + int i, iRes, * pPerm; + int * pMulti = Gia_ManCollectLiterals( nBits ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "multi" ); + for ( i = 0; i < nBits; i++ ) + Gia_ManAppendCi( pNew ); + Gia_ManHashAlloc( pNew ); + pPerm = Gia_ManGenPerm2( nBits ); + //pPerm = Gia_ManGenZero( nBits ); + iRes = Gia_ManMultiInputPerm( pNew, pMulti, nBits, pPerm, 0, 0 ); + Gia_ManAppendCo( pNew, iRes ); + ABC_FREE( pPerm ); + ABC_FREE( pMulti ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Create MUX tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCube( Gia_Man_t * pNew, int Vars, int nVars, int * pLits ) +{ + int i, iLit = 1; + for ( i = 0; i < nVars; i++ ) + iLit = Gia_ManHashAnd( pNew, iLit, Abc_LitNotCond(pLits[i], !((Vars >> i) & 1)) ); + return iLit; +} +int Gia_ManMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, int * pData ) +{ + int iLit0, iLit1; + if ( nCtrl == 0 ) + return pData[0]; + iLit0 = Gia_ManMuxTree_rec( pNew, pCtrl, nCtrl-1, pData ); + iLit1 = Gia_ManMuxTree_rec( pNew, pCtrl, nCtrl-1, pData + (1<<(nCtrl-1)) ); + return Gia_ManHashMux( pNew, pCtrl[nCtrl-1], iLit1, iLit0 ); +} +void Gia_ManUsePerm( int * pTree, int nBits, int * pPerm ) +{ + int fPrint = 0; + int i, k, m, nVars = nBits + (1 << nBits); + if ( fPrint ) + { + for ( i = 0; i < nVars; i++ ) + printf( "%d ", pPerm[i] ); + printf( "\n" ); + } + for ( i = 0; i < nBits; i++ ) + { + for ( k = i+1; k < nBits; k++ ) + if ( pPerm[i] > pPerm[k] ) + break; + if ( k == nBits ) + break; + assert( pPerm[i] > pPerm[k] ); + ABC_SWAP( int, pPerm[i], pPerm[k] ); + ABC_SWAP( int, pTree[i], pTree[k] ); + for ( m = 0; m < (1 << nBits); m++ ) + if ( ((m >> i) & 1) && !((m >> k) & 1) ) + { + ABC_SWAP( int, pTree[nBits+m], pTree[nBits+(m^(1<> i) & 1) ) + return Abc_LitNotCond( pLits[i], (iLate1 >> i) & 1 ); + return -1; +} +int Gia_ManLatest( int * pPerm, int nVars, int iPrev1, int iPrev2, int iPrev3 ) +{ + int i, Value = -1, iLate = -1; + for ( i = 0; i < nVars; i++ ) + if ( Value < pPerm[i] && i != iPrev1 && i != iPrev2 && i != iPrev3 ) + { + Value = pPerm[i]; + iLate = i; + } + return iLate; +} +int Gia_ManEarliest( int * pPerm, int nVars ) +{ + int i, Value = ABC_INFINITY, iLate = -1; + for ( i = 0; i < nVars; i++ ) + if ( Value > pPerm[i] ) + { + Value = pPerm[i]; + iLate = i; + } + return iLate; +} +int Gia_ManDecompOne( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate ) +{ + int iRes, iData; + assert( iLate >= 0 && iLate < (1<= 0 && iLate1 < (1<= 0 && iLate2 < (1<= 0 && iLate1 < (1<= 0 && iLate2 < (1<= 0 && iLate3 < (1< BaseValue && pPerm[nBits+iLate2] > BaseValue && pPerm[nBits+iLate3] > BaseValue && pPerm[nBits+iLate4] == BaseValue ) + return Gia_ManDecompThree( pNew, pTree, nBits, pPerm, iLate1, iLate2, iLate3 ); + if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] > BaseValue && pPerm[nBits+iLate3] == BaseValue ) + return Gia_ManDecompTwo( pNew, pTree, nBits, pPerm, iLate1, iLate2 ); + if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] == BaseValue ) + return Gia_ManDecompOne( pNew, pTree, nBits, pPerm, iLate1 ); + return Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits ); + } +} +Gia_Man_t * Gia_ManMuxTreeTest( int nBits ) +{ + Gia_Man_t * pNew; + int i, iLit, nVars = nBits + (1 << nBits); + int * pPerm, * pTree = Gia_ManCollectLiterals( nVars ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "mux_tree" ); + for ( i = 0; i < nVars; i++ ) + Gia_ManAppendCi( pNew ); + Gia_ManHashAlloc( pNew ); + pPerm = Gia_ManGenPerm( nVars ); + //pPerm = Gia_ManGenZero( nVars ); + pPerm[nBits+1] = 100; + pPerm[nBits+5] = 100; + pPerm[nBits+4] = 100; + Gia_ManUsePerm( pTree, nBits, pPerm ); + iLit = Gia_ManDecomp( pNew, pTree, nBits, pPerm ); + Gia_ManAppendCo( pNew, iLit ); + ABC_FREE( pPerm ); + ABC_FREE( pTree ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index a1343290..06e002af 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -1570,6 +1570,47 @@ void Gia_ManResubTest3_() Vec_PtrFree( vDivs ); } +/**Function************************************************************* + + Synopsis [Top level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManResubPair( Vec_Wrd_t * vOn, Vec_Wrd_t * vOff, int nWords, int nIns ) +{ + Gia_ResbMan_t * p = Gia_ResbAlloc( nWords*2 ); + Vec_Ptr_t * vDivs = Vec_PtrAllocSimInfo( nIns+2, nWords*2 ); + word * pSim; int i; + Vec_PtrForEachEntry( word *, vDivs, pSim, i ) + { + if ( i == 0 ) + { + memset( pSim, 0x00, sizeof(word)*nWords ); + memset( pSim+nWords, 0xFF, sizeof(word)*nWords ); + } + else if ( i == 1 ) + { + memset( pSim, 0xFF, sizeof(word)*nWords ); + memset( pSim+nWords, 0x00, sizeof(word)*nWords ); + } + else + { + memmove( pSim, Vec_WrdEntryP(vOn, (i-2)*nWords), sizeof(word)*nWords ); + memmove( pSim+nWords, Vec_WrdEntryP(vOff, (i-2)*nWords), sizeof(word)*nWords ); + } + } + Gia_ManResubPerform( p, vDivs, nWords*2, 100, 0, 50, 1, 1, 0 ); + Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); + printf( "\n" ); + //Vec_PtrFree( vDivs ); + Gia_ResbFree( p ); +} + /**Function************************************************************* Synopsis [Top level.] diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index efc866b8..85d8b1d2 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2923,6 +2923,166 @@ Gia_Man_t * Gia_ManConvertSupp( Gia_Man_t * p ) return pNew; } + +/**Function************************************************************* + + Synopsis [Transform flops.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManTransformCond2( Gia_Man_t * p ) +{ + int fOnly1 = 0; + int fVerbose = 1; + abctime clk = Abc_Clock(); + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObjPi, * pObjRi, * pObjRo; + int i, n, iTempLit, iLits[2]; + assert( Gia_ManRegNum(p) > 0 ); + 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, pObjPi, i ) + pObjPi->Value = Gia_ManAppendCi( pNew ); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachRi( p, pObjRi, i ) + { + //if ( (i - Gia_ManPoNum(p)) % 8 != 0 ) + // continue; + pObjRo = Gia_ObjRiToRo(p, pObjRi); + iTempLit = pObjRo->Value; + for ( n = 0; n < 2; n++ ) + { + pObjRo->Value = n; + Gia_ManIncrementTravId( p ); + Gia_ManConvertSupp_rec( pNew, p, Gia_ObjFanin0(pObjRi) ); + iLits[n] = Gia_ObjFanin0Copy(pObjRi); + } + pObjRo->Value = iTempLit; + Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[1], Abc_LitNot(iLits[0]) )) ); + Gia_ManAppendCo( pNew, Abc_LitNot(Gia_ManHashAnd( pNew, iLits[0], Abc_LitNot(iLits[1]) )) ); + } + Gia_ManHashStop( pNew ); + //Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + if ( fVerbose ) + printf( "Created %d outputs. ", Gia_ManPoNum(pNew) ); + if ( fVerbose ) + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Transform flops.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Gia_ManDetectSims( Gia_Man_t * p, int iCo, int nWords ) +{ + extern int Cec4_ManGeneratePatterns_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Int_t * vPat, Vec_Int_t * vVisit ); + Vec_Wrd_t * vSim = Vec_WrdStart( nWords * Gia_ManCiNum(p) ); + Vec_Int_t * vPat = Vec_IntAlloc( Gia_ManCiNum(p) ); + Vec_Int_t * vVis = Vec_IntAlloc( Gia_ManAndNum(p) ); + Gia_Obj_t * pObj = Gia_ManCo( p, iCo ), * pTemp; int iLit, i, k, nTries = 0; + if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(p) ) + return NULL; + Gia_ManForEachObj( p, pTemp, k ) + assert( !pTemp->fMark0 && !pTemp->fMark1 ); + for ( i = 0; i < 64*nWords; ) + { + int Res = Cec4_ManGeneratePatterns_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), vPat, vVis ); + if ( Res ) + { + Vec_IntForEachEntry( vPat, iLit, k ) + { + if ( Abc_LitIsCompl(iLit) ) + continue; + pTemp = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + assert( Gia_ObjIsCi(pTemp) ); + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(vSim, nWords*Gia_ObjCioId(pTemp)), i ); + } + i++; + } + Gia_ManForEachObjVec( vVis, p, pTemp, k ) + pTemp->fMark0 = pTemp->fMark1 = 0; + nTries++; + } + //printf( "%d ", nTries ); + Vec_IntFree( vPat ); + Vec_IntFree( vVis ); + return vSim; +} +Vec_Wrd_t * Vec_WrdInterleave( Vec_Wrd_t * p1, Vec_Wrd_t * p2, int nWords, int nIns ) +{ + Vec_Wrd_t * p = Vec_WrdAlloc( Vec_WrdSize(p1)+Vec_WrdSize(p2) ); + int i, k; + assert( Vec_WrdSize(p1) == nWords*nIns ); + assert( Vec_WrdSize(p2) == nWords*nIns ); + for ( i = 0; i < nIns; i++ ) + { + for ( k = 0; k < nWords; k++ ) + Vec_WrdPush( p, Vec_WrdEntry(p1, i*nWords+k) ); + for ( k = 0; k < nWords; k++ ) + Vec_WrdPush( p, Vec_WrdEntry(p2, i*nWords+k) ); + } + return p; +} +Gia_Man_t * Gia_ManTransformCond( Gia_Man_t * p ) +{ + extern void Gia_ManResubPair( Vec_Wrd_t * vOn, Vec_Wrd_t * vOff, int nWords, int nIns ); + abctime clk = Abc_Clock(); + Vec_Wrd_t * vSims; + Vec_Wrd_t * vSim[4]; + Vec_Wrd_t * vInt[6]; + int i; + for ( i = 0; i < Gia_ManCoNum(p); i++ ) + { + vSims = Gia_ManDetectSims( p, i, 1 ); + if ( i >= Gia_ManCoNum(p)-4 ) + vSim[i-(Gia_ManCoNum(p)-4)] = vSims; + else + Vec_WrdFreeP( &vSims ); + //Vec_PtrPush( vAll, vSims ); + } + vInt[0] = Vec_WrdInterleave( vSim[0], vSim[1], 1, Gia_ManCiNum(p) ); + vInt[1] = Vec_WrdInterleave( vSim[0], vSim[2], 1, Gia_ManCiNum(p) ); + vInt[2] = Vec_WrdInterleave( vSim[0], vSim[3], 1, Gia_ManCiNum(p) ); + vInt[3] = Vec_WrdInterleave( vSim[1], vSim[2], 1, Gia_ManCiNum(p) ); + vInt[4] = Vec_WrdInterleave( vSim[1], vSim[3], 1, Gia_ManCiNum(p) ); + vInt[5] = Vec_WrdInterleave( vSim[2], vSim[3], 1, Gia_ManCiNum(p) ); + + Gia_ManResubPair( vInt[0], vInt[5], 2, Gia_ManCiNum(p) ); + Gia_ManResubPair( vInt[1], vInt[4], 2, Gia_ManCiNum(p) ); + Gia_ManResubPair( vInt[2], vInt[3], 2, Gia_ManCiNum(p) ); + + Gia_ManResubPair( vInt[5], vInt[0], 2, Gia_ManCiNum(p) ); + Gia_ManResubPair( vInt[4], vInt[1], 2, Gia_ManCiNum(p) ); + Gia_ManResubPair( vInt[3], vInt[2], 2, Gia_ManCiNum(p) ); + +/* + for ( i = 0; i < 4; i++ ) + for ( k = i+1; k < 4; k++ ) + Gia_ManResubPair( vSim[i], vSim[k], 1, Gia_ManCiNum(p) ); +*/ + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + return NULL; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 67c47fa44aaa566d10abb154b3f89a9d427f5581 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 22 Aug 2021 20:05:15 -0700 Subject: Adding input/output/flop name reading in command &r. --- src/aig/gia/giaAiger.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaDeep.c | 2 +- src/aig/gia/giaUtil.c | 1 - 3 files changed, 114 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index 593743d5..817a15fe 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -176,6 +176,7 @@ Vec_Str_t * Gia_AigerWriteLiterals( Vec_Int_t * vLits ) Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck ) { Gia_Man_t * pNew, * pTemp; + Vec_Ptr_t * vNamesIn = NULL, * vNamesOut = NULL, * vNamesRegIn = NULL, * vNamesRegOut = NULL; Vec_Int_t * vLits = NULL, * vPoTypes = NULL; Vec_Int_t * vNodes, * vDrivers, * vInits = NULL; int iObj, iNode0, iNode1, fHieOnly = 0; @@ -377,6 +378,88 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi pCur = pSymbols; if ( pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' ) { + int fReadNames = 1; + if ( fReadNames ) + { + int fError = 0; + while ( !fError && pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' ) + { + int iTerm; + char * pType = (char *)pCur; + char * pName = NULL; + // check terminal type + if ( *pCur != 'i' && *pCur != 'o' && *pCur != 'l' ) + { + fError = 1; + break; + } + // get terminal number + iTerm = atoi( (char *)++pCur ); while ( *pCur++ != ' ' ); + // skip spaces + while ( *pCur == ' ' ) + pCur++; + // skip till the end of line + for ( pName = pCur; *pCur && *pCur != '\n'; pCur++ ); + if ( *pCur == '\n' ) + *pCur = 0; + // save the name + if ( *pType == 'i' ) + { + if ( vNamesIn == NULL ) + vNamesIn = Vec_PtrAlloc( nInputs + nLatches ); + if ( Vec_PtrSize(vNamesIn) != iTerm ) + { + fError = 1; + break; + } + Vec_PtrPush( vNamesIn, Abc_UtilStrsav(pName) ); + } + else if ( *pType == 'o' ) + { + if ( vNamesOut == NULL ) + vNamesOut = Vec_PtrAlloc( nOutputs + nLatches ); + if ( Vec_PtrSize(vNamesOut) != iTerm ) + { + fError = 1; + break; + } + Vec_PtrPush( vNamesOut, Abc_UtilStrsav(pName) ); + } + else if ( *pType == 'l' ) + { + char Buffer[1000]; + assert( strlen(pName) < 995 ); + sprintf( Buffer, "%s_in", pName ); + if ( vNamesRegIn == NULL ) + vNamesRegIn = Vec_PtrAlloc( nLatches ); + if ( vNamesRegOut == NULL ) + vNamesRegOut = Vec_PtrAlloc( nLatches ); + if ( Vec_PtrSize(vNamesRegIn) != iTerm ) + { + fError = 1; + break; + } + Vec_PtrPush( vNamesRegIn, Abc_UtilStrsav(Buffer) ); + Vec_PtrPush( vNamesRegOut, Abc_UtilStrsav(pName) ); + } + else + { + fError = 1; + break; + } + pCur++; + } + if ( fError ) + { + printf( "Error occurred when reading signal names.\n" ); + if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn ), vNamesIn = NULL; + if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut ), vNamesOut = NULL; + if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn ), vNamesRegIn = NULL; + if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut ), vNamesRegOut = NULL; + } + } + else + { int fBreakUsed = 0; unsigned char * pCurOld = pCur; pNew->vUserPiIds = Vec_IntStartFull( nInputs ); @@ -505,6 +588,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi } Vec_IntFree( vPoNames ); } + } } @@ -867,6 +951,35 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi Abc_Print( 0, "Structural hashing enabled while reading AIGER invalidated the mapping. Consider using \"&r -s\".\n" ); Vec_IntFreeP( &pNew->vMapping ); } + if ( vNamesIn && Gia_ManPiNum(pNew) != Vec_PtrSize(vNamesIn) ) + Abc_Print( 0, "The number of inputs does not match the number of input names.\n" ); + else if ( vNamesOut && Gia_ManPoNum(pNew) != Vec_PtrSize(vNamesOut) ) + Abc_Print( 0, "The number of output does not match the number of output names.\n" ); + else if ( vNamesRegOut && Gia_ManRegNum(pNew) != Vec_PtrSize(vNamesRegOut) ) + Abc_Print( 0, "The number of inputs does not match the number of flop names.\n" ); + else if ( vNamesIn && vNamesOut ) + { + pNew->vNamesIn = vNamesIn; vNamesIn = NULL; + pNew->vNamesOut = vNamesOut; vNamesOut = NULL; + if ( vNamesRegOut ) + { + Vec_PtrAppend( pNew->vNamesIn, vNamesRegOut ); + Vec_PtrClear( vNamesRegOut ); + Vec_PtrFree( vNamesRegOut ); + vNamesRegOut = NULL; + } + if ( vNamesRegIn ) + { + Vec_PtrAppend( pNew->vNamesOut, vNamesRegIn ); + Vec_PtrClear( vNamesRegIn ); + Vec_PtrFree( vNamesRegIn ); + vNamesRegIn = NULL; + } + } + if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn ); + if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut ); + if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn ); + if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut ); return pNew; } diff --git a/src/aig/gia/giaDeep.c b/src/aig/gia/giaDeep.c index eecc598a..815a546e 100644 --- a/src/aig/gia/giaDeep.c +++ b/src/aig/gia/giaDeep.c @@ -73,7 +73,7 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in else if ( fCom == 0 ) pComp = "; &dc2"; sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s", - fDch ? " -f" : "", KLut, fFx ? "; &fx" : "", pComp ); + fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp ); if ( Abc_FrameIsBatchMode() ) { if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) ) diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 85d8b1d2..0a40e63e 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2937,7 +2937,6 @@ Gia_Man_t * Gia_ManConvertSupp( Gia_Man_t * p ) ***********************************************************************/ Gia_Man_t * Gia_ManTransformCond2( Gia_Man_t * p ) { - int fOnly1 = 0; int fVerbose = 1; abctime clk = Abc_Clock(); Gia_Man_t * pNew, * pTemp; -- cgit v1.2.3 From 85a94766a6b4e1870279110a8620cba92832367f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 23 Aug 2021 19:56:26 -0700 Subject: Compiler warnings. --- src/aig/gia/giaAiger.c | 2 +- src/aig/gia/giaUtil.c | 2 +- src/aig/miniaig/ndr.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index 817a15fe..c2c0e969 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -399,7 +399,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi while ( *pCur == ' ' ) pCur++; // skip till the end of line - for ( pName = pCur; *pCur && *pCur != '\n'; pCur++ ); + for ( pName = (char *)pCur; *pCur && *pCur != '\n'; pCur++ ); if ( *pCur == '\n' ) *pCur = 0; // save the name diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 0a40e63e..431be5b7 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2618,7 +2618,7 @@ Gia_Man_t * Gia_ManComputeCofs2( Gia_Man_t * p ) Gia_ManForEachCi( p, pObj, i ) { pObj->Value = Gia_ManAppendCi(pNew); - assert( pObj->Value = Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 ) ); + assert( (int)pObj->Value == Abc_Var2Lit( 1 + Gia_ObjCioId(pObj), 0 ) ); } Gia_ManHashAlloc( pNew ); Gia_ManForEachRi( p, pSink, o ) diff --git a/src/aig/miniaig/ndr.h b/src/aig/miniaig/ndr.h index 78e5cd23..91663616 100644 --- a/src/aig/miniaig/ndr.h +++ b/src/aig/miniaig/ndr.h @@ -517,7 +517,7 @@ static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** p Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int Mod; FILE * pFile = pFileName ? fopen( pFileName, "wb" ) : stdout; - if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; } + if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ? pFileName : "stdout" ); return; } Ndr_DesForEachMod( p, Mod ) Ndr_WriteVerilogModule( pFile, p, Mod, pNames, fSimple ); @@ -633,7 +633,7 @@ static inline void Ndr_Write( char * pFileName, void * pDesign ) { Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int RetValue; FILE * pFile = fopen( pFileName, "wb" ); - if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ); return; } + if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ? pFileName : "stdout" ); return; } RetValue = (int)fwrite( p->pBody, 4, p->pBody[0], pFile ); RetValue = (int)fwrite( p->pHead, 1, p->pBody[0], pFile ); fclose( pFile ); -- cgit v1.2.3 From a718318740a3a50f6058b3d64330dbe8ca1e6303 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Sep 2021 22:54:19 -0700 Subject: Various changes. --- src/aig/gia/gia.h | 8 ++++ src/aig/gia/giaAiger.c | 31 +++++++++++-- src/aig/gia/giaDup.c | 46 +++++++++++++++++++ src/aig/gia/giaIf.c | 3 +- src/aig/gia/giaMan.c | 3 ++ src/aig/gia/giaResub.c | 114 ++++++++++++++++++++++++++++++++++++++--------- src/aig/gia/giaSimBase.c | 22 ++++++++- 7 files changed, 200 insertions(+), 27 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 8a5137fe..73602a03 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -171,6 +171,7 @@ struct Gia_Man_t_ Vec_Int_t * vCoReqs; // CO required times Vec_Int_t * vCoArrs; // CO arrival times Vec_Int_t * vCoAttrs; // CO attributes + Vec_Int_t * vWeights; // object attributes int And2Delay; // delay of the AND gate float DefInArrs; // default PI arrival times float DefOutReqs; // default PO required times @@ -179,6 +180,7 @@ struct Gia_Man_t_ int nTravIdsAlloc; // the number of trav IDs allocated Vec_Ptr_t * vNamesIn; // the input names Vec_Ptr_t * vNamesOut; // the output names + Vec_Ptr_t * vNamesNode; // the node names Vec_Int_t * vUserPiIds; // numbers assigned to PIs by the user Vec_Int_t * vUserPoIds; // numbers assigned to POs by the user Vec_Int_t * vUserFfIds; // numbers assigned to FFs by the user @@ -480,6 +482,8 @@ static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; } static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); } static inline int Gia_ObjPhaseDiff( Gia_Man_t * p, int i, int k ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, k)->fPhase; } +static inline char * Gia_ObjName( Gia_Man_t * p, int i ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, i) : NULL; } +static inline char * Gia_ObjNameObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, Gia_ObjId(p, pObj)) : NULL; } static inline int Gia_ObjIsTerm( Gia_Obj_t * pObj ) { return pObj->fTerm; } static inline int Gia_ObjIsAndOrConst0( Gia_Obj_t * pObj ) { return!pObj->fTerm; } @@ -618,6 +622,8 @@ static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) static inline void Gia_ObjSetTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds - 1; } static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); } static inline int Gia_ObjIsTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds - 1); } +static inline int Gia_ObjUpdateTravIdCurrentId( Gia_Man_t * p, int Id ) { if ( Gia_ObjIsTravIdCurrentId(p, Id) ) return 1; Gia_ObjSetTravIdCurrentId(p, Id); return 0; } +static inline int Gia_ObjUpdateTravIdPreviousId( Gia_Man_t * p, int Id ) { if ( Gia_ObjIsTravIdPreviousId(p, Id) ) return 1; Gia_ObjSetTravIdPreviousId(p, Id); return 0; } static inline void Gia_ManTimeClean( Gia_Man_t * p ) { int i; assert( p->vTiming != NULL ); Vec_FltFill(p->vTiming, 3*Gia_ManObjNum(p), 0); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Vec_FltWriteEntry( p->vTiming, 3*i+1, (float)(ABC_INFINITY) ); } static inline void Gia_ManTimeStart( Gia_Man_t * p ) { assert( p->vTiming == NULL ); p->vTiming = Vec_FltAlloc(0); Gia_ManTimeClean( p ); } @@ -1305,6 +1311,7 @@ extern Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTimes( Gia_Man_t * p, int nTimes ); extern Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupDfsOnePo( Gia_Man_t * p, int iPo ); +extern Gia_Man_t * Gia_ManDupDfsRehash( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupCofactorVar( Gia_Man_t * p, int iVar, int Value ); extern Gia_Man_t * Gia_ManDupCofactorObj( Gia_Man_t * p, int iObj, int Value ); extern Gia_Man_t * Gia_ManDupMux( int iVar, Gia_Man_t * pCof1, Gia_Man_t * pCof0 ); @@ -1567,6 +1574,7 @@ extern int Gia_ManIncrSimCheckOver( Gia_Man_t * p, int iLit0, in extern int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 ); /*=== giaSimBase.c ============================================================*/ extern Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * p ); +extern Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOuts ); /*=== giaSpeedup.c ============================================================*/ extern float Gia_ManDelayTraceLut( Gia_Man_t * p ); extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ); diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index c2c0e969..1bb70612 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -176,7 +176,7 @@ Vec_Str_t * Gia_AigerWriteLiterals( Vec_Int_t * vLits ) Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck ) { Gia_Man_t * pNew, * pTemp; - Vec_Ptr_t * vNamesIn = NULL, * vNamesOut = NULL, * vNamesRegIn = NULL, * vNamesRegOut = NULL; + Vec_Ptr_t * vNamesIn = NULL, * vNamesOut = NULL, * vNamesRegIn = NULL, * vNamesRegOut = NULL, * vNamesNode = NULL; Vec_Int_t * vLits = NULL, * vPoTypes = NULL; Vec_Int_t * vNodes, * vDrivers, * vInits = NULL; int iObj, iNode0, iNode1, fHieOnly = 0; @@ -388,7 +388,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi char * pType = (char *)pCur; char * pName = NULL; // check terminal type - if ( *pCur != 'i' && *pCur != 'o' && *pCur != 'l' ) + if ( *pCur != 'i' && *pCur != 'o' && *pCur != 'l' && *pCur != 'n' ) { fError = 1; break; @@ -442,6 +442,18 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi Vec_PtrPush( vNamesRegIn, Abc_UtilStrsav(Buffer) ); Vec_PtrPush( vNamesRegOut, Abc_UtilStrsav(pName) ); } + else if ( *pType == 'n' ) + { + if ( Vec_IntSize(&pNew->vHTable) != 0 ) + { + printf( "Structural hashing should be disabled to read internal nodes names.\n" ); + fError = 1; + break; + } + if ( vNamesNode == NULL ) + vNamesNode = Vec_PtrStart( Gia_ManObjNum(pNew) ); + Vec_PtrWriteEntry( vNamesNode, iTerm, Abc_UtilStrsav(pName) ); + } else { fError = 1; @@ -451,11 +463,12 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi } if ( fError ) { - printf( "Error occurred when reading signal names.\n" ); + printf( "Error occurred when reading signal names. Signal names ignored.\n" ); if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn ), vNamesIn = NULL; if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut ), vNamesOut = NULL; if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn ), vNamesRegIn = NULL; if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut ), vNamesRegOut = NULL; + if ( vNamesNode ) Vec_PtrFreeFree( vNamesNode ), vNamesNode = NULL; } } else @@ -976,6 +989,10 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi vNamesRegIn = NULL; } } + if ( vNamesNode && Gia_ManObjNum(pNew) != Vec_PtrSize(vNamesNode) ) + Abc_Print( 0, "The size of the node name array does not match the number of objects. Names are not entered.\n" ); + else if ( vNamesNode ) + pNew->vNamesNode = vNamesNode, vNamesNode = NULL; if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn ); if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut ); if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn ); @@ -1311,6 +1328,14 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int Gia_ManForEachPo( p, pObj, i ) fprintf( pFile, "o%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesOut, i) ); } + if ( p->vNamesNode && Vec_PtrSize(p->vNamesNode) != Gia_ManObjNum(p) ) + Abc_Print( 0, "The size of the node name array does not match the number of objects. Names are not written.\n" ); + else if ( p->vNamesNode ) + { + Gia_ManForEachAnd( p, pObj, i ) + if ( Vec_PtrEntry(p->vNamesNode, i) ) + fprintf( pFile, "n%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesNode, i) ); + } // write the comment if ( fWriteNewLine ) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index c1da11da..65eff161 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -1608,6 +1608,52 @@ Gia_Man_t * Gia_ManDupDfsOnePo( Gia_Man_t * p, int iPo ) return pNew; } +/**Function************************************************************* + + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupDfsRehash_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Gia_Man_t * Gia_ManDupDfsRehash( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManDupDfsRehash_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew->nConstrs = p->nConstrs; + if ( p->pCexSeq ) + pNew->pCexSeq = Abc_CexDup( p->pCexSeq, Gia_ManRegNum(p) ); + return pNew; +} + /**Function************************************************************* Synopsis [Cofactors w.r.t. a primary input variable.] diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 2f2566d1..ae87277a 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -2222,10 +2222,11 @@ void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia ) p->DefOutReqs = pGia->DefOutReqs; p->And2Delay = pGia->And2Delay; } - if ( pGia->vNamesIn || pGia->vNamesOut ) + if ( pGia->vNamesIn || pGia->vNamesOut || pGia->vNamesNode ) { p->vNamesIn = pGia->vNamesIn; pGia->vNamesIn = NULL; p->vNamesOut = pGia->vNamesOut; pGia->vNamesOut = NULL; + p->vNamesNode = pGia->vNamesNode; pGia->vNamesNode = NULL; } if ( pGia->vConfigs || pGia->pCellStr ) { diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index e4c9afd0..bb1305be 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -90,6 +90,7 @@ void Gia_ManStop( Gia_Man_t * p ) assert( p->pManTime == NULL ); Vec_PtrFreeFree( p->vNamesIn ); Vec_PtrFreeFree( p->vNamesOut ); + Vec_PtrFreeFree( p->vNamesNode ); Vec_IntFreeP( &p->vSwitching ); Vec_IntFreeP( &p->vSuper ); Vec_IntFreeP( &p->vStore ); @@ -148,6 +149,7 @@ void Gia_ManStop( Gia_Man_t * p ) Vec_IntFreeP( &p->vCoReqs ); Vec_IntFreeP( &p->vCoArrs ); Vec_IntFreeP( &p->vCoAttrs ); + Vec_IntFreeP( &p->vWeights ); Gia_ManStopP( &p->pAigExtra ); Vec_IntFree( p->vCis ); Vec_IntFree( p->vCos ); @@ -202,6 +204,7 @@ double Gia_ManMemory( Gia_Man_t * p ) Memory += Vec_FltMemory( p->vOutReqs ); Memory += Vec_PtrMemory( p->vNamesIn ); Memory += Vec_PtrMemory( p->vNamesOut ); + Memory += Vec_PtrMemory( p->vNamesNode ); return Memory; } diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 06e002af..660440c3 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -558,11 +558,11 @@ int Gia_ManConstructFromMap( Gia_Man_t * pNew, Vec_Int_t * vGates, int nVars, Ve iLitRes = Vec_IntEntry( vCopy, Vec_IntSize(vGates)/2-1 ); return iLitRes; } -Gia_Man_t * Gia_ManConstructFromGates( Vec_Wec_t * vFuncs, int nVars ) +Gia_Man_t * Gia_ManConstructFromGates( Vec_Wec_t * vFuncs, int nDivs ) { Vec_Int_t * vGates; int i, k, iLit; Vec_Int_t * vCopy = Vec_IntAlloc( 100 ); - Vec_Int_t * vUsed = Vec_IntStartFull( nVars ); + Vec_Int_t * vUsed = Vec_IntStartFull( nDivs ); Gia_Man_t * pNew = Gia_ManStart( 100 ); pNew->pName = Abc_UtilStrsav( "resub" ); Vec_WecForEachLevel( vFuncs, vGates, i ) @@ -571,7 +571,7 @@ Gia_Man_t * Gia_ManConstructFromGates( Vec_Wec_t * vFuncs, int nVars ) Vec_IntForEachEntry( vGates, iLit, k ) { int iVar = Abc_Lit2Var(iLit); - if ( iVar > 0 && iVar < nVars && Vec_IntEntry(vUsed, iVar) == -1 ) + if ( iVar > 0 && iVar < nDivs && Vec_IntEntry(vUsed, iVar) == -1 ) Vec_IntWriteEntry( vUsed, iVar, Gia_ManAppendCi(pNew) ); } } @@ -580,16 +580,77 @@ Gia_Man_t * Gia_ManConstructFromGates( Vec_Wec_t * vFuncs, int nVars ) int iLitRes, iTopLit = Vec_IntEntryLast( vGates ); if ( Abc_Lit2Var(iTopLit) == 0 ) iLitRes = 0; - else if ( Abc_Lit2Var(iTopLit) < nVars ) - iLitRes = Gia_ManAppendCi(pNew); + else if ( Abc_Lit2Var(iTopLit) < nDivs ) + iLitRes = Vec_IntEntry( vUsed, Abc_Lit2Var(iTopLit) ); else - iLitRes = Gia_ManConstructFromMap( pNew, vGates, nVars, vUsed, vCopy, 0 ); + iLitRes = Gia_ManConstructFromMap( pNew, vGates, nDivs, vUsed, vCopy, 0 ); Gia_ManAppendCo( pNew, Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ) ); } Vec_IntFree( vCopy ); Vec_IntFree( vUsed ); return pNew; } +Gia_Man_t * Gia_ManConstructFromGates2( Vec_Wec_t * vFuncs, Vec_Wec_t * vDivs, int nObjs, Vec_Int_t ** pvSupp ) +{ + Vec_Int_t * vGates; int i, k, iVar, iLit; + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Int_t * vCopy = Vec_IntAlloc( 100 ); + Vec_Wec_t * vUseds = Vec_WecStart( Vec_WecSize(vDivs) ); + Vec_Int_t * vMap = Vec_IntStartFull( nObjs ); + Gia_Man_t * pNew = Gia_ManStart( 100 ); + pNew->pName = Abc_UtilStrsav( "resub" ); + assert( Vec_WecSize(vFuncs) == Vec_WecSize(vDivs) ); + Vec_WecForEachLevel( vFuncs, vGates, i ) + { + Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i ); + assert( Vec_IntSize(vGates) % 2 == 1 ); + Vec_IntForEachEntry( vGates, iLit, k ) + { + int iVar = Abc_Lit2Var(iLit); + if ( iVar > 0 && iVar < Vec_IntSize(vDiv) && Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) == -1 ) + Vec_IntWriteEntry( vMap, Vec_IntPushReturn(vSupp, Vec_IntEntry(vDiv, iVar)), 0 ); + } + } + Vec_IntSort( vSupp, 0 ); + Vec_IntForEachEntry( vSupp, iVar, k ) + Vec_IntWriteEntry( vMap, iVar, Gia_ManAppendCi(pNew) ); + Vec_WecForEachLevel( vFuncs, vGates, i ) + { + Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i ); + Vec_Int_t * vUsed = Vec_WecEntry( vUseds, i ); + Vec_IntFill( vUsed, Vec_IntSize(vDiv), -1 ); + Vec_IntForEachEntry( vGates, iLit, k ) + { + int iVar = Abc_Lit2Var(iLit); + if ( iVar > 0 && iVar < Vec_IntSize(vDiv) ) + { + assert( Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) > 0 ); + Vec_IntWriteEntry( vUsed, iVar, Vec_IntEntry(vMap, Vec_IntEntry(vDiv, iVar)) ); + } + } + } + Vec_WecForEachLevel( vFuncs, vGates, i ) + { + Vec_Int_t * vDiv = Vec_WecEntry( vDivs, i ); + Vec_Int_t * vUsed = Vec_WecEntry( vUseds, i ); + int iLitRes, iTopLit = Vec_IntEntryLast( vGates ); + if ( Abc_Lit2Var(iTopLit) == 0 ) + iLitRes = 0; + else if ( Abc_Lit2Var(iTopLit) < Vec_IntSize(vDiv) ) + iLitRes = Vec_IntEntry( vUsed, Abc_Lit2Var(iTopLit) ); + else + iLitRes = Gia_ManConstructFromMap( pNew, vGates, Vec_IntSize(vDiv), vUsed, vCopy, 0 ); + Gia_ManAppendCo( pNew, Abc_LitNotCond( iLitRes, Abc_LitIsCompl(iTopLit) ) ); + } + Vec_IntFree( vMap ); + Vec_IntFree( vCopy ); + Vec_WecFree( vUseds ); + if ( pvSupp ) + *pvSupp = vSupp; + else + Vec_IntFree( vSupp ); + return pNew; +} /**Function************************************************************* @@ -1118,11 +1179,13 @@ int Gia_ManResubAddNode( Gia_ResbMan_t * p, int iLit0, int iLit1, int Type ) Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iFan0, Type==1), Abc_LitNotCond(iFan1, Type==1) ); return Abc_Var2Lit( iNode, Type==1 ); } -int Gia_ManResubPerformMux_rec( Gia_ResbMan_t * p, int nLimit ) +int Gia_ManResubPerformMux_rec( Gia_ResbMan_t * p, int nLimit, int Depth ) { - extern int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ); + extern int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit, int Depth ); int iDivBest, iResLit0, iResLit1, nNodes; word * pDiv, * pCopy[2]; + if ( Depth == 0 ) + return -1; if ( nLimit < 3 ) return -1; iDivBest = Gia_ManResubFindBestBinate( p ); @@ -1136,7 +1199,10 @@ int Gia_ManResubPerformMux_rec( Gia_ResbMan_t * p, int nLimit ) Abc_TtAndSharp( p->pSets[0], pCopy[0], pDiv, p->nWords, !Abc_LitIsCompl(iDivBest) ); Abc_TtAndSharp( p->pSets[1], pCopy[1], pDiv, p->nWords, !Abc_LitIsCompl(iDivBest) ); nNodes = Vec_IntSize(p->vGates)/2; - iResLit0 = Gia_ManResubPerform_rec( p, nLimit-3 ); + //iResLit0 = Gia_ManResubPerform_rec( p, nLimit-3 ); + iResLit0 = Gia_ManResubPerform_rec( p, nLimit, 0 ); + if ( iResLit0 == -1 ) + iResLit0 = Gia_ManResubPerformMux_rec( p, nLimit, Depth-1 ); if ( iResLit0 == -1 ) { ABC_FREE( pCopy[0] ); @@ -1150,7 +1216,10 @@ int Gia_ManResubPerformMux_rec( Gia_ResbMan_t * p, int nLimit ) nNodes = Vec_IntSize(p->vGates)/2 - nNodes; if ( nLimit-nNodes < 3 ) return -1; - iResLit1 = Gia_ManResubPerform_rec( p, nLimit-3-nNodes ); + //iResLit1 = Gia_ManResubPerform_rec( p, nLimit-3-nNodes ); + iResLit1 = Gia_ManResubPerform_rec( p, nLimit, 0 ); + if ( iResLit1 == -1 ) + iResLit1 = Gia_ManResubPerformMux_rec( p, nLimit, Depth-1 ); if ( iResLit1 == -1 ) return -1; else @@ -1172,7 +1241,7 @@ int Gia_ManResubPerformMux_rec( Gia_ResbMan_t * p, int nLimit ) SeeAlso [] ***********************************************************************/ -int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) +int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit, int Depth ) { int TopOneW[2] = {0}, TopTwoW[2] = {0}, Max1, Max2, iResLit, nVars = Vec_PtrSize(p->vDivs); if ( p->fVerbose ) @@ -1205,7 +1274,8 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) return Abc_Var2Lit( iNode, fComp ); } Vec_IntTwoFindCommon( p->vNotUnateVars[0], p->vNotUnateVars[1], p->vBinateVars ); - //return Gia_ManResubPerformMux_rec( p, nLimit ); + if ( Depth ) + return Gia_ManResubPerformMux_rec( p, nLimit, Depth ); if ( Vec_IntSize(p->vBinateVars) > p->nDivsMax ) Vec_IntShrink( p->vBinateVars, p->nDivsMax ); if ( p->fVerbose ) printf( " B = %3d", Vec_IntSize(p->vBinateVars) ); @@ -1304,7 +1374,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], pDiv, p->nWords, !fComp ); if ( p->fVerbose ) printf( "\n" ); - iResLit = Gia_ManResubPerform_rec( p, nLimit-1 ); + iResLit = Gia_ManResubPerform_rec( p, nLimit-1, Depth ); if ( iResLit >= 0 ) { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1348,7 +1418,7 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) Abc_TtAndSharp( p->pSets[fUseOr], p->pSets[fUseOr], p->pDivA, p->nWords, !fComp ); if ( p->fVerbose ) printf( "\n" ); - iResLit = Gia_ManResubPerform_rec( p, nLimit-2 ); + iResLit = Gia_ManResubPerform_rec( p, nLimit-2, Depth ); if ( iResLit >= 0 ) { int iNode = nVars + Vec_IntSize(p->vGates)/2; @@ -1383,11 +1453,11 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit ) } return -1; } -void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose ) +void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, int Depth ) { int Res; Gia_ResbInit( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, fVerbose ); - Res = Gia_ManResubPerform_rec( p, nLimit ); + Res = Gia_ManResubPerform_rec( p, nLimit, Depth ); if ( Res >= 0 ) Vec_IntPush( p->vGates, Res ); else @@ -1395,11 +1465,11 @@ void Gia_ManResubPerform( Gia_ResbMan_t * p, Vec_Ptr_t * vDivs, int nWords, int if ( fVerbose ) printf( "\n" ); } -Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc ) +Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc, int Depth ) { Vec_Int_t * vRes; Gia_ResbMan_t * p = Gia_ResbAlloc( nWords ); - Gia_ManResubPerform( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose ); + Gia_ManResubPerform( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, Depth ); if ( fVerbose ) Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); if ( fVerbose ) @@ -1444,7 +1514,7 @@ int Abc_ResubComputeFunction( void ** ppDivs, int nDivs, int nWords, int nLimit, { Vec_Ptr_t Divs = { nDivs, nDivs, ppDivs }; assert( s_pResbMan != NULL ); // first call Abc_ResubPrepareManager() - Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose==2 ); + Gia_ManResubPerform( s_pResbMan, &Divs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose==2, 0 ); if ( fVerbose ) { int nGates = Vec_IntSize(s_pResbMan->vGates)/2; @@ -1563,7 +1633,7 @@ void Gia_ManResubTest3_() printf( " " ); Dau_DsdPrintFromTruth2( &Truth, 6 ); printf( " " ); - Gia_ManResubPerform( p, vDivs, 1, 100, 0, 50, 1, 1, 0 ); + Gia_ManResubPerform( p, vDivs, 1, 100, 0, 50, 1, 1, 0, 0 ); } Gia_ResbFree( p ); Vec_IntFree( vRes ); @@ -1604,7 +1674,7 @@ void Gia_ManResubPair( Vec_Wrd_t * vOn, Vec_Wrd_t * vOff, int nWords, int nIns ) memmove( pSim+nWords, Vec_WrdEntryP(vOff, (i-2)*nWords), sizeof(word)*nWords ); } } - Gia_ManResubPerform( p, vDivs, nWords*2, 100, 0, 50, 1, 1, 0 ); + Gia_ManResubPerform( p, vDivs, nWords*2, 100, 0, 50, 1, 1, 0, 0 ); Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); printf( "\n" ); //Vec_PtrFree( vDivs ); @@ -1672,7 +1742,7 @@ Gia_Man_t * Gia_ManResub1( char * pFileName, int nNodes, int nSupp, int nDivs, i Vec_PtrShrink( vDivs, (1<<14)-1 ); } assert( Vec_PtrSize(vDivs) < (1<<14) ); - Gia_ManResubPerform( p, vDivs, nWords, 100, 50, iChoice, fUseXor, 1, 1 ); + Gia_ManResubPerform( p, vDivs, nWords, 100, 50, iChoice, fUseXor, 1, 1, 0 ); if ( Vec_IntSize(p->vGates) ) { Vec_Wec_t * vGates = Vec_WecStart(1); diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 79377310..42318f5c 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -134,6 +134,27 @@ Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia ) Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); return vSims; } +Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOuts ) +{ + Gia_Obj_t * pObj; + int i, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(pGia); + Vec_Wrd_t * vSimsCo = fOuts ? Vec_WrdStart( Gia_ManCoNum(pGia) * nWords ) : NULL; + Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords ); + assert( Vec_WrdSize(vSimsPi) % Gia_ManCiNum(pGia) == 0 ); + Gia_ManSimPatAssignInputs( pGia, nWords, vSims, vSimsPi ); + Gia_ManForEachAnd( pGia, pObj, i ) + Gia_ManSimPatSimAnd( pGia, i, pObj, nWords, vSims ); + Gia_ManForEachCo( pGia, pObj, i ) + Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); + Gia_ManForEachCo( pGia, pObj, i ) + Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); + if ( !fOuts ) + return vSims; + Gia_ManForEachCo( pGia, pObj, i ) + memcpy( Vec_WrdEntryP(vSimsCo, i*nWords), Vec_WrdEntryP(vSims, Gia_ObjId(pGia, pObj)*nWords), sizeof(word)*nWords ); + Vec_WrdFree( vSims ); + return vSimsCo; +} void Gia_ManSimPatResim( Gia_Man_t * pGia, Vec_Int_t * vObjs, int nWords, Vec_Wrd_t * vSims ) { Gia_Obj_t * pObj; int i; @@ -550,7 +571,6 @@ Vec_Wrd_t * Gia_ManSimBitPacking( Gia_Man_t * p, Vec_Int_t * vCexStore, int nCex return vSimsRes; } - /**Function************************************************************* Synopsis [] -- cgit v1.2.3 From ed9c16d4f5e1484bb287c30a6af50832a62d35ec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Sep 2021 18:14:10 -0700 Subject: Additional MiniLUT API. --- src/aig/gia/giaMini.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 7a18d2d2..045b3b0e 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -589,6 +589,23 @@ int * Abc_FrameReadMiniLutNameMapping( Abc_Frame_t * pAbc ) Gia_ManStop( pGia ); return pRes; } +int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc ) +{ + Vec_Int_t * vSwitching; + int i, iObj, * pRes = NULL; + if ( pAbc->pGiaMiniLut == NULL ) + { + printf( "GIA derived from MiniLut is not available.\n" ); + return NULL; + } + vSwitching = Gia_ManComputeSwitchProbs( pAbc->pGiaMiniLut, 48, 16, 0 ); + pRes = ABC_CALLOC( int, Vec_IntSize(pAbc->vCopyMiniLut) ); + Vec_IntForEachEntry( pAbc->vCopyMiniLut, iObj, i ) + if ( iObj >= 0 ) + pRes[i] = Vec_IntEntry( vSwitching, iObj ); + Vec_IntFree( vSwitching ); + return pRes; +} /**Function************************************************************* -- cgit v1.2.3 From e7a029d73fbce3145063f0e65b952b356014cf63 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 4 Sep 2021 19:21:59 -0700 Subject: Various changes. --- src/aig/gia/giaResub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 660440c3..95ed12cf 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -1472,8 +1472,8 @@ Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDiv Gia_ManResubPerform( p, vDivs, nWords, nLimit, nDivsMax, iChoice, fUseXor, fDebug, fVerbose, Depth ); if ( fVerbose ) Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); - if ( fVerbose ) - printf( "\n" ); + //if ( fVerbose ) + // printf( "\n" ); if ( !Gia_ManResubVerify(p, pFunc) ) { Gia_ManResubPrint( p->vGates, Vec_PtrSize(vDivs) ); -- cgit v1.2.3 From 9d89faa82b8f6b344ff189c0389889efc31e06a8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Sep 2021 11:40:29 -0700 Subject: Bug fix in logic optimization. --- src/aig/gia/giaMinLut.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c index 957ee2c0..5304486d 100644 --- a/src/aig/gia/giaMinLut.c +++ b/src/aig/gia/giaMinLut.c @@ -597,7 +597,7 @@ void Gia_ManPermuteSupp( Gia_Man_t * p, int iOut, int nOuts, Vec_Int_t * vSupp ) for ( i = 0; i < nOuts; i++ ) Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vLevels, vCounts ); Gia_ManForEachObjVec( vSupp, p, pObj, i ) - pCost[i] = 10000 * Vec_IntEntry(vLevels, Gia_ObjCioId(pObj)) / Vec_IntEntry(vCounts, Gia_ObjCioId(pObj)); + pCost[i] = 10000 * Vec_IntEntry(vLevels, Gia_ObjCioId(pObj)) / Abc_MaxInt(1, Vec_IntEntry(vCounts, Gia_ObjCioId(pObj))); Vec_IntFree( vCounts ); Vec_IntFree( vLevels ); Vec_IntSelectSortCost2( Vec_IntArray(vSupp), Vec_IntSize(vSupp), pCost ); @@ -777,6 +777,21 @@ Gia_Man_t * Gia_ManPerformLNetOptNew( Gia_Man_t * p, char * pFileName, int nIns, Gia_ManHashStart( pNew ); for ( g = 0; g < Gia_ManCoNum(p); g += nOuts ) { + for ( k = 0; k < nOuts; k++ ) + if ( Gia_ObjIsAnd(Gia_ObjFanin0(Gia_ManCo( p, g+k ))) ) + break; + if ( k == nOuts ) + { + for ( k = 0; k < nOuts; k++ ) + { + Gia_Obj_t * pObj = Gia_ManCo( p, g+k ); + pObj->Value = Gia_ObjFanin0Copy(pObj); + } + continue; + } + else + { + Vec_Int_t * vSupp = Gia_ManCollectSuppNew( p, g, nOuts ); int Care = 1 << Vec_IntSize(vSupp), Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0; word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) ); @@ -808,6 +823,8 @@ Gia_Man_t * Gia_ManPerformLNetOptNew( Gia_Man_t * p, char * pFileName, int nIns, Gia_ManStop( pMin ); Vec_IntFree( vSupp ); Temp = 0; + + } } CareAve /= Gia_ManCoNum(p)/nOuts; Gia_ManHashStop( pNew ); -- cgit v1.2.3 From d3d564400594128380d5f4603ebd7de445e6f773 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Sep 2021 09:11:02 -0700 Subject: Procedure to printout MiniLUT. --- src/aig/miniaig/minilut.h | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/miniaig/minilut.h b/src/aig/miniaig/minilut.h index b080c983..2a27ccad 100644 --- a/src/aig/miniaig/minilut.h +++ b/src/aig/miniaig/minilut.h @@ -179,7 +179,37 @@ static void Mini_LutPrintStats( Mini_Lut_t * p ) nNodes = 0; Mini_LutForEachNode( p, i ) nNodes++; - printf( "PI = %d. PO = %d. LUT = %d.\n", nPis, nPos, nNodes ); + printf( "PI = %d. PO = %d. LUT = %d. FF = %d.\n", nPis, nPos, nNodes, p->nRegs ); +} +static void Mini_LutPrint( Mini_Lut_t * p ) +{ + int i, k, Fan; + printf( "MiniLUT statistics: " ); + Mini_LutPrintStats( p ); + printf( "Printout of nodes:\n" ); + for ( i = 0; i < p->nSize; i++ ) + { + printf( "%6d : ", i ); + if ( Mini_LutNodeIsConst(p, i) ) + printf( "Const%d", i ); + else if ( Mini_LutNodeIsPi(p, i) ) + printf( "PI" ); + else if ( Mini_LutNodeIsPo(p, i) ) + printf( "PO" ); + else if ( Mini_LutNodeIsNode(p, i) ) + { + printf( "LUT%d Fanins:", p->LutSize ); + Mini_LutForEachFanin( p, i, Fan, k ) + printf( " %6d", Fan ); + while ( k++ < p->LutSize ) + printf( " " ); + printf( " Function: " ); + for ( k = 31; k >= 0; k-- ) + printf( "%c", '0' + ((p->pTruths[i] >> k) & 1) ); + } + printf( "\n" ); + } + printf( "End of printout.\n" ); } // serialization -- cgit v1.2.3 From 2f993e583d2a6e84b38b05e96ecd11fb3c1a195a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 13 Sep 2021 08:40:44 -0700 Subject: Bug fix in MiniLUT code. --- src/aig/gia/giaMini.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 045b3b0e..bc4ce10f 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -602,7 +602,7 @@ int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc ) pRes = ABC_CALLOC( int, Vec_IntSize(pAbc->vCopyMiniLut) ); Vec_IntForEachEntry( pAbc->vCopyMiniLut, iObj, i ) if ( iObj >= 0 ) - pRes[i] = Vec_IntEntry( vSwitching, iObj ); + pRes[i] = Vec_IntEntry( vSwitching, Abc_Lit2Var(iObj) ); Vec_IntFree( vSwitching ); return pRes; } -- cgit v1.2.3 From ecda331a2a921bcac30bf3210f56adf9152ca22f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 14 Sep 2021 22:01:41 -0700 Subject: Various changes. --- src/aig/gia/gia.h | 10 +++- src/aig/gia/giaResub.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 73602a03..9e215454 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -482,6 +482,8 @@ static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; } static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); } static inline int Gia_ObjPhaseDiff( Gia_Man_t * p, int i, int k ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, k)->fPhase; } +static inline char * Gia_ObjCiName( Gia_Man_t * p, int i ) { return p->vNamesIn ? (char*)Vec_PtrEntry(p->vNamesIn, i) : NULL; } +static inline char * Gia_ObjCoName( Gia_Man_t * p, int i ) { return p->vNamesOut ? (char*)Vec_PtrEntry(p->vNamesOut, i) : NULL; } static inline char * Gia_ObjName( Gia_Man_t * p, int i ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, i) : NULL; } static inline char * Gia_ObjNameObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, Gia_ObjId(p, pObj)) : NULL; } @@ -1161,7 +1163,13 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re for ( i = 1; (i < p->nObjs) && ((pObj) = Gia_ManObj(p, i)); i++ ) #define Gia_ManForEachObjVec( vVec, p, pObj, i ) \ for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) -#define Gia_ManForEachObjVecReverse( vVec, p, pObj, i ) \ +#define Gia_ManForEachObjVecStart( vVec, p, pObj, i, Start ) \ + for ( i = Start; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) +#define Gia_ManForEachObjVecStop( vVec, p, pObj, i, Stop ) \ + for ( i = 0; (i < Stop) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) +#define Gia_ManForEachObjVecStartStop( vVec, p, pObj, i, Start, Stop ) \ + for ( i = Start; (i < Stop) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) +#define Gia_ManForEachObjVecReverse( vVec, p, pObj, i ) \ for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i-- ) #define Gia_ManForEachObjVecLit( vVec, p, pObj, fCompl, i ) \ for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Abc_Lit2Var(Vec_IntEntry(vVec,i)))) && (((fCompl) = Abc_LitIsCompl(Vec_IntEntry(vVec,i))),1); i++ ) diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index 95ed12cf..a5017b7d 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -1888,6 +1888,132 @@ void Gia_ManTryResub( Gia_Man_t * p ) } +/**Function************************************************************* + + Synopsis [Deriving a subset.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManDeriveShrink( Vec_Wrd_t * vFuncs, int nWords ) +{ + int i, k = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2; + assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) ); + for ( i = 0; i < nFuncs; i++ ) + { + word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords); + word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords); + if ( Abc_TtIsConst0(pFunc0, nWords) || Abc_TtIsConst0(pFunc1, nWords) ) + continue; + if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), pFunc0, nWords, 0 ); + if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), pFunc1, nWords, 0 ); + k++; + } + Vec_WrdShrink( vFuncs, 2*k*nWords ); + return k; +} +void Gia_ManDeriveCounts( Vec_Wrd_t * vFuncs, int nWords, Vec_Int_t * vCounts ) +{ + int i, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2; + assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) ); + Vec_IntClear( vCounts ); + for ( i = 0; i < 2*nFuncs; i++ ) + Vec_IntPush( vCounts, Abc_TtCountOnesVec(Vec_WrdEntryP(vFuncs, i*nWords), nWords) ); +} +int Gia_ManDeriveCost( Vec_Wrd_t * vFuncs, int nWords, word * pMask, Vec_Int_t * vCounts ) +{ + int i, Res = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2; + assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) ); + assert( Vec_IntSize(vCounts) * nWords == Vec_WrdSize(vFuncs) ); + for ( i = 0; i < nFuncs; i++ ) + { + int Total[2] = { Vec_IntEntry(vCounts, 2*i+0), Vec_IntEntry(vCounts, 2*i+1) }; + int This[2] = { Abc_TtCountOnesVecMask(Vec_WrdEntryP(vFuncs, (2*i+0)*nWords), pMask, nWords, 0), + Abc_TtCountOnesVecMask(Vec_WrdEntryP(vFuncs, (2*i+1)*nWords), pMask, nWords, 0) }; + assert( Total[0] >= This[0] && Total[1] >= This[1] ); + Res += This[0] * This[1] + (Total[0] - This[0]) * (Total[1] - This[1]); + } + return Res; +} +int Gia_ManDeriveSimpleCost( Vec_Int_t * vCounts ) +{ + int i, Ent1, Ent2, Res = 0; + Vec_IntForEachEntryDouble( vCounts, Ent1, Ent2, i ) + Res += Ent1*Ent2; + return Res; +} +void Gia_ManDeriveNext( Vec_Wrd_t * vFuncs, int nWords, word * pMask ) +{ + int i, iStop = Vec_WrdSize(vFuncs); word Data; + int nFuncs = Vec_WrdSize(vFuncs) / nWords / 2; + assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) ); + Vec_WrdForEachEntryStop( vFuncs, Data, i, iStop ) + Vec_WrdPush( vFuncs, Data ); + for ( i = 0; i < nFuncs; i++ ) + { + word * pFunc0n = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords); + word * pFunc1n = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords); + word * pFunc0p = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords + iStop); + word * pFunc1p = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords + iStop); + Abc_TtAnd( pFunc0p, pFunc0n, pMask, nWords, 0 ); + Abc_TtAnd( pFunc1p, pFunc1n, pMask, nWords, 0 ); + Abc_TtSharp( pFunc0n, pFunc0n, pMask, nWords ); + Abc_TtSharp( pFunc1n, pFunc1n, pMask, nWords ); + } +} +Vec_Int_t * Gia_ManDeriveSubset( Gia_Man_t * p, Vec_Wrd_t * vFuncs, Vec_Int_t * vObjs, Vec_Wrd_t * vSims, int nWords, int fVerbose ) +{ + int i, k, iObj, CostBestPrev, nFuncs = Vec_WrdSize(vFuncs) / nWords; + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Vec_Int_t * vCounts = Vec_IntAlloc( nFuncs * 2 ); + Vec_Wrd_t * vFSims = Vec_WrdDup( vFuncs ); + assert( nFuncs * nWords == Vec_WrdSize(vFuncs) ); + assert( Gia_ManObjNum(p) * nWords == Vec_WrdSize(vSims) ); + assert( Vec_IntSize(vObjs) <= Gia_ManCandNum(p) ); + nFuncs = Gia_ManDeriveShrink( vFSims, nWords ); + Gia_ManDeriveCounts( vFSims, nWords, vCounts ); + assert( Vec_IntSize(vCounts) * nWords == Vec_WrdSize(vFSims) ); + CostBestPrev = Gia_ManDeriveSimpleCost( vCounts ); + if ( fVerbose ) + printf( "Processing %d functions and %d objects with cost %d\n", nFuncs, Vec_IntSize(vObjs), CostBestPrev ); + for ( i = 0; nFuncs > 0; i++ ) + { + int iObjBest = -1, CountThis, Count0 = ABC_INFINITY, CountBest = ABC_INFINITY; + Vec_IntForEachEntry( vObjs, iObj, k ) + { + if ( Vec_IntFind(vRes, iObj) >= 0 ) + continue; + CountThis = Gia_ManDeriveCost( vFSims, nWords, Vec_WrdEntryP(vSims, iObj*nWords), vCounts ); + if ( CountBest > CountThis ) + { + CountBest = CountThis; + iObjBest = iObj; + } + if ( !k ) Count0 = CountThis; + } + if ( Count0 < CostBestPrev ) + { + CountBest = Count0; + iObjBest = Vec_IntEntry(vObjs, 0); + } + Gia_ManDeriveNext( vFSims, nWords, Vec_WrdEntryP(vSims, iObjBest*nWords) ); + nFuncs = Gia_ManDeriveShrink( vFSims, nWords ); + Gia_ManDeriveCounts( vFSims, nWords, vCounts ); + assert( CountBest == Gia_ManDeriveSimpleCost(vCounts) ); + Vec_IntPush( vRes, iObjBest ); + CostBestPrev = CountBest; + if ( fVerbose ) + printf( "Iter %2d : Funcs = %6d. Object %6d. Cost %6d.\n", i, nFuncs, iObjBest, CountBest ); + } + Vec_IntFree( vCounts ); + Vec_WrdFree( vFSims ); + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 997e1a2ddceacf8eaeb32ab1d28143da095b63ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Sep 2021 17:48:57 -0700 Subject: Further debugging of MiniLUT APIs. --- src/aig/gia/giaMini.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index bc4ce10f..df0d6533 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -32,6 +32,8 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -260,6 +262,66 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p, Vec_Int_t ** pvCopies ) return pGia; } + +/**Function************************************************************* + + Synopsis [Converts MiniLUT into GIA.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManFromMiniLut2( Mini_Lut_t * p, Vec_Int_t ** pvCopies ) +{ + Gia_Man_t * pGia; + Vec_Int_t * vCopies; + Vec_Int_t * vCover = Vec_IntAlloc( 1000 ); + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + int i, k, Fan, iGiaLit, nNodes; + int LutSize = Abc_MaxInt( 2, Mini_LutSize(p) ); + // get the number of nodes + nNodes = Mini_LutNodeNum(p); + // create ABC network + pGia = Gia_ManStart( 3 * nNodes ); + pGia->pName = Abc_UtilStrsav( "MiniLut" ); + // create mapping from MiniLUT objects into ABC objects + vCopies = Vec_IntAlloc( nNodes ); + Vec_IntPush( vCopies, 0 ); + Vec_IntPush( vCopies, 1 ); + // iterate through the objects + pGia->fGiaSimple = 1; + for ( i = 2; i < nNodes; i++ ) + { + if ( Mini_LutNodeIsPi( p, i ) ) + iGiaLit = Gia_ManAppendCi(pGia); + else if ( Mini_LutNodeIsPo( p, i ) ) + iGiaLit = Gia_ManAppendCo(pGia, Vec_IntEntry(vCopies, Mini_LutNodeFanin(p, i, 0))); + else if ( Mini_LutNodeIsNode( p, i ) ) + { + unsigned * puTruth = Mini_LutNodeTruth( p, i ); + Vec_IntClear( vLits ); + Mini_LutForEachFanin( p, i, Fan, k ) + Vec_IntPush( vLits, Vec_IntEntry(vCopies, Fan) ); + iGiaLit = Kit_TruthToGia( pGia, puTruth, Vec_IntSize(vLits), vCover, vLits, 0 ); + } + else assert( 0 ); + Vec_IntPush( vCopies, iGiaLit ); + } + Vec_IntFree( vCover ); + Vec_IntFree( vLits ); + assert( Vec_IntSize(vCopies) == nNodes ); + if ( pvCopies ) + *pvCopies = vCopies; + else + Vec_IntFree( vCopies ); + Gia_ManSetRegNum( pGia, Mini_LutRegNum(p) ); + return pGia; +} + + /**Function************************************************************* Synopsis [Marks LUTs that should be complemented.] @@ -412,6 +474,15 @@ void Abc_FrameGiaInputMiniLut( Abc_Frame_t * pAbc, void * p ) Abc_FrameUpdateGia( pAbc, pGia ); // Gia_ManDelete( pGia ); } +void Abc_FrameGiaInputMiniLut2( Abc_Frame_t * pAbc, void * p ) +{ + if ( pAbc == NULL ) + printf( "ABC framework is not initialized by calling Abc_Start()\n" ); + Vec_IntFreeP( &pAbc->vCopyMiniLut ); + Gia_ManStopP( &pAbc->pGiaMiniLut ); + pAbc->pGiaMiniLut = Gia_ManFromMiniLut2( (Mini_Lut_t *)p, &pAbc->vCopyMiniLut ); +// Abc_FrameUpdateGia( pAbc, pGia ); +} void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc ) { Mini_Lut_t * pRes = NULL; @@ -602,7 +673,7 @@ int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc ) pRes = ABC_CALLOC( int, Vec_IntSize(pAbc->vCopyMiniLut) ); Vec_IntForEachEntry( pAbc->vCopyMiniLut, iObj, i ) if ( iObj >= 0 ) - pRes[i] = Vec_IntEntry( vSwitching, Abc_Lit2Var(iObj) ); + pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, Abc_Lit2Var(iObj) )); Vec_IntFree( vSwitching ); return pRes; } -- cgit v1.2.3 From 6ca31c475f7ae1605be34a0629559db2beef49d1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Sep 2021 21:51:10 -0700 Subject: Improving MiniAIG and name manager. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaMini.c | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 9e215454..42eb71d5 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1527,7 +1527,7 @@ extern void Mf_ManSetDefaultPars( Jf_Par_t * pPars ); extern Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ); extern void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose ); /*=== giaMini.c ===========================================================*/ -extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName ); +extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple ); extern void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName ); extern Gia_Man_t * Gia_ManReadMiniLut( char * pFileName ); extern void Gia_ManWriteMiniLut( Gia_Man_t * pGia, char * pFileName ); diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index df0d6533..ad7ed197 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -59,7 +59,7 @@ int Gia_ObjFromMiniFanin1Copy( Gia_Man_t * pGia, Vec_Int_t * vCopies, Mini_Aig_t int Lit = Mini_AigNodeFanin1( p, Id ); return Abc_LitNotCond( Vec_IntEntry(vCopies, Abc_Lit2Var(Lit)), Abc_LitIsCompl(Lit) ); } -Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies ) +Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies, int fGiaSimple ) { Gia_Man_t * pGia, * pTemp; Vec_Int_t * vCopies; @@ -73,7 +73,10 @@ Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies ) vCopies = Vec_IntAlloc( nNodes ); Vec_IntPush( vCopies, 0 ); // iterate through the objects - Gia_ManHashAlloc( pGia ); + if ( fGiaSimple ) + pGia->fGiaSimple = fGiaSimple; + else + Gia_ManHashAlloc( pGia ); for ( i = 1; i < nNodes; i++ ) { if ( Mini_AigNodeIsPi( p, i ) ) @@ -85,17 +88,19 @@ Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies ) else assert( 0 ); Vec_IntPush( vCopies, iGiaLit ); } - Gia_ManHashStop( pGia ); assert( Vec_IntSize(vCopies) == nNodes ); if ( pvCopies ) *pvCopies = vCopies; else Vec_IntFree( vCopies ); Gia_ManSetRegNum( pGia, Mini_AigRegNum(p) ); - pGia = Gia_ManCleanup( pTemp = pGia ); - if ( pvCopies ) - Gia_ManDupRemapLiterals( *pvCopies, pTemp ); - Gia_ManStop( pTemp ); + if ( !fGiaSimple ) + { + pGia = Gia_ManCleanup( pTemp = pGia ); + if ( pvCopies ) + Gia_ManDupRemapLiterals( *pvCopies, pTemp ); + Gia_ManStop( pTemp ); + } return pGia; } @@ -150,7 +155,7 @@ void Abc_FrameGiaInputMiniAig( Abc_Frame_t * pAbc, void * p ) printf( "ABC framework is not initialized by calling Abc_Start()\n" ); Gia_ManStopP( &pAbc->pGiaMiniAig ); Vec_IntFreeP( &pAbc->vCopyMiniAig ); - pGia = Gia_ManFromMiniAig( (Mini_Aig_t *)p, &pAbc->vCopyMiniAig ); + pGia = Gia_ManFromMiniAig( (Mini_Aig_t *)p, &pAbc->vCopyMiniAig, 0 ); Abc_FrameUpdateGia( pAbc, pGia ); pAbc->pGiaMiniAig = Gia_ManDup( pGia ); // Gia_ManDelete( pGia ); @@ -177,10 +182,10 @@ void * Abc_FrameGiaOutputMiniAig( Abc_Frame_t * pAbc ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManReadMiniAig( char * pFileName ) +Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple ) { Mini_Aig_t * p = Mini_AigLoad( pFileName ); - Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL ); + Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple ); ABC_FREE( pGia->pName ); pGia->pName = Extra_FileNameGeneric( pFileName ); Mini_AigStop( p ); @@ -281,7 +286,6 @@ Gia_Man_t * Gia_ManFromMiniLut2( Mini_Lut_t * p, Vec_Int_t ** pvCopies ) Vec_Int_t * vCover = Vec_IntAlloc( 1000 ); Vec_Int_t * vLits = Vec_IntAlloc( 100 ); int i, k, Fan, iGiaLit, nNodes; - int LutSize = Abc_MaxInt( 2, Mini_LutSize(p) ); // get the number of nodes nNodes = Mini_LutNodeNum(p); // create ABC network -- cgit v1.2.3 From a36325609845c7114541dd23ccb7dae3137f3fd4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Sep 2021 10:08:04 -0700 Subject: Removing unused command. --- src/aig/gia/module.make | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 843d721b..acb32c18 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -79,8 +79,6 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaShrink7.c \ src/aig/gia/giaSim.c \ src/aig/gia/giaSim2.c \ - src/aig/gia/giaSim4.c \ - src/aig/gia/giaSim5.c \ src/aig/gia/giaSimBase.c \ src/aig/gia/giaSort.c \ src/aig/gia/giaSpeedup.c \ -- cgit v1.2.3 From 1e69e7e7d101cca19dcdca6b61d7ca9a1237283c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Sep 2021 10:22:40 -0700 Subject: Adding command &reshape. --- src/aig/gia/giaMan.c | 2 -- src/aig/gia/module.make | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index bb1305be..772dc31a 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -81,8 +81,6 @@ Gia_Man_t * Gia_ManStart( int nObjsMax ) ***********************************************************************/ void Gia_ManStop( Gia_Man_t * p ) { - extern void Gia_DatFree( Gia_Dat_t * p ); - Gia_DatFree( p->pUData ); if ( p->vSeqModelVec ) Vec_PtrFreeFree( p->vSeqModelVec ); Gia_ManStaticFanoutStop( p ); diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index acb32c18..35ed4ab0 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -60,6 +60,8 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaPat.c \ src/aig/gia/giaPf.c \ src/aig/gia/giaQbf.c \ + src/aig/gia/giaReshape1.c \ + src/aig/gia/giaReshape2.c \ src/aig/gia/giaResub.c \ src/aig/gia/giaResub2.c \ src/aig/gia/giaResub3.c \ -- cgit v1.2.3 From 627c7d33fdf217f60b7795b418c29f7f0e455fb4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Sep 2021 10:28:45 -0700 Subject: Adding command &reshape. --- src/aig/gia/giaReshape1.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaReshape2.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaSim4.c | 55 ---------------------------------------------- src/aig/gia/giaSim5.c | 56 ----------------------------------------------- 4 files changed, 111 insertions(+), 111 deletions(-) create mode 100644 src/aig/gia/giaReshape1.c create mode 100644 src/aig/gia/giaReshape2.c delete mode 100644 src/aig/gia/giaSim4.c delete mode 100644 src/aig/gia/giaSim5.c (limited to 'src/aig') diff --git a/src/aig/gia/giaReshape1.c b/src/aig/gia/giaReshape1.c new file mode 100644 index 00000000..cf2c0dbd --- /dev/null +++ b/src/aig/gia/giaReshape1.c @@ -0,0 +1,56 @@ +/**CFile**************************************************************** + + FileName [giaReshape.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManReshape1( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) +{ + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaReshape2.c b/src/aig/gia/giaReshape2.c new file mode 100644 index 00000000..440c33a0 --- /dev/null +++ b/src/aig/gia/giaReshape2.c @@ -0,0 +1,55 @@ +/**CFile**************************************************************** + + FileName [giaReshape.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManReshape2( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) +{ + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSim4.c b/src/aig/gia/giaSim4.c deleted file mode 100644 index 886807d5..00000000 --- a/src/aig/gia/giaSim4.c +++ /dev/null @@ -1,55 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaSim4.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Simulation engine.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaSim4.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -ABC_NAMESPACE_IMPL_START - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nTimeout, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fSkipMffc, int fVerbose ) -{ - return 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaSim5.c b/src/aig/gia/giaSim5.c deleted file mode 100644 index ab33c218..00000000 --- a/src/aig/gia/giaSim5.c +++ /dev/null @@ -1,56 +0,0 @@ -/**CFile**************************************************************** - - FileName [giaSim5.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Scalable AIG package.] - - Synopsis [Simulation engine.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: giaSim5.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" -#include "base/main/main.h" - -ABC_NAMESPACE_IMPL_START - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -void Sim_Init( Abc_Frame_t * pAbc ) {} -void Sim_End( Abc_Frame_t * pAbc ) {} -void Gia_DatFree( Gia_Dat_t * p ) {} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - -- cgit v1.2.3 From cc13d1fb472957d7798165774c6df386433a3d2b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Sep 2021 10:50:10 -0700 Subject: Adding command &reshape. --- src/aig/gia/giaReshape1.c | 2 +- src/aig/gia/giaReshape2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaReshape1.c b/src/aig/gia/giaReshape1.c index cf2c0dbd..52b40bdc 100644 --- a/src/aig/gia/giaReshape1.c +++ b/src/aig/gia/giaReshape1.c @@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManReshape1( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) +Gia_Man_t * Gia_ManReshape1( Gia_Man_t * p, int fUseSimple, int fVerbose, int fVeryVerbose ) { return NULL; } diff --git a/src/aig/gia/giaReshape2.c b/src/aig/gia/giaReshape2.c index 440c33a0..98a4d855 100644 --- a/src/aig/gia/giaReshape2.c +++ b/src/aig/gia/giaReshape2.c @@ -41,7 +41,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManReshape2( Gia_Man_t * p, int fVerbose, int fVeryVerbose ) +Gia_Man_t * Gia_ManReshape2( Gia_Man_t * p, int fUseSimple, int fVerbose, int fVeryVerbose ) { return NULL; } -- cgit v1.2.3 From baf2a6508dde77b466808d83f98bf7e98b7628d6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 22 Sep 2021 17:43:09 -0700 Subject: Experiment with simulation. --- src/aig/gia/giaSimBase.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 42318f5c..b329ca0b 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -146,8 +146,6 @@ Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOut Gia_ManSimPatSimAnd( pGia, i, pObj, nWords, vSims ); Gia_ManForEachCo( pGia, pObj, i ) Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); - Gia_ManForEachCo( pGia, pObj, i ) - Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); if ( !fOuts ) return vSims; Gia_ManForEachCo( pGia, pObj, i ) @@ -155,6 +153,61 @@ Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOut Vec_WrdFree( vSims ); return vSimsCo; } +static inline void Gia_ManSimPatSimAnd3( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC ) +{ + word pComps[2] = { ~(word)0, 0 }; + word Diff0 = pComps[Gia_ObjFaninC0(pObj)]; + word Diff1 = pComps[Gia_ObjFaninC1(pObj)]; + word * pSims0 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId0(pObj, i); + word * pSims1 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId1(pObj, i); + word * pSims2 = Vec_WrdArray(vSims) + nWords*i; + word * pSimsC0 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId0(pObj, i); + word * pSimsC1 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId1(pObj, i); + word * pSimsC2 = Vec_WrdArray(vSimsC) + nWords*i; int w; + if ( Gia_ObjIsXor(pObj) ) + for ( w = 0; w < nWords; w++ ) + { + pSimsC0[w] |= pSimsC2[w]; + pSimsC1[w] |= pSimsC2[w]; + } + else + for ( w = 0; w < nWords; w++ ) + { + pSimsC0[w] |= (pSims2[w] | (pSims0[w] ^ Diff0)) & pSimsC2[w]; + pSimsC1[w] |= (pSims2[w] | (pSims1[w] ^ Diff1)) & pSimsC2[w]; + } +} +Vec_Wrd_t * Gia_ManSimPatSimIn( Gia_Man_t * pGia, Vec_Wrd_t * vSims, int fIns ) +{ + Gia_Obj_t * pObj; + int i, Id, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia); + Vec_Wrd_t * vSimsCi = fIns ? Vec_WrdStart( Gia_ManCiNum(pGia) * nWords ) : NULL; + Vec_Wrd_t * vSimsC = Vec_WrdStart( Vec_WrdSize(vSims) ); + assert( Vec_WrdSize(vSims) % Gia_ManObjNum(pGia) == 0 ); + Gia_ManForEachCoDriverId( pGia, Id, i ) + memset( Vec_WrdEntryP(vSimsC, Id*nWords), 0xFF, sizeof(word)*nWords ); + Gia_ManForEachAndReverse( pGia, pObj, i ) + Gia_ManSimPatSimAnd3( pGia, i, pObj, nWords, vSims, vSimsC ); + if ( !fIns ) + return vSimsC; + Gia_ManForEachCi( pGia, pObj, i ) + memcpy( Vec_WrdEntryP(vSimsCi, i*nWords), Vec_WrdEntryP(vSimsC, Gia_ObjId(pGia, pObj)*nWords), sizeof(word)*nWords ); + Vec_WrdFree( vSimsC ); + return vSimsCi; +} +void Gia_ManSimPatSimInTest( Gia_Man_t * pGia ) +{ + int nWords = 10; + Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords ); + Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pGia, vSimsCi, 0 ); + Vec_Wrd_t * vSims2 = Gia_ManSimPatSimIn( pGia, vSims, 0 ); + int nOnes = Abc_TtCountOnesVec( Vec_WrdArray(vSims2), Vec_WrdSize(vSims2) ); + int nTotal = 64*nWords*Gia_ManCandNum(pGia); + printf( "Ratio = %6.2f %%\n", 100.0*nOnes/nTotal ); + Vec_WrdFree( vSims ); + Vec_WrdFree( vSims2 ); + Vec_WrdFree( vSimsCi ); +} void Gia_ManSimPatResim( Gia_Man_t * pGia, Vec_Int_t * vObjs, int nWords, Vec_Wrd_t * vSims ) { Gia_Obj_t * pObj; int i; -- cgit v1.2.3 From 2ce1ce8bed69623de58d9394e22a3a8812096561 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 26 Sep 2021 11:12:17 -0700 Subject: Various changes. --- src/aig/gia/giaSimBase.c | 60 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index b329ca0b..bfafdcfd 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -177,15 +177,19 @@ static inline void Gia_ManSimPatSimAnd3( Gia_Man_t * p, int i, Gia_Obj_t * pObj, pSimsC1[w] |= (pSims2[w] | (pSims1[w] ^ Diff1)) & pSimsC2[w]; } } -Vec_Wrd_t * Gia_ManSimPatSimIn( Gia_Man_t * pGia, Vec_Wrd_t * vSims, int fIns ) +Vec_Wrd_t * Gia_ManSimPatSimIn( Gia_Man_t * pGia, Vec_Wrd_t * vSims, int fIns, Vec_Int_t * vAnds ) { Gia_Obj_t * pObj; int i, Id, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia); Vec_Wrd_t * vSimsCi = fIns ? Vec_WrdStart( Gia_ManCiNum(pGia) * nWords ) : NULL; Vec_Wrd_t * vSimsC = Vec_WrdStart( Vec_WrdSize(vSims) ); assert( Vec_WrdSize(vSims) % Gia_ManObjNum(pGia) == 0 ); - Gia_ManForEachCoDriverId( pGia, Id, i ) - memset( Vec_WrdEntryP(vSimsC, Id*nWords), 0xFF, sizeof(word)*nWords ); + if ( vAnds ) + Vec_IntForEachEntry( vAnds, Id, i ) + memset( Vec_WrdEntryP(vSimsC, Id*nWords), 0xFF, sizeof(word)*nWords ); + else + Gia_ManForEachCoDriverId( pGia, Id, i ) + memset( Vec_WrdEntryP(vSimsC, Id*nWords), 0xFF, sizeof(word)*nWords ); Gia_ManForEachAndReverse( pGia, pObj, i ) Gia_ManSimPatSimAnd3( pGia, i, pObj, nWords, vSims, vSimsC ); if ( !fIns ) @@ -200,7 +204,7 @@ void Gia_ManSimPatSimInTest( Gia_Man_t * pGia ) int nWords = 10; Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords ); Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pGia, vSimsCi, 0 ); - Vec_Wrd_t * vSims2 = Gia_ManSimPatSimIn( pGia, vSims, 0 ); + Vec_Wrd_t * vSims2 = Gia_ManSimPatSimIn( pGia, vSims, 0, NULL ); int nOnes = Abc_TtCountOnesVec( Vec_WrdArray(vSims2), Vec_WrdSize(vSims2) ); int nTotal = 64*nWords*Gia_ManCandNum(pGia); printf( "Ratio = %6.2f %%\n", 100.0*nOnes/nTotal ); @@ -208,6 +212,54 @@ void Gia_ManSimPatSimInTest( Gia_Man_t * pGia ) Vec_WrdFree( vSims2 ); Vec_WrdFree( vSimsCi ); } +static inline void Gia_ManSimPatSimAnd4( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC ) +{ + word pComps[2] = { ~(word)0, 0 }; + word Diff0 = pComps[Gia_ObjFaninC0(pObj)]; + word Diff1 = pComps[Gia_ObjFaninC1(pObj)]; + word * pSims0 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId0(pObj, i); + word * pSims1 = Vec_WrdArray(vSims) + nWords*Gia_ObjFaninId1(pObj, i); + word * pSimsC0 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId0(pObj, i); + word * pSimsC1 = Vec_WrdArray(vSimsC) + nWords*Gia_ObjFaninId1(pObj, i); + word * pSimsC2 = Vec_WrdArray(vSimsC) + nWords*i; int w; + if ( Gia_ObjIsXor(pObj) ) + for ( w = 0; w < nWords; w++ ) + pSimsC2[w] = pSimsC0[w] & pSimsC1[w]; + else + for ( w = 0; w < nWords; w++ ) + pSimsC2[w] = (pSimsC0[w] & pSimsC1[w]) | ((pSims0[w] ^ Diff0) & pSimsC0[w]) | ((pSims1[w] ^ Diff1) & pSimsC1[w]); +} +Vec_Wrd_t * Gia_ManSimPatSimC( Gia_Man_t * pGia, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsCiC ) +{ + Gia_Obj_t * pObj; + int i, Id, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia); + Vec_Wrd_t * vSimsC = Vec_WrdStart( Vec_WrdSize(vSims) ); + assert( Vec_WrdSize(vSims) % Gia_ManObjNum(pGia) == 0 ); + memset( Vec_WrdEntryP(vSimsC, 0), 0xFF, sizeof(word)*nWords ); + Gia_ManForEachCiId( pGia, Id, i ) + memmove( Vec_WrdEntryP(vSimsC, Id*nWords), Vec_WrdEntryP(vSimsCiC, i*nWords), sizeof(word)*nWords ); + Gia_ManForEachAnd( pGia, pObj, i ) + Gia_ManSimPatSimAnd4( pGia, i, pObj, nWords, vSims, vSimsC ); + return vSimsC; +} +void Gia_ManSimPatSimCTest( Gia_Man_t * pGia ) +{ + int nWords = 10; + Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(pGia) * nWords ); + Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pGia, vSimsCi, 0 ); + Vec_Wrd_t * vSims2 = Gia_ManSimPatSimIn( pGia, vSims, 0, NULL ); + Vec_Wrd_t * vSimsCi2 = Gia_ManSimPatSimIn( pGia, vSims, 1, NULL ); + Vec_Wrd_t * vSims3 = Gia_ManSimPatSimC( pGia, vSims, vSimsCi2 ); + int nOnes2 = Abc_TtCountOnesVec( Vec_WrdArray(vSims2), Vec_WrdSize(vSims2) ); + int nOnes3 = Abc_TtCountOnesVec( Vec_WrdArray(vSims3), Vec_WrdSize(vSims3) ); + int nTotal = 64*nWords*Gia_ManCandNum(pGia); + printf( "Ratio = %6.2f %% Ratio = %6.2f %%\n", 100.0*nOnes2/nTotal, 100.0*nOnes3/nTotal ); + Vec_WrdFree( vSims ); + Vec_WrdFree( vSims2 ); + Vec_WrdFree( vSims3 ); + Vec_WrdFree( vSimsCi ); + Vec_WrdFree( vSimsCi2 ); +} void Gia_ManSimPatResim( Gia_Man_t * pGia, Vec_Int_t * vObjs, int nWords, Vec_Wrd_t * vSims ) { Gia_Obj_t * pObj; int i; -- cgit v1.2.3 From ba64e78608064612db61d6515f19dd2cabe69cee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 26 Sep 2021 11:30:54 -0700 Subject: Changing declaration of Vec_Ptr_t sorting function to satisfy some compilers. --- src/aig/gia/giaDup.c | 6 +++--- src/aig/gia/giaIso.c | 6 +++--- src/aig/gia/giaIso2.c | 2 +- src/aig/hop/hopBalance.c | 2 +- src/aig/ivy/ivyBalance.c | 2 +- src/aig/ivy/ivyCutTrav.c | 2 +- src/aig/ivy/ivyRwrAlg.c | 2 +- src/aig/saig/saigConstr.c | 4 ++-- src/aig/saig/saigIso.c | 4 ++-- src/aig/saig/saigIsoFast.c | 2 +- src/aig/saig/saigIsoSlow.c | 8 ++++---- src/aig/saig/saigWnd.c | 2 +- 12 files changed, 21 insertions(+), 21 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 65eff161..b3fcd295 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3582,7 +3582,7 @@ Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis ) Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i ) Gia_ManDupCones_rec( p, pObj, vLeaves, vNodes, vRoots ); - Vec_PtrSort( vLeaves, (int (*)(void))Gia_ObjCompareByCioId ); + Vec_PtrSort( vLeaves, (int (*)(const void *, const void *))Gia_ObjCompareByCioId ); // start the new manager // Gia_ManFillValue( p ); @@ -3644,7 +3644,7 @@ Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrim Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i ) Gia_ManDupCones_rec( p, pObj, vLeaves, vNodes, vRoots ); - Vec_PtrSort( vLeaves, (int (*)(void))Gia_ObjCompareByCioId ); + Vec_PtrSort( vLeaves, (int (*)(const void *, const void *))Gia_ObjCompareByCioId ); // start the new manager // Gia_ManFillValue( p ); @@ -4381,7 +4381,7 @@ Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose ) vSuperPtr = Vec_PtrAlloc( Vec_IntSize(vSuper) ); Vec_IntForEachEntry( vSuper, iLit, i ) Vec_PtrPush( vSuperPtr, Gia_Lit2Obj(p, iLit) ); - Vec_PtrSort( vSuperPtr, (int (*)(void))Gia_ManSortByValue ); + Vec_PtrSort( vSuperPtr, (int (*)(const void *, const void *))Gia_ManSortByValue ); // create new manager pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); diff --git a/src/aig/gia/giaIso.c b/src/aig/gia/giaIso.c index 76419e93..fcfa3448 100644 --- a/src/aig/gia/giaIso.c +++ b/src/aig/gia/giaIso.c @@ -894,7 +894,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn Vec_PtrClear( vTemp ); Gia_ManForEachPi( p, pObj, i ) Vec_PtrPush( vTemp, pObj ); - Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue ); + Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue ); // create the result Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i ) Vec_IntPush( vCis, Gia_ObjId(p, pObj) ); @@ -917,7 +917,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn pObj->Value = Abc_Var2Lit( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); Vec_PtrPush( vTemp, pObj ); } - Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue ); + Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue ); Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i ) Vec_IntPush( vCos, Gia_ObjId(p, pObj) ); } @@ -926,7 +926,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn Vec_PtrClear( vTemp ); Gia_ManForEachRo( p, pObj, i ) Vec_PtrPush( vTemp, pObj ); - Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue ); + Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue ); // create the result Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i ) { diff --git a/src/aig/gia/giaIso2.c b/src/aig/gia/giaIso2.c index 576b118f..22b1d09e 100644 --- a/src/aig/gia/giaIso2.c +++ b/src/aig/gia/giaIso2.c @@ -328,7 +328,7 @@ int Gia_Iso2ManUniqify( Gia_Iso2Man_t * p ) } Vec_IntShrink( p->vTied, k ); // sort singletons - Vec_PtrSort( p->vSingles, (int (*)(void))Gia_ObjCompareByValue2 ); + Vec_PtrSort( p->vSingles, (int (*)(const void *, const void *))Gia_ObjCompareByValue2 ); // add them to unique and increment signature Vec_PtrForEachEntry( Gia_Obj_t *, p->vSingles, pObj, i ) { diff --git a/src/aig/hop/hopBalance.c b/src/aig/hop/hopBalance.c index e9aa4d4d..a3ce1c86 100644 --- a/src/aig/hop/hopBalance.c +++ b/src/aig/hop/hopBalance.c @@ -246,7 +246,7 @@ Hop_Obj_t * Hop_NodeBalanceBuildSuper( Hop_Man_t * p, Vec_Ptr_t * vSuper, Hop_Ty int LeftBound; assert( vSuper->nSize > 1 ); // sort the new nodes by level in the decreasing order - Vec_PtrSort( vSuper, (int (*)(void))Hop_NodeCompareLevelsDecrease ); + Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Hop_NodeCompareLevelsDecrease ); // balance the nodes while ( vSuper->nSize > 1 ) { diff --git a/src/aig/ivy/ivyBalance.c b/src/aig/ivy/ivyBalance.c index 6eba318c..2bcc69ee 100644 --- a/src/aig/ivy/ivyBalance.c +++ b/src/aig/ivy/ivyBalance.c @@ -178,7 +178,7 @@ Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Ty int LeftBound; assert( vSuper->nSize > 1 ); // sort the new nodes by level in the decreasing order - Vec_PtrSort( vSuper, (int (*)(void))Ivy_NodeCompareLevelsDecrease ); + Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Ivy_NodeCompareLevelsDecrease ); // balance the nodes while ( vSuper->nSize > 1 ) { diff --git a/src/aig/ivy/ivyCutTrav.c b/src/aig/ivy/ivyCutTrav.c index 74212b10..b1cdb456 100644 --- a/src/aig/ivy/ivyCutTrav.c +++ b/src/aig/ivy/ivyCutTrav.c @@ -329,7 +329,7 @@ void Ivy_NodeComputeVolume2( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNode } while ( Vec_PtrSize(vNodes) < nNodeLimit ); // sort nodes by level - Vec_PtrSort( vNodes, (int (*)(void))Ivy_CompareNodesByLevel ); + Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Ivy_CompareNodesByLevel ); // make sure the nodes are ordered in the increasing number of levels pFanin = (Ivy_Obj_t *)Vec_PtrEntry( vNodes, 0 ); pPivot = (Ivy_Obj_t *)Vec_PtrEntryLast( vNodes ); diff --git a/src/aig/ivy/ivyRwrAlg.c b/src/aig/ivy/ivyRwrAlg.c index ce605003..53fe5817 100644 --- a/src/aig/ivy/ivyRwrAlg.c +++ b/src/aig/ivy/ivyRwrAlg.c @@ -371,7 +371,7 @@ int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeave if ( Vec_PtrSize(vFront) <= 2 ) return 1; // sort the entries in increasing order - Vec_PtrSort( vFront, (int (*)(void))Ivy_ManFindAlgCutCompare ); + Vec_PtrSort( vFront, (int (*)(const void *, const void *))Ivy_ManFindAlgCutCompare ); // remove duplicates from vFront and save the nodes in vLeaves pPrev = Vec_PtrEntry(vFront, 0); Vec_PtrPush( vLeaves, pPrev ); diff --git a/src/aig/saig/saigConstr.c b/src/aig/saig/saigConstr.c index ac58839b..90e82816 100644 --- a/src/aig/saig/saigConstr.c +++ b/src/aig/saig/saigConstr.c @@ -300,8 +300,8 @@ Aig_Man_t * Saig_ManDupUnfoldConstrs( Aig_Man_t * pAig ) Vec_VecFree( (Vec_Vec_t *)vConsAll ); return Aig_ManDupDfs( pAig ); } - Vec_PtrSort( vOuts, (int (*)(void))Saig_ManDupCompare ); - Vec_PtrSort( vCons, (int (*)(void))Saig_ManDupCompare ); + Vec_PtrSort( vOuts, (int (*)(const void *, const void *))Saig_ManDupCompare ); + Vec_PtrSort( vCons, (int (*)(const void *, const void *))Saig_ManDupCompare ); Vec_PtrPush( vOutsAll, vOuts ); Vec_PtrPush( vConsAll, vCons ); } diff --git a/src/aig/saig/saigIso.c b/src/aig/saig/saigIso.c index 40500361..7b8d488a 100644 --- a/src/aig/saig/saigIso.c +++ b/src/aig/saig/saigIso.c @@ -63,7 +63,7 @@ Vec_Int_t * Saig_ManFindIsoPermCos( Aig_Man_t * pAig, Vec_Int_t * vPermCis ) pObj->iData = Abc_Var2Lit( pFanin->iData, Aig_ObjFaninC0(pObj) ); Vec_PtrPush( vRoots, pObj ); } - Vec_PtrSort( vRoots, (int (*)(void))Iso_ObjCompareByData ); + Vec_PtrSort( vRoots, (int (*)(const void *, const void *))Iso_ObjCompareByData ); Vec_PtrForEachEntry( Aig_Obj_t *, vRoots, pObj, i ) Vec_IntPush( vPermCos, Aig_ObjCioId(pObj) ); Vec_PtrFree( vRoots ); @@ -467,7 +467,7 @@ Aig_Man_t * Iso_ManFilterPos( Aig_Man_t * pAig, Vec_Ptr_t ** pvPosEquivs, int fV // sort the infos clk = Abc_Clock(); - Vec_PtrSort( vBuffers, (int (*)(void))Iso_StoCompareVecStr ); + Vec_PtrSort( vBuffers, (int (*)(const void *, const void *))Iso_StoCompareVecStr ); // create classes clk = Abc_Clock(); diff --git a/src/aig/saig/saigIsoFast.c b/src/aig/saig/saigIsoFast.c index 7393e7fc..10d1384d 100644 --- a/src/aig/saig/saigIsoFast.c +++ b/src/aig/saig/saigIsoFast.c @@ -303,7 +303,7 @@ Vec_Vec_t * Saig_IsoDetectFast( Aig_Man_t * pAig ) // sort the infos clk = Abc_Clock(); - Vec_PtrSort( vInfos, (int (*)(void))Iso_StoCompareVecInt ); + Vec_PtrSort( vInfos, (int (*)(const void *, const void *))Iso_StoCompareVecInt ); // create classes clk = Abc_Clock(); diff --git a/src/aig/saig/saigIsoSlow.c b/src/aig/saig/saigIsoSlow.c index a0e2d1d0..4784d98a 100644 --- a/src/aig/saig/saigIsoSlow.c +++ b/src/aig/saig/saigIsoSlow.c @@ -572,8 +572,8 @@ void Iso_ManCollectClasses( Iso_Man_t * p ) } } clk = Abc_Clock(); - Vec_PtrSort( p->vSingles, (int (*)(void))Iso_ObjCompare ); - Vec_PtrSort( p->vClasses, (int (*)(void))Iso_ObjCompare ); + Vec_PtrSort( p->vSingles, (int (*)(const void *, const void *))Iso_ObjCompare ); + Vec_PtrSort( p->vClasses, (int (*)(const void *, const void *))Iso_ObjCompare ); p->timeSort += Abc_Clock() - clk; assert( Vec_PtrSize(p->vSingles) == p->nSingles ); assert( Vec_PtrSize(p->vClasses) == p->nClasses ); @@ -1115,8 +1115,8 @@ Vec_Int_t * Iso_ManFinalize( Iso_Man_t * p ) Vec_PtrPush( p->vTemp1, pObj ); } // sort CIs by their IDs - Vec_PtrSort( p->vTemp1, (int (*)(void))Iso_ObjCompareByData ); - Vec_PtrSort( p->vTemp2, (int (*)(void))Iso_ObjCompareByData ); + Vec_PtrSort( p->vTemp1, (int (*)(const void *, const void *))Iso_ObjCompareByData ); + Vec_PtrSort( p->vTemp2, (int (*)(const void *, const void *))Iso_ObjCompareByData ); // create the result vRes = Vec_IntAlloc( Aig_ManCiNum(p->pAig) ); Vec_PtrForEachEntry( Aig_Obj_t *, p->vTemp1, pObj, i ) diff --git a/src/aig/saig/saigWnd.c b/src/aig/saig/saigWnd.c index ce70e7b4..949a2728 100644 --- a/src/aig/saig/saigWnd.c +++ b/src/aig/saig/saigWnd.c @@ -106,7 +106,7 @@ Vec_Ptr_t * Saig_ManWindowOutline( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist ) vNodes = Vec_PtrAlloc( 1000 ); Aig_ManIncrementTravId( p ); Saig_ManWindowOutline_rec( p, pObj, nDist, vNodes, pDists ); - Vec_PtrSort( vNodes, (int (*)(void))Aig_ObjCompareIdIncrease ); + Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Aig_ObjCompareIdIncrease ); // make sure LI/LO are labeled/unlabeled mutually Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) assert( Aig_ObjIsTravIdCurrent(p, pObjLi) == -- cgit v1.2.3 From a8b5da820df6c008fd02f514a8c93a48ecfe3620 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 26 Sep 2021 11:58:42 -0700 Subject: Other compiler changes. --- src/aig/gia/giaEmbed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c index b646a311..28d28483 100644 --- a/src/aig/gia/giaEmbed.c +++ b/src/aig/gia/giaEmbed.c @@ -32,7 +32,7 @@ ABC_NAMESPACE_IMPL_START http://www.emis.de/journals/JGAA/accepted/2004/HarelKoren2004.8.2.pdf Iterative refinement is described in the paper: F. A. Aloul, I. L. Markov, and K. A. Sakallah. - "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03. + "FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI 03. http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf */ -- cgit v1.2.3 From 674bcbee379b9dcef418ddb62655ee0d3d59f96c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 30 Sep 2021 18:02:33 -0700 Subject: Various changes. --- src/aig/gia/gia.h | 6 + src/aig/gia/giaDecs.c | 350 +++++++++++++++++++++ src/aig/gia/giaMan.c | 1 + src/aig/gia/giaResub.c | 36 ++- src/aig/gia/giaSupps.c | 817 ++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 2 + 6 files changed, 1211 insertions(+), 1 deletion(-) create mode 100644 src/aig/gia/giaDecs.c create mode 100644 src/aig/gia/giaSupps.c (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 42eb71d5..51b4b2e3 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -216,6 +216,7 @@ struct Gia_Man_t_ Vec_Wrd_t * vSimsPo; Vec_Int_t * vClassOld; Vec_Int_t * vClassNew; + Vec_Int_t * vPats; // incremental simulation int fIncrSim; int iNextPi; @@ -1275,6 +1276,11 @@ extern void Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes ); extern Gia_Man_t * Gia_ManDupCof( Gia_Man_t * p, int iVar ); extern Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose ); extern Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose ); +/*=== giaDecs.c ============================================================*/ +extern int Gia_ResubVarNum( Vec_Int_t * vResub ); +extern word Gia_ResubToTruth6( Vec_Int_t * vResub ); +extern int Gia_ManEvalSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int fVerbose ); +extern Vec_Int_t * Gia_ManDeriveSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int Type ); /*=== giaDfs.c ============================================================*/ extern void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp ); extern void Gia_ManCollectAnds_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes ); diff --git a/src/aig/gia/giaDecs.c b/src/aig/gia/giaDecs.c new file mode 100644 index 00000000..343891d5 --- /dev/null +++ b/src/aig/gia/giaDecs.c @@ -0,0 +1,350 @@ +/**CFile**************************************************************** + + FileName [giaDecs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Calling various decomposition engines.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaDecs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig/gia/gia.h" +#include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" +#include "bool/bdc/bdc.h" +#include "bool/kit/kit.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ); +extern Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc, int Depth ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ResubVarNum( Vec_Int_t * vResub ) +{ + if ( Vec_IntSize(vResub) == 1 ) + return Vec_IntEntryLast(vResub) >= 2; + return Vec_IntEntryLast(vResub)/2 - Vec_IntSize(vResub)/2 - 1; +} +word Gia_ResubToTruth6_rec( Vec_Int_t * vResub, int iNode, int nVars ) +{ + assert( iNode >= 0 && nVars <= 6 ); + if ( iNode < nVars ) + return s_Truths6[iNode]; + else + { + int iLit0 = Vec_IntEntry( vResub, Abc_Var2Lit(iNode-nVars, 0) ); + int iLit1 = Vec_IntEntry( vResub, Abc_Var2Lit(iNode-nVars, 1) ); + word Res0 = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iLit0)-2, nVars ); + word Res1 = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iLit1)-2, nVars ); + Res0 = Abc_LitIsCompl(iLit0) ? ~Res0 : Res0; + Res1 = Abc_LitIsCompl(iLit1) ? ~Res1 : Res1; + return iLit0 > iLit1 ? Res0 ^ Res1 : Res0 & Res1; + } +} +word Gia_ResubToTruth6( Vec_Int_t * vResub ) +{ + word Res; + int iRoot = Vec_IntEntryLast(vResub); + if ( iRoot < 2 ) + return iRoot ? ~(word)0 : 0; + assert( iRoot != 2 && iRoot != 3 ); + Res = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iRoot)-2, Gia_ResubVarNum(vResub) ); + return Abc_LitIsCompl(iRoot) ? ~Res : Res; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Gia_ManDeriveTruths( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords ) +{ + int nTtWords = Abc_Truth6WordNum(Vec_IntSize(vSet)); + int nFuncs = Vec_WrdSize(vIsfs) / 2 / nWords; + Vec_Wrd_t * vRes = Vec_WrdStart( 2 * nFuncs * nTtWords ); + Vec_Wrd_t * vIn = Vec_WrdStart( 64*nWords ), * vOut; + int i, f, m, iObj; word Func; + assert( Vec_IntSize(vSet) <= 64 ); + Vec_IntForEachEntry( vSet, iObj, i ) + Abc_TtCopy( Vec_WrdEntryP(vIn, i*nWords), Vec_WrdEntryP(vSims, Vec_IntEntry(vCands, iObj)*nWords), nWords, 0 ); + vOut = Vec_WrdStart( Vec_WrdSize(vIn) ); + Extra_BitMatrixTransposeP( vIn, nWords, vOut, 1 ); + for ( f = 0; f < nFuncs; f++ ) + { + word * pIsf[2] = { Vec_WrdEntryP(vIsfs, (2*f+0)*nWords), + Vec_WrdEntryP(vIsfs, (2*f+1)*nWords) }; + word * pTruth[2] = { Vec_WrdEntryP(vRes, (2*f+0)*nTtWords), + Vec_WrdEntryP(vRes, (2*f+1)*nTtWords) }; + for ( m = 0; m < 64*nWords; m++ ) + { + int iMint = (int)Vec_WrdEntry(vOut, m); + int Value0 = Abc_TtGetBit( pIsf[0], m ); + int Value1 = Abc_TtGetBit( pIsf[1], m ); + if ( !Value0 && !Value1 ) + continue; + if ( Value0 && Value1 ) + printf( "Internal error: Onset and Offset overlap.\n" ); + assert( !Value0 || !Value1 ); + Abc_TtSetBit( pTruth[Value1], iMint ); + } + if ( Abc_TtCountOnesVecMask(pTruth[0], pTruth[1], nTtWords, 0) ) + printf( "Verification for function %d failed for %d minterm pairs.\n", f, + Abc_TtCountOnesVecMask(pTruth[0], pTruth[1], nTtWords, 0) ); + } + if ( Vec_IntSize(vSet) < 6 ) + Vec_WrdForEachEntry( vRes, Func, i ) + Vec_WrdWriteEntry( vRes, i, Abc_Tt6Stretch(Func, Vec_IntSize(vSet)) ); + Vec_WrdFree( vIn ); + Vec_WrdFree( vOut ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManCountResub( Vec_Wrd_t * vTruths, int nVars, int fVerbose ) +{ + Vec_Int_t * vResub; int nNodes; + int nTtWords = Abc_Truth6WordNum(nVars); + int v, nFuncs = Vec_WrdSize(vTruths) / 2 / nTtWords; + Vec_Wrd_t * vElems = Vec_WrdStartTruthTables( nVars ); + Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2 + nVars ); + assert( Vec_WrdSize(vElems) == nTtWords * nVars ); + assert( nFuncs == 1 ); + Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+0)*nTtWords) ); + Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+1)*nTtWords) ); + for ( v = 0; v < nVars; v++ ) + Vec_PtrPush( vDivs, Vec_WrdEntryP(vElems, v*nTtWords) ); + vResub = Gia_ManResubOne( vDivs, nTtWords, 30, 100, 0, 0, 0, fVerbose, NULL, 0 ); + Vec_PtrFree( vDivs ); + Vec_WrdFree( vElems ); + nNodes = Vec_IntSize(vResub) ? Vec_IntSize(vResub)/2 : 999; + Vec_IntFree( vResub ); + return nNodes; +} +Vec_Int_t * Gia_ManDeriveResub( Vec_Wrd_t * vTruths, int nVars ) +{ + Vec_Int_t * vResub; + int nTtWords = Abc_Truth6WordNum(nVars); + int v, nFuncs = Vec_WrdSize(vTruths) / 2 / nTtWords; + Vec_Wrd_t * vElems = Vec_WrdStartTruthTables( nVars ); + Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2 + nVars ); + assert( Vec_WrdSize(vElems) == nTtWords * nVars ); + assert( nFuncs == 1 ); + Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+0)*nTtWords) ); + Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+1)*nTtWords) ); + for ( v = 0; v < nVars; v++ ) + Vec_PtrPush( vDivs, Vec_WrdEntryP(vElems, v*nTtWords) ); + vResub = Gia_ManResubOne( vDivs, nTtWords, 30, 100, 0, 0, 0, 0, NULL, 0 ); + Vec_PtrFree( vDivs ); + Vec_WrdFree( vElems ); + return vResub; +} + +int Gia_ManCountBidec( Vec_Wrd_t * vTruths, int nVars, int fVerbose ) +{ + int nNodes, nTtWords = Abc_Truth6WordNum(nVars); + word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords), + Vec_WrdEntryP(vTruths, 1*nTtWords) }; + Abc_TtOr( pTruth[0], pTruth[0], pTruth[1], nTtWords ); + nNodes = Bdc_ManBidecNodeNum( pTruth[1], pTruth[0], nVars, fVerbose ); + Abc_TtSharp( pTruth[0], pTruth[0], pTruth[1], nTtWords ); + return nNodes; +} +Vec_Int_t * Gia_ManDeriveBidec( Vec_Wrd_t * vTruths, int nVars ) +{ + Vec_Int_t * vRes = NULL; + int nTtWords = Abc_Truth6WordNum(nVars); + word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords), + Vec_WrdEntryP(vTruths, 1*nTtWords) }; + Abc_TtOr( pTruth[0], pTruth[0], pTruth[1], nTtWords ); + vRes = Bdc_ManBidecResub( pTruth[1], pTruth[0], nVars ); + Abc_TtSharp( pTruth[0], pTruth[0], pTruth[1], nTtWords ); + return vRes; +} + +int Gia_ManCountIsop( Vec_Wrd_t * vTruths, int nVars, int fVerbose ) +{ + int nTtWords = Abc_Truth6WordNum(nVars); + word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords), + Vec_WrdEntryP(vTruths, 1*nTtWords) }; + int nNodes = Kit_IsopNodeNum( (unsigned *)pTruth[0], (unsigned *)pTruth[1], nVars, NULL ); + return nNodes; +} +Vec_Int_t * Gia_ManDeriveIsop( Vec_Wrd_t * vTruths, int nVars ) +{ + Vec_Int_t * vRes = NULL; + int nTtWords = Abc_Truth6WordNum(nVars); + word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords), + Vec_WrdEntryP(vTruths, 1*nTtWords) }; + vRes = Kit_IsopResub( (unsigned *)pTruth[0], (unsigned *)pTruth[1], nVars, NULL ); + return vRes; +} + +int Gia_ManCountBdd( Vec_Wrd_t * vTruths, int nVars, int fVerbose ) +{ + extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ); + int nTtWords = Abc_Truth6WordNum(nVars); + word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords), + Vec_WrdEntryP(vTruths, 1*nTtWords) }; + Gia_Man_t * pGia; int nNodes; + + Abc_TtOr( pTruth[1], pTruth[1], pTruth[0], nTtWords ); + Abc_TtNot( pTruth[0], nTtWords ); + pGia = Gia_TryPermOptNew( pTruth[0], nVars, 1, nTtWords, 50, 0 ); + Abc_TtNot( pTruth[0], nTtWords ); + Abc_TtSharp( pTruth[1], pTruth[1], pTruth[0], nTtWords ); + + nNodes = Gia_ManAndNum(pGia); + Gia_ManStop( pGia ); + return nNodes; +} +Vec_Int_t * Gia_ManDeriveBdd( Vec_Wrd_t * vTruths, int nVars ) +{ + extern Vec_Int_t * Gia_ManToGates( Gia_Man_t * p ); + Vec_Int_t * vRes = NULL; + extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose ); + int nTtWords = Abc_Truth6WordNum(nVars); + word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords), + Vec_WrdEntryP(vTruths, 1*nTtWords) }; + Gia_Man_t * pGia; + + Abc_TtOr( pTruth[1], pTruth[1], pTruth[0], nTtWords ); + Abc_TtNot( pTruth[0], nTtWords ); + pGia = Gia_TryPermOptNew( pTruth[0], nVars, 1, nTtWords, 50, 0 ); + Abc_TtNot( pTruth[0], nTtWords ); + Abc_TtSharp( pTruth[1], pTruth[1], pTruth[0], nTtWords ); + + vRes = Gia_ManToGates( pGia ); + Gia_ManStop( pGia ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManEvalSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int fVerbose ) +{ + Vec_Wrd_t * vTruths = Gia_ManDeriveTruths( p, vSims, vIsfs, vCands, vSet, nWords ); + int nTtWords = Vec_WrdSize(vTruths)/2, nVars = Vec_IntSize(vSet); + word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords), + Vec_WrdEntryP(vTruths, 1*nTtWords) }; + int nNodesResub = Gia_ManCountResub( vTruths, nVars, 0 ); + int nNodesBidec = nVars > 2 ? Gia_ManCountBidec( vTruths, nVars, 0 ) : 999; + int nNodesIsop = nVars > 2 ? Gia_ManCountIsop( vTruths, nVars, 0 ) : 999; + int nNodesBdd = nVars > 2 ? Gia_ManCountBdd( vTruths, nVars, 0 ) : 999; + int nNodesMin = Abc_MinInt( Abc_MinInt(nNodesResub, nNodesBidec), Abc_MinInt(nNodesIsop, nNodesBdd) ); + if ( fVerbose ) + { + printf( "Size = %2d ", nVars ); + printf( "Resub =%3d ", nNodesResub ); + printf( "Bidec =%3d ", nNodesBidec ); + printf( "Isop =%3d ", nNodesIsop ); + printf( "Bdd =%3d ", nNodesBdd ); + Abc_TtIsfPrint( pTruth[0], pTruth[1], nTtWords ); + if ( nVars <= 6 ) + { + printf( " " ); + Extra_PrintHex( stdout, (unsigned*)pTruth[0], nVars ); + printf( " " ); + Extra_PrintHex( stdout, (unsigned*)pTruth[1], nVars ); + } + printf( "\n" ); + } + Vec_WrdFree( vTruths ); + if ( nNodesMin > 500 ) + return -1; + if ( nNodesMin == nNodesResub ) + return (nNodesMin << 2) | 0; + if ( nNodesMin == nNodesBidec ) + return (nNodesMin << 2) | 1; + if ( nNodesMin == nNodesIsop ) + return (nNodesMin << 2) | 2; + if ( nNodesMin == nNodesBdd ) + return (nNodesMin << 2) | 3; + return -1; +} +Vec_Int_t * Gia_ManDeriveSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int Type ) +{ + Vec_Int_t * vRes = NULL; + Vec_Wrd_t * vTruths = Gia_ManDeriveTruths( p, vSims, vIsfs, vCands, vSet, nWords ); + int nTtWords = Vec_WrdSize(vTruths)/2, nVars = Vec_IntSize(vSet); + word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords), + Vec_WrdEntryP(vTruths, 1*nTtWords) }; + if ( Type == 0 ) + vRes = Gia_ManDeriveResub( vTruths, nVars ); + else if ( Type == 1 ) + vRes = Gia_ManDeriveBidec( vTruths, nVars ); + else if ( Type == 2 ) + vRes = Gia_ManDeriveIsop( vTruths, nVars ); + else if ( Type == 3 ) + vRes = Gia_ManDeriveBdd( vTruths, nVars ); + if ( vRes && Gia_ResubVarNum(vRes) <= 6 ) + { + word Func = Gia_ResubToTruth6( vRes ); + assert( !(Func & pTruth[0][0]) ); + assert( !(pTruth[1][0] & ~Func) ); + } + Vec_WrdFree( vTruths ); + return vRes; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 772dc31a..464835e4 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -94,6 +94,7 @@ void Gia_ManStop( Gia_Man_t * p ) Vec_IntFreeP( &p->vStore ); Vec_IntFreeP( &p->vClassNew ); Vec_IntFreeP( &p->vClassOld ); + Vec_IntFreeP( &p->vPats ); Vec_WrdFreeP( &p->vSims ); Vec_WrdFreeP( &p->vSimsT ); Vec_WrdFreeP( &p->vSimsPi ); diff --git a/src/aig/gia/giaResub.c b/src/aig/gia/giaResub.c index a5017b7d..33fd5276 100644 --- a/src/aig/gia/giaResub.c +++ b/src/aig/gia/giaResub.c @@ -651,6 +651,37 @@ Gia_Man_t * Gia_ManConstructFromGates2( Vec_Wec_t * vFuncs, Vec_Wec_t * vDivs, i Vec_IntFree( vSupp ); return pNew; } +Vec_Int_t * Gia_ManToGates( Gia_Man_t * p ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 2*Gia_ManAndNum(p) + 1 ); + Gia_Obj_t * pRoot = Gia_ManCo( p, 0 ); + int iRoot = Gia_ObjFaninId0p(p, pRoot) - 1; + int nVars = Gia_ManCiNum(p); + assert( Gia_ManCoNum(p) == 1 ); + if ( iRoot == -1 ) + Vec_IntPush( vRes, Gia_ObjFaninC0(pRoot) ); + else if ( iRoot < nVars ) + Vec_IntPush( vRes, 4 + Abc_Var2Lit(iRoot, Gia_ObjFaninC0(pRoot)) ); + else + { + Gia_Obj_t * pObj, * pLast = NULL; int i; + Gia_ManForEachCi( p, pObj, i ) + assert( Gia_ObjId(p, pObj) == i+1 ); + Gia_ManForEachAnd( p, pObj, i ) + { + int iLit0 = Abc_Var2Lit( Gia_ObjFaninId0(pObj, i) - 1, Gia_ObjFaninC0(pObj) ); + int iLit1 = Abc_Var2Lit( Gia_ObjFaninId1(pObj, i) - 1, Gia_ObjFaninC1(pObj) ); + if ( iLit0 > iLit1 ) + iLit0 ^= iLit1, iLit1 ^= iLit0, iLit0 ^= iLit1; + Vec_IntPushTwo( vRes, 4 + iLit0, 4 + iLit1 ); + pLast = pObj; + } + assert( pLast == Gia_ObjFanin0(pRoot) ); + Vec_IntPush( vRes, 4 + Abc_Var2Lit(iRoot, Gia_ObjFaninC0(pRoot)) ); + } + assert( Vec_IntSize(vRes) == 2*Gia_ManAndNum(p) + 1 ); + return vRes; +} /**Function************************************************************* @@ -1378,7 +1409,10 @@ int Gia_ManResubPerform_rec( Gia_ResbMan_t * p, int nLimit, int Depth ) if ( iResLit >= 0 ) { int iNode = nVars + Vec_IntSize(p->vGates)/2; - Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) ); + if ( iDiv < iResLit ) + Vec_IntPushTwo( p->vGates, Abc_LitNot(iDiv), Abc_LitNotCond(iResLit, fUseOr) ); + else + Vec_IntPushTwo( p->vGates, Abc_LitNotCond(iResLit, fUseOr), Abc_LitNot(iDiv) ); return Abc_Var2Lit( iNode, fUseOr ); } } diff --git a/src/aig/gia/giaSupps.c b/src/aig/gia/giaSupps.c new file mode 100644 index 00000000..f95d815d --- /dev/null +++ b/src/aig/gia/giaSupps.c @@ -0,0 +1,817 @@ +/**CFile**************************************************************** + + FileName [giaSupp.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Support computation manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSupp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig/gia/gia.h" +#include "base/main/mainInt.h" +#include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" +#include "misc/vec/vecHsh.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Supp_Man_t_ Supp_Man_t; +struct Supp_Man_t_ +{ + // user data + int nIters; // optimization rounds + int nRounds; // optimization rounds + int nWords; // the number of simulation words + int nDivWords; // the number of divisor words + Vec_Wrd_t * vIsfs; // functions to synthesize + Vec_Int_t * vCands; // candidate divisors + Vec_Int_t * vWeights; // divisor weights (optional) + Vec_Wrd_t * vSims; // simulation values + Vec_Wrd_t * vSimsC; // simulation values + Gia_Man_t * pGia; // used for object names + // computed data + Vec_Wrd_t * vDivs[2]; // simulation values + Vec_Wrd_t * vPats[2]; // simulation values + Vec_Ptr_t * vMatrix; // simulation values + Vec_Wrd_t * vMask; // simulation values + Vec_Wrd_t * vRowTemp; // simulation values + Vec_Int_t * vCosts; // candidate costs + Hsh_VecMan_t * pHash; // subsets considered + Vec_Wrd_t * vSFuncs; // ISF storage + Vec_Int_t * vSStarts; // subset function starts + Vec_Int_t * vSCount; // subset function count + Vec_Int_t * vSPairs; // subset pair count + Vec_Int_t * vTemp; // temporary + Vec_Int_t * vTempSets; // temporary + Vec_Int_t * vTempPairs; // temporary + Vec_Wec_t * vSolutions; // solutions for each node count +}; + +extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Supp_ManFuncInit( Vec_Wrd_t * vFuncs, int nWords ) +{ + int i, k = 0, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2; + assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) ); + for ( i = 0; i < nFuncs; i++ ) + { + word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords); + word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords); + if ( Abc_TtIsConst0(pFunc0, nWords) || Abc_TtIsConst0(pFunc1, nWords) ) + continue; + if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), pFunc0, nWords, 0 ); + if ( k < i ) Abc_TtCopy( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), pFunc1, nWords, 0 ); + k++; + } + Vec_WrdShrink( vFuncs, 2*k*nWords ); + return k; +} +int Supp_ManCostInit( Vec_Wrd_t * vFuncs, int nWords ) +{ + int Res = 0, i, nFuncs = Vec_WrdSize(vFuncs) / nWords / 2; + assert( 2 * nFuncs * nWords == Vec_WrdSize(vFuncs) ); + for ( i = 0; i < nFuncs; i++ ) + { + word * pFunc0 = Vec_WrdEntryP(vFuncs, (2*i+0)*nWords); + word * pFunc1 = Vec_WrdEntryP(vFuncs, (2*i+1)*nWords); + Res += Abc_TtCountOnesVec(pFunc0, nWords) * Abc_TtCountOnesVec(pFunc1, nWords); + } + assert( nFuncs < 128 ); + assert( Res < (1 << 24) ); + return (nFuncs << 24) | Res; +} +void Supp_ManInit( Supp_Man_t * p ) +{ + int Value, nFuncs, iSet = Hsh_VecManAdd( p->pHash, p->vTemp ); // empty set + assert( iSet == 0 ); + Vec_IntPush( p->vSStarts, Vec_WrdSize(p->vSFuncs) ); + Vec_WrdAppend( p->vSFuncs, p->vIsfs ); + nFuncs = Supp_ManFuncInit( p->vSFuncs, p->nWords ); + assert( Vec_WrdSize(p->vSFuncs) == 2 * nFuncs * p->nWords ); + Value = Supp_ManCostInit(p->vSFuncs, p->nWords); + Vec_IntPush( p->vSCount, Value >> 24 ); + Vec_IntPush( p->vSPairs, Value & 0xFFFFFF ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Supp_DeriveLines( Supp_Man_t * p ) +{ + int n, i, iObj, nWords = p->nWords; + int nDivWords = Abc_Bit6WordNum( Vec_IntSize(p->vCands) ); + for ( n = 0; n < 2; n++ ) + { + p->vDivs[n] = Vec_WrdStart( 64*nWords*nDivWords ); + p->vPats[n] = Vec_WrdStart( 64*nWords*nDivWords ); + if ( p->vSimsC ) + Vec_IntForEachEntry( p->vCands, iObj, i ) + Abc_TtAndSharp( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSimsC, iObj*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n ); + else + Vec_IntForEachEntry( p->vCands, iObj, i ) + Abc_TtCopy( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n ); + Extra_BitMatrixTransposeP( p->vDivs[n], nWords, p->vPats[n], nDivWords ); + } + return nDivWords; +} +Supp_Man_t * Supp_ManCreate( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vWeights, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC, int nWords, Gia_Man_t * pGia, int nIters, int nRounds ) +{ + Supp_Man_t * p = ABC_CALLOC( Supp_Man_t, 1 ); + p->nIters = nIters; + p->nRounds = nRounds; + p->nWords = nWords; + p->vIsfs = vIsfs; + p->vCands = vCands; + p->vWeights = vWeights; + p->vSims = vSims; + p->vSimsC = vSimsC; + p->pGia = pGia; + // computed data + p->nDivWords = Supp_DeriveLines( p ); + p->vMatrix = Vec_PtrAlloc( 100 ); + p->vMask = Vec_WrdAlloc( 100 ); + p->vRowTemp = Vec_WrdStart( 64*p->nDivWords ); + p->vCosts = Vec_IntStart( Vec_IntSize(p->vCands) ); + p->pHash = Hsh_VecManStart( 1000 ); + p->vSFuncs = Vec_WrdAlloc( 1000 ); + p->vSStarts = Vec_IntAlloc( 1000 ); + p->vSCount = Vec_IntAlloc( 1000 ); + p->vSPairs = Vec_IntAlloc( 1000 ); + p->vSolutions = Vec_WecStart( 16 ); + p->vTemp = Vec_IntAlloc( 10 ); + p->vTempSets = Vec_IntAlloc( 10 ); + p->vTempPairs = Vec_IntAlloc( 10 ); + Supp_ManInit( p ); + return p; +} +void Supp_ManCleanMatrix( Supp_Man_t * p ) +{ + Vec_Wrd_t * vTemp; int i; + Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, i ) + Vec_WrdFreeP( &vTemp ); + Vec_PtrClear( p->vMatrix ); +} +void Supp_ManDelete( Supp_Man_t * p ) +{ + Supp_ManCleanMatrix( p ); + Vec_WrdFreeP( &p->vDivs[0] ); + Vec_WrdFreeP( &p->vDivs[1] ); + Vec_WrdFreeP( &p->vPats[0] ); + Vec_WrdFreeP( &p->vPats[1] ); + Vec_PtrFreeP( &p->vMatrix ); + Vec_WrdFreeP( &p->vMask ); + Vec_WrdFreeP( &p->vRowTemp ); + Vec_IntFreeP( &p->vCosts ); + Hsh_VecManStop( p->pHash ); + Vec_WrdFreeP( &p->vSFuncs ); + Vec_IntFreeP( &p->vSStarts ); + Vec_IntFreeP( &p->vSCount ); + Vec_IntFreeP( &p->vSPairs ); + Vec_WecFreeP( &p->vSolutions ); + Vec_IntFreeP( &p->vTemp ); + Vec_IntFreeP( &p->vTempSets ); + Vec_IntFreeP( &p->vTempPairs ); + ABC_FREE( p ); +} +int Supp_ManMemory( Supp_Man_t * p ) +{ + int nMem = sizeof(Supp_Man_t); + nMem += 2*(int)Vec_WrdMemory( p->vDivs[0] ); + nMem += 2*(int)Vec_WrdMemory( p->vPats[0] ); + nMem += (Vec_PtrSize(p->vMatrix)+1)*(int)Vec_WrdMemory( p->vRowTemp ); + nMem += (int)Vec_WrdMemory( p->vMask ); + nMem += (int)Vec_IntMemory( p->vCosts ); + nMem += (int)Hsh_VecManMemory( p->pHash ); + nMem += (int)Vec_WrdMemory( p->vSFuncs ); + nMem += (int)Vec_IntMemory( p->vSStarts ); + nMem += (int)Vec_IntMemory( p->vSCount ); + nMem += (int)Vec_IntMemory( p->vSPairs ); + nMem += (int)Vec_WecMemory( p->vSolutions ); + nMem += (int)Vec_IntMemory( p->vTemp ); + nMem += (int)Vec_IntMemory( p->vTempSets ); + nMem += (int)Vec_IntMemory( p->vTempPairs ); + return nMem; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Supp_ArrayWeight( Vec_Int_t * vRes, Vec_Int_t * vWeights ) +{ + int i, iObj, Cost = 0; + if ( !vWeights ) + return Vec_IntSize(vRes); + Vec_IntForEachEntry( vRes, iObj, i ) + Cost += Vec_IntEntry(vWeights, iObj); + return Cost; +} +int Supp_SetWeight( Supp_Man_t * p, int iSet ) +{ + return Supp_ArrayWeight( Hsh_VecReadEntry(p->pHash, iSet), p->vWeights ); +} +int Supp_SetSize( Supp_Man_t * p, int iSet ) +{ + return Vec_IntSize( Hsh_VecReadEntry(p->pHash, iSet) ); +} +int Supp_SetFuncNum( Supp_Man_t * p, int iSet ) +{ + return Vec_IntEntry(p->vSCount, iSet); +} +int Supp_SetPairNum( Supp_Man_t * p, int iSet ) +{ + return Vec_IntEntry(p->vSPairs, iSet); +} +void Supp_SetConvert( Vec_Int_t * vSet, Vec_Int_t * vCands ) +{ + int i, iObj; + Vec_IntForEachEntry( vSet, iObj, i ) + Vec_IntWriteEntry( vSet, i, Vec_IntEntry(vCands, iObj) ); +} +void Supp_PrintNodes( Gia_Man_t * pGia, Vec_Int_t * vObjs, int Skip, int Limit ) +{ + int i, iObj; + //printf( "Considering %d targets: ", Vec_IntSize(vObjs) ); + Vec_IntForEachEntryStart( vObjs, iObj, i, Skip ) + { + if ( iObj < 0 ) + continue; + printf( "(%d)", iObj ); + if ( pGia && pGia->vWeights && Vec_IntEntry(pGia->vWeights, iObj) > 0 ) + printf( "(%d)", Vec_IntEntry(pGia->vWeights, iObj) ); + if ( pGia ) + printf( " %s ", Gia_ObjName(pGia, iObj)+2 ); + else + printf( " n%d ", iObj ); + if ( i >= Limit ) + { + printf( "... " ); + break; + } + } + printf( "Cost = %d", Supp_ArrayWeight(vObjs, pGia ? pGia->vWeights : NULL) ); + printf( "\n" ); +} +void Supp_PrintOne( Supp_Man_t * p, int iSet ) +{ + Vec_Int_t * vSet = Hsh_VecReadEntry(p->pHash, iSet); + printf( "Set %5d : ", iSet ); + printf( "Funcs %2d ", Supp_SetFuncNum(p, iSet) ); + printf( "Pairs %4d ", Supp_SetPairNum(p, iSet) ); + printf( "Start %8d ", Vec_IntEntry(p->vSStarts, iSet) ); + printf( "Weight %4d ", Supp_ArrayWeight(vSet, p->vWeights) ); + Vec_IntClearAppend( p->vTemp, vSet ); + Supp_SetConvert( p->vTemp, p->vCands ); + Supp_PrintNodes( p->pGia, p->vTemp, 0, 6 ); +} +int Supp_ManRefine1( Supp_Man_t * p, int iSet, int iObj ) +{ + word * pSet = Vec_WrdEntryP( p->vSims, Vec_IntEntry(p->vCands, iObj)*p->nWords ); + word * pIsf; int nFuncs = Vec_IntEntry(p->vSCount, iSet); + int i, n, f, w, nFuncsNew = 0, Mark = Vec_WrdSize(p->vSFuncs), Res = 0; + if ( Vec_WrdSize(p->vSFuncs) + 4*nFuncs*p->nWords > Vec_WrdCap(p->vSFuncs) ) + Vec_WrdGrow( p->vSFuncs, 2*Vec_WrdCap(p->vSFuncs) ); + pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) ); + for ( i = 0; i < nFuncs; i++ ) + { + word * pFunc[2] = { pIsf + (2*i+0)*p->nWords, pIsf + (2*i+1)*p->nWords }; + for ( f = 0; f < 2; f++ ) + { + int nOnes[2], Start = Vec_WrdSize(p->vSFuncs); + for ( n = 0; n < 2; n++ ) + { + word * pLimit = Vec_WrdLimit(p->vSFuncs); + if ( f ) + for ( w = 0; w < p->nWords; w++ ) + Vec_WrdPush( p->vSFuncs, pFunc[n][w] & pSet[w] ); + else + for ( w = 0; w < p->nWords; w++ ) + Vec_WrdPush( p->vSFuncs, pFunc[n][w] & ~pSet[w] ); + nOnes[n] = Abc_TtCountOnesVec( pLimit, p->nWords ); + } + if ( nOnes[0] && nOnes[1] ) + Res += nOnes[0] * nOnes[1]; + else + Vec_WrdShrink( p->vSFuncs, Start ); + } + } + assert( Res < (1 << 24) ); + nFuncsNew = (Vec_WrdSize(p->vSFuncs) - Mark)/2/p->nWords; + assert( nFuncsNew < 128 ); + assert( nFuncsNew >= 0 && nFuncsNew <= 2*nFuncs ); + return (nFuncsNew << 24) | Res; +} +void Supp_ManRefine( Supp_Man_t * p, int iSet, int iObj, int * pnFuncs, int * pnPairs ) +{ + word * pDivs0 = Vec_WrdEntryP( p->vDivs[0], iObj*p->nWords ); + word * pDivs1 = Vec_WrdEntryP( p->vDivs[1], iObj*p->nWords ); + word * pIsf; int nFuncs = Supp_SetFuncNum(p, iSet); + int i, f, w, nFuncsNew = 0, Mark = Vec_WrdSize(p->vSFuncs), Res = 0; + if ( Vec_WrdSize(p->vSFuncs) + 6*nFuncs*p->nWords > Vec_WrdCap(p->vSFuncs) ) + Vec_WrdGrow( p->vSFuncs, 2*Vec_WrdCap(p->vSFuncs) ); + if ( Vec_WrdSize(p->vSFuncs) == Vec_IntEntry(p->vSStarts, iSet) ) + pIsf = Vec_WrdLimit( p->vSFuncs ); + else + pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) ); + for ( i = 0; i < nFuncs; i++ ) + { + word * pFunc[2] = { pIsf + (2*i+0)*p->nWords, pIsf + (2*i+1)*p->nWords }; + for ( f = 0; f < 3; f++ ) + { + int nOnes[2], Start = Vec_WrdSize(p->vSFuncs); + word * pLimit[2] = { Vec_WrdLimit(p->vSFuncs), Vec_WrdLimit(p->vSFuncs) + p->nWords }; + if ( f == 0 ) + { + for ( w = 0; w < p->nWords; w++ ) + Vec_WrdPush( p->vSFuncs, pFunc[0][w] & pDivs0[w] ); + for ( w = 0; w < p->nWords; w++ ) + Vec_WrdPush( p->vSFuncs, pFunc[1][w] & ~pDivs1[w] ); + } + else if ( f == 1 ) + { + for ( w = 0; w < p->nWords; w++ ) + Vec_WrdPush( p->vSFuncs, pFunc[0][w] & pDivs1[w] ); + for ( w = 0; w < p->nWords; w++ ) + Vec_WrdPush( p->vSFuncs, pFunc[1][w] & ~pDivs0[w] ); + } + else + { + for ( w = 0; w < p->nWords; w++ ) + Vec_WrdPush( p->vSFuncs, pFunc[0][w] & ~pDivs0[w] & ~pDivs1[w] ); + for ( w = 0; w < p->nWords; w++ ) + Vec_WrdPush( p->vSFuncs, pFunc[1][w] ); + } + nOnes[0] = Abc_TtCountOnesVec( pLimit[0], p->nWords ); + nOnes[1] = Abc_TtCountOnesVec( pLimit[1], p->nWords ); + if ( nOnes[0] && nOnes[1] ) + Res += nOnes[0] * nOnes[1]; + else + Vec_WrdShrink( p->vSFuncs, Start ); + } + } + assert( Res < (1 << 24) ); + nFuncsNew = (Vec_WrdSize(p->vSFuncs) - Mark)/2/p->nWords; + *pnFuncs = nFuncsNew; + *pnPairs = Res; +} +int Supp_ManSubsetAdd( Supp_Man_t * p, int iSet, int iObj, int fVerbose ) +{ + int iSetNew, nEntries = Hsh_VecSize( p->pHash ); + Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet ); + Vec_IntClear( p->vTemp ); + Vec_IntAppend( p->vTemp, vSet ); + Vec_IntPushOrder( p->vTemp, iObj ); + assert( Vec_IntIsOrdered(p->vTemp, 0) ); + iSetNew = Hsh_VecManAdd( p->pHash, p->vTemp ); + if ( iSetNew == nEntries ) // new entry + { + int nFuncs, nPairs; + Vec_IntPush( p->vSStarts, Vec_WrdSize(p->vSFuncs) ); + Supp_ManRefine( p, iSet, iObj, &nFuncs, &nPairs ); + Vec_IntPush( p->vSCount, nFuncs ); + Vec_IntPush( p->vSPairs, nPairs ); + assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSStarts) ); + assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSCount) ); + assert( Hsh_VecSize(p->pHash) == Vec_IntSize(p->vSPairs) ); + if ( Supp_SetFuncNum(p, iSetNew) == 0 && Supp_SetSize(p, iSetNew) < Vec_WecSize(p->vSolutions) ) + Vec_WecPush( p->vSolutions, Supp_SetSize(p, iSetNew), iSetNew ); + if ( fVerbose ) + Supp_PrintOne( p, iSetNew ); + } + return iSetNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Supp_ComputePair1( Supp_Man_t * p, int iSet ) +{ + int Random = 0xFFFFFF & Abc_Random(0); + int nFuncs = Vec_IntEntry(p->vSCount, iSet); + int iFunc = Random % nFuncs; + word * pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) ); + word * pFunc[2] = { pIsf + (2*iFunc+0)*p->nWords, pIsf + (2*iFunc+1)*p->nWords }; + int iBit0 = ((Random >> 16) & 1) ? Abc_TtFindFirstBit2(pFunc[0], p->nWords) : Abc_TtFindLastBit2(pFunc[0], p->nWords); + int iBit1 = ((Random >> 17) & 1) ? Abc_TtFindFirstBit2(pFunc[1], p->nWords) : Abc_TtFindLastBit2(pFunc[1], p->nWords); + if ( 1 ) + { + Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet ); int i, iObj; + Vec_IntForEachEntry( vSet, iObj, i ) + { + word * pSet = Vec_WrdEntryP( p->vSims, Vec_IntEntry(p->vCands, iObj)*p->nWords ); + assert( Abc_TtGetBit(pSet, iBit0) == Abc_TtGetBit(pSet, iBit1) ); + } + } + return (iBit0 << 16) | iBit1; +} +int Supp_ComputePair( Supp_Man_t * p, int iSet ) +{ + int Random = 0xFFFFFF & Abc_Random(0); + int nFuncs = Vec_IntEntry(p->vSCount, iSet); + int iFunc = Random % nFuncs; + word * pIsf = Vec_WrdEntryP( p->vSFuncs, Vec_IntEntry(p->vSStarts, iSet) ); + word * pFunc[2] = { pIsf + (2*iFunc+0)*p->nWords, pIsf + (2*iFunc+1)*p->nWords }; + int iBit0 = ((Random >> 16) & 1) ? Abc_TtFindFirstBit2(pFunc[0], p->nWords) : Abc_TtFindLastBit2(pFunc[0], p->nWords); + int iBit1 = ((Random >> 17) & 1) ? Abc_TtFindFirstBit2(pFunc[1], p->nWords) : Abc_TtFindLastBit2(pFunc[1], p->nWords); + if ( 1 ) + { + Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSet ); int i, iObj; + Vec_IntForEachEntry( vSet, iObj, i ) + { + word * pSet0 = Vec_WrdEntryP( p->vDivs[0], iObj*p->nWords ); + word * pSet1 = Vec_WrdEntryP( p->vDivs[1], iObj*p->nWords ); + int Value00 = Abc_TtGetBit(pSet0, iBit0); + int Value01 = Abc_TtGetBit(pSet0, iBit1); + int Value10 = Abc_TtGetBit(pSet1, iBit0); + int Value11 = Abc_TtGetBit(pSet1, iBit1); + assert( !Value00 || !Value11 ); + assert( !Value01 || !Value10 ); + } + } + return (iBit0 << 16) | iBit1; +} +Vec_Int_t * Supp_Compute64Pairs( Supp_Man_t * p, Vec_Int_t * vSets ) +{ + int i; + Vec_IntClear( p->vTempPairs ); + for ( i = 0; i < 64; i++ ) + { + int Rand = 0xFFFFFF & Abc_Random(0); + int iSet = Vec_IntEntry( vSets, Rand % Vec_IntSize(vSets) ); + Vec_IntPush( p->vTempPairs, Supp_ComputePair(p, iSet) ); + } + return p->vTempPairs; +} +void Supp_ManFillBlock( Supp_Man_t * p, Vec_Int_t * vPairs, Vec_Wrd_t * vRes ) +{ + int i, Pair; + assert( Vec_IntSize(vPairs) == 64 ); + Vec_IntForEachEntry( vPairs, Pair, i ) + { + int iBit0 = Pair >> 16, iBit1 = Pair & 0xFFFF; + word * pPat00 = Vec_WrdEntryP(p->vPats[0], iBit0*p->nDivWords); + word * pPat01 = Vec_WrdEntryP(p->vPats[0], iBit1*p->nDivWords); + word * pPat10 = Vec_WrdEntryP(p->vPats[1], iBit0*p->nDivWords); + word * pPat11 = Vec_WrdEntryP(p->vPats[1], iBit1*p->nDivWords); + word * pPat = Vec_WrdEntryP(p->vRowTemp, i*p->nDivWords); + Abc_TtAnd( pPat, pPat00, pPat11, p->nDivWords, 0 ); + Abc_TtOrAnd( pPat, pPat01, pPat10, p->nDivWords ); + } + Extra_BitMatrixTransposeP( p->vRowTemp, p->nDivWords, vRes, 1 ); +} +void Supp_ManAddPatterns( Supp_Man_t * p, Vec_Int_t * vSets ) +{ + Vec_Int_t * vPairs = Supp_Compute64Pairs( p, vSets ); + Vec_Wrd_t * vRow = Vec_WrdStart( 64*p->nDivWords ); + Supp_ManFillBlock( p, vPairs, vRow ); + Vec_PtrPush( p->vMatrix, vRow ); +} +Vec_Int_t * Supp_ManCollectOnes( word * pSim, int nWords ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); int i; + for ( i = 0; i < 64*nWords; i++ ) + if ( Abc_TtGetBit(pSim, i) ) + Vec_IntPush( vRes, i ); + return vRes; +} +Vec_Int_t * Supp_Compute64PairsFunc( Supp_Man_t * p, Vec_Int_t * vBits0, Vec_Int_t * vBits1 ) +{ + int i; + Vec_IntClear( p->vTempPairs ); + for ( i = 0; i < 64; i++ ) + { + int Random = 0xFFFFFF & Abc_Random(0); + int iBit0 = Vec_IntEntry( vBits0, (Random & 0xFFF) % Vec_IntSize(vBits0) ); + int iBit1 = Vec_IntEntry( vBits1, (Random >> 12) % Vec_IntSize(vBits1) ); + Vec_IntPush( p->vTempPairs, (iBit0 << 16) | iBit1 ); + } + return p->vTempPairs; +} +void Supp_ManAddPatternsFunc( Supp_Man_t * p, int nBatches ) +{ + int b; + Vec_Int_t * vBits0 = Supp_ManCollectOnes( Vec_WrdEntryP(p->vSFuncs, 0*p->nWords), p->nWords ); + Vec_Int_t * vBits1 = Supp_ManCollectOnes( Vec_WrdEntryP(p->vSFuncs, 1*p->nWords), p->nWords ); + for ( b = 0; b < nBatches; b++ ) + { + Vec_Int_t * vPairs = Supp_Compute64PairsFunc( p, vBits0, vBits1 ); + Vec_Wrd_t * vRow = Vec_WrdStart( 64*p->nDivWords ); + Supp_ManFillBlock( p, vPairs, vRow ); + Vec_PtrPush( p->vMatrix, vRow ); + } + Vec_IntFree( vBits0 ); + Vec_IntFree( vBits1 ); +} +int Supp_FindNextDiv( Supp_Man_t * p, int Pair ) +{ + int iDiv, iBit0 = Pair >> 16, iBit1 = Pair & 0xFFFF; + word * pPat00 = Vec_WrdEntryP(p->vPats[0], iBit0*p->nDivWords); + word * pPat01 = Vec_WrdEntryP(p->vPats[0], iBit1*p->nDivWords); + word * pPat10 = Vec_WrdEntryP(p->vPats[1], iBit0*p->nDivWords); + word * pPat11 = Vec_WrdEntryP(p->vPats[1], iBit1*p->nDivWords); + int iDiv1 = Abc_TtFindFirstAndBit2( pPat00, pPat11, p->nDivWords ); + int iDiv2 = Abc_TtFindFirstAndBit2( pPat01, pPat10, p->nDivWords ); + iDiv1 = iDiv1 == -1 ? ABC_INFINITY : iDiv1; + iDiv2 = iDiv2 == -1 ? ABC_INFINITY : iDiv2; + iDiv = Abc_MinInt( iDiv1, iDiv2 ); + assert( iDiv >= 0 && iDiv < Vec_IntSize(p->vCands) ); + return iDiv; +} +int Supp_ManRandomSolution( Supp_Man_t * p, int iSet, int fVerbose ) +{ + Vec_IntClear( p->vTempSets ); + while ( Supp_SetFuncNum(p, iSet) > 0 ) + { + int Pair = Supp_ComputePair( p, iSet ); + int iDiv = Supp_FindNextDiv( p, Pair ); + iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose ); + if ( Supp_SetFuncNum(p, iSet) > 0 ) + Vec_IntPush( p->vTempSets, iSet ); + } + if ( Vec_IntSize(p->vTempSets) < 2 ) + return iSet; + Supp_ManAddPatterns( p, p->vTempSets ); + return iSet; +} +int Supp_ManSubsetRemove( Supp_Man_t * p, int iSet, int iPos ) +{ + int i, iSetNew = 0, nSize = Supp_SetSize(p, iSet); + for ( i = 0; i < nSize; i++ ) + if ( i != iPos && Supp_SetFuncNum(p, iSetNew) > 0 ) + iSetNew = Supp_ManSubsetAdd( p, iSetNew, Vec_IntEntry(Hsh_VecReadEntry(p->pHash, iSet), i), 0 ); + return iSetNew; +} +int Supp_ManMinimize( Supp_Man_t * p, int iSet0, int r, int fVerbose ) +{ + int i, nSize = Supp_SetSize(p, iSet0); + Vec_Int_t * vPerm = Vec_IntStartNatural( Supp_SetSize(p, iSet0) ); + Vec_IntRandomizeOrder( vPerm ); + Vec_IntClear( p->vTempSets ); + if ( fVerbose ) + printf( "Removing items from %d:\n", iSet0 ); + // make sure we first try to remove items with higher weight + for ( i = 0; i < nSize; i++ ) + { + int Index = Vec_IntEntry( vPerm, i ); + int iSet = Supp_ManSubsetRemove( p, iSet0, Index ); + if ( fVerbose ) + printf( "Item %2d : ", Index ); + if ( fVerbose ) + Supp_PrintOne( p, iSet ); + if ( Supp_SetFuncNum(p, iSet) == 0 ) + { + Vec_IntFree( vPerm ); + return Supp_ManMinimize( p, iSet, r, fVerbose ); + } + Vec_IntPush( p->vTempSets, iSet ); + } + Supp_ManAddPatterns( p, p->vTempSets ); + Vec_IntFree( vPerm ); + return iSet0; +} +int Supp_ManFindNextObj( Supp_Man_t * p, int fVerbose ) +{ + Vec_Wrd_t * vTemp; int r, k, iDiv; + word Sim, * pMask = Vec_WrdArray(p->vMask); + assert( Vec_WrdSize(p->vMask) == Vec_PtrSize(p->vMatrix) ); + Vec_IntFill( p->vCosts, Vec_IntSize(p->vCosts), 0 ); + Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, r ) + Vec_WrdForEachEntryStop( vTemp, Sim, k, Vec_IntSize(p->vCosts) ) + Vec_IntAddToEntry( p->vCosts, k, Abc_TtCountOnes(Sim & pMask[r]) ); + iDiv = Vec_IntArgMax( p->vCosts ); + if ( fVerbose ) + printf( "Choosing divisor %d with weight %d.\n", iDiv, Vec_IntEntry(p->vCosts, iDiv) ); + Vec_PtrForEachEntry( Vec_Wrd_t *, p->vMatrix, vTemp, r ) + pMask[r] &= ~Vec_WrdEntry( vTemp, iDiv ); + return iDiv; +} +int Supp_ManReconstruct( Supp_Man_t * p, int fVerbose ) +{ + int iSet = 0; + Vec_WrdFill( p->vMask, Vec_PtrSize(p->vMatrix), ~(word)0 ); + if ( fVerbose ) + printf( "\nBuilding a new set:\n" ); + while ( Supp_SetPairNum(p, iSet) ) + { + int iDiv = Supp_ManFindNextObj( p, fVerbose ); + iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose ); + if ( Abc_TtIsConst0(Vec_WrdArray(p->vMask), Vec_WrdSize(p->vMask)) ) + break; + } + if ( fVerbose ) + printf( "Adding random part:\n" ); + return Supp_ManRandomSolution( p, iSet, fVerbose ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVerbose, Vec_Int_t ** pvDivs ) +{ + Vec_Int_t * vLevel, * vRes = NULL; + int i, k, iSet, nFuncs = 0, Count = 0; + int iSolBest = -1, Cost, CostBest = ABC_INFINITY; + Vec_WecForEachLevel( vSols, vLevel, i ) + { + Count += Vec_IntSize(vLevel) > 0; + Vec_IntForEachEntry( vLevel, iSet, k ) + { + if ( fVerbose ) + printf( "%3d : ", nFuncs++ ); + Cost = Gia_ManEvalSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, Hsh_VecReadEntry(p->pHash, iSet), p->nWords, fVerbose ); + if ( Cost == -1 ) + continue; + if ( CostBest > Cost ) + { + CostBest = Cost; + iSolBest = iSet; + } + if ( nFuncs > 5 ) + break; + } + if ( Count == 2 || k < Vec_IntSize(vLevel) ) + break; + } + if ( iSolBest > 0 && (CostBest >> 2) < 50 ) + { + Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSolBest ); int i, iObj; + vRes = Gia_ManDeriveSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, vSet, p->nWords, CostBest & 3 ); + assert( !vRes || Vec_IntSize(vRes) == 2*(CostBest >> 2)+1 ); + if ( vRes && pvDivs ) + { + Vec_IntClear( *pvDivs ); + Vec_IntPushTwo( *pvDivs, -1, -1 ); + Vec_IntForEachEntry( vSet, iObj, i ) + Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) ); + } + } + return vRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Supp_FindGivenOne( Supp_Man_t * p ) +{ + int i, iObj, iSet = 0; + Vec_Int_t * vSet = Vec_IntStart( 2 ); + //extern void Patch_GenerateSet11( Gia_Man_t * p, Vec_Int_t * vDivs, Vec_Int_t * vCands ); + //Patch_GenerateSet11( p->pGia, vSet, p->vCands ); + Vec_IntDrop( vSet, 0 ); + Vec_IntDrop( vSet, 0 ); + Vec_IntForEachEntry( vSet, iObj, i ) + iSet = Supp_ManSubsetAdd( p, iSet, iObj, 1 ); + Vec_IntFree( vSet ); + return iSet; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vWeights, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsC, int nWords, Gia_Man_t * pGia, Vec_Int_t ** pvDivs, int nIters, int nRounds, int fVerbose ) +{ + int fVeryVerbose = 0; + int i, r, iSet, iBest = -1; + abctime clk = Abc_Clock(); + Vec_Int_t * vRes = NULL; + Supp_Man_t * p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds ); + if ( Supp_SetFuncNum(p, 0) == 0 ) + { + Supp_ManDelete( p ); + Vec_IntClear( *pvDivs ); + Vec_IntPushTwo( *pvDivs, -1, -1 ); + vRes = Vec_IntAlloc( 1 ); + Vec_IntPush( vRes, Abc_TtIsConst0(Vec_WrdArray(vIsfs), nWords) ); + return vRes; + } + if ( fVerbose ) + printf( "\nUsing %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n", + Vec_IntSize(p->vCands), p->nWords, Supp_SetFuncNum(p, 0), Supp_SetPairNum(p, 0) ); + //iBest = Supp_FindGivenOne( p ); + if ( iBest == -1 ) + for ( i = 0; i < p->nIters; i++ ) + { + Supp_ManAddPatternsFunc( p, i ); + iSet = Supp_ManRandomSolution( p, 0, fVeryVerbose ); + for ( r = 0; r < p->nRounds; r++ ) + { + if ( fVeryVerbose ) + printf( "\n\nITER %d ROUND %d\n", i, r ); + iSet = Supp_ManMinimize( p, iSet, r, fVeryVerbose ); + if ( iBest == -1 || Supp_SetWeight(p, iBest) > Supp_SetWeight(p, iSet) ) + //if ( Supp_SetSize(p, iBest) > Supp_SetSize(p, iSet) ) + { + if ( fVeryVerbose ) + printf( "\nThe best solution found:\n" ); + if ( fVeryVerbose ) + Supp_PrintOne( p, iSet ); + iBest = iSet; + } + iSet = Supp_ManReconstruct( p, fVeryVerbose ); + } + if ( fVeryVerbose ) + printf( "Matrix size %d.\n", Vec_PtrSize(p->vMatrix) ); + Supp_ManCleanMatrix( p ); + } + if ( fVerbose ) + { + printf( "Explored %d divisor sets. Found %d solutions. Memory usage %.2f MB. ", + Hsh_VecSize(p->pHash), Vec_WecSizeSize(p->vSolutions), 1.0*Supp_ManMemory(p)/(1<<20) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + printf( "The best solution: " ); + if ( iBest == -1 ) + printf( "No solution.\n" ); + else + Supp_PrintOne( p, iBest ); + } + vRes = Supp_ManFindBestSolution( p, p->vSolutions, fVerbose, pvDivs ); + Supp_ManDelete( p ); +// if ( vRes && Vec_IntSize(vRes) == 0 ) +// Vec_IntFreeP( &vRes ); + return vRes; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 35ed4ab0..0786ce44 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -16,6 +16,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaCSat2.c \ src/aig/gia/giaCTas.c \ src/aig/gia/giaCut.c \ + src/aig/gia/giaDecs.c \ src/aig/gia/giaDeep.c \ src/aig/gia/giaDfs.c \ src/aig/gia/giaDup.c \ @@ -89,6 +90,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaStr.c \ src/aig/gia/giaSupMin.c \ src/aig/gia/giaSupp.c \ + src/aig/gia/giaSupps.c \ src/aig/gia/giaSweep.c \ src/aig/gia/giaSweeper.c \ src/aig/gia/giaSwitch.c \ -- cgit v1.2.3 From 31f88974e211f9bf9db74dd1dba5b4e026ed173e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 6 Oct 2021 17:14:57 -0700 Subject: Various changes. --- src/aig/gia/gia.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 51b4b2e3..66ac9e13 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -548,6 +548,7 @@ static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) { static inline int Gia_ObjFaninNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsMux(p, pObj) ) return 3; if ( Gia_ObjIsAnd(pObj) ) return 2; if ( Gia_ObjIsCo(pObj) ) return 1; return 0; } static inline int Gia_ObjWhatFanin( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { if ( Gia_ObjFanin0(pObj) == pFanin ) return 0; if ( Gia_ObjFanin1(pObj) == pFanin ) return 1; if ( Gia_ObjFanin2(p, pObj) == pFanin ) return 2; assert(0); return -1; } +static inline int Gia_ManCoDriverId( Gia_Man_t * p, int iCoIndex ) { return Gia_ObjFaninId0p(p, Gia_ManCo(p, iCoIndex)); } static inline int Gia_ManPoIsConst( Gia_Man_t * p, int iPoIndex ) { return Gia_ObjFaninId0p(p, Gia_ManPo(p, iPoIndex)) == 0; } static inline int Gia_ManPoIsConst0( Gia_Man_t * p, int iPoIndex ) { return Gia_ManIsConst0Lit( Gia_ObjFaninLit0p(p, Gia_ManPo(p, iPoIndex)) ); } static inline int Gia_ManPoIsConst1( Gia_Man_t * p, int iPoIndex ) { return Gia_ManIsConst1Lit( Gia_ObjFaninLit0p(p, Gia_ManPo(p, iPoIndex)) ); } -- cgit v1.2.3 From 227b0c775b0d61aee54423cc22a3f6644b2c2bb7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 6 Oct 2021 20:33:41 -0700 Subject: New command &stochsyn for stochastic synthesis. --- src/aig/gia/giaStoch.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 1 + 2 files changed, 322 insertions(+) create mode 100644 src/aig/gia/giaStoch.c (limited to 'src/aig') diff --git a/src/aig/gia/giaStoch.c b/src/aig/gia/giaStoch.c new file mode 100644 index 00000000..390deb26 --- /dev/null +++ b/src/aig/gia/giaStoch.c @@ -0,0 +1,321 @@ +/**CFile**************************************************************** + + FileName [giaDeep.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Experiments with synthesis.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaDeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "base/main/main.h" +#include "base/cmd/cmd.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void Vec_PtrFreeFunc( Vec_Ptr_t * p, void (*pFuncItemFree)(void *) ) ___unused; +static void Vec_PtrFreeFunc( Vec_Ptr_t * p, void (*pFuncItemFree)(void *) ) +{ + void * pItem; int i; + Vec_PtrForEachEntry( void *, p, pItem, i ) + pFuncItemFree( pItem ); + Vec_PtrFree( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript ) +{ + Gia_Man_t * pGia, * pNew; int i; + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) + { + Gia_Man_t * pCopy = Gia_ManDup(pGia); + Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pGia ); + if ( Abc_FrameIsBatchMode() ) + { + if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) ) + { + Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript ); + return; + } + } + else + { + Abc_FrameSetBatchMode( 1 ); + if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) ) + { + Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript ); + Abc_FrameSetBatchMode( 0 ); + return; + } + Abc_FrameSetBatchMode( 0 ); + } + pNew = Abc_FrameReadGia(Abc_FrameGetGlobalFrame()); + if ( Gia_ManAndNum(pNew) < Gia_ManAndNum(pCopy) ) + { + Gia_ManStop( pCopy ); + pCopy = Gia_ManDup( pNew ); + } + Vec_PtrWriteEntry( vAigs, i, pCopy ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; int i; + pNew = Gia_ManStart( 1+Vec_IntSize(vCis)+Vec_IntSize(vAnds)+Vec_IntSize(vCos) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObjVec( vCis, p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachObjVec( vAnds, p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachObjVec( vCos, p, pObj, i ) + Gia_ManAppendCo( pNew, pObj->Value ); + assert( Gia_ManCiNum(pNew) > 0 && Gia_ManCoNum(pNew) > 0 ); + return pNew; +} +Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript ) +{ + Vec_Ptr_t * vAigs = Vec_PtrAlloc( Vec_WecSize(vCis) ); int i; + for ( i = 0; i < Vec_WecSize(vCis); i++ ) + Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i)) ); + Gia_ManStochSynthesis( vAigs, pScript ); + return vAigs; +} +Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs ) +{ + Gia_Man_t * pGia, * pNew; + Gia_Obj_t * pObj; int i, k; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManCleanValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManHashAlloc( pNew ); + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) + { + Vec_Int_t * vCi = Vec_WecEntry( vCis, i ); + Vec_Int_t * vCo = Vec_WecEntry( vCos, i ); + Gia_ManCleanValue( pGia ); + Gia_ManConst0(pGia)->Value = 0; + Gia_ManForEachObjVec( vCi, p, pObj, k ) + Gia_ManCi(pGia, k)->Value = pObj->Value; + Gia_ManForEachAnd( pGia, pObj, k ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachObjVec( vCo, p, pObj, k ) + pObj->Value = Gia_ObjFanin0Copy(Gia_ManCo(pGia, k)); + } + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + pNew = Gia_ManCleanup( pGia = pNew ); + Gia_ManStop( pGia ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManStochCollect_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vAnds ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjUpdateTravIdCurrentId( p, iObj ) ) + return; + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) || iObj == 0 ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManStochCollect_rec( p, Gia_ObjFaninId0(pObj, iObj), vAnds ); + Gia_ManStochCollect_rec( p, Gia_ObjFaninId1(pObj, iObj), vAnds ); + Vec_IntPush( vAnds, iObj ); +} +Vec_Wec_t * Gia_ManStochNodes( Gia_Man_t * p, int nMaxSize, int Seed ) +{ + Vec_Wec_t * vRes = Vec_WecAlloc( 100 ); + Vec_Int_t * vPart = Vec_WecPushLevel( vRes ); + int i, iStart = Seed % Gia_ManCoNum(p); + //Gia_ManLevelNum( p ); + Gia_ManIncrementTravId( p ); + for ( i = 0; i < Gia_ManCoNum(p); i++ ) + { + Gia_Obj_t * pObj = Gia_ManCo( p, (iStart+i) % Gia_ManCoNum(p) ); + if ( Vec_IntSize(vPart) > nMaxSize ) + vPart = Vec_WecPushLevel( vRes ); + Gia_ManStochCollect_rec( p, Gia_ObjFaninId0p(p, pObj), vPart ); + } + if ( Vec_IntSize(vPart) == 0 ) + Vec_WecShrink( vRes, Vec_WecSize(vRes)-1 ); + //Vec_WecPrint( vRes, 0 ); + return vRes; +} +Vec_Wec_t * Gia_ManStochInputs( Gia_Man_t * p, Vec_Wec_t * vAnds ) +{ + Vec_Wec_t * vRes = Vec_WecAlloc( 100 ); + Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k, iObj; + Vec_WecForEachLevel( vAnds, vLevel, i ) + { + Vec_Int_t * vVec = Vec_WecPushLevel( vRes ); + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vLevel, iObj, k ) + Gia_ObjSetTravIdCurrentId( p, iObj ); + Gia_ManForEachObjVec( vLevel, p, pObj, k ) + { + iObj = Gia_ObjFaninId0p(p, pObj); + if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) ) + Vec_IntPush( vVec, iObj ); + iObj = Gia_ObjFaninId1p(p, pObj); + if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) ) + Vec_IntPush( vVec, iObj ); + } + } + return vRes; +} +Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds ) +{ + Vec_Wec_t * vRes = Vec_WecAlloc( 100 ); + Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k; + Gia_ManCreateRefs( p ); + Vec_WecForEachLevel( vAnds, vLevel, i ) + { + Vec_Int_t * vVec = Vec_WecPushLevel( vRes ); + Gia_ManForEachObjVec( vLevel, p, pObj, k ) + { + Gia_ObjRefDecId( p, Gia_ObjFaninId0p(p, pObj) ); + Gia_ObjRefDecId( p, Gia_ObjFaninId1p(p, pObj) ); + } + Gia_ManForEachObjVec( vLevel, p, pObj, k ) + if ( Gia_ObjRefNum(p, pObj) ) + Vec_IntPush( vVec, Gia_ObjId(p, pObj) ); + Gia_ManForEachObjVec( vLevel, p, pObj, k ) + { + Gia_ObjRefIncId( p, Gia_ObjFaninId0p(p, pObj) ); + Gia_ObjRefIncId( p, Gia_ObjFaninId1p(p, pObj) ); + } + } + return vRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript ) +{ + abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0; + abctime clkStart = Abc_Clock(); + int i, nEnd, nBeg = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); + Abc_Random(1); + for ( i = 0; i < 10+Seed; i++ ) + Abc_Random(0); + if ( fVerbose ) + printf( "Running %d iterations of script \"%s\".\n", nIters, pScript ); + for ( i = 0; i < nIters; i++ ) + { + abctime clk = Abc_Clock(); + Gia_Man_t * pGia = Gia_ManDup( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) ); + Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF ); + Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds ); + Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds ); + Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript ); + Gia_Man_t * pNew = Gia_ManDupStitch( pGia, vIns, vAnds, vOuts, vAigs ); + Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew ); + if ( fVerbose ) + printf( "Iteration %3d : Using %3d partitions. Reducing %6d nodes to %6d nodes. ", + i, Vec_PtrSize(vAigs), Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) ); + if ( fVerbose ) + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + Gia_ManStop( pGia ); + Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop ); + Vec_WecFree( vAnds ); + Vec_WecFree( vIns ); + Vec_WecFree( vOuts ); + if ( nTimeToStop && Abc_Clock() > nTimeToStop ) + { + printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i ); + break; + } + } + nEnd = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); + if ( fVerbose ) + printf( "Cumulatively reduced %d AIG nodes after %d iterations. ", + nBeg - nEnd, nIters, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC ); + if ( fVerbose ) + Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 0786ce44..b767c49a 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -87,6 +87,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaSpeedup.c \ src/aig/gia/giaSplit.c \ src/aig/gia/giaStg.c \ + src/aig/gia/giaStoch.c \ src/aig/gia/giaStr.c \ src/aig/gia/giaSupMin.c \ src/aig/gia/giaSupp.c \ -- cgit v1.2.3 From e56a767640e57df42f463792333e5a1ff817a65e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 6 Oct 2021 20:34:53 -0700 Subject: Compiler warning. --- src/aig/gia/giaStoch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaStoch.c b/src/aig/gia/giaStoch.c index 390deb26..1261a311 100644 --- a/src/aig/gia/giaStoch.c +++ b/src/aig/gia/giaStoch.c @@ -307,7 +307,7 @@ void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerb nEnd = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); if ( fVerbose ) printf( "Cumulatively reduced %d AIG nodes after %d iterations. ", - nBeg - nEnd, nIters, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC ); + nBeg - nEnd, nIters ); if ( fVerbose ) Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart ); } -- cgit v1.2.3 From 1afd156dbdf4a0845610bbfd2159e930944b1f57 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 7 Oct 2021 20:34:58 -0700 Subject: New command &stochsyn for stochastic synthesis. --- src/aig/gia/giaStoch.c | 261 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 204 insertions(+), 57 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaStoch.c b/src/aig/gia/giaStoch.c index 1261a311..063bf985 100644 --- a/src/aig/gia/giaStoch.c +++ b/src/aig/gia/giaStoch.c @@ -63,12 +63,36 @@ static void Vec_PtrFreeFunc( Vec_Ptr_t * p, void (*pFuncItemFree)(void *) ) SeeAlso [] ***********************************************************************/ +void Gia_ManDupMapping( Gia_Man_t * pNew, Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pFanin; int i, k; + Vec_Int_t * vMapping = p->vMapping ? Vec_IntAlloc( Vec_IntSize(p->vMapping) ) : NULL; + if ( p->vMapping == NULL ) + return; + Vec_IntFill( vMapping, Gia_ManObjNum(p), 0 ); + Gia_ManForEachLut( p, i ) + { + pObj = Gia_ManObj( p, i ); + Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) ); + Vec_IntPush( vMapping, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFaninObj( p, i, pFanin, k ) + Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) ); + Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) ); + } + pNew->vMapping = vMapping; +} +Gia_Man_t * Gia_ManDupWithMapping( Gia_Man_t * pGia ) +{ + Gia_Man_t * pCopy = Gia_ManDup(pGia); + Gia_ManDupMapping( pCopy, pGia ); + return pCopy; +} void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript ) { Gia_Man_t * pGia, * pNew; int i; Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) { - Gia_Man_t * pCopy = Gia_ManDup(pGia); + Gia_Man_t * pCopy = Gia_ManDupWithMapping(pGia); Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pGia ); if ( Abc_FrameIsBatchMode() ) { @@ -90,10 +114,21 @@ void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript ) Abc_FrameSetBatchMode( 0 ); } pNew = Abc_FrameReadGia(Abc_FrameGetGlobalFrame()); - if ( Gia_ManAndNum(pNew) < Gia_ManAndNum(pCopy) ) + if ( Gia_ManHasMapping(pNew) && Gia_ManHasMapping(pCopy) ) { - Gia_ManStop( pCopy ); - pCopy = Gia_ManDup( pNew ); + if ( Gia_ManLutNum(pNew) < Gia_ManLutNum(pCopy) ) + { + Gia_ManStop( pCopy ); + pCopy = Gia_ManDupWithMapping( pNew ); + } + } + else + { + if ( Gia_ManAndNum(pNew) < Gia_ManAndNum(pCopy) ) + { + Gia_ManStop( pCopy ); + pCopy = Gia_ManDup( pNew ); + } } Vec_PtrWriteEntry( vAigs, i, pCopy ); } @@ -110,12 +145,38 @@ void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript ) SeeAlso [] ***********************************************************************/ +void Gia_ManCollectNodes_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vAnds ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjUpdateTravIdCurrentId( p, iObj ) ) + return; + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) || iObj == 0 ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManCollectNodes_rec( p, Gia_ObjFaninId0(pObj, iObj), vAnds ); + Gia_ManCollectNodes_rec( p, Gia_ObjFaninId1(pObj, iObj), vAnds ); + Vec_IntPush( vAnds, iObj ); +} +void Gia_ManCollectNodes( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos ) +{ + int i, iObj; + if ( !Gia_ManHasMapping(p) ) + return; + Vec_IntClear( vAnds ); + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vCis, iObj, i ) + Gia_ObjSetTravIdCurrentId( p, iObj ); + Vec_IntForEachEntry( vCos, iObj, i ) + Gia_ManCollectNodes_rec( p, iObj, vAnds ); +} Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos ) { - Gia_Man_t * pNew; - Gia_Obj_t * pObj; int i; + Vec_Int_t * vMapping; int i; + Gia_Man_t * pNew; Gia_Obj_t * pObj; pNew = Gia_ManStart( 1+Vec_IntSize(vCis)+Vec_IntSize(vAnds)+Vec_IntSize(vCos) ); pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManFillValue(p); Gia_ManConst0(p)->Value = 0; Gia_ManForEachObjVec( vCis, p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); @@ -124,17 +185,37 @@ Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vA Gia_ManForEachObjVec( vCos, p, pObj, i ) Gia_ManAppendCo( pNew, pObj->Value ); assert( Gia_ManCiNum(pNew) > 0 && Gia_ManCoNum(pNew) > 0 ); + if ( !Gia_ManHasMapping(p) ) + return pNew; + vMapping = Vec_IntAlloc( 4*Gia_ManObjNum(pNew) ); + Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 ); + Gia_ManForEachObjVec( vAnds, p, pObj, i ) + { + Gia_Obj_t * pFanin; int k; + int iObj = Gia_ObjId(p, pObj); + if ( !Gia_ObjIsLut(p, iObj) ) + continue; + Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) ); + Vec_IntPush( vMapping, Gia_ObjLutSize(p, iObj) ); + Gia_LutForEachFaninObj( p, iObj, pFanin, k ) + Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) ); + Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) ); + } + pNew->vMapping = vMapping; return pNew; } Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript ) { Vec_Ptr_t * vAigs = Vec_PtrAlloc( Vec_WecSize(vCis) ); int i; for ( i = 0; i < Vec_WecSize(vCis); i++ ) + { + Gia_ManCollectNodes( p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i) ); Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i)) ); + } Gia_ManStochSynthesis( vAigs, pScript ); return vAigs; } -Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs ) +Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs, int fHash ) { Gia_Man_t * pGia, * pNew; Gia_Obj_t * pObj; int i, k; @@ -145,7 +226,8 @@ Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); - Gia_ManHashAlloc( pNew ); + if ( fHash ) + Gia_ManHashAlloc( pNew ); Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) { Vec_Int_t * vCi = Vec_WecEntry( vCis, i ); @@ -154,18 +236,51 @@ Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds Gia_ManConst0(pGia)->Value = 0; Gia_ManForEachObjVec( vCi, p, pObj, k ) Gia_ManCi(pGia, k)->Value = pObj->Value; - Gia_ManForEachAnd( pGia, pObj, k ) - pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( fHash ) + Gia_ManForEachAnd( pGia, pObj, k ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else + Gia_ManForEachAnd( pGia, pObj, k ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachObjVec( vCo, p, pObj, k ) pObj->Value = Gia_ObjFanin0Copy(Gia_ManCo(pGia, k)); } Gia_ManForEachCo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - pNew = Gia_ManCleanup( pGia = pNew ); - Gia_ManStop( pGia ); + if ( fHash ) + { + pNew = Gia_ManCleanup( pGia = pNew ); + Gia_ManStop( pGia ); + } Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); return pNew; } +Gia_Man_t * Gia_ManDupStitchMap( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs ) +{ + Vec_Int_t * vMapping; int n; + Gia_Man_t * pGia, * pNew = Gia_ManDupStitch( p, vCis, vAnds, vCos, vAigs, !Gia_ManHasMapping(p) ); + if ( !Gia_ManHasMapping(p) ) + return pNew; + vMapping = Vec_IntAlloc( Vec_IntSize(p->vMapping) ); + Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 ); + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, n ) + { + Gia_Obj_t * pFanin; int iObj, k; + //printf( "Gia %d has %d Luts\n", n, Gia_ManLutNum(pGia) ); + + Gia_ManForEachLut( pGia, iObj ) + { + Gia_Obj_t * pObj = Gia_ManObj( pGia, iObj ); + Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) ); + Vec_IntPush( vMapping, Gia_ObjLutSize(pGia, iObj) ); + Gia_LutForEachFaninObj( pGia, iObj, pFanin, k ) + Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) ); + Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) ); + } + } + pNew->vMapping = vMapping; + return pNew; +} /**Function************************************************************* @@ -178,19 +293,6 @@ Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds SeeAlso [] ***********************************************************************/ -void Gia_ManStochCollect_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vAnds ) -{ - Gia_Obj_t * pObj; - if ( Gia_ObjUpdateTravIdCurrentId( p, iObj ) ) - return; - pObj = Gia_ManObj( p, iObj ); - if ( Gia_ObjIsCi(pObj) || iObj == 0 ) - return; - assert( Gia_ObjIsAnd(pObj) ); - Gia_ManStochCollect_rec( p, Gia_ObjFaninId0(pObj, iObj), vAnds ); - Gia_ManStochCollect_rec( p, Gia_ObjFaninId1(pObj, iObj), vAnds ); - Vec_IntPush( vAnds, iObj ); -} Vec_Wec_t * Gia_ManStochNodes( Gia_Man_t * p, int nMaxSize, int Seed ) { Vec_Wec_t * vRes = Vec_WecAlloc( 100 ); @@ -203,7 +305,7 @@ Vec_Wec_t * Gia_ManStochNodes( Gia_Man_t * p, int nMaxSize, int Seed ) Gia_Obj_t * pObj = Gia_ManCo( p, (iStart+i) % Gia_ManCoNum(p) ); if ( Vec_IntSize(vPart) > nMaxSize ) vPart = Vec_WecPushLevel( vRes ); - Gia_ManStochCollect_rec( p, Gia_ObjFaninId0p(p, pObj), vPart ); + Gia_ManCollectNodes_rec( p, Gia_ObjFaninId0p(p, pObj), vPart ); } if ( Vec_IntSize(vPart) == 0 ) Vec_WecShrink( vRes, Vec_WecSize(vRes)-1 ); @@ -213,45 +315,83 @@ Vec_Wec_t * Gia_ManStochNodes( Gia_Man_t * p, int nMaxSize, int Seed ) Vec_Wec_t * Gia_ManStochInputs( Gia_Man_t * p, Vec_Wec_t * vAnds ) { Vec_Wec_t * vRes = Vec_WecAlloc( 100 ); - Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k, iObj; + Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k, iObj, iFan, f; Vec_WecForEachLevel( vAnds, vLevel, i ) { Vec_Int_t * vVec = Vec_WecPushLevel( vRes ); + assert( Vec_IntSize(vVec) == 0 ); Gia_ManIncrementTravId( p ); Vec_IntForEachEntry( vLevel, iObj, k ) Gia_ObjSetTravIdCurrentId( p, iObj ); - Gia_ManForEachObjVec( vLevel, p, pObj, k ) + if ( Gia_ManHasMapping(p) ) { - iObj = Gia_ObjFaninId0p(p, pObj); - if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) ) - Vec_IntPush( vVec, iObj ); - iObj = Gia_ObjFaninId1p(p, pObj); - if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) ) - Vec_IntPush( vVec, iObj ); + Vec_IntForEachEntry( vLevel, iObj, k ) + if ( Gia_ObjIsLut(p, iObj) ) + Gia_LutForEachFanin( p, iObj, iFan, f ) + if ( !Gia_ObjUpdateTravIdCurrentId(p, iFan) ) + Vec_IntPush( vVec, iFan ); + } + else + { + Gia_ManForEachObjVec( vLevel, p, pObj, k ) + { + iObj = Gia_ObjFaninId0p(p, pObj); + if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) ) + Vec_IntPush( vVec, iObj ); + iObj = Gia_ObjFaninId1p(p, pObj); + if ( !Gia_ObjUpdateTravIdCurrentId(p, iObj) ) + Vec_IntPush( vVec, iObj ); + } } + assert( Vec_IntSize(vVec) > 0 ); } return vRes; } Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds ) { Vec_Wec_t * vRes = Vec_WecAlloc( 100 ); - Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k; - Gia_ManCreateRefs( p ); - Vec_WecForEachLevel( vAnds, vLevel, i ) + Vec_Int_t * vLevel; Gia_Obj_t * pObj; int i, k, iObj, iFan, f; + if ( Gia_ManHasMapping(p) ) { - Vec_Int_t * vVec = Vec_WecPushLevel( vRes ); - Gia_ManForEachObjVec( vLevel, p, pObj, k ) + Gia_ManSetLutRefs( p ); + Vec_WecForEachLevel( vAnds, vLevel, i ) { - Gia_ObjRefDecId( p, Gia_ObjFaninId0p(p, pObj) ); - Gia_ObjRefDecId( p, Gia_ObjFaninId1p(p, pObj) ); + Vec_Int_t * vVec = Vec_WecPushLevel( vRes ); + assert( Vec_IntSize(vVec) == 0 ); + Vec_IntForEachEntry( vLevel, iObj, k ) + if ( Gia_ObjIsLut(p, iObj) ) + Gia_LutForEachFanin( p, iObj, iFan, f ) + Gia_ObjLutRefDecId( p, iFan ); + Vec_IntForEachEntry( vLevel, iObj, k ) + if ( Gia_ObjIsLut(p, iObj) ) + if ( Gia_ObjLutRefNumId(p, iObj) ) + Vec_IntPush( vVec, iObj ); + Vec_IntForEachEntry( vLevel, iObj, k ) + if ( Gia_ObjIsLut(p, iObj) ) + Gia_LutForEachFanin( p, iObj, iFan, f ) + Gia_ObjLutRefIncId( p, iFan ); + assert( Vec_IntSize(vVec) > 0 ); } - Gia_ManForEachObjVec( vLevel, p, pObj, k ) - if ( Gia_ObjRefNum(p, pObj) ) - Vec_IntPush( vVec, Gia_ObjId(p, pObj) ); - Gia_ManForEachObjVec( vLevel, p, pObj, k ) + } + else + { + Gia_ManCreateRefs( p ); + Vec_WecForEachLevel( vAnds, vLevel, i ) { - Gia_ObjRefIncId( p, Gia_ObjFaninId0p(p, pObj) ); - Gia_ObjRefIncId( p, Gia_ObjFaninId1p(p, pObj) ); + Vec_Int_t * vVec = Vec_WecPushLevel( vRes ); + Gia_ManForEachObjVec( vLevel, p, pObj, k ) + { + Gia_ObjRefDecId( p, Gia_ObjFaninId0p(p, pObj) ); + Gia_ObjRefDecId( p, Gia_ObjFaninId1p(p, pObj) ); + } + Gia_ManForEachObjVec( vLevel, p, pObj, k ) + if ( Gia_ObjRefNum(p, pObj) ) + Vec_IntPush( vVec, Gia_ObjId(p, pObj) ); + Gia_ManForEachObjVec( vLevel, p, pObj, k ) + { + Gia_ObjRefIncId( p, Gia_ObjFaninId0p(p, pObj) ); + Gia_ObjRefIncId( p, Gia_ObjFaninId1p(p, pObj) ); + } } } return vRes; @@ -270,9 +410,11 @@ Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds ) ***********************************************************************/ void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript ) { - abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0; - abctime clkStart = Abc_Clock(); - int i, nEnd, nBeg = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); + abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0; + abctime clkStart = Abc_Clock(); + int fMapped = Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); + int nLutEnd, nLutBeg = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0; + int i, nEnd, nBeg = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); Abc_Random(1); for ( i = 0; i < 10+Seed; i++ ) Abc_Random(0); @@ -281,16 +423,19 @@ void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerb for ( i = 0; i < nIters; i++ ) { abctime clk = Abc_Clock(); - Gia_Man_t * pGia = Gia_ManDup( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) ); + Gia_Man_t * pGia = Gia_ManDupWithMapping( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) ); Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF ); Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds ); Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds ); Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript ); - Gia_Man_t * pNew = Gia_ManDupStitch( pGia, vIns, vAnds, vOuts, vAigs ); + Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs ); + int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew); Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew ); if ( fVerbose ) - printf( "Iteration %3d : Using %3d partitions. Reducing %6d nodes to %6d nodes. ", - i, Vec_PtrSize(vAigs), Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) ); + printf( "Iteration %3d : Using %3d partitions. Reducing %6d to %6d %s. ", + i, Vec_PtrSize(vAigs), fMapped ? Gia_ManLutNum(pGia) : Gia_ManAndNum(pGia), + fMapped ? Gia_ManLutNum(pNew) : Gia_ManAndNum(pNew), + fMapped ? "LUTs" : "ANDs" ); if ( fVerbose ) Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); Gia_ManStop( pGia ); @@ -304,10 +449,12 @@ void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerb break; } } - nEnd = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); + fMapped &= Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); + nLutEnd = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0; + nEnd = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())); if ( fVerbose ) - printf( "Cumulatively reduced %d AIG nodes after %d iterations. ", - nBeg - nEnd, nIters ); + printf( "Cumulatively reduced %d %s after %d iterations. ", + fMapped ? nLutBeg - nLutEnd : nBeg - nEnd, fMapped ? "LUTs" : "ANDs", nIters ); if ( fVerbose ) Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart ); } -- cgit v1.2.3 From d514029e342f3ed72459fccce89666049e62867c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 9 Oct 2021 15:16:18 -0700 Subject: Experiments with SAT solving. --- src/aig/gia/giaCSat3.c | 1365 +++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 1 + 2 files changed, 1366 insertions(+) create mode 100644 src/aig/gia/giaCSat3.c (limited to 'src/aig') diff --git a/src/aig/gia/giaCSat3.c b/src/aig/gia/giaCSat3.c new file mode 100644 index 00000000..c34c84ca --- /dev/null +++ b/src/aig/gia/giaCSat3.c @@ -0,0 +1,1365 @@ +/**CFile**************************************************************** + + FileName [giaCSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [A simple circuit-based solver.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Cbs3_Par_t_ Cbs3_Par_t; +struct Cbs3_Par_t_ +{ + // conflict limits + int nBTLimit; // limit on the number of conflicts + int nJustLimit; // limit on the size of justification queue + int nRestLimit; // limit on the number of restarts + // current parameters + int nBTThis; // number of conflicts + int nJustThis; // max size of the frontier + int nBTTotal; // total number of conflicts + int nJustTotal; // total size of the frontier + // other + int fVerbose; +}; + +typedef struct Cbs3_Que_t_ Cbs3_Que_t; +struct Cbs3_Que_t_ +{ + int iHead; // beginning of the queue + int iTail; // end of the queue + int nSize; // allocated size + int * pData; // nodes stored in the queue +}; + +typedef struct Cbs3_Man_t_ Cbs3_Man_t; +struct Cbs3_Man_t_ +{ + Cbs3_Par_t Pars; // parameters + Gia_Man_t * pAig; // AIG manager + Cbs3_Que_t pProp; // propagation queue + Cbs3_Que_t pJust; // justification queue + Cbs3_Que_t pClauses; // clause queue + Vec_Int_t * vModel; // satisfying assignment + Vec_Int_t * vTemp; // temporary storage + // circuit structure + int nVars; + int nVarsAlloc; + int var_inc; + Vec_Int_t vMap; + Vec_Int_t vRef; + Vec_Int_t vFans; + Vec_Wec_t vImps; + // internal data + Vec_Str_t vAssign; + Vec_Str_t vMark; + Vec_Int_t vLevReason; + Vec_Int_t vActs; + Vec_Int_t vWatches; + Vec_Int_t vWatchUpds; + // SAT calls statistics + int nSatUnsat; // the number of proofs + int nSatSat; // the number of failure + int nSatUndec; // the number of timeouts + int nSatTotal; // the number of calls + // conflicts + int nConfUnsat; // conflicts in unsat problems + int nConfSat; // conflicts in sat problems + int nConfUndec; // conflicts in undec problems + // runtime stats + abctime timeJFront; + abctime timeSatLoad; // SAT solver loading time + abctime timeSatUnsat; // unsat + abctime timeSatSat; // sat + abctime timeSatUndec; // undecided + abctime timeTotal; // total runtime + // other statistics + int nPropCalls[3]; + int nFails[2]; + int nClauseConf; + int nDecs; +}; + +static inline int Cbs3_VarUnused( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry(&p->vLevReason, 3*iVar) == -1; } +static inline void Cbs3_VarSetUnused( Cbs3_Man_t * p, int iVar ) { Vec_IntWriteEntry(&p->vLevReason, 3*iVar, -1); } + +static inline int Cbs3_VarMark0( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vMark, iVar); } +static inline void Cbs3_VarSetMark0( Cbs3_Man_t * p, int iVar, int Value ) { Vec_StrWriteEntry(&p->vMark, iVar, (char)Value); } + +static inline int Cbs3_VarIsAssigned( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vAssign, iVar) < 2; } +static inline void Cbs3_VarUnassign( Cbs3_Man_t * p, int iVar ) { assert( Cbs3_VarIsAssigned(p, iVar)); Vec_StrWriteEntry(&p->vAssign, iVar, (char)(2+Vec_StrEntry(&p->vAssign, iVar))); Cbs3_VarSetUnused(p, iVar); } + +static inline int Cbs3_VarValue( Cbs3_Man_t * p, int iVar ) { return Vec_StrEntry(&p->vAssign, iVar); } +static inline void Cbs3_VarSetValue( Cbs3_Man_t * p, int iVar, int v ) { assert( !Cbs3_VarIsAssigned(p, iVar)); Vec_StrWriteEntry(&p->vAssign, iVar, (char)v); } + +static inline int Cbs3_VarLit0( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 0) ); } +static inline int Cbs3_VarLit1( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 1) ); } +static inline int Cbs3_VarIsPi( Cbs3_Man_t * p, int iVar ) { return Vec_IntEntry( &p->vFans, Abc_Var2Lit(iVar, 0) ) == 0; } +static inline int Cbs3_VarIsJust( Cbs3_Man_t * p, int iVar ) { int * pLits = Vec_IntEntryP(&p->vFans, Abc_Var2Lit(iVar, 0)); return pLits[0] > 0 && Cbs3_VarValue(p, Abc_Lit2Var(pLits[0])) >= 2 && Cbs3_VarValue(p, Abc_Lit2Var(pLits[1])) >= 2; } + +static inline int Cbs3_VarDecLevel( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar); } +static inline int Cbs3_VarReason0( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar+1); } +static inline int Cbs3_VarReason1( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntry(&p->vLevReason, 3*iVar+2); } +static inline int * Cbs3_VarReasonP( Cbs3_Man_t * p, int iVar ) { assert( !Cbs3_VarUnused(p, iVar) ); return Vec_IntEntryP(&p->vLevReason, 3*iVar+1); } +static inline int Cbs3_ClauseDecLevel( Cbs3_Man_t * p, int hClause ) { return Cbs3_VarDecLevel( p, p->pClauses.pData[hClause] ); } + +static inline int Cbs3_ClauseSize( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData[hClause]; } +static inline int * Cbs3_ClauseLits( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData+hClause+1; } +static inline int Cbs3_ClauseLit( Cbs3_Man_t * p, int hClause, int i ) { return p->pClauses.pData[hClause+1+i]; } +static inline int * Cbs3_ClauseNext1p( Cbs3_Man_t * p, int hClause ) { return p->pClauses.pData+hClause+Cbs3_ClauseSize(p, hClause)+2; } + +static inline void Cbs3_ClauseSetSize( Cbs3_Man_t * p, int hClause, int x ) { p->pClauses.pData[hClause] = x; } +static inline void Cbs3_ClauseSetLit( Cbs3_Man_t * p, int hClause, int i, int x ) { p->pClauses.pData[hClause+i+1] = x; } +static inline void Cbs3_ClauseSetNext( Cbs3_Man_t * p, int hClause, int n, int x ){ p->pClauses.pData[hClause+Cbs3_ClauseSize(p, hClause)+1+n] = x; } + + +#define Cbs3_QueForEachEntry( Que, iObj, i ) \ + for ( i = (Que).iHead; (i < (Que).iTail) && ((iObj) = (Que).pData[i]); i++ ) + +#define Cbs3_ClauseForEachEntry( p, hClause, iObj, i ) \ + for ( i = 1; i <= Cbs3_ClauseSize(p, hClause) && (iObj = (p)->pClauses.pData[hClause+i]); i++ ) +#define Cbs3_ClauseForEachEntry1( p, hClause, iObj, i ) \ + for ( i = 2; i <= Cbs3_ClauseSize(p, hClause) && (iObj = (p)->pClauses.pData[hClause+i]); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets default values of the parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cbs3_SetDefaultParams( Cbs3_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Cbs3_Par_t) ); + pPars->nBTLimit = 1000; // limit on the number of conflicts + pPars->nJustLimit = 500; // limit on the size of justification queue + pPars->nRestLimit = 10; // limit on the number of restarts + pPars->fVerbose = 1; // print detailed statistics +} +void Cbs3_ManSetConflictNum( Cbs3_Man_t * p, int Num ) +{ + p->Pars.nBTLimit = Num; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cbs3_Man_t * Cbs3_ManAlloc( Gia_Man_t * pGia ) +{ + Cbs3_Man_t * p; + p = ABC_CALLOC( Cbs3_Man_t, 1 ); + p->pProp.nSize = p->pJust.nSize = p->pClauses.nSize = 10000; + p->pProp.pData = ABC_ALLOC( int, p->pProp.nSize ); + p->pJust.pData = ABC_ALLOC( int, p->pJust.nSize ); + p->pClauses.pData = ABC_ALLOC( int, p->pClauses.nSize ); + p->pClauses.iHead = p->pClauses.iTail = 1; + p->vModel = Vec_IntAlloc( 1000 ); + p->vTemp = Vec_IntAlloc( 1000 ); + p->pAig = pGia; + Cbs3_SetDefaultParams( &p->Pars ); + // circuit structure + Vec_IntPush( &p->vMap, -1 ); + Vec_IntPush( &p->vRef, -1 ); + Vec_IntPushTwo( &p->vFans, -1, -1 ); + Vec_WecPushLevel( &p->vImps ); + Vec_WecPushLevel( &p->vImps ); + p->nVars = 1; + // internal data + p->nVarsAlloc = 1000; + Vec_StrFill( &p->vAssign, p->nVarsAlloc, 2 ); + Vec_StrFill( &p->vMark, p->nVarsAlloc, 0 ); + Vec_IntFill( &p->vLevReason, 3*p->nVarsAlloc, -1 ); + Vec_IntFill( &p->vActs, p->nVarsAlloc, 0 ); + Vec_IntFill( &p->vWatches, 2*p->nVarsAlloc, 0 ); + Vec_IntGrow( &p->vWatchUpds, 1000 ); + return p; +} +static inline void Cbs3_ManReset( Cbs3_Man_t * p ) +{ + assert( p->nVars == Vec_IntSize(&p->vMap) ); + Vec_IntShrink( &p->vMap, 1 ); + Vec_IntShrink( &p->vRef, 1 ); + Vec_IntShrink( &p->vFans, 2 ); + Vec_WecShrink( &p->vImps, 2 ); + p->nVars = 1; +} +static inline void Cbs3_ManGrow( Cbs3_Man_t * p ) +{ + if ( p->nVarsAlloc < p->nVars ) + { + p->nVarsAlloc = 2*p->nVars; + Vec_StrFill( &p->vAssign, p->nVarsAlloc, 2 ); + Vec_StrFill( &p->vMark, p->nVarsAlloc, 0 ); + Vec_IntFill( &p->vLevReason, 3*p->nVarsAlloc, -1 ); + Vec_IntFill( &p->vActs, p->nVarsAlloc, 0 ); + Vec_IntFill( &p->vWatches, 2*p->nVarsAlloc, 0 ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cbs3_ManStop( Cbs3_Man_t * p ) +{ + // circuit structure + Vec_IntErase( &p->vMap ); + Vec_IntErase( &p->vRef ); + Vec_IntErase( &p->vFans ); + Vec_WecErase( &p->vImps ); + // internal data + Vec_StrErase( &p->vAssign ); + Vec_StrErase( &p->vMark ); + Vec_IntErase( &p->vLevReason ); + Vec_IntErase( &p->vActs ); + Vec_IntErase( &p->vWatches ); + Vec_IntErase( &p->vWatchUpds ); + Vec_IntFree( p->vModel ); + Vec_IntFree( p->vTemp ); + ABC_FREE( p->pClauses.pData ); + ABC_FREE( p->pProp.pData ); + ABC_FREE( p->pJust.pData ); + ABC_FREE( p ); +} +int Cbs3_ManMemory( Cbs3_Man_t * p ) +{ + int nMem = sizeof(Cbs3_Man_t); + nMem += (int)Vec_IntMemory( &p->vMap ); + nMem += (int)Vec_IntMemory( &p->vRef ); + nMem += (int)Vec_IntMemory( &p->vFans ); + nMem += (int)Vec_WecMemory( &p->vImps ); + nMem += (int)Vec_StrMemory( &p->vAssign ); + nMem += (int)Vec_StrMemory( &p->vMark ); + nMem += (int)Vec_IntMemory( &p->vActs ); + nMem += (int)Vec_IntMemory( &p->vWatches ); + nMem += (int)Vec_IntMemory( &p->vWatchUpds ); + nMem += (int)Vec_IntMemory( p->vModel ); + nMem += (int)Vec_IntMemory( p->vTemp ); + nMem += 4*p->pClauses.nSize; + nMem += 4*p->pProp.nSize; + nMem += 4*p->pJust.nSize; + return nMem; +} + +/**Function************************************************************* + + Synopsis [Returns satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Cbs3_ReadModel( Cbs3_Man_t * p ) +{ + return p->vModel; +} + + +/**Function************************************************************* + + Synopsis [Activity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +//#define USE_ACTIVITY + +#ifdef USE_ACTIVITY +static inline void Cbs3_ActReset( Cbs3_Man_t * p ) +{ + int i, * pAct = Vec_IntArray(&p->vActs); + for ( i = 0; i < p->nVars; i++ ) + pAct[i] = (1 << 10); + p->var_inc = (1 << 5); +} +static inline void Cbs3_ActRescale( Cbs3_Man_t * p ) +{ + int i, * pAct = Vec_IntArray(&p->vActs); + for ( i = 0; i < p->nVars; i++ ) + pAct[i] >>= 19; + p->var_inc >>= 19; + p->var_inc = Abc_MaxInt( (unsigned)p->var_inc, (1<<5) ); +} +static inline void Cbs3_ActBumpVar( Cbs3_Man_t * p, int iVar ) +{ + int * pAct = Vec_IntArray(&p->vActs); + pAct[iVar] += p->var_inc; + if ((unsigned)pAct[iVar] & 0x80000000) + Cbs3_ActRescale(p); +} +static inline void Cbs3_ActDecay( Cbs3_Man_t * p ) +{ + p->var_inc += (p->var_inc >> 4); +} +#else +static inline void Cbs3_ActReset( Cbs3_Man_t * p ) {} +static inline void Cbs3_ActRescale( Cbs3_Man_t * p ) {} +static inline void Cbs3_ActBumpVar( Cbs3_Man_t * p, int iVar ) {} +static inline void Cbs3_ActDecay( Cbs3_Man_t * p ) {} +#endif + + +/**Function************************************************************* + + Synopsis [Returns 1 if the solver is out of limits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_ManCheckLimits( Cbs3_Man_t * p ) +{ + p->nFails[0] += p->Pars.nJustThis > p->Pars.nJustLimit; + p->nFails[1] += p->Pars.nBTThis > p->Pars.nBTLimit; + return p->Pars.nJustThis > p->Pars.nJustLimit || p->Pars.nBTThis > p->Pars.nBTLimit; +} + +/**Function************************************************************* + + Synopsis [Saves the satisfying assignment as an array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_ManSaveModel( Cbs3_Man_t * p, Vec_Int_t * vCex ) +{ + int i, iLit; + Vec_IntClear( vCex ); + p->pProp.iHead = 0; + Cbs3_QueForEachEntry( p->pProp, iLit, i ) + if ( Cbs3_VarIsPi(p, Abc_Lit2Var(iLit)) ) + Vec_IntPush( vCex, Abc_Lit2LitV(Vec_IntArray(&p->vMap), iLit)-2 ); +} +static inline void Cbs3_ManSaveModelAll( Cbs3_Man_t * p, Vec_Int_t * vCex ) +{ + int i, iLit; + Vec_IntClear( vCex ); + p->pProp.iHead = 0; + Cbs3_QueForEachEntry( p->pProp, iLit, i ) + { + int iVar = Abc_Lit2Var(iLit); + Vec_IntPush( vCex, Abc_Var2Lit(iVar, !Cbs3_VarValue(p, iVar)) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_QueIsEmpty( Cbs3_Que_t * p ) +{ + return p->iHead == p->iTail; +} +static inline int Cbs3_QueSize( Cbs3_Que_t * p ) +{ + return p->iTail - p->iHead; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_QuePush( Cbs3_Que_t * p, int iObj ) +{ + if ( p->iTail == p->nSize ) + { + p->nSize *= 2; + p->pData = ABC_REALLOC( int, p->pData, p->nSize ); + } + p->pData[p->iTail++] = iObj; +} +static inline void Cbs3_QueGrow( Cbs3_Que_t * p, int Plus ) +{ + if ( p->iTail + Plus > p->nSize ) + { + p->nSize *= 2; + p->pData = ABC_REALLOC( int, p->pData, p->nSize ); + } + assert( p->iTail + Plus <= p->nSize ); +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the object in the queue.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_QueHasNode( Cbs3_Que_t * p, int iObj ) +{ + int i, iTemp; + Cbs3_QueForEachEntry( *p, iTemp, i ) + if ( iTemp == iObj ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_QueStore( Cbs3_Que_t * p, int * piHeadOld, int * piTailOld ) +{ + int i; + *piHeadOld = p->iHead; + *piTailOld = p->iTail; + for ( i = *piHeadOld; i < *piTailOld; i++ ) + Cbs3_QuePush( p, p->pData[i] ); + p->iHead = *piTailOld; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_QueRestore( Cbs3_Que_t * p, int iHeadOld, int iTailOld ) +{ + p->iHead = iHeadOld; + p->iTail = iTailOld; +} + +/**Function************************************************************* + + Synopsis [Find variable with the highest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_ManDecide( Cbs3_Man_t * p ) +{ + int i, iObj, iObjMax = 0; +#ifdef USE_ACTIVITY + Cbs3_QueForEachEntry( p->pJust, iObj, i ) + if ( iObjMax == 0 || + Vec_IntEntry(&p->vActs, iObjMax) < Vec_IntEntry(&p->vActs, iObj) || + (Vec_IntEntry(&p->vActs, iObjMax) == Vec_IntEntry(&p->vActs, iObj) && Vec_IntEntry(&p->vMap, iObjMax) < Vec_IntEntry(&p->vMap, iObj)) ) + iObjMax = iObj; +#else + Cbs3_QueForEachEntry( p->pJust, iObj, i ) +// if ( iObjMax == 0 || iObjMax < iObj ) + if ( iObjMax == 0 || Vec_IntEntry(&p->vMap, iObjMax) < Vec_IntEntry(&p->vMap, iObj) ) + iObjMax = iObj; +#endif + return iObjMax; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_ManCancelUntil( Cbs3_Man_t * p, int iBound ) +{ + int i, iLit; + assert( iBound <= p->pProp.iTail ); + p->pProp.iHead = iBound; + Cbs3_QueForEachEntry( p->pProp, iLit, i ) + Cbs3_VarUnassign( p, Abc_Lit2Var(iLit) ); + p->pProp.iTail = iBound; +} + +/**Function************************************************************* + + Synopsis [Assigns the variables a value.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_ManAssign( Cbs3_Man_t * p, int iLit, int Level, int iRes0, int iRes1 ) +{ + int iObj = Abc_Lit2Var(iLit); + assert( Cbs3_VarUnused(p, iObj) ); + assert( !Cbs3_VarIsAssigned(p, iObj) ); + Cbs3_VarSetValue( p, iObj, !Abc_LitIsCompl(iLit) ); + Cbs3_QuePush( &p->pProp, iLit ); + Vec_IntWriteEntry( &p->vLevReason, 3*iObj, Level ); + Vec_IntWriteEntry( &p->vLevReason, 3*iObj+1, iRes0 ); + Vec_IntWriteEntry( &p->vLevReason, 3*iObj+2, iRes1 ); +} + + + + +/**Function************************************************************* + + Synopsis [Prints conflict clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_ManPrintClause( Cbs3_Man_t * p, int Level, int hClause ) +{ + int i, iLit; + assert( Cbs3_QueIsEmpty( &p->pClauses ) ); + printf( "Level %2d : ", Level ); + Cbs3_ClauseForEachEntry( p, hClause, iLit, i ) + printf( "%c%d ", Abc_LitIsCompl(iLit) ? '-':'+', Abc_Lit2Var(iLit) ); +// printf( "%d=%d(%d) ", iObj, Cbs3_VarValue(p, Abc_Lit2Var(iLit)), Cbs3_VarDecLevel(p, Abc_Lit2Var(iLit)) ); + printf( "\n" ); +} +static inline void Cbs3_ManPrintCube( Cbs3_Man_t * p, int Level, int hClause ) +{ + int i, iObj; + assert( Cbs3_QueIsEmpty( &p->pClauses ) ); + printf( "Level %2d : ", Level ); + Cbs3_ClauseForEachEntry( p, hClause, iObj, i ) + printf( "%c%d ", Cbs3_VarValue(p, iObj)? '+':'-', iObj ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Finalized the clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_ManCleanWatch( Cbs3_Man_t * p ) +{ + int i, iLit; + Vec_IntForEachEntry( &p->vWatchUpds, iLit, i ) + Vec_IntWriteEntry( &p->vWatches, iLit, 0 ); + Vec_IntClear( &p->vWatchUpds ); + //Vec_IntForEachEntry( &p->vWatches, iLit, i ) + // assert( iLit == 0 ); +} +static inline void Cbs3_ManWatchClause( Cbs3_Man_t * p, int hClause, int Lit ) +{ + int * pLits = Cbs3_ClauseLits( p, hClause ); + int * pPlace = Vec_IntEntryP( &p->vWatches, Abc_LitNot(Lit) ); + if ( *pPlace == 0 ) + Vec_IntPush( &p->vWatchUpds, Abc_LitNot(Lit) ); +/* + if ( pClause->pLits[0] == Lit ) + pClause->pNext0 = p->pWatches[lit_neg(Lit)]; + else + { + assert( pClause->pLits[1] == Lit ); + pClause->pNext1 = p->pWatches[lit_neg(Lit)]; + } + p->pWatches[lit_neg(Lit)] = pClause; +*/ + assert( Lit == pLits[0] || Lit == pLits[1] ); + Cbs3_ClauseSetNext( p, hClause, Lit == pLits[1], *pPlace ); + *pPlace = hClause; +} +static inline int Cbs3_QueFinish( Cbs3_Man_t * p, int Level ) +{ + Cbs3_Que_t * pQue = &(p->pClauses); + int i, iObj, hClauseC, hClause = pQue->iHead, Size = pQue->iTail - pQue->iHead - 1; + assert( pQue->iHead+1 < pQue->iTail ); + Cbs3_ClauseSetSize( p, pQue->iHead, Size ); + hClauseC = pQue->iHead = pQue->iTail; + //printf( "Adding cube: " ); Cbs3_ManPrintCube(p, Level, hClause); + if ( Size == 1 ) + return hClause; + // create watched clause + pQue->iHead = hClause; + Cbs3_QueForEachEntry( p->pClauses, iObj, i ) + { + if ( i == hClauseC ) + break; + else if ( i == hClause ) // nlits + Cbs3_QuePush( pQue, iObj ); + else // literals + Cbs3_QuePush( pQue, Abc_Var2Lit(iObj, Cbs3_VarValue(p, iObj)) ); // complement + } + Cbs3_QuePush( pQue, 0 ); // next0 + Cbs3_QuePush( pQue, 0 ); // next1 + pQue->iHead = pQue->iTail; + Cbs3_ManWatchClause( p, hClauseC, Cbs3_ClauseLit(p, hClauseC, 0) ); + Cbs3_ManWatchClause( p, hClauseC, Cbs3_ClauseLit(p, hClauseC, 1) ); + //printf( "Adding clause %d: ", hClauseC ); Cbs3_ManPrintClause(p, Level, hClauseC); + Cbs3_ActDecay( p ); + return hClause; +} + +/**Function************************************************************* + + Synopsis [Returns conflict clause.] + + Description [Performs conflict analysis.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_ManDeriveReason( Cbs3_Man_t * p, int Level ) +{ + Cbs3_Que_t * pQue = &(p->pClauses); + int i, k, iObj, iLitLevel, * pReason; + assert( pQue->pData[pQue->iHead] == 0 ); + assert( pQue->pData[pQue->iHead+1] == 0 ); + assert( pQue->iHead + 2 < pQue->iTail ); + //for ( i = pQue->iHead + 2; i < pQue->iTail; i++ ) + // assert( !Cbs3_VarMark0(p, pQue->pData[i]) ); + // compact literals + Vec_IntClear( p->vTemp ); + for ( i = k = pQue->iHead + 2; i < pQue->iTail; i++ ) + { + iObj = pQue->pData[i]; + if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again + continue; + //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 ) + // Vec_IntPush( &p->vActStore, iObj ); + //Vec_IntAddToEntry( &p->vActivity, iObj, 1 ); + // assigned - seen first time + Cbs3_VarSetMark0(p, iObj, 1); + Cbs3_ActBumpVar(p, iObj); + Vec_IntPush( p->vTemp, iObj ); + // check decision level + iLitLevel = Cbs3_VarDecLevel( p, iObj ); + if ( iLitLevel < Level ) + { + pQue->pData[k++] = iObj; + continue; + } + assert( iLitLevel == Level ); + pReason = Cbs3_VarReasonP( p, iObj ); + if ( pReason[0] == 0 && pReason[1] == 0 ) // no reason + { + assert( pQue->pData[pQue->iHead+1] == 0 ); + pQue->pData[pQue->iHead+1] = iObj; + } + else if ( pReason[0] != 0 ) // circuit reason + { + Cbs3_QuePush( pQue, pReason[0] ); + if ( pReason[1] ) + Cbs3_QuePush( pQue, pReason[1] ); + } + else // clause reason + { + int i, * pLits, nLits = Cbs3_ClauseSize( p, pReason[1] ); + assert( pReason[1] ); + Cbs3_QueGrow( pQue, nLits ); + pLits = Cbs3_ClauseLits( p, pReason[1] ); + assert( iObj == Abc_Lit2Var(pLits[0]) ); + for ( i = 1; i < nLits; i++ ) + Cbs3_QuePush( pQue, Abc_Lit2Var(pLits[i]) ); + } + } + assert( pQue->pData[pQue->iHead] == 0 ); + assert( pQue->pData[pQue->iHead+1] != 0 ); + pQue->iTail = k; + // clear the marks + Vec_IntForEachEntry( p->vTemp, iObj, i ) + Cbs3_VarSetMark0(p, iObj, 0); + return Cbs3_QueFinish( p, Level ); +} +static inline int Cbs3_ManAnalyze( Cbs3_Man_t * p, int Level, int iVar, int iFan0, int iFan1 ) +{ + Cbs3_Que_t * pQue = &(p->pClauses); + assert( Cbs3_VarIsAssigned(p, iVar) ); + assert( Cbs3_QueIsEmpty( pQue ) ); + Cbs3_QuePush( pQue, 0 ); + Cbs3_QuePush( pQue, 0 ); + if ( iFan0 ) // circuit conflict + { + assert( Cbs3_VarIsAssigned(p, iFan0) ); + assert( iFan1 == 0 || Cbs3_VarIsAssigned(p, iFan1) ); + Cbs3_QuePush( pQue, iVar ); + Cbs3_QuePush( pQue, iFan0 ); + if ( iFan1 ) + Cbs3_QuePush( pQue, iFan1 ); + } + else // clause conflict + { + int i, * pLits, nLits = Cbs3_ClauseSize( p, iFan1 ); + assert( iFan1 ); + Cbs3_QueGrow( pQue, nLits ); + pLits = Cbs3_ClauseLits( p, iFan1 ); + assert( iVar == Abc_Lit2Var(pLits[0]) ); + assert( Cbs3_VarValue(p, iVar) == Abc_LitIsCompl(pLits[0]) ); + for ( i = 0; i < nLits; i++ ) + Cbs3_QuePush( pQue, Abc_Lit2Var(pLits[i]) ); + } + return Cbs3_ManDeriveReason( p, Level ); +} + + +/**Function************************************************************* + + Synopsis [Propagate one assignment.] + + Description [Returns handle of the conflict clause, if conflict occurs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_ManPropagateClauses( Cbs3_Man_t * p, int Level, int Lit ) +{ + int i, Value, Cur, LitF = Abc_LitNot(Lit); + int * pPrev = Vec_IntEntryP( &p->vWatches, Lit ); + //for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev ) + for ( Cur = *pPrev; Cur; Cur = *pPrev ) + { + int nLits = Cbs3_ClauseSize( p, Cur ); + int * pLits = Cbs3_ClauseLits( p, Cur ); + p->nPropCalls[1]++; +//printf( " Watching literal %c%d on level %d.\n", Abc_LitIsCompl(Lit) ? '-':'+', Abc_Lit2Var(Lit), Level ); + // make sure the false literal is in the second literal of the clause + //if ( pCur->pLits[0] == LitF ) + if ( pLits[0] == LitF ) + { + //pCur->pLits[0] = pCur->pLits[1]; + pLits[0] = pLits[1]; + //pCur->pLits[1] = LitF; + pLits[1] = LitF; + //pTemp = pCur->pNext0; + //pCur->pNext0 = pCur->pNext1; + //pCur->pNext1 = pTemp; + ABC_SWAP( int, pLits[nLits], pLits[nLits+1] ); + } + //assert( pCur->pLits[1] == LitF ); + assert( pLits[1] == LitF ); + + // if the first literal is true, the clause is satisfied + //if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] ) + if ( Cbs3_VarValue(p, Abc_Lit2Var(pLits[0])) == !Abc_LitIsCompl(pLits[0]) ) + { + //ppPrev = &pCur->pNext1; + pPrev = Cbs3_ClauseNext1p(p, Cur); + continue; + } + + // look for a new literal to watch + for ( i = 2; i < nLits; i++ ) + { + // skip the case when the literal is false + //if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] ) + if ( Cbs3_VarValue(p, Abc_Lit2Var(pLits[i])) == Abc_LitIsCompl(pLits[i]) ) + continue; + // the literal is either true or unassigned - watch it + //pCur->pLits[1] = pCur->pLits[i]; + //pCur->pLits[i] = LitF; + pLits[1] = pLits[i]; + pLits[i] = LitF; + // remove this clause from the watch list of Lit + //*ppPrev = pCur->pNext1; + *pPrev = *Cbs3_ClauseNext1p(p, Cur); + // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1]) + //Intb_ManWatchClause( p, pCur, pCur->pLits[1] ); + Cbs3_ManWatchClause( p, Cur, Cbs3_ClauseLit(p, Cur, 1) ); + break; + } + if ( i < nLits ) // found new watch + continue; + + // clause is unit - enqueue new implication + //if ( Inta_ManEnqueue(p, pCur->pLits[0], pCur) ) + //{ + // ppPrev = &pCur->pNext1; + // continue; + //} + + // clause is unit - enqueue new implication + Value = Cbs3_VarValue(p, Abc_Lit2Var(pLits[0])); + if ( Value >= 2 ) // unassigned + { + Cbs3_ManAssign( p, pLits[0], Level, 0, Cur ); + pPrev = Cbs3_ClauseNext1p(p, Cur); + continue; + } + + // conflict detected - return the conflict clause + //return pCur; + if ( Value == Abc_LitIsCompl(pLits[0]) ) + { + p->nClauseConf++; + return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(pLits[0]), 0, Cur ); + } + } + return 0; +} + + +/**Function************************************************************* + + Synopsis [Performs resolution of two clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_ManResolve( Cbs3_Man_t * p, int Level, int hClause0, int hClause1 ) +{ + Cbs3_Que_t * pQue = &(p->pClauses); + int i, iObj, LevelMax = -1, LevelCur; + assert( pQue->pData[hClause0+1] != 0 ); + assert( pQue->pData[hClause0+1] == pQue->pData[hClause1+1] ); + //Cbs3_ClauseForEachEntry1( p, hClause0, iObj, i ) + // assert( !Cbs3_VarMark0(p, iObj) ); + //Cbs3_ClauseForEachEntry1( p, hClause1, iObj, i ) + // assert( !Cbs3_VarMark0(p, iObj) ); + assert( Cbs3_QueIsEmpty( pQue ) ); + Cbs3_QuePush( pQue, 0 ); + Cbs3_QuePush( pQue, 0 ); +// for ( i = hClause0 + 1; (iObj = pQue->pData[i]); i++ ) + Cbs3_ClauseForEachEntry1( p, hClause0, iObj, i ) + { + if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again + continue; + //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 ) + // Vec_IntPush( &p->vActStore, iObj ); + //Vec_IntAddToEntry( &p->vActivity, iObj, 1 ); + // assigned - seen first time + Cbs3_VarSetMark0(p, iObj, 1); + Cbs3_ActBumpVar(p, iObj); + Cbs3_QuePush( pQue, iObj ); + LevelCur = Cbs3_VarDecLevel( p, iObj ); + if ( LevelMax < LevelCur ) + LevelMax = LevelCur; + } +// for ( i = hClause1 + 1; (iObj = pQue->pData[i]); i++ ) + Cbs3_ClauseForEachEntry1( p, hClause1, iObj, i ) + { + if ( Cbs3_VarMark0(p, iObj) ) // unassigned - seen again + continue; + //if ( Vec_IntEntry(&p->vActivity, iObj) == 0 ) + // Vec_IntPush( &p->vActStore, iObj ); + //Vec_IntAddToEntry( &p->vActivity, iObj, 1 ); + // assigned - seen first time + Cbs3_VarSetMark0(p, iObj, 1); + Cbs3_ActBumpVar(p, iObj); + Cbs3_QuePush( pQue, iObj ); + LevelCur = Cbs3_VarDecLevel( p, iObj ); + if ( LevelMax < LevelCur ) + LevelMax = LevelCur; + } + for ( i = pQue->iHead + 2; i < pQue->iTail; i++ ) + Cbs3_VarSetMark0(p, pQue->pData[i], 0); + return Cbs3_ManDeriveReason( p, LevelMax ); +} + +/**Function************************************************************* + + Synopsis [Propagates a variable.] + + Description [Returns clause handle if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cbs3_ManUpdateJFrontier( Cbs3_Man_t * p ) +{ + //abctime clk = Abc_Clock(); + int iVar, iLit, i, k = p->pJust.iTail; + Cbs3_QueGrow( &p->pJust, Cbs3_QueSize(&p->pJust) + Cbs3_QueSize(&p->pProp) ); + Cbs3_QueForEachEntry( p->pJust, iVar, i ) + if ( Cbs3_VarIsJust(p, iVar) ) + p->pJust.pData[k++] = iVar; + Cbs3_QueForEachEntry( p->pProp, iLit, i ) + if ( Cbs3_VarIsJust(p, Abc_Lit2Var(iLit)) ) + p->pJust.pData[k++] = Abc_Lit2Var(iLit); + p->pJust.iHead = p->pJust.iTail; + p->pJust.iTail = k; + //p->timeJFront += Abc_Clock() - clk; +} +int Cbs3_ManPropagateNew( Cbs3_Man_t * p, int Level ) +{ + int i, k, iLit, hClause, nLits, * pLits; + p->nPropCalls[0]++; + Cbs3_QueForEachEntry( p->pProp, iLit, i ) + { + if ( (hClause = Cbs3_ManPropagateClauses(p, Level, iLit)) ) + return hClause; + p->nPropCalls[2]++; + nLits = Vec_IntSize(Vec_WecEntry(&p->vImps, iLit)); + pLits = Vec_IntArray(Vec_WecEntry(&p->vImps, iLit)); + for ( k = 0; k < nLits; k += 2 ) + { + int Value0 = Cbs3_VarValue(p, Abc_Lit2Var(pLits[k])); + int Value1 = pLits[k+1] ? Cbs3_VarValue(p, Abc_Lit2Var(pLits[k+1])) : -1; + if ( Value1 == -1 || Value1 == Abc_LitIsCompl(pLits[k+1]) ) // pLits[k+1] is false + { + if ( Value0 >= 2 ) // pLits[k] is unassigned + Cbs3_ManAssign( p, pLits[k], Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k+1]) ); + else if ( Value0 == Abc_LitIsCompl(pLits[k]) ) // pLits[k] is false + return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]), Abc_Lit2Var(pLits[k+1]) ); + } + if ( Value1 != -1 && Value0 == Abc_LitIsCompl(pLits[k]) ) // pLits[k] is false + { + if ( Value1 >= 2 ) // pLits[k+1] is unassigned + Cbs3_ManAssign( p, pLits[k+1], Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]) ); + else if ( Value1 == Abc_LitIsCompl(pLits[k+1]) ) // pLits[k+1] is false + return Cbs3_ManAnalyze( p, Level, Abc_Lit2Var(iLit), Abc_Lit2Var(pLits[k]), Abc_Lit2Var(pLits[k+1]) ); + } + } + } + Cbs3_ManUpdateJFrontier( p ); + // finalize propagation queue + p->pProp.iHead = p->pProp.iTail; + return 0; +} + +/**Function************************************************************* + + Synopsis [Solve the problem recursively.] + + Description [Returns learnt clause if unsat, NULL if sat or undecided.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cbs3_ManSolve2_rec( Cbs3_Man_t * p, int Level ) +{ + Cbs3_Que_t * pQue = &(p->pClauses); + int iPropHead, iJustHead, iJustTail; + int hClause, hLearn0, hLearn1, iVar, iDecLit; + int nRef0, nRef1; + // propagate assignments + assert( !Cbs3_QueIsEmpty(&p->pProp) ); + //if ( (hClause = Cbs3_ManPropagate( p, Level )) ) + if ( (hClause = Cbs3_ManPropagateNew( p, Level )) ) + return hClause; + // check for satisfying assignment + assert( Cbs3_QueIsEmpty(&p->pProp) ); + if ( Cbs3_QueIsEmpty(&p->pJust) ) + return 0; + // quit using resource limits + p->Pars.nJustThis = Abc_MaxInt( p->Pars.nJustThis, p->pJust.iTail - p->pJust.iHead ); + if ( Cbs3_ManCheckLimits( p ) ) + return 0; + // remember the state before branching + iPropHead = p->pProp.iHead; + iJustHead = p->pJust.iHead; + iJustTail = p->pJust.iTail; + // find the decision variable + p->nDecs++; + iVar = Cbs3_ManDecide( p ); + assert( !Cbs3_VarIsPi(p, iVar) ); + assert( Cbs3_VarIsJust(p, iVar) ); + // chose decision variable using fanout count + nRef0 = Vec_IntEntry(&p->vRef, Abc_Lit2Var(Cbs3_VarLit0(p, iVar))); + nRef1 = Vec_IntEntry(&p->vRef, Abc_Lit2Var(Cbs3_VarLit1(p, iVar))); +// if ( nRef0 >= nRef1 || (nRef0 == nRef1) && (Abc_Random(0) & 1) ) + if ( nRef0 >= nRef1 ) + iDecLit = Abc_LitNot(Cbs3_VarLit0(p, iVar)); + else + iDecLit = Abc_LitNot(Cbs3_VarLit1(p, iVar)); + // decide on first fanin + Cbs3_ManAssign( p, iDecLit, Level+1, 0, 0 ); + if ( !(hLearn0 = Cbs3_ManSolve2_rec( p, Level+1 )) ) + return 0; + if ( pQue->pData[hLearn0+1] != Abc_Lit2Var(iDecLit) ) + return hLearn0; + Cbs3_ManCancelUntil( p, iPropHead ); + Cbs3_QueRestore( &p->pJust, iJustHead, iJustTail ); + // decide on second fanin + Cbs3_ManAssign( p, Abc_LitNot(iDecLit), Level+1, 0, 0 ); + if ( !(hLearn1 = Cbs3_ManSolve2_rec( p, Level+1 )) ) + return 0; + if ( pQue->pData[hLearn1+1] != Abc_Lit2Var(iDecLit) ) + return hLearn1; + hClause = Cbs3_ManResolve( p, Level, hLearn0, hLearn1 ); + p->Pars.nBTThis++; + return hClause; +} + +/**Function************************************************************* + + Synopsis [Looking for a satisfying assignment of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_ManSolveInt( Cbs3_Man_t * p, int iLit ) +{ + int RetValue = 0; + assert( !p->pProp.iHead && !p->pProp.iTail ); + assert( !p->pJust.iHead && !p->pJust.iTail ); + p->Pars.nBTThis = p->Pars.nJustThis = 0; + Cbs3_ManAssign( p, iLit, 0, 0, 0 ); + if ( !Cbs3_ManSolve2_rec(p, 0) && !Cbs3_ManCheckLimits(p) ) + Cbs3_ManSaveModel( p, p->vModel ); + else + RetValue = 1; + Cbs3_ManCancelUntil( p, 0 ); + p->pJust.iHead = p->pJust.iTail = 0; + p->Pars.nBTTotal += p->Pars.nBTThis; + p->Pars.nJustTotal = Abc_MaxInt( p->Pars.nJustTotal, p->Pars.nJustThis ); + if ( Cbs3_ManCheckLimits( p ) ) + RetValue = -1; + return RetValue; +} +int Cbs3_ManSolve( Cbs3_Man_t * p, int iLit, int nRestarts ) +{ + int i, RetValue = -1; + assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 ); + for ( i = 0; i < nRestarts; i++ ) + if ( (RetValue = Cbs3_ManSolveInt(p, iLit)) != -1 ) + break; + Cbs3_ManCleanWatch( p ); + p->pClauses.iHead = p->pClauses.iTail = 1; + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Prints statistics of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cbs3_ManSatPrintStats( Cbs3_Man_t * p ) +{ + printf( "CO = %8d ", Gia_ManCoNum(p->pAig) ); + printf( "AND = %8d ", Gia_ManAndNum(p->pAig) ); + printf( "Conf = %6d ", p->Pars.nBTLimit ); + printf( "Restart = %2d ", p->Pars.nRestLimit ); + printf( "JustMax = %5d ", p->Pars.nJustLimit ); + printf( "\n" ); + printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal :0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); + ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); + printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal :0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); + ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); + printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal :0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); + ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); + ABC_PRT( "Total time", p->timeTotal ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cbs3_ManAddVar( Cbs3_Man_t * p, int iGiaObj ) +{ + assert( Vec_IntSize(&p->vMap) == p->nVars ); + Vec_IntPush( &p->vMap, iGiaObj ); + Vec_IntPush( &p->vRef, Gia_ObjRefNumId(p->pAig, iGiaObj) ); + Vec_IntPushTwo( &p->vFans, 0, 0 ); + Vec_WecPushLevel(&p->vImps); + Vec_WecPushLevel(&p->vImps); + return Abc_Var2Lit( p->nVars++, 0 ); +} +static inline void Cbs3_ManAddConstr( Cbs3_Man_t * p, int x, int x0, int x1 ) +{ + Vec_WecPushTwo( &p->vImps, x , x0, 0 ); // ~x + x0 + Vec_WecPushTwo( &p->vImps, x , x1, 0 ); // ~x + x1 + Vec_WecPushTwo( &p->vImps, 1^x0, 1^x , 0 ); // ~x + x0 + Vec_WecPushTwo( &p->vImps, 1^x1, 1^x , 0 ); // ~x + x1 + Vec_WecPushTwo( &p->vImps, 1^x , 1^x0, 1^x1 ); // x + ~x0 + ~x1 + Vec_WecPushTwo( &p->vImps, x0, x , 1^x1 ); // x + ~x0 + ~x1 + Vec_WecPushTwo( &p->vImps, x1, x , 1^x0 ); // x + ~x0 + ~x1 +} +static inline void Cbs3_ManAddAnd( Cbs3_Man_t * p, int x, int x0, int x1 ) +{ + assert( x > 0 && x0 > 0 && x1 > 0 ); + Vec_IntWriteEntry( &p->vFans, x, x0 ); + Vec_IntWriteEntry( &p->vFans, x+1, x1 ); + Cbs3_ManAddConstr( p, x, x0, x1 ); +} +static inline int Cbs3_ManToSolver1_rec( Cbs3_Man_t * pSol, Gia_Man_t * p, int iObj, int Depth ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int Lit0, Lit1; + if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) ) + return pObj->Value; + pObj->Value = Cbs3_ManAddVar( pSol, iObj ); + if ( Gia_ObjIsCi(pObj) || Depth == 0 ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Lit0 = Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId0(pObj, iObj), Depth - Gia_ObjFaninC0(pObj) ); + Lit1 = Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId1(pObj, iObj), Depth - Gia_ObjFaninC1(pObj) ); + Cbs3_ManAddAnd( pSol, pObj->Value, Lit0 ^ Gia_ObjFaninC0(pObj), Lit1 ^ Gia_ObjFaninC1(pObj) ); + return pObj->Value; +} +static inline int Cbs3_ManToSolver1( Cbs3_Man_t * pSol, Gia_Man_t * p, Gia_Obj_t * pRoot, int nRestarts, int Depth ) +{ + //abctime clk = Abc_Clock(); + assert( Gia_ObjIsCo(pRoot) ); + Cbs3_ManReset( pSol ); + Gia_ManIncrementTravId( p ); + Cbs3_ManToSolver1_rec( pSol, p, Gia_ObjFaninId0p(p, pRoot), Depth ); + Cbs3_ManGrow( pSol ); + Cbs3_ActReset( pSol ); + //pSol->timeSatLoad += Abc_Clock() - clk; + return Cbs3_ManSolve( pSol, Gia_ObjFanin0Copy(pRoot), nRestarts ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cbs3_ManPrepare( Cbs3_Man_t * p ) +{ + int x, x0, x1; + Vec_WecInit( &p->vImps, Abc_Var2Lit(p->nVars, 0) ); + Vec_IntForEachEntryDoubleStart( &p->vFans, x0, x1, x, 2 ) + if ( x0 ) Cbs3_ManAddConstr( p, x, x0, x1 ); +} +static inline int Cbs3_ManAddNode( Cbs3_Man_t * p, int iGiaObj, int iLit0, int iLit1 ) +{ + assert( Vec_IntSize(&p->vMap) == p->nVars ); + Vec_IntPush( &p->vMap, iGiaObj ); + Vec_IntPush( &p->vRef, Gia_ObjRefNumId(p->pAig, iGiaObj) ); + Vec_IntPushTwo( &p->vFans, iLit0, iLit1 ); + return Abc_Var2Lit( p->nVars++, 0 ); +} +static inline int Cbs3_ManToSolver2_rec( Cbs3_Man_t * pSol, Gia_Man_t * p, int iObj, int Depth ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int Lit0, Lit1; + if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) ) + return pObj->Value; + if ( Gia_ObjIsCi(pObj) || Depth == 0 ) + return pObj->Value = Cbs3_ManAddNode(pSol, iObj, 0, 0); + assert( Gia_ObjIsAnd(pObj) ); + Lit0 = Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId0(pObj, iObj), Depth - Gia_ObjFaninC0(pObj) ); + Lit1 = Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId1(pObj, iObj), Depth - Gia_ObjFaninC1(pObj) ); + return pObj->Value = Cbs3_ManAddNode(pSol, iObj, Lit0 ^ Gia_ObjFaninC0(pObj), Lit1 ^ Gia_ObjFaninC1(pObj)); +} +static inline int Cbs3_ManToSolver2( Cbs3_Man_t * pSol, Gia_Man_t * p, Gia_Obj_t * pRoot, int nRestarts, int Depth ) +{ + //abctime clk = Abc_Clock(); + assert( Gia_ObjIsCo(pRoot) ); + Cbs3_ManReset( pSol ); + Gia_ManIncrementTravId( p ); + Cbs3_ManToSolver2_rec( pSol, p, Gia_ObjFaninId0p(p, pRoot), Depth ); + Cbs3_ManGrow( pSol ); + Cbs3_ManPrepare( pSol ); + Cbs3_ActReset( pSol ); + //pSol->timeSatLoad += Abc_Clock() - clk; + return Cbs3_ManSolve( pSol, Gia_ObjFanin0Copy(pRoot), nRestarts ); +} + + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Cbs3_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, int nRestarts, Vec_Str_t ** pvStatus, int fVerbose ) +{ + extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); + Cbs3_Man_t * p; + Vec_Int_t * vCex, * vVisit, * vCexStore; + Vec_Str_t * vStatus; + Gia_Obj_t * pRoot; + int i, status; // 1 = unsat, 0 = sat, -1 = undec + abctime clk, clkTotal = Abc_Clock(); + //assert( Gia_ManRegNum(pAig) == 0 ); + Gia_ManCreateRefs( pAig ); + //Gia_ManLevelNum( pAig ); + // create logic network + p = Cbs3_ManAlloc( pAig ); + p->Pars.nBTLimit = nConfs; + p->Pars.nRestLimit = nRestarts; + // create resulting data-structures + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); + vCexStore = Vec_IntAlloc( 10000 ); + vVisit = Vec_IntAlloc( 100 ); + vCex = Cbs3_ReadModel( p ); + // solve for each output + Gia_ManForEachCo( pAig, pRoot, i ) + { + if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) + { + Vec_IntClear( vCex ); + Vec_StrPush( vStatus, (char)(!Gia_ObjFaninC0(pRoot)) ); + if ( Gia_ObjFaninC0(pRoot) ) // const1 + Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example + continue; + } + clk = Abc_Clock(); + status = Cbs3_ManToSolver2( p, pAig, pRoot, p->Pars.nRestLimit, 10000 ); + Vec_StrPush( vStatus, (char)status ); + if ( status == -1 ) + { + p->nSatUndec++; + p->nConfUndec += p->Pars.nBTThis; + Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout + p->timeSatUndec += Abc_Clock() - clk; + continue; + } + if ( status == 1 ) + { + p->nSatUnsat++; + p->nConfUnsat += p->Pars.nBTThis; + p->timeSatUnsat += Abc_Clock() - clk; + continue; + } + p->nSatSat++; + p->nConfSat += p->Pars.nBTThis; + //Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); + p->timeSatSat += Abc_Clock() - clk; + } + Vec_IntFree( vVisit ); + p->nSatTotal = Gia_ManPoNum(pAig); + p->timeTotal = Abc_Clock() - clkTotal; + if ( fVerbose ) + Cbs3_ManSatPrintStats( p ); + if ( fVerbose ) + { + printf( "Prop1 = %d. Prop2 = %d. Prop3 = %d. ClaConf = %d. FailJ = %d. FailC = %d. ", p->nPropCalls[0], p->nPropCalls[1], p->nPropCalls[2], p->nClauseConf, p->nFails[0], p->nFails[1] ); + printf( "Mem usage %.2f MB.\n", 1.0*Cbs3_ManMemory(p)/(1<<20) ); + //Abc_PrintTime( 1, "JFront", p->timeJFront ); + //Abc_PrintTime( 1, "Loading", p->timeSatLoad ); + //printf( "Decisions = %d.\n", p->nDecs ); + } + Cbs3_ManStop( p ); + *pvStatus = vStatus; + return vCexStore; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index b767c49a..8cbcaa25 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -14,6 +14,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaCSatOld.c \ src/aig/gia/giaCSat.c \ src/aig/gia/giaCSat2.c \ + src/aig/gia/giaCSat3.c \ src/aig/gia/giaCTas.c \ src/aig/gia/giaCut.c \ src/aig/gia/giaDecs.c \ -- cgit v1.2.3 From f0236d5ac1b6d127354b5dd67aba79735bfceaa2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 10 Oct 2021 14:43:19 -0700 Subject: Experiments with pattern generation. --- src/aig/gia/gia.h | 2 + src/aig/gia/giaPat2.c | 1273 ++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaSimBase.c | 100 ++++ src/aig/gia/module.make | 1 + 4 files changed, 1376 insertions(+) create mode 100644 src/aig/gia/giaPat2.c (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 66ac9e13..fb924ce5 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -622,6 +622,8 @@ static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * p static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; } static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); } static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); } +static inline int Gia_ObjUpdateTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return 1; Gia_ObjSetTravIdCurrent(p, pObj); return 0; } +static inline int Gia_ObjUpdateTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdPrevious(p, pObj) ) return 1; Gia_ObjSetTravIdPrevious(p, pObj); return 0; } static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; } static inline void Gia_ObjSetTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds - 1; } static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); } diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c new file mode 100644 index 00000000..3151ed22 --- /dev/null +++ b/src/aig/gia/giaPat2.c @@ -0,0 +1,1273 @@ +/**CFile**************************************************************** + + FileName [giaPat2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Pattern generation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaPat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "misc/vec/vecHsh.h" +#include "sat/cnf/cnf.h" +#include "sat/bsat/satStore.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Min_Man_t_ Min_Man_t; +struct Min_Man_t_ +{ + int nCis; + int nCos; + int FirstAndLit; + int FirstCoLit; + Vec_Int_t vFans; + Vec_Str_t vValsN; + Vec_Str_t vValsL; + Vec_Int_t vVis; + Vec_Int_t vPat; +}; + +static inline int Min_ManCiNum( Min_Man_t * p ) { return p->nCis; } +static inline int Min_ManCoNum( Min_Man_t * p ) { return p->nCos; } +static inline int Min_ManObjNum( Min_Man_t * p ) { return Vec_IntSize(&p->vFans) >> 1; } +static inline int Min_ManAndNum( Min_Man_t * p ) { return Min_ManObjNum(p) - p->nCis - p->nCos - 1; } + +static inline int Min_ManCi( Min_Man_t * p, int i ) { return 1 + i; } +static inline int Min_ManCo( Min_Man_t * p, int i ) { return Min_ManObjNum(p) - Min_ManCoNum(p) + i; } + +static inline int Min_ObjIsCi( Min_Man_t * p, int i ) { return i > 0 && i <= Min_ManCiNum(p); } +static inline int Min_ObjIsNode( Min_Man_t * p, int i ) { return i > Min_ManCiNum(p) && i < Min_ManObjNum(p) - Min_ManCoNum(p); } +static inline int Min_ObjIsAnd( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) < Vec_IntEntry(&p->vFans, 2*i+1); } +static inline int Min_ObjIsXor( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) > Vec_IntEntry(&p->vFans, 2*i+1); } +static inline int Min_ObjIsBuf( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) ==Vec_IntEntry(&p->vFans, 2*i+1); } +static inline int Min_ObjIsCo( Min_Man_t * p, int i ) { return i >= Min_ManObjNum(p) - Min_ManCoNum(p) && i < Min_ManObjNum(p); } + +static inline int Min_ObjLit( Min_Man_t * p, int i, int n ) { return Vec_IntEntry(&p->vFans, i + i + n); } +static inline int Min_ObjLit0( Min_Man_t * p, int i ) { return Vec_IntEntry(&p->vFans, i + i + 0); } +static inline int Min_ObjLit1( Min_Man_t * p, int i ) { return Vec_IntEntry(&p->vFans, i + i + 1); } +static inline int Min_ObjCioId( Min_Man_t * p, int i ) { assert( i && !Min_ObjIsNode(p, i) ); return Min_ObjLit1(p, i); } + +static inline int Min_ObjFan0( Min_Man_t * p, int i ) { return Abc_Lit2Var( Min_ObjLit0(p, i) ); } +static inline int Min_ObjFan1( Min_Man_t * p, int i ) { return Abc_Lit2Var( Min_ObjLit1(p, i) ); } + +static inline int Min_ObjFanC0( Min_Man_t * p, int i ) { return Abc_LitIsCompl( Min_ObjLit0(p, i) ); } +static inline int Min_ObjFanC1( Min_Man_t * p, int i ) { return Abc_LitIsCompl( Min_ObjLit1(p, i) ); } + +static inline char Min_ObjValN( Min_Man_t * p, int i ) { return Vec_StrEntry(&p->vValsN, i); } +static inline void Min_ObjSetValN( Min_Man_t * p, int i, char v ){ Vec_StrWriteEntry(&p->vValsN, i, v); } + +static inline char Min_LitValL( Min_Man_t * p, int i ) { return Vec_StrEntry(&p->vValsL, i); } +static inline void Min_LitSetValL( Min_Man_t * p, int i, char v ){ assert(v==0 || v==1); Vec_StrWriteEntry(&p->vValsL, i, v); Vec_StrWriteEntry(&p->vValsL, i^1, (char)!v); Vec_IntPush(&p->vVis, Abc_Lit2Var(i)); } +static inline void Min_ObjCleanValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] = 0x0202; } +static inline void Min_ObjMarkValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] |= 0x0404; } + +static inline int Min_LitIsCi( Min_Man_t * p, int v ) { return v > 1 && v < p->FirstAndLit; } +static inline int Min_LitIsNode( Min_Man_t * p, int v ) { return v >= p->FirstAndLit && v < p->FirstCoLit; } +static inline int Min_LitIsCo( Min_Man_t * p, int v ) { return v >= p->FirstCoLit; } + +static inline int Min_LitIsAnd( int v, int v0, int v1 ) { return Abc_LitIsCompl(v) ^ (v0 < v1); } +static inline int Min_LitIsXor( int v, int v0, int v1 ) { return Abc_LitIsCompl(v) ^ (v0 > v1); } +static inline int Min_LitIsBuf( int v, int v0, int v1 ) { return v0 == v1; } + +static inline int Min_LitFan( Min_Man_t * p, int v ) { return Vec_IntEntry(&p->vFans, v); } +static inline int Min_LitFanC( Min_Man_t * p, int v ) { return Abc_LitIsCompl( Min_LitFan(p, v) ); } + +static inline void Min_ManStartValsN( Min_Man_t * p ) { Vec_StrGrow(&p->vValsN, Vec_IntCap(&p->vFans)/2); Vec_StrFill(&p->vValsN, Min_ManObjNum(p), 2); } +static inline void Min_ManStartValsL( Min_Man_t * p ) { Vec_StrGrow(&p->vValsL, Vec_IntCap(&p->vFans)); Vec_StrFill(&p->vValsL, Vec_IntSize(&p->vFans), 2); } +static inline int Min_ManCheckCleanValsL( Min_Man_t * p ) { int i; char c; Vec_StrForEachEntry( &p->vValsL, c, i ) if ( c != 2 ) return 0; return 1; } +static inline void Min_ManCleanVisitedValL( Min_Man_t * p ) { int i, iObj; Vec_IntForEachEntry(&p->vVis, iObj, i) Min_ObjCleanValL(p, iObj); Vec_IntClear(&p->vVis); } + + +#define Min_ManForEachObj( p, i ) \ + for ( i = 0; i < Min_ManObjNum(p); i++ ) +#define Min_ManForEachCi( p, i ) \ + for ( i = 1; i <= Min_ManCiNum(p); i++ ) +#define Min_ManForEachCo( p, i ) \ + for ( i = Min_ManObjNum(p) - Min_ManCoNum(p); i < Min_ManObjNum(p); i++ ) +#define Min_ManForEachAnd( p, i ) \ + for ( i = 1 + Min_ManCiNum(p); i < Min_ManObjNum(p) - Min_ManCoNum(p); i++ ) + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Min_Man_t * Min_ManStart( int nObjMax ) +{ + Min_Man_t * p = ABC_CALLOC( Min_Man_t, 1 ); + Vec_IntGrow( &p->vFans, nObjMax ); + Vec_IntPushTwo( &p->vFans, -1, -1 ); + return p; +} +static inline void Min_ManStop( Min_Man_t * p ) +{ + Vec_IntErase( &p->vFans ); + Vec_StrErase( &p->vValsN ); + Vec_StrErase( &p->vValsL ); + Vec_IntErase( &p->vVis ); + Vec_IntErase( &p->vPat ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_ManAppendObj( Min_Man_t * p, int iLit0, int iLit1 ) +{ + int iLit = Vec_IntSize(&p->vFans); + Vec_IntPushTwo( &p->vFans, iLit0, iLit1 ); + return iLit; +} +static inline int Min_ManAppendCi( Min_Man_t * p ) +{ + p->nCis++; + p->FirstAndLit = Vec_IntSize(&p->vFans) + 2; + return Min_ManAppendObj( p, 0, p->nCis-1 ); +} +static inline int Min_ManAppendCo( Min_Man_t * p, int iLit0 ) +{ + p->nCos++; + if ( p->FirstCoLit == 0 ) + p->FirstCoLit = Vec_IntSize(&p->vFans); + return Min_ManAppendObj( p, iLit0, p->nCos-1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_ManFromGia_rec( Min_Man_t * pNew, Gia_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj) ); + Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj) ); + pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts ) +{ + Gia_Obj_t * pObj; int i; + Min_Man_t * pNew = Min_ManStart( Gia_ManObjNum(p) ); + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Min_ManAppendCi( pNew ); + if ( vOuts == NULL ) + { + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFaninLit0p(p, pObj) ); + } + else + { + Gia_ManForEachCoVec( vOuts, p, pObj, i ) + Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0p(p, pObj) ); + Gia_ManForEachCoVec( vOuts, p, pObj, i ) + Min_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline char Min_XsimNot( char Val ) +{ + if ( Val < 2 ) + return Val ^ 1; + return 2; +} +static inline char Min_XsimXor( char Val0, char Val1 ) +{ + if ( Val0 < 2 && Val1 < 2 ) + return Val0 ^ Val1; + return 2; +} +static inline char Min_XsimAnd( char Val0, char Val1 ) +{ + if ( Val0 == 0 || Val1 == 0 ) + return 0; + if ( Val0 == 1 && Val1 == 1 ) + return 1; + return 2; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char Min_LitVerify_rec( Min_Man_t * p, int iLit ) +{ + char Val = Min_LitValL(p, iLit); + if ( Val == 2 && Min_LitIsNode(p, iLit) ) // unassigned + { + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitVerify_rec( p, iLit0 ); + char Val1 = Min_LitVerify_rec( p, iLit1 ); + assert( Min_LitIsNode(p, iLit) ); // internal node + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + } + return Val; +} +char Min_LitVerify( Min_Man_t * p, int iLit, Vec_Int_t * vLits ) +{ + int i, Entry; char Res; + if ( iLit < 2 ) return 1; + assert( !Min_LitIsCo(p, iLit) ); + //assert( Min_ManCheckCleanValsL(p) ); + assert( Vec_IntSize(&p->vVis) == 0 ); + Vec_IntForEachEntry( vLits, Entry, i ) + Min_LitSetValL( p, Entry, 1 ); // ms notation + Res = Min_LitVerify_rec( p, iLit ); + Min_ManCleanVisitedValL( p ); + return Res; +} + +void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits ) +{ + int i, iObj, iTemp; char Res; + Vec_IntClear( &p->vPat ); + if ( iLit < 2 ) return; + assert( !Min_LitIsCo(p, iLit) ); + //assert( Min_ManCheckCleanValsL(p) ); + assert( Vec_IntSize(&p->vVis) == 0 ); + Vec_IntForEachEntry( vLits, iTemp, i ) + Min_LitSetValL( p, iTemp, 1 ); // ms notation + Res = Min_LitVerify_rec( p, iLit ); + assert( Res == 1 ); + Min_ObjMarkValL( p, Abc_Lit2Var(iLit) ); + Vec_IntForEachEntryReverse( &p->vVis, iObj, i ) + { + int iLit = Abc_Var2Lit( iObj, 0 ); + int Value = Min_LitValL(p, iLit); + if ( Value >= 4 ) + { + if ( Min_LitIsCi(p, iLit) ) + Vec_IntPush( &p->vPat, Abc_LitNotCond(iLit, !(Value&1)) ); + else + { + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL( p, iLit0 ); + char Val1 = Min_LitValL( p, iLit1 ); + if ( Value == 5 ) // value == 1 + { + assert( (Val0&1) && (Val1&1) ); + Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); + Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); + } + else // value == 0 + { + int Zero0 = !(Val0&3); + int Zero1 = !(Val1&3); + assert( Zero0 || Zero1 ); + if ( Zero0 && !Zero1 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); + else if ( !Zero0 && Zero1 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); + else if ( Val0 == 4 && Val1 != 4 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); + else if ( Val1 == 4 && Val1 != 4 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); + else if ( Abc_Random(0) & 1 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); + else + Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); + } + } + } + Min_ObjCleanValL( p, Abc_Lit2Var(iLit) ); + } + Vec_IntClear( &p->vVis ); + //Min_ManCleanVisitedValL( p ); + //assert( Min_LitVerify(p, iLit, &p->vPat) == 1 ); + assert( Vec_IntSize(&p->vPat) <= Vec_IntSize(vLits) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline char Min_LitIsImplied1( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +static inline char Min_LitIsImplied2( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + Val0 = Min_LitIsImplied1(p, iLit0); + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + Val1 = Min_LitIsImplied1(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +static inline char Min_LitIsImplied3( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + Val0 = Min_LitIsImplied2(p, iLit0); + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + Val1 = Min_LitIsImplied2(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +static inline char Min_LitIsImplied4( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + Val0 = Min_LitIsImplied3(p, iLit0); + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + Val1 = Min_LitIsImplied3(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +static inline char Min_LitIsImplied5( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + Val0 = Min_LitIsImplied4(p, iLit0); + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + Val1 = Min_LitIsImplied4(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} + +// this recursive procedure is about 10% slower +char Min_LitIsImplied_rec( Min_Man_t * p, int iLit, int Depth ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Depth > 0 ); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Depth > 1 && Val0 == 2 && Min_LitIsNode(p, iLit0) ) + { + Val0 = Min_LitIsImplied_rec(p, iLit0, Depth-1); + Val1 = Min_LitValL(p, iLit1); + } + if ( Depth > 1 && Val1 == 2 && Min_LitIsNode(p, iLit1) ) + { + Val1 = Min_LitIsImplied_rec(p, iLit1, Depth-1); + Val0 = Min_LitValL(p, iLit0); + } + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +int Min_LitJustify_rec( Min_Man_t * p, int iLit ) +{ + int Res = 1, LitValue = !Abc_LitIsCompl(iLit); + int Val = (int)Min_LitValL(p, iLit); + if ( Val < 2 ) // assigned + return Val == LitValue; + // unassigned + if ( Min_LitIsCi(p, iLit) ) + Vec_IntPush( &p->vPat, iLit ); // ms notation + else + { + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + { + if ( Val0 < 2 && Val1 < 2 ) + Res = LitValue == (Val0 ^ Val1); + else if ( Val0 < 2 ) + Res = Min_LitJustify_rec(p, iLit1^Val0^!LitValue); + else if ( Val1 < 2 ) + Res = Min_LitJustify_rec(p, iLit0^Val1^!LitValue); + else if ( Abc_Random(0) & 1 ) + Res = Min_LitJustify_rec(p, iLit0) && Min_LitJustify_rec(p, iLit1^ LitValue); + else + Res = Min_LitJustify_rec(p, iLit0^1) && Min_LitJustify_rec(p, iLit1^!LitValue); + assert( !Res || LitValue == Min_XsimXor(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) ); + } + else if ( LitValue ) // value 1 + { + if ( Val0 == 0 || Val1 == 0 ) + Res = 0; + else if ( Val0 == 1 && Val1 == 1 ) + Res = 1; + else if ( Val0 == 1 ) + Res = Min_LitJustify_rec(p, iLit1); + else if ( Val1 == 1 ) + Res = Min_LitJustify_rec(p, iLit0); + else + Res = Min_LitJustify_rec(p, iLit0) && Min_LitJustify_rec(p, iLit1); + assert( !Res || 1 == Min_XsimAnd(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) ); + } + else // value 0 + { +/* + int Depth = 3; + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + { + Val0 = Min_LitIsImplied_rec(p, iLit0, Depth); + Val1 = Min_LitValL(p, iLit1); + } + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + { + Val1 = Min_LitIsImplied_rec(p, iLit1, Depth); + Val0 = Min_LitValL(p, iLit0); + } +*/ + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + { + Val0 = Min_LitIsImplied3(p, iLit0); + Val1 = Min_LitValL(p, iLit1); + } + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + { + Val1 = Min_LitIsImplied3(p, iLit1); + Val0 = Min_LitValL(p, iLit0); + } + if ( Val0 == 0 || Val1 == 0 ) + Res = 1; + else if ( Val0 == 1 && Val1 == 1 ) + Res = 0; + else if ( Val0 == 1 ) + Res = Min_LitJustify_rec(p, iLit1^1); + else if ( Val1 == 1 ) + Res = Min_LitJustify_rec(p, iLit0^1); + else if ( Abc_Random(0) & 1 ) + //else if ( (p->Random >> (iLit & 0x1F)) & 1 ) + Res = Min_LitJustify_rec(p, iLit0^1); + else + Res = Min_LitJustify_rec(p, iLit1^1); + //Val0 = Min_LitValL(p, iLit0); + //Val1 = Min_LitValL(p, iLit1); + assert( !Res || 0 == Min_XsimAnd(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) ); + } + } + if ( Res ) + Min_LitSetValL( p, iLit, 1 ); + return Res; +} +int Min_LitJustify( Min_Man_t * p, int iLit ) +{ + int Res, fCheck = 1; + Vec_IntClear( &p->vPat ); + if ( iLit < 2 ) return 1; + assert( !Min_LitIsCo(p, iLit) ); + //assert( Min_ManCheckCleanValsL(p) ); + assert( Vec_IntSize(&p->vVis) == 0 ); + //p->Random = Abc_Random(0); + Res = Min_LitJustify_rec( p, iLit ); + Min_ManCleanVisitedValL( p ); + if ( Res ) + { + Vec_IntSort( &p->vPat, 0 ); + if ( fCheck && Min_LitVerify(p, iLit, &p->vPat) != 1 ) + printf( "Verification FAILED for literal %d.\n", iLit ); + //else + // printf( "Verification succeeded for literal %d.\n", iLit ); + } + //else + // printf( "Could not justify literal %d.\n", iLit ); + return Res; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Min_TargGenerateCexes( Min_Man_t * p, Vec_Int_t * vCoErrs, int nCexes, int nCexesStop, int * pnComputed, int fVerbose ) +{ + abctime clk = Abc_Clock(); + int t, iObj, Count = 0, CountPos = 0, CountPosSat = 0, nRuns[2] = {0}, nCountCexes[2] = {0}; + Vec_Int_t * vPats = Vec_IntAlloc( 1000 ); + Vec_Int_t * vPatBest = Vec_IntAlloc( Min_ManCiNum(p) ); + Hsh_VecMan_t * pHash = Hsh_VecManStart( 10000 ); + Min_ManForEachCo( p, iObj ) if ( Min_ObjLit0(p, iObj) > 1 ) + { + int nCexesGenSim0 = 0; + int nCexesGenSim = 0; + int nCexesGenSat = 0; + if ( vCoErrs && Vec_IntEntry(vCoErrs, Min_ObjCioId(p, iObj)) >= nCexesStop ) + continue; + //printf( "%d ", i ); + for ( t = 0; t < nCexes; t++ ) + { + nRuns[0]++; + if ( Min_LitJustify( p, Min_ObjLit0(p, iObj) ) ) + { + int Before, After; + assert( Vec_IntSize(&p->vPat) > 0 ); + //printf( "%d ", Vec_IntSize(vPat) ); + Vec_IntClear( vPatBest ); + if ( 1 ) // no minimization + Vec_IntAppend( vPatBest, &p->vPat ); + else + { +/* + for ( k = 0; k < 10; k++ ) + { + Vec_IntClear( vPat2 ); + Gia_ManIncrementTravId( p ); + Cexes_MinimizePattern_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), vPat2 ); + assert( Vec_IntSize(vPat2) <= Vec_IntSize(vPat) ); + if ( Vec_IntSize(vPatBest) == 0 || Vec_IntSize(vPatBest) > Vec_IntSize(vPat2) ) + { + Vec_IntClear( vPatBest ); + Vec_IntAppend( vPatBest, vPat2 ); + } + //printf( "%d ", Vec_IntSize(vPat2) ); + } +*/ + } + + //Gia_CexVerify( p, Gia_ObjFaninId0p(p, pObj), !Gia_ObjFaninC0(pObj), vPatBest ); + //printf( "\n" ); + Before = Hsh_VecSize( pHash ); + Vec_IntSort( vPatBest, 0 ); + Hsh_VecManAdd( pHash, vPatBest ); + After = Hsh_VecSize( pHash ); + if ( Before != After ) + { + Vec_IntPush( vPats, Min_ObjCioId(p, iObj) ); + Vec_IntPush( vPats, Vec_IntSize(vPatBest) ); + Vec_IntAppend( vPats, vPatBest ); + nCexesGenSim++; + } + nCexesGenSim0++; + if ( nCexesGenSim0 > nCexesGenSim*10 ) + { + printf( "**** Skipping output %d (out of %d)\n", Min_ObjCioId(p, iObj), Min_ManCoNum(p) ); + break; + } + } + if ( nCexesGenSim == nCexesStop ) + break; + } + //printf( "(%d %d) ", nCexesGenSim0, nCexesGenSim ); + //printf( "%d ", t/nCexesGenSim ); + + //printf( "The number of CEXes = %d\n", nCexesGen ); + //if ( fVerbose ) + // printf( "%d ", nCexesGen ); + nCountCexes[0] += nCexesGenSim; + nCountCexes[1] += nCexesGenSat; + Count += nCexesGenSim + nCexesGenSat; + CountPos++; + + if ( nCexesGenSim0 == 0 && t == nCexes ) + printf( "#### Output %d (out of %d)\n", Min_ObjCioId(p, iObj), Min_ManCoNum(p) ); + } + //printf( "\n" ); + if ( fVerbose ) + printf( "\n" ); + if ( fVerbose ) + printf( "Got %d unique CEXes using %d sim (%d) and %d SAT (%d) runs (ave size %.1f). PO = %d ErrPO = %d SatPO = %d ", + Count, nRuns[0], nCountCexes[0], nRuns[1], nCountCexes[1], + 1.0*Vec_IntSize(vPats)/Abc_MaxInt(1, Count)-2, Min_ManCoNum(p), CountPos, CountPosSat ); + if ( fVerbose ) + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + Hsh_VecManStop( pHash ); + Vec_IntFree( vPatBest ); + *pnComputed = Count; + return vPats; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_ManTest3( Gia_Man_t * p, Vec_Int_t * vCoErrs ) +{ + int fXor = 0; + int nComputed; + Vec_Int_t * vPats; + Gia_Man_t * pXor = fXor ? Gia_ManDupMuxes(p, 1) : NULL; + Min_Man_t * pNew = Min_ManFromGia( fXor ? pXor : p, NULL ); + Gia_ManStopP( &pXor ); + Min_ManStartValsL( pNew ); + //Vec_IntFill( vCoErrs, Vec_IntSize(vCoErrs), 0 ); + //vPats = Min_TargGenerateCexes( pNew, vCoErrs, 10000, 10, &nComputed, 1 ); + vPats = Min_TargGenerateCexes( pNew, vCoErrs, 10000, 10, &nComputed, 1 ); + Vec_IntFree( vPats ); + Min_ManStop( pNew ); +} +void Min_ManTest4( Gia_Man_t * p ) +{ + Vec_Int_t * vCoErrs = Vec_IntStartNatural( Gia_ManCoNum(p) ); + Min_ManTest3(p, vCoErrs); + Vec_IntFree( vCoErrs ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupCones2CollectPis_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vMap ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) ) + return; + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManDupCones2CollectPis_rec( p, Gia_ObjFaninId0(pObj, iObj), vMap ); + Gia_ManDupCones2CollectPis_rec( p, Gia_ObjFaninId1(pObj, iObj), vMap ); + } + else if ( Gia_ObjIsCi(pObj) ) + Vec_IntPush( vMap, iObj ); + else assert( 0 ); +} +void Gia_ManDupCones2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsCi(pObj) || Gia_ObjUpdateTravIdCurrent(p, pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Gia_Man_t * Gia_ManDupCones2( Gia_Man_t * p, int * pOuts, int nOuts, Vec_Int_t * vMap ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; int i; + Vec_IntClear( vMap ); + Gia_ManIncrementTravId( p ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManDupCones2CollectPis_rec( p, Gia_ManCoDriverId(p, pOuts[i]), vMap ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObjVec( vMap, p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManIncrementTravId( p ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin0(Gia_ManCo(p, pOuts[i])) ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManCo(p, pOuts[i])) ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_ManRemoveItem( Vec_Wec_t * vCexes, int iItem, int iFirst, int iLimit ) +{ + Vec_Int_t * vLevel, * vLevel0 = Vec_WecEntry(vCexes, iItem); int i; + assert( iFirst <= iItem && iItem < iLimit ); + Vec_WecForEachLevelReverseStartStop( vCexes, vLevel, i, iLimit, iFirst ) + if ( Vec_IntSize(vLevel) > 0 ) + break; + assert( iFirst <= i && iItem <= i ); + Vec_IntClear( vLevel0 ); + if ( iItem < i ) + ABC_SWAP( Vec_Int_t, *vLevel0, *vLevel ); + return -1; +} +int Min_ManAccumulate( Vec_Wec_t * vCexes, int iFirst, int iLimit, Vec_Int_t * vCex ) +{ + Vec_Int_t * vLevel; int i, nCommon, nDiff = 0; + Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iFirst, iLimit ) + { + if ( Vec_IntSize(vLevel) == 0 ) + { + Vec_IntAppend(vLevel, vCex); + return nDiff+1; + } + nCommon = Vec_IntTwoCountCommon( vLevel, vCex ); + if ( nCommon == Vec_IntSize(vLevel) ) // ignore vCex + return nDiff; + if ( nCommon == Vec_IntSize(vCex) ) // remove vLevel + nDiff += Min_ManRemoveItem( vCexes, i, iFirst, iLimit ); + } + assert( 0 ); + return ABC_INFINITY; +} +int Min_ManCountSize( Vec_Wec_t * vCexes, int iFirst, int iLimit ) +{ + Vec_Int_t * vLevel; int i, nTotal = 0; + Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iFirst, iLimit ) + nTotal += Vec_IntSize(vLevel) > 0; + return nTotal; +} +Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTries, int nMinCexes, Vec_Int_t * vStats[3], int fUseSim, int fUseSat, int fVerbose ) +{ + Vec_Int_t * vOuts = vOuts0 ? vOuts0 : Vec_IntStartNatural( Gia_ManCoNum(p) ); + Min_Man_t * pNew = Min_ManFromGia( p, vOuts ); + Vec_Wec_t * vCexes = Vec_WecStart( Vec_IntSize(vOuts) * nMinCexes ); + Vec_Int_t * vPatBest = Vec_IntAlloc( 100 ); + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + Gia_Obj_t * pObj; int i, iObj, nOuts = 0, nSimOuts = 0, nSatOuts = 0; + vStats[0] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // total calls + vStats[1] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // successful calls + SAT runs + vStats[2] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // results + Min_ManStartValsL( pNew ); + Min_ManForEachCo( pNew, iObj ) + { + int nAllCalls = 0; + int nGoodCalls = 0; + int nCurrCexes = 0; + if ( fUseSim && Min_ObjLit0(pNew, iObj) >= 2 ) + { + while ( nAllCalls++ < nMaxTries ) + { + if ( Min_LitJustify( pNew, Min_ObjLit0(pNew, iObj) ) ) + { + Vec_IntClearAppend( vLits, &pNew->vPat ); + Vec_IntClearAppend( vPatBest, &pNew->vPat ); + if ( 1 ) // minimization + { + //printf( "%d -> ", Vec_IntSize(vPatBest) ); + for ( i = 0; i < 10; i++ ) + { + Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits ); + if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) ) + Vec_IntClearAppend( vPatBest, &pNew->vPat ); + } + //printf( "%d ", Vec_IntSize(vPatBest) ); + } + assert( Vec_IntSize(vPatBest) > 0 ); + nCurrCexes += Min_ManAccumulate( vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes, vPatBest ); + nGoodCalls++; + } + if ( nCurrCexes == nMinCexes || nGoodCalls > 10*nCurrCexes ) + break; + } + nSimOuts++; + } + assert( nCurrCexes <= nMinCexes ); + assert( nCurrCexes == Min_ManCountSize(vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes) ); + Vec_IntPush( vStats[0], nAllCalls ); + Vec_IntPush( vStats[1], nGoodCalls ); + Vec_IntPush( vStats[2], nCurrCexes ); + nOuts++; + } + assert( Vec_IntSize(vOuts) == nOuts ); + assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[0]) ); + assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[1]) ); + assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[2]) ); + + if ( fUseSat ) + Gia_ManForEachCoVec( vOuts, p, pObj, i ) + { + if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) ) + continue; + { + int iObj = Min_ManCo(pNew, i); + int Index = Gia_ObjCioId(pObj); + Vec_Int_t * vMap = Vec_IntAlloc( 100 ); + Gia_Man_t * pCon = Gia_ManDupCones2( p, &Index, 1, vMap ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCon, 8, 0, 0, 0, 0 ); + sat_solver* pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + int Lit = Abc_Var2Lit( 1, 0 ); + int status = sat_solver_addclause( pSat, &Lit, &Lit+1 ); + int nAllCalls = 0; + int nCurrCexes = Vec_IntEntry(vStats[2], i); + //Gia_AigerWrite( pCon, "temp_miter.aig", 0, 0, 0 ); + if ( status == l_True ) + { + nSatOuts++; + //printf( "Running SAT for output %d\n", i ); + if ( Min_ObjLit0(pNew, iObj) >= 2 ) + { + while ( nAllCalls++ < 100 ) + { + int v, iVar = pCnf->nVars - Gia_ManPiNum(pCon), nVars = Gia_ManPiNum(pCon); + sat_solver_randomize( pSat, iVar, nVars ); + status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 ); + assert( status == l_True ); + Vec_IntClear( vLits ); + for ( v = 0; v < nVars; v++ ) + Vec_IntPush( vLits, Abc_Var2Lit(Vec_IntEntry(vMap, v), !sat_solver_var_value(pSat, iVar + v)) ); + Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits ); + Vec_IntClearAppend( vPatBest, &pNew->vPat ); + if ( 1 ) // minimization + { + //printf( "%d -> ", Vec_IntSize(vPatBest) ); + for ( v = 0; v < 20; v++ ) + { + Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits ); + if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) ) + Vec_IntClearAppend( vPatBest, &pNew->vPat ); + } + //printf( "%d ", Vec_IntSize(vPatBest) ); + } + Vec_IntSort( vPatBest, 0 ); + nCurrCexes += Min_ManAccumulate( vCexes, i*nMinCexes, (i+1)*nMinCexes, vPatBest ); + if ( nCurrCexes == nMinCexes || nAllCalls > 10*nCurrCexes ) + break; + } + } + } + Vec_IntWriteEntry( vStats[0], i, nAllCalls*nMaxTries ); + Vec_IntWriteEntry( vStats[1], i, nAllCalls*nMaxTries ); + Vec_IntWriteEntry( vStats[2], i, nCurrCexes ); + sat_solver_delete( pSat ); + Cnf_DataFree( pCnf ); + Gia_ManStop( pCon ); + Vec_IntFree( vMap ); + } + } + if ( fVerbose ) + printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts ); + //Vec_WecPrint( vCexes, 0 ); + if ( vOuts != vOuts0 ) + Vec_IntFreeP( &vOuts ); + Min_ManStop( pNew ); + Vec_IntFree( vPatBest ); + Vec_IntFree( vLits ); + return vCexes; +} + +/**Function************************************************************* + + Synopsis [Bit-packing for selected patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_ManBitPackTry( Vec_Wrd_t * vSimsPi, int nWords, int iPat, Vec_Int_t * vLits ) +{ + int i, Lit; + assert( iPat >= 0 && iPat < 64 * nWords ); + Vec_IntForEachEntry( vLits, Lit, i ) + { + word * pInfo = Vec_WrdEntryP( vSimsPi, nWords * Abc_Lit2Var(Lit-2) ); // Lit is based on ObjId + word * pCare = pInfo + Vec_WrdSize(vSimsPi); + if ( Abc_InfoHasBit( (unsigned *)pCare, iPat ) && + Abc_InfoHasBit( (unsigned *)pInfo, iPat ) == Abc_LitIsCompl(Lit) ) // Lit is in ms notation + return 0; + } + Vec_IntForEachEntry( vLits, Lit, i ) + { + word * pInfo = Vec_WrdEntryP( vSimsPi, nWords * Abc_Lit2Var(Lit-2) ); // Lit is based on ObjId + word * pCare = pInfo + Vec_WrdSize(vSimsPi); + Abc_InfoSetBit( (unsigned *)pCare, iPat ); + if ( Abc_InfoHasBit( (unsigned *)pInfo, iPat ) == Abc_LitIsCompl(Lit) ) // Lit is in ms notation + Abc_InfoXorBit( (unsigned *)pInfo, iPat ); + } + return 1; +} +int Min_ManBitPackOne( Vec_Wrd_t * vSimsPi, int iPat0, int nWords, Vec_Int_t * vLits ) +{ + int iPat, nTotal = 64*nWords; + for ( iPat = iPat0 + 1; iPat != iPat0; iPat = (iPat + 1) % nTotal ) + if ( Min_ManBitPackTry( vSimsPi, nWords, iPat, vLits ) ) + break; + return iPat; +} +Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose ) +{ + abctime clk = Abc_Clock(); + int fVeryVerbose = 0; + Vec_Wrd_t * vSimsPi = NULL; + Vec_Int_t * vLevel; + int w, nBits, nTotal = 0, fFailed = ABC_INFINITY; + Vec_Int_t * vOrder = Vec_IntStartNatural( Vec_WecSize(vCexes)/nMinCexes ); + assert( Vec_IntSize(vOrder) == Vec_IntSize(vScores) ); + assert( Vec_WecSize(vCexes)%nMinCexes == 0 ); + Abc_MergeSortCost2Reverse( Vec_IntArray(vOrder), Vec_IntSize(vOrder), Vec_IntArray(vScores) ); + if ( fVerbose ) + printf( "Packing: " ); + //for ( w = 1; fFailed > 100; w++ ) + for ( w = 1; fFailed > 0; w++ ) + { + int i, k, iOut, iPatUsed, iPat = 0; + Vec_WrdFreeP( &vSimsPi ); + vSimsPi = fRandom ? Vec_WrdStartRandom(2 * Gia_ManCiNum(p) * w) : Vec_WrdStart(2 * Gia_ManCiNum(p) * w); + Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 ); + Abc_TtClear( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) ); + fFailed = nTotal = 0; + Vec_IntForEachEntry( vOrder, iOut, k ) + Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iOut*nMinCexes, (iOut+1)*nMinCexes ) + { + if ( fVeryVerbose && i%nMinCexes == 0 ) + printf( "\n" ); + if ( Vec_IntSize(vLevel) == 0 ) + continue; + iPatUsed = Min_ManBitPackOne( vSimsPi, iPat, w, vLevel ); + fFailed += iPatUsed == iPat; + iPat = (iPatUsed + 1) % (64*w - 1); + if ( fVeryVerbose ) + printf( "Adding output %3d cex %3d to pattern %3d ", i/nMinCexes, i%nMinCexes, iPatUsed ); + if ( fVeryVerbose ) + Vec_IntPrint( vLevel ); + nTotal++; + } + if ( fVerbose ) + printf( "W = %d (F = %d) ", w, fFailed ); + } + if ( fVerbose ) + printf( "Total = %d\n", nTotal ); + if ( fVerbose ) + { + nBits = Abc_TtCountOnesVec( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) ); + printf( "Bit-packing is using %d words and %d bits. Density =%8.4f %%. ", + Vec_WrdSize(vSimsPi)/Gia_ManCiNum(p), nBits, 100.0*nBits/64/Vec_WrdSize(vSimsPi) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + Vec_IntFree( vOrder ); + return vSimsPi; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Patt_ManOutputErrorCoverage( Vec_Wrd_t * vErrors, int nOuts ) +{ + Vec_Int_t * vCounts = Vec_IntAlloc( nOuts ); + int i, nWords = Vec_WrdSize(vErrors)/nOuts; + assert( Vec_WrdSize(vErrors) == nOuts * nWords ); + for ( i = 0; i < nOuts; i++ ) + Vec_IntPush( vCounts, Abc_TtCountOnesVec(Vec_WrdEntryP(vErrors, nWords * i), nWords) ); + return vCounts; +} +Vec_Wrd_t * Patt_ManTransposeErrors( Vec_Wrd_t * vErrors, int nOuts ) +{ + extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ); + int nWordsIn = Vec_WrdSize(vErrors) / nOuts; + int nWordsOut = Abc_Bit6WordNum(nOuts); + Vec_Wrd_t * vSims1 = Vec_WrdStart( 64*nWordsIn*nWordsOut ); + Vec_Wrd_t * vSims2 = Vec_WrdStart( 64*nWordsIn*nWordsOut ); + assert( Vec_WrdSize(vErrors) == nWordsIn * nOuts ); + Abc_TtCopy( Vec_WrdArray(vSims1), Vec_WrdArray(vErrors), Vec_WrdSize(vErrors), 0 ); + Extra_BitMatrixTransposeP( vSims1, nWordsIn, vSims2, nWordsOut ); + Vec_WrdFree( vSims1 ); + return vSims2; +} +Vec_Int_t * Patt_ManPatternErrorCoverage( Vec_Wrd_t * vErrors, int nOuts ) +{ + int nWords = Vec_WrdSize(vErrors)/nOuts; + Vec_Wrd_t * vErrors2 = Patt_ManTransposeErrors( vErrors, nOuts ); + Vec_Int_t * vPatErrs = Patt_ManOutputErrorCoverage( vErrors2, 64*nWords ); + Vec_WrdFree( vErrors2 ); + return vPatErrs; +} + +#define ERR_REPT_SIZE 32 +void Patt_ManProfileErrors( Vec_Int_t * vOutErrs, Vec_Int_t * vPatErrs ) +{ + int nOuts = Vec_IntSize(vOutErrs); + int nPats = Vec_IntSize(vPatErrs); + int ErrOuts[ERR_REPT_SIZE+1] = {0}; + int ErrPats[ERR_REPT_SIZE+1] = {0}; + int i, Errs, nErrors1 = 0, nErrors2 = 0; + Vec_IntForEachEntry( vOutErrs, Errs, i ) + { + nErrors1 += Errs; + ErrOuts[Errs < ERR_REPT_SIZE ? Errs : ERR_REPT_SIZE]++; + } + Vec_IntForEachEntry( vPatErrs, Errs, i ) + { + nErrors2 += Errs; + ErrPats[Errs < ERR_REPT_SIZE ? Errs : ERR_REPT_SIZE]++; + } + assert( nErrors1 == nErrors2 ); + // errors/error_outputs/error_patterns + //printf( "\nError statistics:\n" ); + printf( "Errors =%6d ", nErrors1 ); + printf( "ErrPOs =%5d (Ave = %5.2f) ", nOuts-ErrOuts[0], 1.0*nErrors1/Abc_MaxInt(1, nOuts-ErrOuts[0]) ); + printf( "Patterns =%5d (Ave = %5.2f) ", nPats, 1.0*nErrors1/nPats ); + printf( "Density =%8.4f %%\n", 100.0*nErrors1/nPats/Abc_MaxInt(1, nOuts-ErrOuts[0]) ); + // how many times each output fails + printf( "Outputs: " ); + for ( i = 0; i <= ERR_REPT_SIZE; i++ ) + if ( ErrOuts[i] ) + printf( "%s%d=%d ", i == ERR_REPT_SIZE? ">" : "", i, ErrOuts[i] ); + printf( "\n" ); + // how many times each patterns fails an output + printf( "Patterns: " ); + for ( i = 0; i <= ERR_REPT_SIZE; i++ ) + if ( ErrPats[i] ) + printf( "%s%d=%d ", i == ERR_REPT_SIZE? ">" : "", i, ErrPats[i] ); + printf( "\n" ); +} +int Patt_ManProfileErrorsOne( Vec_Wrd_t * vErrors, int nOuts ) +{ + Vec_Int_t * vCoErrs = Patt_ManOutputErrorCoverage( vErrors, nOuts ); + Vec_Int_t * vPatErrs = Patt_ManPatternErrorCoverage( vErrors, nOuts ); + Patt_ManProfileErrors( vCoErrs, vPatErrs ); + Vec_IntFree( vPatErrs ); + Vec_IntFree( vCoErrs ); + return 1; +} + +Vec_Int_t * Min_ManGetUnsolved( Gia_Man_t * p ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + int i, Driver; + Gia_ManForEachCoDriverId( p, Driver, i ) + if ( Driver > 0 ) + Vec_IntPush( vRes, i ); + return vRes; +} +Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Vec_Int_t * vStats[3] = {0}; int i, iObj; + extern Gia_Man_t * Cec4_ManSimulateTest4( Gia_Man_t * p, int nBTLimit, int nBTLimitPo, int fVerbose ); + Gia_Man_t * pSwp = Cec4_ManSimulateTest4( p, nConf, nConf2, 0 ); + abctime clkSweep = Abc_Clock() - clk; + int nArgs = fVerbose ? printf( "Generating patterns: Conf = %d (%d). Tries = %d. Pats = %d. Sim = %d. SAT = %d.\n", + nConf, nConf2, nMaxTries, nMinCexes, fUseSim, fUseSat ) : 0; + Vec_Int_t * vOuts = Min_ManGetUnsolved( pSwp ); + Gia_Man_t * pSwp2 = Gia_ManDupSelectedOutputs( pSwp, vOuts ); + Vec_Wec_t * vCexes = Min_ManComputeCexes( pSwp2, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose ); + Vec_Wrd_t * vSimsPi = Min_ManBitPack( p, vCexes, 1, nMinCexes, vStats[0], fVerbose ); + Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 ); + Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) ); + if ( fVerbose ) + { + Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) ); + Abc_PrintTime( 1, "Sweep time", clkSweep ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); + } + if ( 0 ) + { + printf( "Unsolved = %4d ", Vec_IntSize(vOuts) ); + Gia_ManPrintStats( pSwp2, NULL ); + Vec_IntForEachEntry( vOuts, iObj, i ) + { + printf( "%4d : ", i ); + printf( "Out = %5d ", iObj ); + printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) ); + printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) ); + printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) ); + printf( "Count = %5d ", Vec_IntEntry(vCounts, i) ); + printf( "\n" ); + if ( i == 20 ) + break; + } + } + for ( i = 0; i < 3; i++ ) + Vec_IntFree( vStats[i] ); + Vec_IntFree( vCounts ); + Vec_WrdFree( vSimsPo ); + Vec_WecFree( vCexes ); + Vec_IntFree( vOuts ); + Gia_ManStop( pSwp ); + Gia_ManStop( pSwp2 ); + nArgs = 0; + return vSimsPi; +} +void Min_ManTest2( Gia_Man_t * p ) +{ + Vec_Wrd_t * vSimsPi = Min_ManCollect( p, 100000, 100000, 10000, 20, 1, 1, 0 ); + Vec_WrdFreeP( &vSimsPi ); +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index bfafdcfd..a9706742 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -2522,6 +2522,106 @@ int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int return RetValue; } +/**Function************************************************************* + + Synopsis [Serialization.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSim2ArrayOne( Vec_Wrd_t * vSimsPi, Vec_Int_t * vRes ) +{ + word * pInfo = Vec_WrdArray(vSimsPi); int w, i; + word * pCare = pInfo + Vec_WrdSize(vSimsPi); + Vec_IntClear( vRes ); + for ( w = 0; w < Vec_WrdSize(vSimsPi); w++ ) + if ( pCare[w] ) + for ( i = 0; i < 64; i++ ) + if ( Abc_TtGetBit(pCare, w*64+i) ) + Vec_IntPush( vRes, Abc_Var2Lit(w*64+i, Abc_TtGetBit(pInfo, w*64+i)) ); + Vec_IntPush( vRes, Vec_WrdSize(vSimsPi) ); +} +Vec_Wec_t * Gia_ManSim2Array( Vec_Ptr_t * vSims ) +{ + Vec_Wec_t * vRes = Vec_WecStart( Vec_PtrSize(vSims) ); + Vec_Int_t * vLevel; int i; + Vec_WecForEachLevel( vRes, vLevel, i ) + Gia_ManSim2ArrayOne( (Vec_Wrd_t *)Vec_PtrEntry(vSims, i), vLevel ); + return vRes; +} + +Vec_Wrd_t * Gia_ManArray2SimOne( Vec_Int_t * vRes ) +{ + int i, iLit, nWords = Vec_IntEntryLast(vRes); + Vec_Wrd_t * vSimsPi = Vec_WrdStart( 2*nWords ); + word * pInfo = Vec_WrdArray(vSimsPi); + word * pCare = pInfo + nWords; + Vec_IntPop( vRes ); + Vec_IntForEachEntry( vRes, iLit, i ) + { + Abc_TtXorBit( pCare, Abc_Lit2Var(iLit) ); + if ( Abc_LitIsCompl(iLit) ) + Abc_TtXorBit( pInfo, Abc_Lit2Var(iLit) ); + } + Vec_IntPush( vRes, nWords ); + Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 ); + return vSimsPi; +} +Vec_Ptr_t * Gia_ManArray2Sim( Vec_Wec_t * vRes ) +{ + Vec_Ptr_t * vSims = Vec_PtrAlloc( Vec_WecSize(vRes) ); + Vec_Int_t * vLevel; int i; + Vec_WecForEachLevel( vRes, vLevel, i ) + Vec_PtrPush( vSims, Gia_ManArray2SimOne(vLevel) ); + return vSims; +} + +void Gia_ManSimArrayTest( Vec_Wrd_t * vSimsPi ) +{ + Vec_Ptr_t * vTemp = Vec_PtrAlloc( 2 ); + Vec_PtrPushTwo( vTemp, vSimsPi, vSimsPi ); + { + Vec_Wec_t * vRes = Gia_ManSim2Array( vTemp ); + Vec_WecDumpBin( "temp.sims", vRes, 1 ); + { + Vec_Wec_t * vRes = Vec_WecReadBin( "temp.sims", 1 ); + Vec_Ptr_t * vTemp2 = Gia_ManArray2Sim( vRes ); + Vec_Wrd_t * vSimsPi2 = (Vec_Wrd_t *)Vec_PtrEntry( vTemp2, 0 ); + Vec_Wrd_t * vSimsPi3 = (Vec_Wrd_t *)Vec_PtrEntry( vTemp2, 1 ); + + Abc_TtAnd( Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi)+Vec_WrdSize(vSimsPi), Vec_WrdSize(vSimsPi), 0 ); + + vSimsPi->nSize *= 2; + vSimsPi2->nSize *= 2; + vSimsPi3->nSize *= 2; + Vec_WrdDumpHex( "test1.hex", vSimsPi, 1, 1 ); + Vec_WrdDumpHex( "test2.hex", vSimsPi2, 1, 1 ); + Vec_WrdDumpHex( "test3.hex", vSimsPi3, 1, 1 ); + vSimsPi->nSize /= 2; + vSimsPi2->nSize /= 2; + vSimsPi3->nSize /= 2; + + if ( Vec_WrdEqual( vSimsPi, vSimsPi2 ) ) + printf( "Success.\n" ); + else + printf( "Failure.\n" ); + if ( Vec_WrdEqual( vSimsPi, vSimsPi3 ) ) + printf( "Success.\n" ); + else + printf( "Failure.\n" ); + Vec_WrdFree( vSimsPi2 ); + Vec_WrdFree( vSimsPi3 ); + Vec_PtrFree( vTemp2 ); + Vec_WecFree( vRes ); + } + Vec_WecFree( vRes ); + } + Vec_PtrFree( vTemp ); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 8cbcaa25..d801a243 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -60,6 +60,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaOf.c \ src/aig/gia/giaPack.c \ src/aig/gia/giaPat.c \ + src/aig/gia/giaPat2.c \ src/aig/gia/giaPf.c \ src/aig/gia/giaQbf.c \ src/aig/gia/giaReshape1.c \ -- cgit v1.2.3 From d4f073bad759874161e2de5952ef7d466bc3eb07 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 22 Oct 2021 00:00:01 -0700 Subject: Various changes. --- src/aig/gia/gia.h | 7 +++ src/aig/gia/giaMan.c | 1 + src/aig/gia/giaPat2.c | 148 ++++++++++++++++++++++++++++++++--------------- src/aig/gia/giaSimBase.c | 78 +++++++++++++++++++++++++ src/aig/gia/giaStoch.c | 20 ------- 5 files changed, 187 insertions(+), 67 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index fb924ce5..5548def6 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -217,6 +217,7 @@ struct Gia_Man_t_ Vec_Int_t * vClassOld; Vec_Int_t * vClassNew; Vec_Int_t * vPats; + Vec_Bit_t * vPolars; // incremental simulation int fIncrSim; int iNextPi; @@ -1592,6 +1593,12 @@ extern int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, i /*=== giaSimBase.c ============================================================*/ extern Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * p ); extern Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOuts ); +extern void Gia_ManSim2ArrayOne( Vec_Wrd_t * vSimsPi, Vec_Int_t * vRes ); +extern Vec_Wec_t * Gia_ManSim2Array( Vec_Ptr_t * vSims ); +extern Vec_Wrd_t * Gia_ManArray2SimOne( Vec_Int_t * vRes ); +extern Vec_Ptr_t * Gia_ManArray2Sim( Vec_Wec_t * vRes ); +extern void Gia_ManPtrWrdDumpBin( char * pFileName, Vec_Ptr_t * p, int fVerbose ); +extern Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose ); /*=== giaSpeedup.c ============================================================*/ extern float Gia_ManDelayTraceLut( Gia_Man_t * p ); extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ); diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 464835e4..a40673a7 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -95,6 +95,7 @@ void Gia_ManStop( Gia_Man_t * p ) Vec_IntFreeP( &p->vClassNew ); Vec_IntFreeP( &p->vClassOld ); Vec_IntFreeP( &p->vPats ); + Vec_BitFreeP( &p->vPolars ); Vec_WrdFreeP( &p->vSims ); Vec_WrdFreeP( &p->vSimsT ); Vec_WrdFreeP( &p->vSimsPi ); diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c index 3151ed22..094bdee1 100644 --- a/src/aig/gia/giaPat2.c +++ b/src/aig/gia/giaPat2.c @@ -78,6 +78,8 @@ static inline char Min_LitValL( Min_Man_t * p, int i ) { return Vec_ static inline void Min_LitSetValL( Min_Man_t * p, int i, char v ){ assert(v==0 || v==1); Vec_StrWriteEntry(&p->vValsL, i, v); Vec_StrWriteEntry(&p->vValsL, i^1, (char)!v); Vec_IntPush(&p->vVis, Abc_Lit2Var(i)); } static inline void Min_ObjCleanValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] = 0x0202; } static inline void Min_ObjMarkValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] |= 0x0404; } +static inline void Min_ObjMark2ValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] |= 0x0808; } +static inline void Min_ObjUnmark2ValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] &= 0xF7F7; } static inline int Min_LitIsCi( Min_Man_t * p, int v ) { return v > 1 && v < p->FirstAndLit; } static inline int Min_LitIsNode( Min_Man_t * p, int v ) { return v >= p->FirstAndLit && v < p->FirstCoLit; } @@ -270,7 +272,7 @@ char Min_LitVerify_rec( Min_Man_t * p, int iLit ) int iLit1 = Min_LitFan(p, iLit^1); char Val0 = Min_LitVerify_rec( p, iLit0 ); char Val1 = Min_LitVerify_rec( p, iLit1 ); - assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Val0 < 3 && Val1 < 3 ); if ( Min_LitIsXor(iLit, iLit0, iLit1) ) Val = Min_XsimXor( Val0, Val1 ); else @@ -280,8 +282,11 @@ char Min_LitVerify_rec( Min_Man_t * p, int iLit ) Val ^= Abc_LitIsCompl(iLit); Min_LitSetValL( p, iLit, Val ); } + else + Vec_IntPush( &p->vVis, Abc_Lit2Var(iLit) ); + Min_ObjMark2ValL( p, Abc_Lit2Var(iLit) ); } - return Val; + return Val&3; } char Min_LitVerify( Min_Man_t * p, int iLit, Vec_Int_t * vLits ) { @@ -313,7 +318,7 @@ void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits ) Vec_IntForEachEntryReverse( &p->vVis, iObj, i ) { int iLit = Abc_Var2Lit( iObj, 0 ); - int Value = Min_LitValL(p, iLit); + int Value = 7 & Min_LitValL(p, iLit); if ( Value >= 4 ) { if ( Min_LitIsCi(p, iLit) ) @@ -324,7 +329,7 @@ void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits ) int iLit1 = Min_LitFan(p, iLit^1); char Val0 = Min_LitValL( p, iLit0 ); char Val1 = Min_LitValL( p, iLit1 ); - if ( Value == 5 ) // value == 1 + if ( Value&1 ) // value == 1 { assert( (Val0&1) && (Val1&1) ); Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); @@ -610,7 +615,7 @@ int Min_LitJustify_rec( Min_Man_t * p, int iLit ) } int Min_LitJustify( Min_Man_t * p, int iLit ) { - int Res, fCheck = 1; + int Res, fCheck = 0; Vec_IntClear( &p->vPat ); if ( iLit < 2 ) return 1; assert( !Min_LitIsCo(p, iLit) ); @@ -621,7 +626,6 @@ int Min_LitJustify( Min_Man_t * p, int iLit ) Min_ManCleanVisitedValL( p ); if ( Res ) { - Vec_IntSort( &p->vPat, 0 ); if ( fCheck && Min_LitVerify(p, iLit, &p->vPat) != 1 ) printf( "Verification FAILED for literal %d.\n", iLit ); //else @@ -912,7 +916,7 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie if ( 1 ) // minimization { //printf( "%d -> ", Vec_IntSize(vPatBest) ); - for ( i = 0; i < 10; i++ ) + for ( i = 0; i < 20; i++ ) { Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits ); if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) ) @@ -921,6 +925,7 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie //printf( "%d ", Vec_IntSize(vPatBest) ); } assert( Vec_IntSize(vPatBest) > 0 ); + Vec_IntSort( vPatBest, 0 ); nCurrCexes += Min_ManAccumulate( vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes, vPatBest ); nGoodCalls++; } @@ -1054,46 +1059,69 @@ int Min_ManBitPackOne( Vec_Wrd_t * vSimsPi, int iPat0, int nWords, Vec_Int_t * v break; return iPat; } -Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose ) +Vec_Ptr_t * Min_ReloadCexes( Vec_Wec_t * vCexes, int nMinCexes ) +{ + Vec_Ptr_t * vRes = Vec_PtrAlloc( Vec_WecSize(vCexes) ); + int i, c, nOuts = Vec_WecSize(vCexes)/nMinCexes; + for ( i = 0; i < nMinCexes; i++ ) + for ( c = 0; c < nOuts; c++ ) + { + Vec_Int_t * vLevel = Vec_WecEntry( vCexes, c*nMinCexes+i ); + if ( Vec_IntSize(vLevel) ) + Vec_PtrPush( vRes, vLevel ); + } + return vRes; +} + +Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, int nWords0, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose ) { abctime clk = Abc_Clock(); int fVeryVerbose = 0; Vec_Wrd_t * vSimsPi = NULL; Vec_Int_t * vLevel; int w, nBits, nTotal = 0, fFailed = ABC_INFINITY; - Vec_Int_t * vOrder = Vec_IntStartNatural( Vec_WecSize(vCexes)/nMinCexes ); - assert( Vec_IntSize(vOrder) == Vec_IntSize(vScores) ); - assert( Vec_WecSize(vCexes)%nMinCexes == 0 ); - Abc_MergeSortCost2Reverse( Vec_IntArray(vOrder), Vec_IntSize(vOrder), Vec_IntArray(vScores) ); + Vec_Int_t * vOrder = NULL; + Vec_Ptr_t * vReload = NULL; + if ( 0 ) + { + vOrder = Vec_IntStartNatural( Vec_WecSize(vCexes)/nMinCexes ); + assert( Vec_IntSize(vOrder) == Vec_IntSize(vScores) ); + assert( Vec_WecSize(vCexes)%nMinCexes == 0 ); + Abc_MergeSortCost2Reverse( Vec_IntArray(vOrder), Vec_IntSize(vOrder), Vec_IntArray(vScores) ); + } + else + vReload = Min_ReloadCexes( vCexes, nMinCexes ); if ( fVerbose ) printf( "Packing: " ); - //for ( w = 1; fFailed > 100; w++ ) - for ( w = 1; fFailed > 0; w++ ) + for ( w = nWords0 ? nWords0 : 1; nWords0 ? w <= nWords0 : fFailed > 0; w++ ) { - int i, k, iOut, iPatUsed, iPat = 0; + int i, iPatUsed, iPat = 0; + //int k, iOut; Vec_WrdFreeP( &vSimsPi ); vSimsPi = fRandom ? Vec_WrdStartRandom(2 * Gia_ManCiNum(p) * w) : Vec_WrdStart(2 * Gia_ManCiNum(p) * w); Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 ); Abc_TtClear( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) ); fFailed = nTotal = 0; - Vec_IntForEachEntry( vOrder, iOut, k ) - Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iOut*nMinCexes, (iOut+1)*nMinCexes ) + //Vec_IntForEachEntry( vOrder, iOut, k ) + //Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iOut*nMinCexes, (iOut+1)*nMinCexes ) + Vec_PtrForEachEntry( Vec_Int_t *, vReload, vLevel, i ) { - if ( fVeryVerbose && i%nMinCexes == 0 ) - printf( "\n" ); + //if ( fVeryVerbose && i%nMinCexes == 0 ) + // printf( "\n" ); if ( Vec_IntSize(vLevel) == 0 ) continue; iPatUsed = Min_ManBitPackOne( vSimsPi, iPat, w, vLevel ); fFailed += iPatUsed == iPat; - iPat = (iPatUsed + 1) % (64*w - 1); - if ( fVeryVerbose ) - printf( "Adding output %3d cex %3d to pattern %3d ", i/nMinCexes, i%nMinCexes, iPatUsed ); - if ( fVeryVerbose ) - Vec_IntPrint( vLevel ); + iPat = (iPatUsed + 1) % (64*(w-1) - 1); + //if ( fVeryVerbose ) + //printf( "Adding output %3d cex %3d to pattern %3d ", i/nMinCexes, i%nMinCexes, iPatUsed ); + //if ( fVeryVerbose ) + //Vec_IntPrint( vLevel ); nTotal++; } if ( fVerbose ) printf( "W = %d (F = %d) ", w, fFailed ); +// printf( "Failed patterns = %d\n", fFailed ); } if ( fVerbose ) printf( "Total = %d\n", nTotal ); @@ -1104,7 +1132,8 @@ Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, Vec_Wec_t * vCexes, int fRandom, int Vec_WrdSize(vSimsPi)/Gia_ManCiNum(p), nBits, 100.0*nBits/64/Vec_WrdSize(vSimsPi) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } - Vec_IntFree( vOrder ); + Vec_IntFreeP( &vOrder ); + Vec_PtrFreeP( &vReload ); return vSimsPi; } @@ -1205,37 +1234,42 @@ Vec_Int_t * Min_ManGetUnsolved( Gia_Man_t * p ) Gia_ManForEachCoDriverId( p, Driver, i ) if ( Driver > 0 ) Vec_IntPush( vRes, i ); + if ( Vec_IntSize(vRes) == 0 ) + Vec_IntFreeP( &vRes ); return vRes; } -Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose ) +Vec_Wrd_t * Min_ManRemapSims( int nInputs, Vec_Int_t * vMap, Vec_Wrd_t * vSimsPi ) { - abctime clk = Abc_Clock(); - Vec_Int_t * vStats[3] = {0}; int i, iObj; - extern Gia_Man_t * Cec4_ManSimulateTest4( Gia_Man_t * p, int nBTLimit, int nBTLimitPo, int fVerbose ); - Gia_Man_t * pSwp = Cec4_ManSimulateTest4( p, nConf, nConf2, 0 ); - abctime clkSweep = Abc_Clock() - clk; - int nArgs = fVerbose ? printf( "Generating patterns: Conf = %d (%d). Tries = %d. Pats = %d. Sim = %d. SAT = %d.\n", - nConf, nConf2, nMaxTries, nMinCexes, fUseSim, fUseSat ) : 0; - Vec_Int_t * vOuts = Min_ManGetUnsolved( pSwp ); - Gia_Man_t * pSwp2 = Gia_ManDupSelectedOutputs( pSwp, vOuts ); + int i, iObj, nWords = Vec_WrdSize(vSimsPi)/Vec_IntSize(vMap); + Vec_Wrd_t * vSimsNew = Vec_WrdStart( 2 * nInputs * nWords ); + assert( Vec_WrdSize(vSimsPi)%Vec_IntSize(vMap) == 0 ); + Vec_WrdShrink( vSimsNew, Vec_WrdSize(vSimsNew)/2 ); + Vec_IntForEachEntry( vMap, iObj, i ) + { + Abc_TtCopy( Vec_WrdArray(vSimsNew) + (iObj-1)*nWords, Vec_WrdArray(vSimsPi) + i*nWords, nWords, 0 ); + Abc_TtCopy( Vec_WrdLimit(vSimsNew) + (iObj-1)*nWords, Vec_WrdLimit(vSimsPi) + i*nWords, nWords, 0 ); + } + return vSimsNew; +} +Vec_Wrd_t * Gia_ManCollectSims( Gia_Man_t * pSwp, int nWords, Vec_Int_t * vOuts, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose ) +{ + Vec_Int_t * vStats[3] = {0}; int i, iObj; + Vec_Int_t * vMap = Vec_IntAlloc( 100 ); + Gia_Man_t * pSwp2 = Gia_ManDupCones2( pSwp, Vec_IntArray(vOuts), Vec_IntSize(vOuts), vMap ); Vec_Wec_t * vCexes = Min_ManComputeCexes( pSwp2, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose ); - Vec_Wrd_t * vSimsPi = Min_ManBitPack( p, vCexes, 1, nMinCexes, vStats[0], fVerbose ); + Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose ); Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 ); Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) ); if ( fVerbose ) - { Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) ); - Abc_PrintTime( 1, "Sweep time", clkSweep ); - Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); - } - if ( 0 ) + if ( fVeryVerbose ) { printf( "Unsolved = %4d ", Vec_IntSize(vOuts) ); Gia_ManPrintStats( pSwp2, NULL ); Vec_IntForEachEntry( vOuts, iObj, i ) { printf( "%4d : ", i ); - printf( "Out = %5d ", iObj ); + printf( "Out = %5d ", Vec_IntEntry(vMap, i) ); printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) ); printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) ); printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) ); @@ -1250,20 +1284,40 @@ Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, Vec_IntFree( vCounts ); Vec_WrdFree( vSimsPo ); Vec_WecFree( vCexes ); - Vec_IntFree( vOuts ); - Gia_ManStop( pSwp ); Gia_ManStop( pSwp2 ); + //printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) ); + vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi ); + Vec_WrdFree( vSimsPo ); + Vec_IntFree( vMap ); + return vSimsPi; +} +Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose ) +{ + abctime clk = Abc_Clock(); + extern Gia_Man_t * Cec4_ManSimulateTest4( Gia_Man_t * p, int nBTLimit, int nBTLimitPo, int fVerbose ); + Gia_Man_t * pSwp = Cec4_ManSimulateTest4( p, nConf, nConf2, 0 ); + abctime clkSweep = Abc_Clock() - clk; + int nArgs = fVerbose ? printf( "Generating patterns: Conf = %d (%d). Tries = %d. Pats = %d. Sim = %d. SAT = %d.\n", + nConf, nConf2, nMaxTries, nMinCexes, fUseSim, fUseSat ) : 0; + Vec_Int_t * vOuts = Min_ManGetUnsolved( pSwp ); + Vec_Wrd_t * vSimsPi = vOuts ? Gia_ManCollectSims( pSwp, 0, vOuts, nMaxTries, nMinCexes, fUseSim, fUseSat, fVerbose, fVeryVerbose ) : NULL; + if ( vOuts == NULL ) + printf( "There is no satisfiable outputs.\n" ); + if ( fVerbose ) + Abc_PrintTime( 1, "Sweep time", clkSweep ); + if ( fVerbose ) + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); + Vec_IntFreeP( &vOuts ); + Gia_ManStop( pSwp ); nArgs = 0; return vSimsPi; } void Min_ManTest2( Gia_Man_t * p ) { - Vec_Wrd_t * vSimsPi = Min_ManCollect( p, 100000, 100000, 10000, 20, 1, 1, 0 ); + Vec_Wrd_t * vSimsPi = Min_ManCollect( p, 100000, 100000, 10000, 20, 1, 0, 1, 1 ); Vec_WrdFreeP( &vSimsPi ); } - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index a9706742..c31064fe 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -2622,6 +2622,84 @@ void Gia_ManSimArrayTest( Vec_Wrd_t * vSimsPi ) } Vec_PtrFree( vTemp ); } + + +/**Function************************************************************* + + Synopsis [Serialization.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPtrWrdDumpBin( char * pFileName, Vec_Ptr_t * p, int fVerbose ) +{ + Vec_Wrd_t * vLevel; + int i, nSize, RetValue; + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + return; + } + nSize = Vec_PtrSize(p); + RetValue = fwrite( &nSize, 1, sizeof(int), pFile ); + Vec_PtrForEachEntry( Vec_Wrd_t *, p, vLevel, i ) + { + nSize = Vec_WrdSize(vLevel); + RetValue += fwrite( &nSize, 1, sizeof(int), pFile ); + RetValue += fwrite( Vec_WrdArray(vLevel), 1, sizeof(word)*nSize, pFile ); + } + fclose( pFile ); + if ( fVerbose ) + printf( "Written %d arrays into file \"%s\".\n", Vec_PtrSize(p), pFileName ); +} +Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose ) +{ + Vec_Ptr_t * p = NULL; Vec_Wrd_t * vLevel; int i, nSize, RetValue; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return NULL; + } + fseek( pFile, 0, SEEK_END ); + nSize = ftell( pFile ); + if ( nSize == 0 ) + { + printf( "The input file is empty.\n" ); + fclose( pFile ); + return NULL; + } + if ( nSize % (int)sizeof(int) > 0 ) + { + printf( "Cannot read file with integers because it is not aligned at 4 bytes (remainder = %d).\n", nSize % (int)sizeof(int) ); + fclose( pFile ); + return NULL; + } + rewind( pFile ); + RetValue = fread( &nSize, 1, sizeof(int), pFile ); + assert( RetValue == 4 ); + p = Vec_PtrAlloc( nSize ); + for ( i = 0; i < nSize; i++ ) + Vec_PtrPush( p, Vec_WrdAlloc(100) ); + Vec_PtrForEachEntry( Vec_Wrd_t *, p, vLevel, i ) + { + RetValue = fread( &nSize, 1, sizeof(int), pFile ); + assert( RetValue == 4 ); + Vec_WrdFill( vLevel, nSize, 0 ); + RetValue = fread( Vec_WrdArray(vLevel), 1, sizeof(word)*nSize, pFile ); + assert( RetValue == 8*nSize ); + } + fclose( pFile ); + if ( fVerbose ) + printf( "Read %d arrays from file \"%s\".\n", Vec_PtrSize(p), pFileName ); + return p; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaStoch.c b/src/aig/gia/giaStoch.c index 063bf985..94f53998 100644 --- a/src/aig/gia/giaStoch.c +++ b/src/aig/gia/giaStoch.c @@ -32,26 +32,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static void Vec_PtrFreeFunc( Vec_Ptr_t * p, void (*pFuncItemFree)(void *) ) ___unused; -static void Vec_PtrFreeFunc( Vec_Ptr_t * p, void (*pFuncItemFree)(void *) ) -{ - void * pItem; int i; - Vec_PtrForEachEntry( void *, p, pItem, i ) - pFuncItemFree( pItem ); - Vec_PtrFree( p ); -} - /**Function************************************************************* Synopsis [] -- cgit v1.2.3 From dbc5f8a3b69d1a8d90fce00b7d1e2aa7d164488b Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Thu, 21 Oct 2021 10:19:48 +0200 Subject: Added including unconnected carry-outs in the carry-chain connection list. Signed-off-by: Maciej Kurc --- src/aig/gia/giaSweep.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSweep.c b/src/aig/gia/giaSweep.c index 1d66caee..344eca44 100644 --- a/src/aig/gia/giaSweep.c +++ b/src/aig/gia/giaSweep.c @@ -388,6 +388,14 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p ) Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; int i, iLast, iBox, nBoxes = Tim_ManBoxNum( pManTime ); Vec_Int_t * vCarryOuts = Vec_IntAlloc( nBoxes ); + + // Create and populare reference count (and free later) only if not already + // done. + int createRefs = (p->pRefs == NULL); + if (createRefs) { + Gia_ManCreateRefs( p ); + } + for ( i = 0; i < nBoxes; i++ ) { iLast = Tim_ManBoxInputLast( pManTime, i ); @@ -398,9 +406,24 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p ) if ( iBox == -1 ) continue; assert( Gia_ObjIsCi(pObj) ); - if ( Gia_ObjCioId(pObj) == Tim_ManBoxOutputLast(pManTime, iBox) ) + if ( Gia_ObjCioId(pObj) == Tim_ManBoxOutputLast(pManTime, iBox) ) { Vec_IntPush( vCarryOuts, Gia_ObjId(p, pObj) ); + + // We have identified a carry connection. Check if the carry out + // of the destination box is unconnected. If so then add it to + // the carry list as well. + iLast = Tim_ManBoxOutputLast(pManTime, i); + pObj = Gia_ManCi(p, iLast); + if ( Gia_ObjRefNum(p, pObj) == 0 ) { + Vec_IntPush( vCarryOuts, Gia_ObjId(p, pObj) ); + } + } + } + + if (createRefs) { + ABC_FREE( p->pRefs ); } + return vCarryOuts; } -- cgit v1.2.3 From 348c74e0a63b54d3341c48a4ce71cee50e7bd41c Mon Sep 17 00:00:00 2001 From: Michael Gielda Date: Tue, 26 Oct 2021 09:36:25 +0200 Subject: Fix typo --- src/aig/gia/giaSweep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaSweep.c b/src/aig/gia/giaSweep.c index 344eca44..8a7fcbd0 100644 --- a/src/aig/gia/giaSweep.c +++ b/src/aig/gia/giaSweep.c @@ -389,7 +389,7 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p ) int i, iLast, iBox, nBoxes = Tim_ManBoxNum( pManTime ); Vec_Int_t * vCarryOuts = Vec_IntAlloc( nBoxes ); - // Create and populare reference count (and free later) only if not already + // Create and populate reference count (and free later) only if not already // done. int createRefs = (p->pRefs == NULL); if (createRefs) { -- cgit v1.2.3 From d13e33cdd8451ad4ecfcb9093fbaa628f0e6659d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 26 Oct 2021 16:58:59 -0700 Subject: New API for external calls. --- src/aig/gia/giaMini.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/aig') diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index ad7ed197..6cc528f2 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -681,6 +681,22 @@ int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc ) Vec_IntFree( vSwitching ); return pRes; } +int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc ) +{ + Vec_Int_t * vSwitching; + int i, iObj, * pRes = NULL; + if ( pAbc->pGiaMiniAig == NULL ) + { + printf( "GIA derived from MiniAIG is not available.\n" ); + return NULL; + } + vSwitching = Gia_ManComputeSwitchProbs( pAbc->pGiaMiniAig, 48, 16, 0 ); + pRes = ABC_CALLOC( int, Gia_ManCoNum(pAbc->pGiaMiniAig) ); + Gia_ManForEachCoDriverId( pAbc->pGiaMiniAig, iObj, i ) + pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, iObj )); + Vec_IntFree( vSwitching ); + return pRes; +} /**Function************************************************************* -- cgit v1.2.3 From a80a91e45f5edf59fb7475ae1a461ba3602c6731 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 2 Nov 2021 20:28:01 -0700 Subject: Bug fix and new procedures. --- src/aig/gia/giaAiger.c | 8 ++++---- src/aig/gia/giaPat2.c | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index 1bb70612..aafe311b 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -1702,8 +1702,8 @@ int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int int uLit = 2*(1 + nIns + nLats + i); int uLit1 = uLit - Aiger_ReadUnsigned( pFile ); int uLit0 = uLit1 - Aiger_ReadUnsigned( pFile ); - pObjs[2*(1+nIns+i)+0] = uLit0; - pObjs[2*(1+nIns+i)+1] = uLit1; + pObjs[2*(1+nIns+nLats+i)+0] = uLit0; + pObjs[2*(1+nIns+nLats+i)+1] = uLit1; } fclose( pFile ); if ( pnObjs ) *pnObjs = nObjs; @@ -1729,8 +1729,8 @@ void Aiger_Write( char * pFileName, int * pObjs, int nObjs, int nIns, int nLats, for ( i = 0; i < nAnds; i++ ) { int uLit = 2*(1 + nIns + nLats + i); - int uLit0 = pObjs[2*(1+nIns+i)+0]; - int uLit1 = pObjs[2*(1+nIns+i)+1]; + int uLit0 = pObjs[2*(1+nIns+nLats+i)+0]; + int uLit1 = pObjs[2*(1+nIns+nLats+i)+1]; Aiger_WriteUnsigned( pFile, uLit - uLit1 ); Aiger_WriteUnsigned( pFile, uLit1 - uLit0 ); } diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c index 094bdee1..f14ce34a 100644 --- a/src/aig/gia/giaPat2.c +++ b/src/aig/gia/giaPat2.c @@ -1242,6 +1242,8 @@ Vec_Wrd_t * Min_ManRemapSims( int nInputs, Vec_Int_t * vMap, Vec_Wrd_t * vSimsPi { int i, iObj, nWords = Vec_WrdSize(vSimsPi)/Vec_IntSize(vMap); Vec_Wrd_t * vSimsNew = Vec_WrdStart( 2 * nInputs * nWords ); + //Vec_Wrd_t * vSimsNew = Vec_WrdStartRandom( nInputs * nWords ); + //Vec_WrdFillExtra( vSimsNew, 2 * nInputs * nWords, 0 ); assert( Vec_WrdSize(vSimsPi)%Vec_IntSize(vMap) == 0 ); Vec_WrdShrink( vSimsNew, Vec_WrdSize(vSimsNew)/2 ); Vec_IntForEachEntry( vMap, iObj, i ) -- cgit v1.2.3 From 5e4a78470b71fc2adabde6397e3ed44fae79c172 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 5 Nov 2021 16:07:31 -0700 Subject: Compiler warnings. --- src/aig/miniaig/abcOper.h | 6 ++++-- src/aig/miniaig/ndr.h | 53 +++++++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 22 deletions(-) (limited to 'src/aig') diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h index 881810fd..c3d6e176 100644 --- a/src/aig/miniaig/abcOper.h +++ b/src/aig/miniaig/abcOper.h @@ -29,7 +29,9 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// +#ifndef _YOSYS_ ABC_NAMESPACE_HEADER_START +#endif //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -264,9 +266,9 @@ static inline const char * Abc_OperNameSimple( int Type ) /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// - +#ifndef _YOSYS_ ABC_NAMESPACE_HEADER_END - +#endif #endif diff --git a/src/aig/miniaig/ndr.h b/src/aig/miniaig/ndr.h index 91663616..68c2779c 100644 --- a/src/aig/miniaig/ndr.h +++ b/src/aig/miniaig/ndr.h @@ -33,7 +33,9 @@ #include "abcOper.h" +#ifndef _YOSYS_ ABC_NAMESPACE_HEADER_START +#endif #ifdef _WIN32 #define inline __inline @@ -215,8 +217,9 @@ static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, ch return; if ( ObjType == ABC_OPER_LUT ) { - word Truth = (word)pFunc; - Ndr_DataPushArray( p, Type, 2, (int *)&Truth ); + //word Truth = (word)pFunc; + //Ndr_DataPushArray( p, Type, 2, (int *)&Truth ); + Ndr_DataPushArray( p, Type, 2, (int *)&pFunc ); } else { @@ -662,7 +665,7 @@ static inline void Ndr_ModuleTest() // array of fanins of node s int Fanins[2] = { NameIdA, NameIdC }; // map name IDs into char strings - char * ppNames[5] = { NULL, "add10", "a", "s", "const10" }; + //char * ppNames[5] = { NULL, "add10", "a", "s", "const10" }; // create a new module void * pDesign = Ndr_Create( 1 ); @@ -671,13 +674,13 @@ static inline void Ndr_ModuleTest() // add objects to the modele Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &NameIdA, NULL ); // no fanins - Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST, 0, 3, 0, 0, 0, NULL, 1, &NameIdC, "4'b1010" ); // no fanins + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST, 0, 3, 0, 0, 0, NULL, 1, &NameIdC, (char*)"4'b1010" ); // no fanins Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADD, 0, 3, 0, 0, 2, Fanins, 1, &NameIdS, NULL ); // fanins are a and const10 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdS, 0, NULL, NULL ); // fanin is a // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); - Ndr_Write( "add4.ndr", pDesign ); + //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); + Ndr_Write( (char*)"add4.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -706,6 +709,7 @@ static inline void Ndr_ModuleTest() static inline void Ndr_ModuleTestAdder() { +/* // map name IDs into char strings char * ppNames[20] = { NULL, "a", "b", "s", "co", // 1, 2, 3, 4 @@ -713,6 +717,7 @@ static inline void Ndr_ModuleTestAdder() "r0", "s0", "rco", // 9, 10, 11 "r1", "s1", "add8" // 12, 13, 14 }; +*/ // fanins int FaninA = 1; int FaninB = 2; @@ -764,8 +769,8 @@ static inline void Ndr_ModuleTestAdder() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &FaninCO, 0, NULL, NULL ); // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); - Ndr_Write( "add8.ndr", pDesign ); + //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); + Ndr_Write( (char*)"add8.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -792,6 +797,7 @@ static inline void Ndr_ModuleTestAdder() static inline void Ndr_ModuleTestHierarchy() { +/* // map name IDs into char strings char * ppNames[20] = { NULL, "mux21w", "mux41w", // 1, 2 @@ -801,6 +807,7 @@ static inline void Ndr_ModuleTestHierarchy() "t0", "t1", // 12, 13 "i0", "i1", "i2" // 14, 15, 16 }; +*/ // fanins int FaninSel = 3; int FaninSel0 = 10; @@ -850,8 +857,8 @@ static inline void Ndr_ModuleTestHierarchy() Ndr_AddObject( pDesign, Module41, ABC_OPER_CO, 0, 3, 0, 0, 1, &FaninOut, 0, NULL, NULL ); // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); - Ndr_Write( "mux41w.ndr", pDesign ); + //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); + Ndr_Write( (char*)"mux41w.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -879,6 +886,7 @@ static inline void Ndr_ModuleTestHierarchy() static inline void Ndr_ModuleTestMemory() { +/* // map name IDs into char strings char * ppNames[20] = { NULL, "clk", "raddr", "waddr", "data", "mem_init", "out", // 1, 2, 3, 4, 5, 6 @@ -888,6 +896,7 @@ static inline void Ndr_ModuleTestMemory() "i_read1", "i_read2", // 15, 16 "i_write1", "i_write2", "memtest" // 17, 18, 19 }; +*/ // inputs int NameIdClk = 1; int NameIdRaddr = 2; @@ -939,8 +948,8 @@ static inline void Ndr_ModuleTestMemory() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_COMP_NOTEQU, 0, 0, 0, 0, 2, FaninsComp, 1, &NameIdComp, NULL ); // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); - Ndr_Write( "memtest.ndr", pDesign ); + //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); + Ndr_Write( (char*)"memtest.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -954,7 +963,7 @@ static inline void Ndr_ModuleTestMemory() static inline void Ndr_ModuleTestFlop() { // map name IDs into char strings - char * ppNames[12] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "sre", "init", "q" }; + //char * ppNames[12] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "sre", "init", "q" }; // name IDs int NameIdData = 2; int NameIdClk = 3; @@ -988,8 +997,8 @@ static inline void Ndr_ModuleTestFlop() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdQ, 0, NULL, NULL ); // write Verilog for verification - Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); - Ndr_Write( "flop.ndr", pDesign ); + //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); + Ndr_Write( (char*)"flop.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -1043,7 +1052,7 @@ static inline void Ndr_ModuleTestSelSel() // write Verilog for verification //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); - Ndr_Write( "sel.ndr", pDesign ); + Ndr_Write( (char*)"sel.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -1076,7 +1085,7 @@ static inline void Ndr_ModuleTestDec() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SEL_DEC, 0, 3, 0, 0, 1, &NameIdIn, 1, &NameIdOut, NULL ); Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL ); - Ndr_Write( "dec.ndr", pDesign ); + Ndr_Write( (char*)"dec.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -1112,7 +1121,7 @@ static inline void Ndr_ModuleTestAddSub() Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADDSUB, 0, 3, 0, 0, 4, Fanins, 1, &NameIdOut, NULL ); Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL ); - Ndr_Write( "addsub.ndr", pDesign ); + Ndr_Write( (char*)"addsub.ndr", pDesign ); Ndr_Delete( pDesign ); } @@ -1136,16 +1145,20 @@ static inline void Ndr_ModuleTestLut() int ModuleID = Ndr_AddModule( pDesign, 1 ); + unsigned pTruth[2] = { 0x88888888, 0x88888888 }; + // add objects to the modele Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL ); - Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)(ABC_CONST(0x8)) ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)pTruth ); Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &NameIdOut, 0, NULL, NULL ); - Ndr_Write( "lut_test.ndr", pDesign ); + Ndr_Write( (char*)"lut_test.ndr", pDesign ); Ndr_Delete( pDesign ); } +#ifndef _YOSYS_ ABC_NAMESPACE_HEADER_END +#endif #endif -- cgit v1.2.3 From 621d6355f475670cfdba5b685c65ee4dfd4207ea Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 7 Nov 2021 21:15:03 -0800 Subject: Temporary fix to a &blut problem. --- src/aig/gia/giaStr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/aig') diff --git a/src/aig/gia/giaStr.c b/src/aig/gia/giaStr.c index 2233d0fc..a87662a8 100644 --- a/src/aig/gia/giaStr.c +++ b/src/aig/gia/giaStr.c @@ -736,7 +736,7 @@ Str_Ntk_t * Str_ManNormalizeInt( Gia_Man_t * p, Vec_Wec_t * vGroups, Vec_Int_t * if ( p->vStore == NULL ) p->vStore = Vec_IntAlloc( STR_SUPER ); Gia_ManFillValue( p ); - pNtk = Str_NtkCreate( Gia_ManObjNum(p), 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) ); + pNtk = Str_NtkCreate( Gia_ManObjNum(p) + 10000, 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) + 10000 ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachObj1( p, pObj, i ) { @@ -749,7 +749,7 @@ Str_Ntk_t * Str_ManNormalizeInt( Gia_Man_t * p, Vec_Wec_t * vGroups, Vec_Int_t * pObj->Value = Str_ObjCreate( pNtk, STR_PO, 1, &iFanin ); } } - assert( pNtk->nObjs <= Gia_ManObjNum(p) ); + //assert( pNtk->nObjs <= Gia_ManObjNum(p) ); return pNtk; } Str_Ntk_t * Str_ManNormalize( Gia_Man_t * p ) -- cgit v1.2.3