From f93e5244219b75224df0c75b424654bd2424852b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 22 Jun 2014 17:08:21 -0700 Subject: Added command &mux_profile. --- src/aig/gia/giaMuxes.c | 219 ++++++++++++++++++++++++++++++++++--------------- src/base/abci/abc.c | 43 ++++++++++ 2 files changed, 197 insertions(+), 65 deletions(-) diff --git a/src/aig/gia/giaMuxes.c b/src/aig/gia/giaMuxes.c index b215bac7..7834fdea 100644 --- a/src/aig/gia/giaMuxes.c +++ b/src/aig/gia/giaMuxes.c @@ -19,6 +19,8 @@ ***********************************************************************/ #include "gia.h" +#include "misc/util/utilNam.h" +#include "misc/vec/vecWec.h" ABC_NAMESPACE_IMPL_START @@ -299,27 +301,34 @@ void Gia_MuxStructPrint_rec( Gia_Man_t * p, int iObj, int fFirst ) Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); int iCtrl; if ( !fFirst && (!Gia_ObjIsMuxId(p, iObj) || Gia_ObjRefNumId(p, iObj) > 0) ) + { +// printf( "%d", iObj ); + printf( "<%02d>", Gia_ObjLevelId(p, iObj) ); return; + } iCtrl = Gia_ObjFaninId2p(p, pObj); printf( " [(" ); if ( Gia_ObjIsMuxId(p, iCtrl) && Gia_ObjRefNumId(p, iCtrl) == 0 ) Gia_MuxStructPrint_rec( p, iCtrl, 0 ); else + { printf( "%d", iCtrl ); + printf( "<%d>", Gia_ObjLevelId(p, iCtrl) ); + } printf( ")" ); if ( Gia_ObjFaninC2(p, pObj) ) { Gia_MuxStructPrint_rec( p, Gia_ObjFaninId0p(p, pObj), 0 ); printf( "|" ); Gia_MuxStructPrint_rec( p, Gia_ObjFaninId1p(p, pObj), 0 ); - printf( "] " ); + printf( "]" ); } else { Gia_MuxStructPrint_rec( p, Gia_ObjFaninId1p(p, pObj), 0 ); printf( "|" ); Gia_MuxStructPrint_rec( p, Gia_ObjFaninId0p(p, pObj), 0 ); - printf( "] " ); + printf( "]" ); } } void Gia_MuxStructPrint( Gia_Man_t * p, int iObj ) @@ -373,13 +382,13 @@ void Gia_MuxStructDump_rec( Gia_Man_t * p, int iObj, int fFirst, Vec_Str_t * vSt Vec_StrPush( vStr, ']' ); } } -void Gia_MuxStructDump( Gia_Man_t * p, int iObj, Vec_Str_t * vStr, int Num, int nDigitsNum, int nDigitsId ) +void Gia_MuxStructDump( Gia_Man_t * p, int iObj, Vec_Str_t * vStr, int nDigitsNum, int nDigitsId ) { int Count1, Count2; assert( Gia_ObjIsMuxId(p, iObj) ); Count1 = Gia_MuxDeref( p, iObj ); Vec_StrClear( vStr ); - Vec_StrPrintNumStar( vStr, Num, nDigitsNum ); + Vec_StrPrintNumStar( vStr, Count1, nDigitsNum ); Gia_MuxStructDump_rec( p, iObj, 1, vStr, nDigitsId ); Vec_StrPush( vStr, '\0' ); Count2 = Gia_MuxRef( p, iObj ); @@ -413,92 +422,172 @@ int Gia_ManMuxCountOne( char * p ) Count += (*p == '['); return Count; } -void Gia_ManMuxProfile( Vec_Ptr_t * p, Vec_Int_t * vCounts ) + +typedef struct Mux_Man_t_ Mux_Man_t; +struct Mux_Man_t_ +{ + Gia_Man_t * pGia; // manager + Abc_Nam_t * pNames; // hashing name into ID + Vec_Wec_t * vTops; // top nodes for each struct +}; + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mux_Man_t * Mux_ManAlloc( Gia_Man_t * pGia ) +{ + Mux_Man_t * p; + p = ABC_CALLOC( Mux_Man_t, 1 ); + p->pGia = pGia; + p->pNames = Abc_NamStart( 10000, 50 ); + p->vTops = Vec_WecAlloc( 1000 ); + Vec_WecPushLevel( p->vTops ); + return p; +} +void Mux_ManFree( Mux_Man_t * p ) { - int i; char * pTemp; - Vec_IntFill( vCounts, 1000, 0 ); - Vec_PtrForEachEntry( char *, p, pTemp, i ) - Vec_IntAddToEntry( vCounts, Abc_MinInt(Gia_ManMuxCountOne(pTemp), 999), 1 ); + Abc_NamStop( p->pNames ); + Vec_WecFree( p->vTops ); + ABC_FREE( p ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManMuxProfile( Mux_Man_t * p, int fWidth ) +{ + int i, Entry, Counter; + Vec_Int_t * vVec, * vCounts; + vCounts = Vec_IntStart( 1000 ); + if ( fWidth ) + { + Vec_WecForEachLevelStart( p->vTops, vVec, i, 1 ) + Vec_IntAddToEntry( vCounts, Abc_MinInt(Vec_IntSize(vVec), 999), 1 ); + printf( "The distribution of MUX tree widths:\n" ); + } + else + { + for ( i = 1; i < Vec_WecSize(p->vTops); i++ ) + Vec_IntAddToEntry( vCounts, Abc_MinInt(atoi(Abc_NamStr(p->pNames, i)), 999), 1 ); + printf( "The distribution of MUX tree sizes:\n" ); + } + Counter = 0; + Vec_IntForEachEntry( vCounts, Entry, i ) + { + if ( !Entry ) continue; + if ( ++Counter == 12 ) + printf( "\n" ), Counter = 0; + printf( " %d=%d", i, Entry ); + } + printf( "\nSummary: " ); + printf( "Max = %d ", Vec_IntFindMax(vCounts) ); + printf( "Ave = %.2f", 1.0*Vec_IntSum(vCounts)/Vec_IntCountPositive(vCounts) ); + printf( "\n" ); + Vec_IntFree( vCounts ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ void Gia_ManMuxProfiling( Gia_Man_t * p ) { + Mux_Man_t * pMan; Gia_Man_t * pNew; Gia_Obj_t * pObj; - Vec_Int_t * vFans; - Vec_Int_t * vCounts = Vec_IntAlloc( 100 ); - Vec_Ptr_t * vTrees = Vec_PtrAlloc( 1000 ); - Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); - Vec_Int_t * vDegree = Vec_IntAlloc( 1000 ); - int i, nRefs, Size, Count, Total = 0, Roots = 0; - int nDigitsId, nMemory = 0; - char * pTemp; + Vec_Str_t * vStr; + Vec_Int_t * vFans, * vVec; + int i, Counter, fFound, iStructId, nDigitsId; abctime clk = Abc_Clock(); pNew = Gia_ManDupMuxes( p, 2 ); nDigitsId = Abc_Base10Log( Gia_ManObjNum(pNew) ); + pMan = Mux_ManAlloc( pNew ); + + Gia_ManLevelNum( pNew ); Gia_ManCreateRefs( pNew ); Gia_ManForEachCo( pNew, pObj, i ) Gia_ObjRefFanin0Inc( pNew, pObj ); - Vec_IntFill( vCounts, 1000, 0 ); + vStr = Vec_StrAlloc( 1000 ); vFans = Gia_ManFirstFanouts( pNew ); Gia_ManForEachMux( pNew, pObj, i ) { - Total++; - nRefs = Gia_ObjRefNumId(pNew, i); - assert( nRefs > 0 ); - if ( nRefs > 1 || !Gia_ObjIsMuxId(pNew, Vec_IntEntry(vFans, i)) ) - { - Roots++; - Size = Gia_MuxMffcSize(pNew, i); - Vec_IntAddToEntry( vCounts, Abc_MinInt(Size, 999), 1 ); - if ( Size >= 2 ) - { - Gia_MuxStructDump( pNew, i, vStr, Size, 3, nDigitsId ); - Vec_PtrPush( vTrees, Abc_UtilStrsav(Vec_StrArray(vStr)) ); - nMemory += Vec_StrSize(vStr); - } - } + // skip MUXes in the middle of the tree (which have only one MUX fanout) + if ( Gia_ObjRefNumId(pNew, i) == 1 && Gia_ObjIsMuxId(pNew, Vec_IntEntry(vFans, i)) ) + continue; + // this node is the root of the MUX structure - create hash key + Gia_MuxStructDump( pNew, i, vStr, 3, nDigitsId ); + iStructId = Abc_NamStrFindOrAdd( pMan->pNames, Vec_StrArray(vStr), &fFound ); + if ( !fFound ) + Vec_WecPushLevel( pMan->vTops ); + assert( Abc_NamObjNumMax(pMan->pNames) == Vec_WecSize(pMan->vTops) ); + Vec_IntPush( Vec_WecEntry(pMan->vTops, iStructId), i ); } - printf( "MUXes: Total = %d. Roots = %d. Trees = %d. Memory = %.2f MB\n", Total, Roots, Vec_PtrSize(vTrees), 1.0*nMemory/(1<<20) ); - Vec_IntForEachEntry( vCounts, Count, i ) - if ( Count ) - printf( "%d=%d ", i, Count ); - printf( "\n" ); - -// Vec_PtrForEachEntryStop( char *, vTrees, pTemp, i, Abc_MinInt(Vec_PtrSize(vTrees), 40) ) -// printf( "%6d : %3d %3d %s\n", i, -1, Gia_ManMuxCountOne(pTemp), pTemp ); - - // uniqify - Vec_PtrUniqify2( vTrees, (int (*)(void))Gia_ManMuxCompare, (void (*)(void))free, vDegree ); - Gia_ManMuxProfile( vTrees, vCounts ); - - nMemory = 0; - Vec_PtrForEachEntry( char *, vTrees, pTemp, i ) - nMemory += strlen(pTemp); + Vec_StrFree( vStr ); + Vec_IntFree( vFans ); - printf( "MUXes: Trees = %d. Memory = %.2f MB\n", Vec_PtrSize(vTrees), 1.0*nMemory/(1<<20) ); - Vec_IntForEachEntry( vCounts, Count, i ) - if ( Count ) - printf( "%d=%d ", i, Count ); - printf( "\n" ); + printf( "MUX structure profile for AIG \"%s\":\n", p->pName ); + printf( "Total MUXes = %d. Total trees = %d. Unique trees = %d. Memory = %.2f MB ", + Gia_ManMuxNum(pNew), Vec_WecSizeSize(pMan->vTops), Vec_WecSize(pMan->vTops), + 1.0*Abc_NamMemUsed(pMan->pNames)/(1<<20) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); -// Vec_PtrForEachEntryStop( char *, vTrees, pTemp, i, Abc_MinInt(Vec_PtrSize(vTrees), 40) ) -// printf( "%6d : %3d %3d %s\n", i, Vec_IntEntry(vDegree, i), Gia_ManMuxCountOne(pTemp), pTemp ); + Gia_ManMuxProfile( pMan, 0 ); + Gia_ManMuxProfile( pMan, 1 ); - Vec_PtrForEachEntryStop( char *, vTrees, pTemp, i, Abc_MinInt(Vec_PtrSize(vTrees), 5000) ) - if ( Vec_IntEntry(vDegree, i) > 10 ) - printf( "%6d : %3d %3d %s\n", i, Vec_IntEntry(vDegree, i), Gia_ManMuxCountOne(pTemp), pTemp ); + // short the first ones + printf( "The first %d structures: \n", 10 ); + Vec_WecForEachLevelStartStop( pMan->vTops, vVec, i, 1, 10 ) + { + char * pTemp = Abc_NamStr(pMan->pNames, i); + printf( "%5d : ", i ); + printf( "Occur = %4d ", Vec_IntSize(vVec) ); + printf( "Size = %4d ", atoi(pTemp) ); + printf( "%s\n", pTemp ); + } - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + // print trees for the first one + Counter = 0; + Vec_WecForEachLevelStart( pMan->vTops, vVec, i, 1 ) + { + char * pTemp = Abc_NamStr(pMan->pNames, i); + if ( Vec_IntSize(vVec) > 5 && atoi(pTemp) > 5 ) + { + int k, Entry; + printf( "For example, structure %d has %d MUXes and bit-width %d:\n", i, atoi(pTemp), Vec_IntSize(vVec) ); + Vec_IntForEachEntry( vVec, Entry, k ) + Gia_MuxStructPrint( pNew, Entry ); + if ( ++Counter == 5 ) + break; + } + } - Vec_PtrFreeFree( vTrees ); - Vec_StrFree( vStr ); - Vec_IntFree( vDegree ); - Vec_IntFree( vCounts ); - Vec_IntFree( vFans ); + Mux_ManFree( pMan ); Gia_ManStop( pNew ); } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index a7e8c384..0fb1e406 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -326,6 +326,7 @@ static int Abc_CommandAbc9Ps ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9PFan ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9PSig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Status ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9MuxProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Show ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Strash ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Topand ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -905,6 +906,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&pfan", Abc_CommandAbc9PFan, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&psig", Abc_CommandAbc9PSig, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&status", Abc_CommandAbc9Status, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&mux_profile", Abc_CommandAbc9MuxProfile, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&show", Abc_CommandAbc9Show, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&st", Abc_CommandAbc9Strash, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&topand", Abc_CommandAbc9Topand, 0 ); @@ -25620,6 +25622,47 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9MuxProfile( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManMuxProfiling( Gia_Man_t * p ); + int c; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9MuxProfile(): There is no AIG.\n" ); + return 1; + } + Gia_ManMuxProfiling( pAbc->pGia ); + return 0; + +usage: + Abc_Print( -2, "usage: &mux_profile [-h]\n" ); + Abc_Print( -2, "\t profile MUXes appearing in the design\n" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] -- cgit v1.2.3