Skip to content

Commit

Permalink
New command to detect presence of a function in the AIG.
Browse files Browse the repository at this point in the history
  • Loading branch information
alanminko committed Aug 2, 2024
1 parent 3286179 commit 7d88bf2
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 0 deletions.
75 changes: 75 additions & 0 deletions src/aig/gia/giaCut.c
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,81 @@ void Gia_ManExploreCutsTest( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fV
Vec_WecFree( vCutSel );
}


/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Sto_t * Gia_ManMatchCutsInt( Gia_Man_t * pGia, int nCutSize0, int nCutNum0, int fVerbose0 )
{
int nCutSize = nCutSize0;
int nCutNum = nCutNum0;
int fCutMin = 1;
int fTruthMin = 1;
int fVerbose = fVerbose0;
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 );
}
return p;
}
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 );
Vec_Int_t * vLevel; int i, k, * pCut;
Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
abctime clkStart = Abc_Clock();
assert( Abc_Truth6WordNum(nCutSize) == Vec_MemEntrySize(vTtMem) );
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
{
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
{
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
if ( *pSpot == -1 )
continue;
Vec_IntPush( vNodes, i );
break;
}
}
printf( "Nodes with matching cuts: " );
Vec_IntPrint( vNodes );
Vec_IntFree( vNodes );
Gia_StoFree( p );
if ( fVerbose )
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
}

////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
Expand Down
89 changes: 89 additions & 0 deletions src/base/abci/abc.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,7 @@ static int Abc_CommandAbc9GenMux ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Window ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9FunAbs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9DsdInfo ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9FunTrace ( Abc_Frame_t * pAbc, int argc, char ** argv );

static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv );

Expand Down Expand Up @@ -1412,6 +1413,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&window", Abc_CommandAbc9Window, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&funabs", Abc_CommandAbc9FunAbs, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&dsdinfo", Abc_CommandAbc9DsdInfo, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&funtrace", Abc_CommandAbc9FunTrace, 0 );

Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 );
{
Expand Down Expand Up @@ -53951,6 +53953,93 @@ int Abc_CommandAbc9DsdInfo( Abc_Frame_t * pAbc, int argc, char ** argv )
}


/**Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

***********************************************************************/
int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose );
extern void Gia_ManMatchCuts( Vec_Mem_t * vTtMem, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose );
int c, nVars, nVars2, nCutNum = 8, fVerbose = 0; word * pTruth = NULL;
char * pStr = NULL; Vec_Mem_t * vTtMem = NULL;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Cvh" ) ) != EOF )
{
switch ( c )
{
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 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pGia == NULL )
{
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): There is no AIG.\n" );
return 0;
}
if ( argc != globalUtilOptind + 1 )
{
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): Truth table in hex notation should be given on the command line.\n" );
return 0;
}
pStr = argv[globalUtilOptind];
if ( pStr[0] == '0' && pStr[1] == 'x' )
pStr += 2;
nVars = Abc_Base2Log(strlen(pStr)*4);
if ( (1 << nVars) != strlen(pStr)*4 )
{
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): String \"%s\" does not look like a truth table of a %d-var function.\n", pStr, nVars );
return 0;
}
pTruth = ABC_CALLOC( word, Abc_Truth6WordNum(nVars+1) );
nVars2 = Abc_TtReadHex( pTruth, pStr );
if ( nVars != nVars2 )
{
ABC_FREE( pTruth );
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): String \"%s\" does not look like a truth table of a %d-var function.\n", pStr, nVars );
return 0;
}
//Abc_TtPrintHexRev( stdout, pTruth, nVars ); printf( "\n" );
vTtMem = Dau_CollectNpnFunctions( pTruth, nVars, fVerbose );
Gia_ManMatchCuts( vTtMem, pAbc->pGia, nVars, nCutNum, fVerbose );
Vec_MemHashFree( vTtMem );
Vec_MemFree( vTtMem );
return 0;

usage:
Abc_Print( -2, "usage: &funtrace [-C num] [-vh] <truth>\n" );
Abc_Print( -2, "\t traces the presence of the function in the current AIG\n" );
Abc_Print( -2, "\t-C num : the number of cuts to compute at each node [default = %d]\n", nCutNum );
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose ? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t<truth> : truth table in the hexadecimal notation\n");
return 1;
}


/**Function*************************************************************

Synopsis []
Expand Down
59 changes: 59 additions & 0 deletions src/opt/dau/dauNpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,65 @@ void Dau_FunctionEnum( int nInputs, int nVars, int nNodeMax, int fUseTwo, int fR
fflush(stdout);
}

/**Function*************************************************************
Synopsis [Function enumeration.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose )
{
abctime clkStart = Abc_Clock();
Vec_Mem_t * vTtMem = Vec_MemAllocForTTSimple( nVars );
int nWords = Abc_Truth6WordNum(nVars);
word * pCopy = ABC_ALLOC( word, nWords );
Abc_TtCopy( pCopy, p, nWords, p[0] & 1 );
Vec_MemHashInsert( vTtMem, pCopy );
int nPerms = Extra_Factorial( nVars );
int nMints = 1 << nVars;
int * pPerm = Extra_PermSchedule( nVars );
int * pComp = Extra_GreyCodeSchedule( nVars );
int m, i, k, nFuncs;
for ( m = 0; m < nMints; m++ ) {
Abc_TtFlip( pCopy, nWords, pComp[m] );
if ( pCopy[0] & 1 ) {
Abc_TtNot( pCopy, nWords );
assert( (pCopy[0] & 1) == 0 );
Vec_MemHashInsert( vTtMem, pCopy );
Abc_TtNot( pCopy, nWords );
}
else
Vec_MemHashInsert( vTtMem, pCopy );
}
assert( Abc_TtEqual(pCopy, Vec_MemReadEntry(vTtMem, 0), nWords) );
nFuncs = Vec_MemEntryNum(vTtMem);
if ( fVerbose )
printf( "Collected %d NN functions and ", nFuncs ), fflush(stdout);
for ( i = 0; i < nFuncs; i++ ) {
Abc_TtCopy( pCopy, Vec_MemReadEntry(vTtMem, i), nWords, 0 );
for ( k = 0; k < nPerms; k++ ) {
Abc_TtSwapAdjacent( pCopy, nWords, pPerm[k] );
assert( (pCopy[0] & 1) == 0 );
Vec_MemHashInsert( vTtMem, pCopy );
}
assert( Abc_TtEqual(pCopy, Vec_MemReadEntry(vTtMem, i), nWords) );
}
ABC_FREE( pPerm );
ABC_FREE( pComp );
ABC_FREE( pCopy );
nFuncs = Vec_MemEntryNum(vTtMem);
if ( fVerbose )
printf( "%d NPN functions. ", nFuncs ),
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ),
fflush(stdout);
return vTtMem;
}

////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 7d88bf2

Please sign in to comment.