mirror of https://github.com/YosysHQ/abc.git
Adding command "cuts".
This commit is contained in:
parent
c956f02eb0
commit
6d2bedd609
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue