Commit f93e5244 by Alan Mishchenko

Added command &mux_profile.

parent 13dd4eeb
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
***********************************************************************/ ***********************************************************************/
#include "gia.h" #include "gia.h"
#include "misc/util/utilNam.h"
#include "misc/vec/vecWec.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
...@@ -299,27 +301,34 @@ void Gia_MuxStructPrint_rec( Gia_Man_t * p, int iObj, int fFirst ) ...@@ -299,27 +301,34 @@ void Gia_MuxStructPrint_rec( Gia_Man_t * p, int iObj, int fFirst )
Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
int iCtrl; int iCtrl;
if ( !fFirst && (!Gia_ObjIsMuxId(p, iObj) || Gia_ObjRefNumId(p, iObj) > 0) ) if ( !fFirst && (!Gia_ObjIsMuxId(p, iObj) || Gia_ObjRefNumId(p, iObj) > 0) )
{
// printf( "%d", iObj );
printf( "<%02d>", Gia_ObjLevelId(p, iObj) );
return; return;
}
iCtrl = Gia_ObjFaninId2p(p, pObj); iCtrl = Gia_ObjFaninId2p(p, pObj);
printf( " [(" ); printf( " [(" );
if ( Gia_ObjIsMuxId(p, iCtrl) && Gia_ObjRefNumId(p, iCtrl) == 0 ) if ( Gia_ObjIsMuxId(p, iCtrl) && Gia_ObjRefNumId(p, iCtrl) == 0 )
Gia_MuxStructPrint_rec( p, iCtrl, 0 ); Gia_MuxStructPrint_rec( p, iCtrl, 0 );
else else
{
printf( "%d", iCtrl ); printf( "%d", iCtrl );
printf( "<%d>", Gia_ObjLevelId(p, iCtrl) );
}
printf( ")" ); printf( ")" );
if ( Gia_ObjFaninC2(p, pObj) ) if ( Gia_ObjFaninC2(p, pObj) )
{ {
Gia_MuxStructPrint_rec( p, Gia_ObjFaninId0p(p, pObj), 0 ); Gia_MuxStructPrint_rec( p, Gia_ObjFaninId0p(p, pObj), 0 );
printf( "|" ); printf( "|" );
Gia_MuxStructPrint_rec( p, Gia_ObjFaninId1p(p, pObj), 0 ); Gia_MuxStructPrint_rec( p, Gia_ObjFaninId1p(p, pObj), 0 );
printf( "] " ); printf( "]" );
} }
else else
{ {
Gia_MuxStructPrint_rec( p, Gia_ObjFaninId1p(p, pObj), 0 ); Gia_MuxStructPrint_rec( p, Gia_ObjFaninId1p(p, pObj), 0 );
printf( "|" ); printf( "|" );
Gia_MuxStructPrint_rec( p, Gia_ObjFaninId0p(p, pObj), 0 ); Gia_MuxStructPrint_rec( p, Gia_ObjFaninId0p(p, pObj), 0 );
printf( "] " ); printf( "]" );
} }
} }
void Gia_MuxStructPrint( Gia_Man_t * p, int iObj ) 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 ...@@ -373,13 +382,13 @@ void Gia_MuxStructDump_rec( Gia_Man_t * p, int iObj, int fFirst, Vec_Str_t * vSt
Vec_StrPush( vStr, ']' ); 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; int Count1, Count2;
assert( Gia_ObjIsMuxId(p, iObj) ); assert( Gia_ObjIsMuxId(p, iObj) );
Count1 = Gia_MuxDeref( p, iObj ); Count1 = Gia_MuxDeref( p, iObj );
Vec_StrClear( vStr ); Vec_StrClear( vStr );
Vec_StrPrintNumStar( vStr, Num, nDigitsNum ); Vec_StrPrintNumStar( vStr, Count1, nDigitsNum );
Gia_MuxStructDump_rec( p, iObj, 1, vStr, nDigitsId ); Gia_MuxStructDump_rec( p, iObj, 1, vStr, nDigitsId );
Vec_StrPush( vStr, '\0' ); Vec_StrPush( vStr, '\0' );
Count2 = Gia_MuxRef( p, iObj ); Count2 = Gia_MuxRef( p, iObj );
...@@ -413,92 +422,172 @@ int Gia_ManMuxCountOne( char * p ) ...@@ -413,92 +422,172 @@ int Gia_ManMuxCountOne( char * p )
Count += (*p == '['); Count += (*p == '[');
return Count; 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; Abc_NamStop( p->pNames );
Vec_IntFill( vCounts, 1000, 0 ); Vec_WecFree( p->vTops );
Vec_PtrForEachEntry( char *, p, pTemp, i ) ABC_FREE( p );
Vec_IntAddToEntry( vCounts, Abc_MinInt(Gia_ManMuxCountOne(pTemp), 999), 1 );
} }
/**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 ) void Gia_ManMuxProfiling( Gia_Man_t * p )
{ {
Mux_Man_t * pMan;
Gia_Man_t * pNew; Gia_Man_t * pNew;
Gia_Obj_t * pObj; Gia_Obj_t * pObj;
Vec_Int_t * vFans; Vec_Str_t * vStr;
Vec_Int_t * vCounts = Vec_IntAlloc( 100 ); Vec_Int_t * vFans, * vVec;
Vec_Ptr_t * vTrees = Vec_PtrAlloc( 1000 ); int i, Counter, fFound, iStructId, nDigitsId;
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;
abctime clk = Abc_Clock(); abctime clk = Abc_Clock();
pNew = Gia_ManDupMuxes( p, 2 ); pNew = Gia_ManDupMuxes( p, 2 );
nDigitsId = Abc_Base10Log( Gia_ManObjNum(pNew) ); nDigitsId = Abc_Base10Log( Gia_ManObjNum(pNew) );
pMan = Mux_ManAlloc( pNew );
Gia_ManLevelNum( pNew );
Gia_ManCreateRefs( pNew ); Gia_ManCreateRefs( pNew );
Gia_ManForEachCo( pNew, pObj, i ) Gia_ManForEachCo( pNew, pObj, i )
Gia_ObjRefFanin0Inc( pNew, pObj ); Gia_ObjRefFanin0Inc( pNew, pObj );
Vec_IntFill( vCounts, 1000, 0 ); vStr = Vec_StrAlloc( 1000 );
vFans = Gia_ManFirstFanouts( pNew ); vFans = Gia_ManFirstFanouts( pNew );
Gia_ManForEachMux( pNew, pObj, i ) Gia_ManForEachMux( pNew, pObj, i )
{ {
Total++; // skip MUXes in the middle of the tree (which have only one MUX fanout)
nRefs = Gia_ObjRefNumId(pNew, i); if ( Gia_ObjRefNumId(pNew, i) == 1 && Gia_ObjIsMuxId(pNew, Vec_IntEntry(vFans, i)) )
assert( nRefs > 0 ); continue;
if ( nRefs > 1 || !Gia_ObjIsMuxId(pNew, Vec_IntEntry(vFans, i)) ) // this node is the root of the MUX structure - create hash key
{ Gia_MuxStructDump( pNew, i, vStr, 3, nDigitsId );
Roots++; iStructId = Abc_NamStrFindOrAdd( pMan->pNames, Vec_StrArray(vStr), &fFound );
Size = Gia_MuxMffcSize(pNew, i); if ( !fFound )
Vec_IntAddToEntry( vCounts, Abc_MinInt(Size, 999), 1 ); Vec_WecPushLevel( pMan->vTops );
if ( Size >= 2 ) assert( Abc_NamObjNumMax(pMan->pNames) == Vec_WecSize(pMan->vTops) );
{ Vec_IntPush( Vec_WecEntry(pMan->vTops, iStructId), i );
Gia_MuxStructDump( pNew, i, vStr, Size, 3, nDigitsId );
Vec_PtrPush( vTrees, Abc_UtilStrsav(Vec_StrArray(vStr)) );
nMemory += Vec_StrSize(vStr);
}
}
} }
printf( "MUXes: Total = %d. Roots = %d. Trees = %d. Memory = %.2f MB\n", Total, Roots, Vec_PtrSize(vTrees), 1.0*nMemory/(1<<20) ); Vec_StrFree( vStr );
Vec_IntForEachEntry( vCounts, Count, i ) Vec_IntFree( vFans );
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);
printf( "MUXes: Trees = %d. Memory = %.2f MB\n", Vec_PtrSize(vTrees), 1.0*nMemory/(1<<20) ); printf( "MUX structure profile for AIG \"%s\":\n", p->pName );
Vec_IntForEachEntry( vCounts, Count, i ) printf( "Total MUXes = %d. Total trees = %d. Unique trees = %d. Memory = %.2f MB ",
if ( Count ) Gia_ManMuxNum(pNew), Vec_WecSizeSize(pMan->vTops), Vec_WecSize(pMan->vTops),
printf( "%d=%d ", i, Count ); 1.0*Abc_NamMemUsed(pMan->pNames)/(1<<20) );
printf( "\n" ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
// Vec_PtrForEachEntryStop( char *, vTrees, pTemp, i, Abc_MinInt(Vec_PtrSize(vTrees), 40) ) Gia_ManMuxProfile( pMan, 0 );
// printf( "%6d : %3d %3d %s\n", i, Vec_IntEntry(vDegree, i), Gia_ManMuxCountOne(pTemp), pTemp ); Gia_ManMuxProfile( pMan, 1 );
Vec_PtrForEachEntryStop( char *, vTrees, pTemp, i, Abc_MinInt(Vec_PtrSize(vTrees), 5000) ) // short the first ones
if ( Vec_IntEntry(vDegree, i) > 10 ) printf( "The first %d structures: \n", 10 );
printf( "%6d : %3d %3d %s\n", i, Vec_IntEntry(vDegree, i), Gia_ManMuxCountOne(pTemp), pTemp ); 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 ); Mux_ManFree( pMan );
Vec_StrFree( vStr );
Vec_IntFree( vDegree );
Vec_IntFree( vCounts );
Vec_IntFree( vFans );
Gia_ManStop( pNew ); Gia_ManStop( pNew );
} }
......
...@@ -326,6 +326,7 @@ static int Abc_CommandAbc9Ps ( Abc_Frame_t * pAbc, int argc, cha ...@@ -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_CommandAbc9PFan ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9PSig ( 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_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_CommandAbc9Show ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Strash ( 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 ); static int Abc_CommandAbc9Topand ( Abc_Frame_t * pAbc, int argc, char ** argv );
...@@ -905,6 +906,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) ...@@ -905,6 +906,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&pfan", Abc_CommandAbc9PFan, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&pfan", Abc_CommandAbc9PFan, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&psig", Abc_CommandAbc9PSig, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&psig", Abc_CommandAbc9PSig, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&status", Abc_CommandAbc9Status, 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", "&show", Abc_CommandAbc9Show, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&st", Abc_CommandAbc9Strash, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&st", Abc_CommandAbc9Strash, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&topand", Abc_CommandAbc9Topand, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&topand", Abc_CommandAbc9Topand, 0 );
...@@ -25631,6 +25633,47 @@ usage: ...@@ -25631,6 +25633,47 @@ usage:
SeeAlso [] 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 []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
Aig_Man_t * pMan; Aig_Man_t * pMan;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment