diff --git a/src/aig/gia/giaCut.c b/src/aig/gia/giaCut.c index 61ce665a7..e3a38dabb 100644 --- a/src/aig/gia/giaCut.c +++ b/src/aig/gia/giaCut.c @@ -29,9 +29,9 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define GIA_MAX_CUTSIZE 8 -#define GIA_MAX_CUTNUM 257 -#define GIA_MAX_TT_WORDS ((GIA_MAX_CUTSIZE > 6) ? 1 << (GIA_MAX_CUTSIZE-6) : 1) +#define GIA_MAX_CUTSIZE 14 +#define GIA_MAX_CUTNUM 257 +#define GIA_MAX_TT_WORDS ((GIA_MAX_CUTSIZE > 6) ? 1 << (GIA_MAX_CUTSIZE-6) : 1) #define GIA_CUT_NO_LEAF 0xF @@ -649,7 +649,7 @@ void Gia_StoComputeCuts( Gia_Man_t * pGia ) 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). ", + printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ", p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) ); Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart ); } @@ -724,7 +724,7 @@ Vec_Wec_t * Gia_ManExtractCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int 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). ", + printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ", p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) ); Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart ); } @@ -999,7 +999,7 @@ Vec_Wec_t * Gia_ManExploreCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int 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). ", + printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ", p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) ); Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart ); } @@ -1027,12 +1027,12 @@ void Gia_ManExploreCutsTest( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fV SeeAlso [] ***********************************************************************/ -Gia_Sto_t * Gia_ManMatchCutsInt( Gia_Man_t * pGia, int nCutSize0, int nCutNum0, int fVerbose0 ) +Gia_Sto_t * Gia_ManMatchCutsInt( Gia_Man_t * pGia, int nCutSize0, int nCutNum0, int fTruth0, int fVerbose0 ) { int nCutSize = nCutSize0; int nCutNum = nCutNum0; - int fCutMin = 1; - int fTruthMin = 1; + int fCutMin = fTruth0; + int fTruthMin = fTruth0; int fVerbose = fVerbose0; Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose ); Gia_Obj_t * pObj; int i, iObj; @@ -1057,15 +1057,90 @@ Gia_Sto_t * Gia_ManMatchCutsInt( Gia_Man_t * pGia, int nCutSize0, int nCutNum0, 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). ", + printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ", p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) ); Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart ); } return p; } +int Gia_ManCountSelfCuts( Gia_Man_t * p, Gia_Sto_t * pSto ) +{ + Vec_Int_t * vLevel; int i, k, * pCut, nNodes = 0; + Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) { + Gia_Obj_t * pObj = Gia_ManObj(p, i); + if ( !Gia_ObjIsAnd(pObj) ) + continue; + Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) + nNodes += pCut[0] == 2 && pCut[1] == Gia_ObjFaninId0p(p, pObj) && pCut[2] == Gia_ObjFaninId1p(p, pObj); + } + return nNodes; +} + +void Gia_ManDumpCuts( Gia_Man_t * p, Gia_Sto_t * pSto, FILE * pFile, int fVerbose, char * pFileName ) +{ + Vec_Int_t * vLevel; int i, k, c, * pCut, nCuts = 0, nNodes = 0; + Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) { + if ( !Gia_ObjIsAnd(Gia_ManObj(p, i)) ) + continue; + int nNodeCuts = 0; + Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) { + if ( pCut[0] == 1 ) + continue; + fprintf( pFile, "%d ", i ); + for ( c = 1; c <= pCut[0]; c++ ) + fprintf( pFile, "%d ", pCut[c] ); + fprintf( pFile, "1\n" ); + nNodeCuts++; + nNodes++; + } + nCuts += nNodeCuts; + } + Gia_Obj_t * pObj; + Gia_ManForEachCo( p, pObj, i ) + fprintf( pFile, "%d %d 0\n", Gia_ObjId(p, pObj), Gia_ObjFaninId0p(p, pObj) ); + if ( fVerbose ) + printf( "Dumped %d cuts for %d nodes into file \"%s\".\n", nCuts, nNodes, pFileName ? pFileName : "stdout" ); +} +void Gia_ManComputeCutsCore( Gia_Man_t * pGia, int nCutSize, int nCutNum, int fTruth, int fVerbose, int fDumpText, int fDumpBin, char * pFileName ) +{ + Gia_Sto_t * pSto = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fTruth, fVerbose ); + if ( fDumpText ) { + FILE * pFile = pFileName ? fopen(pFileName, "wb") : stdout; + if ( !pFile ) return; + Gia_ManDumpCuts( pGia, pSto, pFile, fVerbose, pFileName ); + } + else if ( fDumpBin ) { + FILE * pFile = pFileName ? fopen(pFileName, "wb") : NULL; + if ( !pFile ) return; + Gia_ManDumpCuts( pGia, pSto, pFile, fVerbose, pFileName ); + } + //printf( "The number of nodes with self-cuts = %d (out of %d).\n", Gia_ManCountSelfCuts(pGia, pSto), Gia_ManAndNum(pGia) ); + Gia_StoFree( pSto ); +} + +Vec_Wec_t * Gia_ManCompute54Cuts( Gia_Man_t * pGia, int fVerbose ) +{ + Gia_Sto_t * pSto = Gia_ManMatchCutsInt( pGia, 5, 16, 0, fVerbose ); + Vec_Wec_t * vRes = Vec_WecAlloc( 1000 ); + Vec_Int_t * vLevel; int i, k, c, * pCut; + Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) { + if ( !Gia_ObjIsAnd(Gia_ManObj(pGia, i)) ) + continue; + Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) { + if ( pCut[0] != 4 && pCut[0] != 5 ) + continue; + Vec_Int_t * vCut = Vec_WecPushLevel( vRes ); + for ( c = 1; c <= pCut[0]; c++ ) + Vec_IntPush( vCut, pCut[c] ); + Vec_IntPush( vCut, i ); + } + } + Gia_StoFree( pSto ); + return vRes; +} void Gia_ManMatchCuts( Vec_Mem_t * vTtMem, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose ) { - Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fVerbose ); + Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose ); Vec_Int_t * vLevel; int i, j, k, * pCut; Vec_Int_t * vNodes = Vec_IntAlloc( 100 ); Vec_Wec_t * vCuts = Vec_WecAlloc( 100 ); @@ -1101,7 +1176,7 @@ void Gia_ManMatchCuts( Vec_Mem_t * vTtMem, Gia_Man_t * pGia, int nCutSize, int n Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose ) { Vec_Ptr_t * vRes = Vec_PtrAlloc( Vec_PtrSize(vTtMems) ); - Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fVerbose ); + Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose ); Vec_Int_t * vLevel, * vTemp; int i, k, c, * pCut; abctime clkStart = Abc_Clock(); for ( i = 0; i < Vec_PtrSize(vTtMems); i++ ) @@ -1136,7 +1211,7 @@ Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nC } Vec_Ptr_t * Gia_ManMatchCutsMany( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, int nFuncs, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose ) { - Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fVerbose ); + Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose ); Vec_Int_t * vLevel; int i, j, k, * pCut; abctime clkStart = Abc_Clock(); assert( Abc_Truth6WordNum(nCutSize) == Vec_MemEntrySize(vTtMem) ); @@ -1168,46 +1243,6 @@ Vec_Ptr_t * Gia_ManMatchCutsMany( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, int nFun return vRes; } -/**Function************************************************************* - - Synopsis [Function enumeration.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManDumpCuts( Gia_Man_t * p, int nCutSize, int nCutNum, int fVerbose ) -{ - FILE * pFile = fopen( "input.txt", "wb" ); if ( !pFile ) return; - Gia_Sto_t * pSto = Gia_ManMatchCutsInt( p, nCutSize, nCutNum, 0 ); - Vec_Int_t * vLevel; int i, k, c, * pCut, nCuts = 0, nNodes = 0; - Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) { - if ( !Gia_ObjIsAnd(Gia_ManObj(p, i)) ) - continue; - Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) { - if ( pCut[0] == 1 ) - continue; - fprintf( pFile, "%d ", i ); - for ( c = 1; c <= pCut[0]; c++ ) - fprintf( pFile, "%d ", pCut[c] ); - fprintf( pFile, "1\n" ); - nCuts += pCut[0]; - nNodes++; - } - } - Gia_Obj_t * pObj; - Gia_ManForEachCo( p, pObj, i ) { - fprintf( pFile, "%d %d 0\n", Gia_ObjId(p, pObj), Gia_ObjFaninId0p(p, pObj) ); - } - fclose( pFile ); - Gia_StoFree( pSto ); - if ( fVerbose ) - printf( "Dumped %d cuts for %d nodes into file \"input.txt\".\n", nCuts, nNodes ); -} - /**Function************************************************************* Synopsis [Function enumeration.] @@ -1221,7 +1256,7 @@ void Gia_ManDumpCuts( Gia_Man_t * p, int nCutSize, int nCutNum, int fVerbose ) ***********************************************************************/ Vec_Wrd_t * Gia_ManCollectCutFuncs( Gia_Man_t * p, int nCutSize, int nCutNum, int fVerbose ) { - Gia_Sto_t * pSto = Gia_ManMatchCutsInt( p, nCutSize, nCutNum, 0 ); + Gia_Sto_t * pSto = Gia_ManMatchCutsInt( p, nCutSize, nCutNum, 1, 0 ); Vec_Wrd_t * vFuncs = Vec_WrdAlloc( 1000 ); Vec_Int_t * vLevel; int i, k, * pCut; Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] == nCutSize ) { diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fc6592452..ca0ff576c 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -649,6 +649,7 @@ static int Abc_CommandAbc9MulFind ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9MulFind3 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9BsFind ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9AndCare ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Cuts ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1480,6 +1481,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&mulfind3", Abc_CommandAbc9MulFind3, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&bsfind", Abc_CommandAbc9BsFind, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&andcare", Abc_CommandAbc9AndCare, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&cuts", Abc_CommandAbc9Cuts, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 ); @@ -58195,6 +58197,114 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Cuts( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManComputeCutsCore( Gia_Man_t * pGia, int nCutSize0, int nCutNum0, int fTruth0, int fVerbose0, int fDumpText, int fDumpBin, char * pFileName ); + int nCutSize = 6; + int nCutNum = 16; + int fTruth = 1; + int fVerbose = 1; + int fDumpText = 0; + int fDumpBin = 0; + int c; + char * pFileName = NULL; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "KCtdbvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + nCutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCutSize < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + nCutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCutNum < 0 ) + goto usage; + break; + case 't': + fTruth ^= 1; + break; + case 'd': + fDumpText ^= 1; + break; + case 'b': + fDumpBin ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Cuts(): There is no AIG.\n" ); + return 0; + } + if ( argc == globalUtilOptind + 1 ) + pFileName = argv[globalUtilOptind]; + else if ( argc != globalUtilOptind ) + { + Abc_Print( 1,"Abc_CommandAbc9Cuts(): Trailing arguments on the command line.\n" ); + return 0; + } + if ( nCutSize < 2 || nCutSize > 14 ) + { + Abc_Print( -1, "The number of cut leaves should belong to the range: %d <= K <= %d.\n", 2, 14 ); + return 1; + } + if ( nCutNum < 2 || nCutNum > 256 ) + { + Abc_Print( -1, "The number of cuts per node should belong to the range: %d <= C <= %d.\n", 2, 256 ); + return 1; + } + if ( fDumpBin && !pFileName ) + { + Abc_Print( -1, "Output binary file name should be provided on the command line.\n" ); + return 1; + } + Gia_ManComputeCutsCore( pAbc->pGia, nCutSize, nCutNum, fTruth, fVerbose, fDumpText, fDumpBin, pFileName ); + return 0; + +usage: + Abc_Print( -2, "usage: cuts [-KC num] [-tdbvh]\n" ); + Abc_Print( -2, "\t computes K-input cuts for the nodes in the current AIG\n" ); + Abc_Print( -2, "\t-K num : max number of leaves (%d <= num <= %d) [default = %d]\n", 2, 14, nCutSize ); + Abc_Print( -2, "\t-C num : max number of cuts at a node (%d <= num <= %d) [default = %d]\n", 2, 256, nCutNum ); + Abc_Print( -2, "\t-t : toggle truth table computation and cut minimization [default = %s]\n", fTruth? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle dumping cuts into a text file [default = %s]\n", fDumpText? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fDumpBin? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} /**Function*************************************************************