From 93388c0d26e6958338005d9fbeb048dfb2c0de5a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 27 Jul 2024 14:48:02 -0700 Subject: [PATCH] Experiments with DSD. --- src/aig/gia/giaClp.c | 41 +++++++++++++++++ src/aig/gia/giaCof.c | 91 +++++++++++++++++++++++++++++++++++++ src/aig/gia/giaUtil.c | 2 +- src/base/abci/abc.c | 98 ++++++++++++++++++++++++++++++++++++++-- src/base/io/ioWriteDot.c | 13 ++++-- 5 files changed, 237 insertions(+), 8 deletions(-) diff --git a/src/aig/gia/giaClp.c b/src/aig/gia/giaClp.c index 68f9bf565..6703c8ca8 100644 --- a/src/aig/gia/giaClp.c +++ b/src/aig/gia/giaClp.c @@ -404,6 +404,43 @@ void Gia_ManCollapseTestTest( Gia_Man_t * p ) Gia_ManStop( pNew ); } +void Gia_ManCheckDsd( Gia_Man_t * p, int fVerbose ) +{ + DdManager * dd; + Dsd_Manager_t * pManDsd; + Vec_Ptr_t * vFuncs; + dd = Cudd_Init( Gia_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); + vFuncs = Gia_ManCollapse( p, dd, 10000, 0 ); + Cudd_AutodynDisable( dd ); + if ( vFuncs == NULL ) + { + Extra_StopManager( dd ); + return; + } + pManDsd = Dsd_ManagerStart( dd, Gia_ManCiNum(p), 0 ); + if ( pManDsd == NULL ) + { + Gia_ManCollapseDeref( dd, vFuncs ); + Cudd_Quit( dd ); + return; + } + Dsd_Decompose( pManDsd, (DdNode **)vFuncs->pArray, Gia_ManCoNum(p) ); + if ( fVerbose ) + { + Vec_Ptr_t * vNamesCi = Gia_GetFakeNames( Gia_ManCiNum(p) ); + Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p) ); + char ** ppNamesCi = (char **)Vec_PtrArray( vNamesCi ); + char ** ppNamesCo = (char **)Vec_PtrArray( vNamesCo ); + Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1 ); + Vec_PtrFreeFree( vNamesCi ); + Vec_PtrFreeFree( vNamesCo ); + } + Dsd_ManagerStop( pManDsd ); + Gia_ManCollapseDeref( dd, vFuncs ); + Extra_StopManager( dd ); +} + #else Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose ) @@ -411,6 +448,10 @@ Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose ) return NULL; } +void Gia_ManCheckDsd( Gia_Man_t * p, int fVerbose ) +{ +} + #endif //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c index c6ccb7d1f..d89e25867 100644 --- a/src/aig/gia/giaCof.c +++ b/src/aig/gia/giaCof.c @@ -993,6 +993,97 @@ Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose ) return pNew; } +/**Function************************************************************* + + Synopsis [Print the matrix.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDsdMatrix( Gia_Man_t * p, int iIn ) +{ + Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, j; + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + assert( Gia_ManPoNum(p) == 1 ); + assert( iIn >= 0 && iIn < Gia_ManPiNum(p) ); + 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_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + for ( i = 0; i < Gia_ManPiNum(p); i++ ) if ( i != iIn ) + for ( j = i+1; j < Gia_ManPiNum(p); j++ ) if ( j != iIn ) + { + int pRes[8], k, n; + int iLit0 = Gia_ManPi(p, iIn)->Value; + int iLit1 = Gia_ManPi(p, i)->Value; + int iLit2 = Gia_ManPi(p, j)->Value; + for ( k = 0; k < 8; k++ ) + { + Gia_ManPi(p, iIn)->Value = k & 1; + Gia_ManPi(p, i)->Value = (k >> 1) & 1; + Gia_ManPi(p, j)->Value = (k >> 2) & 1; + Gia_ManForEachAnd( p, pObj, n ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + pRes[k] = Gia_ObjFanin0Copy(Gia_ManPo(p, 0)); + } + Gia_ManPi(p, iIn)->Value = iLit0; + Gia_ManPi(p, i)->Value = iLit1; + Gia_ManPi(p, j)->Value = iLit2; + for ( k = 0; k < 4; k++ ) + pRes[k] = Gia_ManHashXor( pNew, pRes[2*k], pRes[2*k+1] ); + Vec_IntPush( vRes, Gia_ManHashXor(pNew, Gia_ManHashAnd(pNew, pRes[0], pRes[3]), Gia_ManHashAnd(pNew, pRes[1], pRes[2])) ); + } + Vec_IntForEachEntry( vRes, j, i ) + Gia_ManAppendCo( pNew, j ); + Vec_IntFree( vRes ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} +void Gia_ManPrintDsdMatrix( Gia_Man_t * p, int iIn ) +{ + extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); + Gia_Man_t * pNew = Gia_ManDsdMatrix( p, iIn ); int i, j, fFirst = 1, Count = 0; + Gia_Man_t * pSweep = Cec4_ManSimulateTest3( pNew, 0, 0 ); + Gia_ManStop( pNew ); + printf( "%4c : ", ' ' ); + for ( j = 0; j < Gia_ManPiNum(p); j++ ) + printf( "%4d", j ); + printf( "\n" ); + for ( i = 0; i < Gia_ManPiNum(p); i++, printf("\n"), fFirst = 1 ) + for ( j = 0; j < Gia_ManPiNum(p); j++ ) + { + if ( fFirst ) + printf( "%4d : ", i ), fFirst = 0; + if ( i == iIn ) + continue; + if ( j == iIn ) + printf( "%4c", ' ' ); + else + { + if ( j > i ) { + if ( Gia_ObjFaninLit0p(pSweep, Gia_ManPo(pSweep, Count++)) == 0 ) + printf( "%4c", '.' ); + else + printf( "%4c", '+' ); + } + else + printf( "%4c", ' ' ); + } + } + assert( Count == Gia_ManPoNum(pSweep) ); + Gia_ManStop( pSweep ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 2a29ea431..5338662d0 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -3458,7 +3458,7 @@ Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t Vec_IntFree( vMap ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); - Gia_ManPrint( pNew ); + //Gia_ManPrint( pNew ); return pNew; } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index cca768542..16d443177 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -612,6 +612,7 @@ static int Abc_CommandAbc9GenRel ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9GenMux ( Abc_Frame_t * pAbc, int argc, char ** argv ); 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_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1406,6 +1407,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&genmux", Abc_CommandAbc9GenMux, 0 ); 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", "&test", Abc_CommandAbc9Test, 0 ); { @@ -33837,9 +33839,9 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Gia_Man_t * Gia_ManComputeCofs( Gia_Man_t * p, int nVars ); Gia_Man_t * pTemp; int c, fVerbose = 0; - int iVar = 0, nLimFan = 0, nVars = 0; + int iVar = 0, Const = -1, nLimFan = 0, nVars = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "VLNvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "VCLNvh" ) ) != EOF ) { switch ( c ) { @@ -33854,6 +33856,17 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( iVar < 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; + } + Const = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Const < 0 || Const > 1 ) + goto usage; + break; case 'L': if ( globalUtilOptind >= argc ) { @@ -33890,7 +33903,13 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Cof(): There is no AIG.\n" ); return 1; } - if ( nVars ) + if ( Const == 0 || Const == 1 ) + { + Abc_Print( 0, "Computing cofactor of var %d with value %d.\n", iVar, Const ); + pTemp = Gia_ManDupCofactorVar( pAbc->pGia, iVar, Const ); + Abc_FrameUpdateGia( pAbc, pTemp ); + } + else if ( nVars ) { Abc_Print( 0, "Cofactoring the last %d inputs.\n", nVars ); pTemp = Gia_ManComputeCofs( pAbc->pGia, nVars ); @@ -33916,9 +33935,10 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &cof [-VLN num] [-vh]\n" ); + Abc_Print( -2, "usage: &cof [-VCLN num] [-vh]\n" ); Abc_Print( -2, "\t performs cofactoring w.r.t. variable(s)\n" ); Abc_Print( -2, "\t-V num : the zero-based ID of one variable to cofactor [default = %d]\n", iVar ); + Abc_Print( -2, "\t-C num : cofactor one variable with a given constant (0 or 1) [default = unused]\n" ); Abc_Print( -2, "\t-L num : cofactor vars with fanout count higher than this [default = %d]\n", nLimFan ); Abc_Print( -2, "\t-N num : cofactoring the given number of last input variables [default = %d]\n", nVars ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); @@ -53579,6 +53599,76 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9DsdInfo( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManPrintDsdMatrix( Gia_Man_t * p, int iIn ); + extern void Gia_ManCheckDsd( Gia_Man_t * p, int fVerbose ); + int c, iIn = 0, fDsd = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Vdvh" ) ) != EOF ) + { + switch ( c ) + { + case 'V': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-V\" should be followed by an integer.\n" ); + goto usage; + } + iIn = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( iIn < 0 ) + goto usage; + break; + case 'd': + fDsd ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9DsdInfo(): There is no AIG.\n" ); + return 0; + } + if ( iIn < 0 || iIn >= Gia_ManPiNum(pAbc->pGia) ) + { + Abc_Print( -1, "Abc_CommandAbc9DsdInfo(): There is no AIG.\n" ); + return 0; + } + if ( fDsd ) + Gia_ManCheckDsd( pAbc->pGia, fVerbose ); + else + Gia_ManPrintDsdMatrix( pAbc->pGia, iIn ); + return 0; + +usage: + Abc_Print( -2, "usage: &dsdinfo [-V num] [-dvh]\n" ); + Abc_Print( -2, "\t computes and displays information related to DSD\n" ); + Abc_Print( -2, "\t-V num : the zero-based index of the input variable [default = %d]\n", iIn ); + Abc_Print( -2, "\t-d : toggles showing DSD structure [default = %s]\n", fDsd ? "yes": "no" ); + 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"); + return 1; +} + /**Function************************************************************* diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c index a5ba4c178..dc1f97698 100644 --- a/src/base/io/ioWriteDot.c +++ b/src/base/io/ioWriteDot.c @@ -72,7 +72,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho { FILE * pFile; Abc_Obj_t * pNode, * pFanin; - char * pSopString; + char * pSopString, SopString[32]; int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl, Prev, AigNodeId; int Limit = 500; @@ -302,8 +302,15 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho pSopString = Mio_GateReadName((Mio_Gate_t *)pNode->pData); else if ( Abc_NtkHasMapping(pNtk) ) pSopString = Abc_NtkPrintSop(Mio_GateReadSop((Mio_Gate_t *)pNode->pData)); - else - pSopString = Abc_NtkPrintSop((char *)pNode->pData); + else { + int nCubes = Abc_SopGetCubeNum((char *)pNode->pData); + if ( nCubes <= 16 ) + pSopString = Abc_NtkPrintSop((char *)pNode->pData); + else { + sprintf( SopString, "%d cubes", nCubes ); + pSopString = SopString; + } + } //if ( pNtk->vOrigNodeIds ) // printf( "%d = %d \n", pNode->Id, Vec_IntEntry(pNtk->vOrigNodeIds, pNode->Id) ) AigNodeId = (fAigIds && pNtk->vOrigNodeIds) ? Vec_IntEntry(pNtk->vOrigNodeIds, pNode->Id) : -1;