From 36b357175a558687806f28b23c7679ef4ca9271e Mon Sep 17 00:00:00 2001 From: MyskYko Date: Sat, 6 May 2023 04:15:34 -0700 Subject: [PATCH] stochastic script for transduction --- src/aig/gia/giaTranStoch.c | 233 ++++++++++++++++++++++++++++++++++ src/aig/gia/giaTransduction.h | 2 + src/aig/gia/module.make | 1 + src/base/abci/abc.c | 133 +++++++++++++++++-- 4 files changed, 360 insertions(+), 9 deletions(-) create mode 100644 src/aig/gia/giaTranStoch.c diff --git a/src/aig/gia/giaTranStoch.c b/src/aig/gia/giaTranStoch.c new file mode 100644 index 000000000..8fb25aa81 --- /dev/null +++ b/src/aig/gia/giaTranStoch.c @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ABC_NAMESPACE_IMPL_START + +extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); +extern Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars ); +extern int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars ); +extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); +extern int Abc_NtkFxPerform( Abc_Ntk_t * pNtk, int nNewNodesMax, int nLitCountMax, int fCanonDivs, int fVerbose, int fVeryVerbose ); + +Abc_Ntk_t * Gia_ManTranStochPut( Gia_Man_t * pGia ) { + Abc_Ntk_t * pNtk; + Aig_Man_t * pMan = Gia_ManToAig( pGia, 0 ); + pNtk = Abc_NtkFromAigPhase( pMan ); + Aig_ManStop( pMan ); + return pNtk; +} +Abc_Ntk_t * Gia_ManTranStochIf( Abc_Ntk_t * pNtk ) { + If_Par_t Pars, * pPars = &Pars; + If_ManSetDefaultPars( pPars ); + pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); + pPars->nLutSize = pPars->pLutLib->LutMax; + return Abc_NtkIf( pNtk, pPars ); +} +void Gia_ManTranStochMfs2( Abc_Ntk_t * pNtk ) { + Sfm_Par_t Pars, * pPars = &Pars; + Sfm_ParSetDefault( pPars ); + Abc_NtkPerformMfs( pNtk, pPars ); +} +Gia_Man_t * Gia_ManTranStochGet( Abc_Ntk_t * pNtk ) { + Gia_Man_t * pGia; + Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 ); + pGia = Gia_ManFromAig( pAig ); + Aig_ManStop( pAig ); + return pGia; +} +void Gia_ManTranStochFx( Abc_Ntk_t * pNtk ) { + Fxu_Data_t Params, * p = &Params; + Abc_NtkSetDefaultFxParams( p ); + Abc_NtkFxPerform( pNtk, p->nNodesExt, p->LitCountMax, p->fCanonDivs, p->fVerbose, p->fVeryVerbose ); + Abc_NtkFxuFreeInfo( p ); +} + +struct Gia_ManTranStochParam { + int nSeed; + int nHops; + int nRestarts; + int nSeedBase; + int fCspf; + int fMerge; + int fResetHop; + int fTruth; + int fNewLine; + int nVerbose; +}; + +typedef struct Gia_ManTranStochParam Gia_ManTranStochParam; + +Gia_Man_t * Gia_ManTranStochOpt1( Gia_ManTranStochParam * p, Gia_Man_t * pOld ) { + Gia_Man_t * pGia, * pNew; + int i = 0, n; + pGia = Gia_ManDup( pOld ); + do { + n = Gia_ManAndNum( pGia ); + if ( p->fTruth ) + pNew = Gia_ManTransductionTt( pGia, (p->fMerge? 8: 7), !p->fCspf, p->nSeed++, 0, 0, 0, 0, NULL, p->fNewLine, p->nVerbose > 0? p->nVerbose - 1: 0 ); + else + pNew = Gia_ManTransductionBdd( pGia, (p->fMerge? 8: 7), !p->fCspf, p->nSeed++, 0, 0, 0, 0, NULL, p->fNewLine, p->nVerbose > 0? p->nVerbose - 1: 0 ); + Gia_ManStop( pGia ); + pGia = pNew; + pNew = Gia_ManCompress2( pGia, 1, 0 ); + Gia_ManStop( pGia ); + pGia = pNew; + if ( p->nVerbose ) + printf( "* ite %d : #nodes = %5d\n", i, Gia_ManAndNum( pGia ) ); + i++; + } while ( n > Gia_ManAndNum( pGia ) ); + return pGia; +} + +Gia_Man_t * Gia_ManTranStochOpt2( Gia_ManTranStochParam * p, Gia_Man_t * pOld ) { + int i, n = Gia_ManAndNum( pOld ); + Gia_Man_t * pGia, * pBest, * pNew; + Abc_Ntk_t * pNtk, * pNtkRes; + pGia = Gia_ManDup( pOld ); + pBest = Gia_ManDup( pGia ); + for ( i = 0; 1; i++ ) { + pNew = Gia_ManTranStochOpt1( p, pGia ); + Gia_ManStop( pGia ); + pGia = pNew; + if ( n > Gia_ManAndNum( pGia ) ) { + n = Gia_ManAndNum( pGia ); + Gia_ManStop( pBest ); + pBest = Gia_ManDup( pGia ); + if ( p->fResetHop ) + i = 0; + } + if ( i == p->nHops ) + break; + pNtk = Gia_ManTranStochPut( pGia ); + Gia_ManStop( pGia ); + pNtkRes = Gia_ManTranStochIf( pNtk ); + Abc_NtkDelete( pNtk ); + pNtk = pNtkRes; + Gia_ManTranStochMfs2( pNtk ); + pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 ); + Abc_NtkDelete( pNtk ); + pNtk = pNtkRes; + pGia = Gia_ManTranStochGet( pNtk ); + Abc_NtkDelete( pNtk ); + if ( p->nVerbose ) + printf( "* hop %d : #nodes = %5d\n", i, Gia_ManAndNum( pGia ) ); + } + Gia_ManStop( pGia ); + return pBest; +} + +Gia_Man_t * Gia_ManTranStochOpt3( Gia_ManTranStochParam * p, Gia_Man_t * pOld ) { + int i, n = Gia_ManAndNum( pOld ); + Gia_Man_t * pBest, * pNew; + pBest = Gia_ManDup( pOld ); + for ( i = 0; i <= p->nRestarts; i++ ) { + p->nSeed = 1234 * (i + p->nSeedBase); + pNew = Gia_ManTranStochOpt2( p, pOld ); + if ( p->nRestarts && p->nVerbose ) + printf( "* res %d : #nodes = %5d\n", i, Gia_ManAndNum( pNew ) ); + if ( n > Gia_ManAndNum( pNew ) ) { + n = Gia_ManAndNum( pNew ); + Gia_ManStop( pBest ); + pBest = pNew; + } else { + Gia_ManStop( pNew ); + } + } + return pBest; +} + +Gia_Man_t * Gia_ManTranStoch( Gia_Man_t * pGia, int nRestarts, int nHops, int nSeedBase, int fCspf, int fMerge, int fResetHop, int fTruth, int fSingle, int fOriginalOnly, int fNewLine, int nVerbose ) { + int i, j = 0; + Gia_Man_t * pNew, * pBest, * pStart; + Abc_Ntk_t * pNtk, * pNtkRes; + Gia_ManTranStochParam Par, *p = &Par; + p->nRestarts = nRestarts; + p->nHops = nHops; + p->nSeedBase = nSeedBase; + p->fCspf = fCspf; + p->fMerge = fMerge; + p->fResetHop = fResetHop; + p->fTruth = fTruth; + p->fNewLine = fNewLine; + p->nVerbose = nVerbose; + // setup start points + Vec_Ptr_t * vpStarts = Vec_PtrAlloc( 4 ); + Vec_PtrPush( vpStarts, Gia_ManDup( pGia ) ); + if ( !fOriginalOnly ) { + { // &put; collapse; st; &get; + pNtk = Gia_ManTranStochPut( pGia ); + pNtkRes = Abc_NtkCollapse( pNtk, ABC_INFINITY, 0, 1, 0, 0, 0 ); + Abc_NtkDelete( pNtk ); + pNtk = pNtkRes; + pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 ); + Abc_NtkDelete( pNtk ); + pNtk = pNtkRes; + pNew = Gia_ManTranStochGet( pNtk ); + Abc_NtkDelete( pNtk ); + Vec_PtrPush( vpStarts, pNew ); + } + { // &ttopt; + pNew = Gia_ManTtopt( pGia, Gia_ManCiNum( pGia ), Gia_ManCoNum( pGia ), 100 ); + Vec_PtrPush( vpStarts, pNew ); + } + { // &put; collapse; sop; fx; + pNtk = Gia_ManTranStochPut( pGia ); + pNtkRes = Abc_NtkCollapse( pNtk, ABC_INFINITY, 0, 1, 0, 0, 0 ); + Abc_NtkDelete( pNtk ); + pNtk = pNtkRes; + Abc_NtkToSop( pNtk, -1, ABC_INFINITY ); + Gia_ManTranStochFx( pNtk ); + pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 ); + Abc_NtkDelete( pNtk ); + pNtk = pNtkRes; + pNew = Gia_ManTranStochGet( pNtk ); + Abc_NtkDelete( pNtk ); + Vec_PtrPush( vpStarts, pNew ); + } + } + if ( fSingle ) { + pBest = (Gia_Man_t *)Vec_PtrEntry( vpStarts, 0 ); + for ( i = 1; i < Vec_PtrSize( vpStarts ); i++ ) { + pStart = (Gia_Man_t *)Vec_PtrEntry( vpStarts, i ); + if ( Gia_ManAndNum( pStart ) < Gia_ManAndNum( pBest ) ) { + Gia_ManStop( pBest ); + pBest = pStart; + j = i; + } else { + Gia_ManStop( pStart ); + } + } + Vec_PtrClear( vpStarts ); + Vec_PtrPush( vpStarts, pBest ); + } + // optimize + pBest = Gia_ManDup( pGia ); + Vec_PtrForEachEntry( Gia_Man_t *, vpStarts, pStart, i ) { + if ( p->nVerbose ) + printf( "*begin starting point %d: #nodes = %5d\n", i + j, Gia_ManAndNum( pStart ) ); + pNew = Gia_ManTranStochOpt3( p, pStart ); + if ( p->nVerbose ) + printf( "*end starting point %d: #nodes = %5d\n", i + j, Gia_ManAndNum( pNew ) ); + if ( Gia_ManAndNum( pBest ) > Gia_ManAndNum( pNew ) ) { + Gia_ManStop( pBest ); + pBest = pNew; + } else { + Gia_ManStop( pNew ); + } + Gia_ManStop( pStart ); + } + if ( p->nVerbose ) + printf( "best: %d\n", Gia_ManAndNum( pBest ) ); + Vec_PtrFree( vpStarts ); + return pBest; +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/aig/gia/giaTransduction.h b/src/aig/gia/giaTransduction.h index 963147839..162cd7d24 100644 --- a/src/aig/gia/giaTransduction.h +++ b/src/aig/gia/giaTransduction.h @@ -1623,6 +1623,8 @@ public: // Constructor PrintStats("Init", true, 11); } ~Transduction() { + if(nVerbose) + PrintStats("End", true, 11); this->DelVec(vFs); this->DelVec(vGs); this->DelVec(vvCs); diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 8584f3764..236d43b32 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -104,6 +104,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaTim.c \ src/aig/gia/giaTis.c \ src/aig/gia/giaTransduction.cpp \ + src/aig/gia/giaTranStoch.c \ src/aig/gia/giaTruth.c \ src/aig/gia/giaTsim.c \ src/aig/gia/giaTtopt.cpp \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index faea8c879..ddf062e9c 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -504,6 +504,7 @@ static int Abc_CommandAbc9LNetOpt ( Abc_Frame_t * pAbc, int argc, cha //#ifndef _WIN32 static int Abc_CommandAbc9Ttopt ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Transduction ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9TranStoch ( Abc_Frame_t * pAbc, int argc, char ** argv ); //#endif static int Abc_CommandAbc9LNetMap ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Unmap ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1262,6 +1263,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) //#ifndef _WIN32 Cmd_CommandAdd( pAbc, "ABC9", "&ttopt", Abc_CommandAbc9Ttopt, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&transduction", Abc_CommandAbc9Transduction, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&transtoch" , Abc_CommandAbc9TranStoch, 0 ); //#endif Cmd_CommandAdd( pAbc, "ABC9", "&lnetmap", Abc_CommandAbc9LNetMap, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&unmap", Abc_CommandAbc9Unmap, 0 ); @@ -42588,7 +42590,7 @@ int Abc_CommandAbc9Transduction( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_Man_t * pTemp, * pExdc = NULL; int c, nType = 1, fMspf = 0, nRandom = 0, nSortType = 0, nPiShuffle = 0, nParameter = 0, fLevel = 0, fTruth = 0, fNewLine = 0, nVerbose = 2; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "TSIPRVtmnl" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "TSIPRVtmnlh" ) ) != EOF ) { switch ( c ) { @@ -42708,7 +42710,7 @@ int Abc_CommandAbc9Transduction( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: &transduction [-TSIPRV num] [-bmlh] \n" ); Abc_Print( -2, "\t performs transduction-based AIG optimization\n" ); - Abc_Print( -2, "\t-T num : transduction type [default = %d]\n", nType ); + Abc_Print( -2, "\t-T num : transduction type [default = %d]\n", nType ); Abc_Print( -2, "\t 0: remove simply redundant nodes\n" ); Abc_Print( -2, "\t 1: Resub\n" ); Abc_Print( -2, "\t 2: ResubMono\n" ); @@ -42718,22 +42720,135 @@ usage: Abc_Print( -2, "\t 6: script RepeatInner\n" ); Abc_Print( -2, "\t 7: script RepeatOuter\n" ); Abc_Print( -2, "\t 8: script RepeatAll\n" ); - Abc_Print( -2, "\t-S num : fanin sort type [default = %d]\n", nSortType ); + Abc_Print( -2, "\t-S num : fanin sort type [default = %d]\n", nSortType ); Abc_Print( -2, "\t 0: topological order\n" ); Abc_Print( -2, "\t 1: number of ones\n" ); Abc_Print( -2, "\t 2: number of ones before complemented edges\n" ); Abc_Print( -2, "\t 3: pseudo random\n" ); Abc_Print( -2, "\t 4: no sorting\n" ); - Abc_Print( -2, "\t-I num : random seed to shuffle PIs (0 = no shuffle) [default = %d]\n", nPiShuffle ); - Abc_Print( -2, "\t-P num : parameters for scripts [default = %d]\n", nParameter ); + Abc_Print( -2, "\t-I num : random seed to shuffle PIs (0 = no shuffle) [default = %d]\n", nPiShuffle ); + Abc_Print( -2, "\t-P num : parameters for scripts [default = %d]\n", nParameter ); Abc_Print( -2, "\t-R num : random seed to set all parameters (0 = no random) ([default = %d]\n", nRandom ); - Abc_Print( -2, "\t-V num : verbosity level [default = %d]\n", nVerbose); + Abc_Print( -2, "\t-V num : verbosity level [default = %d]\n", nVerbose ); Abc_Print( -2, "\t-t : toggles using truth table instead of BDD [default = %s]\n", fTruth? "yes": "no" ); - Abc_Print( -2, "\t-m : toggles using MSPF [default = %s]\n", fMspf? "yes": "no" ); + Abc_Print( -2, "\t-m : toggles using MSPF instead of CSPF [default = %s]\n", fMspf? "yes": "no" ); Abc_Print( -2, "\t-n : toggles printing with a new line [default = %s]\n", fNewLine? "yes": "no" ); Abc_Print( -2, "\t-l : toggles level preserving optimization [default = %s]\n", fLevel? "yes": "no" ); - Abc_Print( -2, "\t-h : prints the command usage\n"); - Abc_Print( -2, "\t : AIGER specifying external don't-cares\n"); + Abc_Print( -2, "\t-h : prints the command usage\n" ); + Abc_Print( -2, "\t : AIGER specifying external don't-cares\n" ); + Abc_Print( -2, "\t\n" ); + Abc_Print( -2, "\t This command was contributed by Yukio Miyasaka.\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9TranStoch( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_ManTranStoch( Gia_Man_t * pGia, int nRestarts, int nHops, int nSeedBase, int fCspf, int fMerge, int fResetHop, int fTruth, int fSingle, int fOriginalOnly, int fNewLine, int nVerbose ); + Gia_Man_t * pTemp; + int c, nRestarts = 0, nHops = 10, nSeedBase = 0, fCspf = 0, fMerge = 1, fResetHop = 1, fTruth = 0, fSingle = 0, fOriginalOnly = 0, fNewLine = 0, nVerbose = 1; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "NMRVcmrtsonh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" ); + goto usage; + } + nRestarts = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by a positive integer.\n" ); + goto usage; + } + nHops = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by a positive integer.\n" ); + goto usage; + } + nSeedBase = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'V': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-V\" should be followed by a positive integer.\n" ); + goto usage; + } + nVerbose = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'c': + fCspf ^= 1; + break; + case 'm': + fMerge ^= 1; + break; + case 'r': + fResetHop ^= 1; + break; + case 't': + fTruth ^= 1; + break; + case 's': + fSingle ^= 1; + break; + case 'o': + fOriginalOnly ^= 1; + break; + case 'n': + fNewLine ^= 1; + break; + case 'h': + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Empty GIA network.\n" ); + return 1; + } + + pTemp = Gia_ManTranStoch( pAbc->pGia, nRestarts, nHops, nSeedBase, fCspf, fMerge, fResetHop, fTruth, fSingle, fOriginalOnly, fNewLine, nVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &transtoch [-NMRV num] [-cmrtsonh]\n" ); + Abc_Print( -2, "\t iterates transduction with randomized parameters\n" ); + Abc_Print( -2, "\t-N num : number of restarts [default = %d]\n", nRestarts ); + Abc_Print( -2, "\t-M num : number of hops (if; mfs2; strash) [default = %d]\n", nHops ); + Abc_Print( -2, "\t-R num : random seed [default = %d]\n", nSeedBase ); + Abc_Print( -2, "\t-V num : verbosity level [default = %d]\n", nVerbose); + Abc_Print( -2, "\t-c : toggles using CSPF instead of MSPF [default = %s]\n", fCspf? "yes": "no" ); + Abc_Print( -2, "\t-m : toggles using ResubShared [default = %s]\n", fMerge? "yes": "no" ); + Abc_Print( -2, "\t-r : toggles resetting hop count when new minimum is found [default = %s]\n", fResetHop? "yes": "no" ); + Abc_Print( -2, "\t-t : toggles using truth table instead of BDD [default = %s]\n", fTruth? "yes": "no" ); + Abc_Print( -2, "\t-s : toggles starting from the smallest starting point [default = %s]\n", fSingle? "yes": "no" ); + Abc_Print( -2, "\t-o : toggles starting from the given AIG [default = %s]\n", fOriginalOnly? "yes": "no" ); + Abc_Print( -2, "\t-n : toggles printing with a new line [default = %s]\n", fNewLine? "yes": "no" ); + Abc_Print( -2, "\t-h : prints the command usage\n" ); Abc_Print( -2, "\t\n" ); Abc_Print( -2, "\t This command was contributed by Yukio Miyasaka.\n" ); return 1;