Commit b60ea3b0 by Alan Mishchenko

Experiments with mapping.

parent b46ac51a
...@@ -21,6 +21,17 @@ ...@@ -21,6 +21,17 @@
#include "gia.h" #include "gia.h"
#include "misc/vec/vecSet.h" #include "misc/vec/vecSet.h"
//#ifdef ABC_USE_PTHREADS
#ifdef _WIN32
#include "../lib/pthread.h"
#else
#include <pthread.h>
#include <unistd.h>
#endif
//#endif
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -69,6 +80,7 @@ struct Kf_Set_t_ ...@@ -69,6 +80,7 @@ struct Kf_Set_t_
Kf_Cut_t pCuts1[KF_NUM_MAX]; Kf_Cut_t pCuts1[KF_NUM_MAX];
Kf_Cut_t pCutsR[KF_NUM_MAX*KF_NUM_MAX]; Kf_Cut_t pCutsR[KF_NUM_MAX*KF_NUM_MAX];
Kf_Cut_t * ppCuts[KF_NUM_MAX]; Kf_Cut_t * ppCuts[KF_NUM_MAX];
Kf_Cut_t * pCutBest;
word CutCount[4]; // statistics word CutCount[4]; // statistics
}; };
struct Kf_Man_t_ struct Kf_Man_t_
...@@ -262,20 +274,20 @@ static inline int Kf_SetStoreAddOne( Kf_Set_t * p, int nCuts, int nCutNum, Kf_Cu ...@@ -262,20 +274,20 @@ static inline int Kf_SetStoreAddOne( Kf_Set_t * p, int nCuts, int nCutNum, Kf_Cu
break; break;
return Abc_MinInt( nCuts+1, nCutNum ); return Abc_MinInt( nCuts+1, nCutNum );
} }
static inline Kf_Cut_t * Kf_SetSelectBest( Kf_Set_t * p, int fArea, int fSort ) static inline void Kf_SetSelectBest( Kf_Set_t * p, int fArea, int fSort )
{ {
// int fArea = p->pMan->pPars->fArea; // int fArea = p->pMan->pPars->fArea;
Kf_Cut_t * pCut, * pCutBest; Kf_Cut_t * pCut;
int i, nCuts = 0; int i, nCuts = 0;
for ( i = 0; i <= p->nLutSize; i++ ) for ( i = 0; i <= p->nLutSize; i++ )
Kf_ListForEachCut( p, i, pCut ) Kf_ListForEachCut( p, i, pCut )
nCuts = Kf_SetStoreAddOne( p, nCuts, p->nCutNum-1, pCut, fArea ); nCuts = Kf_SetStoreAddOne( p, nCuts, p->nCutNum-1, pCut, fArea );
assert( nCuts > 0 && nCuts < p->nCutNum ); assert( nCuts > 0 && nCuts < p->nCutNum );
p->nCuts = nCuts; p->nCuts = nCuts;
p->pCutBest = p->ppCuts[0];
if ( !fSort ) if ( !fSort )
return p->ppCuts[0]; return;
// sort by size in the reverse order // sort by size in the reverse order
pCutBest = p->ppCuts[0];
for ( i = 0; i <= p->nLutSize; i++ ) for ( i = 0; i <= p->nLutSize; i++ )
p->pList[i] = -1; p->pList[i] = -1;
for ( i = 0; i < nCuts; i++ ) for ( i = 0; i < nCuts; i++ )
...@@ -285,7 +297,6 @@ static inline Kf_Cut_t * Kf_SetSelectBest( Kf_Set_t * p, int fArea, int fSort ) ...@@ -285,7 +297,6 @@ static inline Kf_Cut_t * Kf_SetSelectBest( Kf_Set_t * p, int fArea, int fSort )
Kf_ListForEachCut( p, i, pCut ) Kf_ListForEachCut( p, i, pCut )
p->ppCuts[p->nCuts++] = pCut; p->ppCuts[p->nCuts++] = pCut;
assert( p->nCuts == nCuts ); assert( p->nCuts == nCuts );
return pCutBest;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -414,7 +425,7 @@ static inline void Kf_SetMergePairs( Kf_Set_t * p, Kf_Cut_t * pCut0, Kf_Cut_t * ...@@ -414,7 +425,7 @@ static inline void Kf_SetMergePairs( Kf_Set_t * p, Kf_Cut_t * pCut0, Kf_Cut_t *
} }
Kf_HashCleanup( p, 0 ); Kf_HashCleanup( p, 0 );
} }
static inline Kf_Cut_t * Kf_SetMerge( Kf_Set_t * p, int * pCuts0, int * pCuts1, int fArea, int fCutMin ) static inline void Kf_SetMerge( Kf_Set_t * p, int * pCuts0, int * pCuts1, int fArea, int fCutMin )
{ {
int c0, c1; int c0, c1;
Kf_SetPrepare( p, pCuts0, pCuts1 ); Kf_SetPrepare( p, pCuts0, pCuts1 );
...@@ -429,7 +440,7 @@ static inline Kf_Cut_t * Kf_SetMerge( Kf_Set_t * p, int * pCuts0, int * pCuts1, ...@@ -429,7 +440,7 @@ static inline Kf_Cut_t * Kf_SetMerge( Kf_Set_t * p, int * pCuts0, int * pCuts1,
p->CutCount[2] += p->nCuts; p->CutCount[2] += p->nCuts;
Kf_SetFilter( p ); Kf_SetFilter( p );
p->CutCount[3] += Abc_MinInt( p->nCuts, p->nCutNum-1 ); p->CutCount[3] += Abc_MinInt( p->nCuts, p->nCutNum-1 );
return Kf_SetSelectBest( p, fArea, 1 ); Kf_SetSelectBest( p, fArea, 1 );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -586,7 +597,7 @@ int Kf_SetComputeTruth( Kf_Man_t * p, int iFuncLit0, int iFuncLit1, int * pCut0, ...@@ -586,7 +597,7 @@ int Kf_SetComputeTruth( Kf_Man_t * p, int iFuncLit0, int iFuncLit1, int * pCut0,
return Abc_Var2Lit( truthId, fCompl ); return Abc_Var2Lit( truthId, fCompl );
} }
*/ */
static inline Kf_Cut_t * Kf_SetMerge2( Kf_Set_t * p, int * pCuts0, int * pCuts1, int fArea, int fCutMin ) static inline void Kf_SetMerge2( Kf_Set_t * p, int * pCuts0, int * pCuts1, int fArea, int fCutMin )
{ {
Kf_Cut_t * pCut0, * pCut1, * pCutR; Kf_Cut_t * pCut0, * pCut1, * pCutR;
Kf_SetPrepare( p, pCuts0, pCuts1 ); Kf_SetPrepare( p, pCuts0, pCuts1 );
...@@ -622,7 +633,7 @@ static inline Kf_Cut_t * Kf_SetMerge2( Kf_Set_t * p, int * pCuts0, int * pCuts1, ...@@ -622,7 +633,7 @@ static inline Kf_Cut_t * Kf_SetMerge2( Kf_Set_t * p, int * pCuts0, int * pCuts1,
} }
Kf_SetFilter2( p ); Kf_SetFilter2( p );
p->CutCount[3] += Abc_MinInt( p->nCuts, p->nCutNum-1 ); p->CutCount[3] += Abc_MinInt( p->nCuts, p->nCutNum-1 );
return Kf_SetSelectBest( p, fArea, 1 ); Kf_SetSelectBest( p, fArea, 1 );
} }
...@@ -667,7 +678,7 @@ static inline void Kf_CutPrint( int * pCut ) ...@@ -667,7 +678,7 @@ static inline void Kf_CutPrint( int * pCut )
printf( " %d", Kf_CutLeaf(pCut, i) ); printf( " %d", Kf_CutLeaf(pCut, i) );
printf( " } Func = %d\n", Kf_CutFunc(pCut) ); printf( " } Func = %d\n", Kf_CutFunc(pCut) );
} }
static inline void Gia_CutPrintSetPrint( int * pCuts ) static inline void Gia_CutSetPrint( int * pCuts )
{ {
int i, * pCut; int i, * pCut;
Kf_ObjForEachCutInt( pCuts, pCut, i ) Kf_ObjForEachCutInt( pCuts, pCut, i )
...@@ -751,6 +762,156 @@ int Kf_ManComputeRefs( Kf_Man_t * p ) ...@@ -751,6 +762,156 @@ int Kf_ManComputeRefs( Kf_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
#define PAR_THR_MAX 100
typedef struct Kf_ThData_t_
{
Kf_Set_t * pSett;
int Id;
int Status;
} Kf_ThData_t;
void * Kf_WorkerThread( void * pArg )
{
Kf_ThData_t * pThData = (Kf_ThData_t *)pArg;
Kf_Man_t * pMan = pThData->pSett->pMan;
int fAreaOnly = pThData->pSett->pMan->pPars->fAreaOnly;
int fCutMin = pThData->pSett->pMan->pPars->fCutMin;
volatile int * pPlace = &pThData->Status;
while ( 1 )
{
while ( *pPlace == 0 );
assert( pThData->Status == 1 );
if ( pThData->Id == -1 )
{
pthread_exit( NULL );
assert( 0 );
return NULL;
}
assert( pThData->Id >= 0 );
Kf_SetMerge2( pThData->pSett, Kf_ObjCuts0(pMan, pThData->Id), Kf_ObjCuts1(pMan, pThData->Id), fAreaOnly, fCutMin );
pThData->Status = 0;
// printf( "Finished object %d\n", pThData->Id );
}
assert( 0 );
return NULL;
}
Vec_Int_t * Kf_ManCreateFaninCounts( Gia_Man_t * p )
{
Vec_Int_t * vCounts;
Gia_Obj_t * pObj; int i;
vCounts = Vec_IntAlloc( Gia_ManObjNum(p) );
Gia_ManForEachObj( p, pObj, i )
{
if ( Gia_ObjIsAnd(pObj) )
Vec_IntPush( vCounts, 2 - Gia_ObjIsCi(Gia_ObjFanin0(pObj)) - Gia_ObjIsCi(Gia_ObjFanin1(pObj)) );
else
Vec_IntPush( vCounts, 0 );
}
assert( Vec_IntSize(vCounts) == Gia_ManObjNum(p) );
return vCounts;
}
void Kf_ManComputeCuts( Kf_Man_t * p )
{
pthread_t WorkerThread[PAR_THR_MAX];
Kf_ThData_t ThData[PAR_THR_MAX];
Vec_Int_t * vStack, * vFanins;
Gia_Obj_t * pObj;
int nProcs = p->pPars->nProcNumMax;
int i, k, iFan, status, nCountFanins, fRunning;
assert( nProcs <= PAR_THR_MAX );
// start fanins
vFanins = Kf_ManCreateFaninCounts( p->pGia );
Gia_ManStaticFanoutStart( p->pGia );
// start the stack
vStack = Vec_IntAlloc( 1000 );
Gia_ManForEachObjReverse( p->pGia, pObj, k )
if ( Gia_ObjIsAnd(pObj) && Vec_IntEntry(vFanins, k) == 0 )
Vec_IntPush( vStack, k );
// start the threads
for ( i = 0; i < nProcs; i++ )
{
ThData[i].pSett = p->pSett + i;
ThData[i].Id = -1;
ThData[i].Status = 0;
status = pthread_create( WorkerThread + i, NULL, Kf_WorkerThread, (void *)(ThData + i) ); assert( status == 0 );
}
nCountFanins = Vec_IntSum(vFanins);
fRunning = 1;
while ( nCountFanins > 0 || Vec_IntSize(vStack) > 0 || fRunning )
{
for ( i = 0; i < nProcs; i++ )
{
if ( ThData[i].Status )
continue;
assert( ThData[i].Status == 0 );
if ( ThData[i].Id >= 0 )
{
int iObj = ThData[i].Id;
Kf_Set_t * pSett = p->pSett + i;
//printf( "Closing obj %d with Thread %d:\n", iObj, i );
// finalize the results
Kf_ManSaveResults( pSett->ppCuts, pSett->nCuts, pSett->pCutBest, p->vTemp );
Vec_IntWriteEntry( &p->vTime, iObj, pSett->pCutBest->Delay + 1 );
Vec_FltWriteEntry( &p->vArea, iObj, (pSett->pCutBest->Area + 1)/Kf_ObjRefs(p, iObj) );
if ( pSett->pCutBest->nLeaves > 1 )
Kf_ManStoreAddUnit( p->vTemp, iObj, Kf_ObjTime(p, iObj), Kf_ObjArea(p, iObj) );
Kf_ObjSetCuts( p, iObj, p->vTemp );
//Gia_CutSetPrint( Kf_ObjCuts(p, iObj) );
// schedule other nodes
Gia_ObjForEachFanoutStaticId( p->pGia, iObj, iFan, k )
{
if ( !Gia_ObjIsAnd(Gia_ManObj(p->pGia, iFan)) )
continue;
assert( Vec_IntEntry(vFanins, iFan) > 0 );
if ( Vec_IntAddToEntry(vFanins, iFan, -1) == 0 )
Vec_IntPush( vStack, iFan );
assert( nCountFanins > 0 );
nCountFanins--;
}
ThData[i].Id = -1;
}
if ( Vec_IntSize(vStack) > 0 )
{
ThData[i].Id = Vec_IntPop( vStack );
ThData[i].Status = 1;
//printf( "Scheduling %d for Thread %d\n", ThData[i].Id, i );
}
}
fRunning = 0;
for ( i = 0; i < nProcs; i++ )
if ( ThData[i].Status == 1 || (ThData[i].Status == 0 && ThData[i].Id >= 0) )
fRunning = 1;
// printf( "fRunning %d\n", fRunning );
}
Vec_IntForEachEntry( vFanins, iFan, k )
if ( iFan != 0 )
{
printf( "%d -> %d ", k, iFan );
Gia_ObjPrint( p->pGia, Gia_ManObj(p->pGia, k) );
}
assert( Vec_IntSum(vFanins) == 0 );
// stop the threads
for ( i = 0; i < nProcs; i++ )
{
assert( ThData[i].Status == 0 );
ThData[i].Id = -1;
ThData[i].Status = 1;
}
Gia_ManStaticFanoutStop( p->pGia );
Vec_IntFree( vStack );
Vec_IntFree( vFanins );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle ) void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle )
{ {
if ( !p->pPars->fVerbose ) if ( !p->pPars->fVerbose )
...@@ -764,8 +925,7 @@ void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle ) ...@@ -764,8 +925,7 @@ void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle )
} }
void Kf_ManComputeMapping( Kf_Man_t * p ) void Kf_ManComputeMapping( Kf_Man_t * p )
{ {
Kf_Cut_t * pCutBest; Gia_Obj_t * pObj; int i, iPi;
Gia_Obj_t * pObj; int i;
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
{ {
printf( "Aig: CI = %d CO = %d AND = %d ", Gia_ManCiNum(p->pGia), Gia_ManCoNum(p->pGia), Gia_ManAndNum(p->pGia) ); printf( "Aig: CI = %d CO = %d AND = %d ", Gia_ManCiNum(p->pGia), Gia_ManCoNum(p->pGia), Gia_ManAndNum(p->pGia) );
...@@ -773,28 +933,31 @@ void Kf_ManComputeMapping( Kf_Man_t * p ) ...@@ -773,28 +933,31 @@ void Kf_ManComputeMapping( Kf_Man_t * p )
printf( "Computing cuts...\r" ); printf( "Computing cuts...\r" );
fflush( stdout ); fflush( stdout );
} }
Gia_ManForEachObj( p->pGia, pObj, i ) Gia_ManForEachCi( p->pGia, pObj, iPi )
{
if ( Gia_ObjIsCi(pObj) )
{ {
i = Gia_ObjId(p->pGia, pObj);
Kf_ManStoreStart( p->vTemp, 0 ); Kf_ManStoreStart( p->vTemp, 0 );
Kf_ManStoreAddUnit( p->vTemp, i, 0, 0 ); Kf_ManStoreAddUnit( p->vTemp, i, 0, 0 );
assert( Vec_IntSize(p->vTemp) == 1 + KF_ADD_ON1 + KF_ADD_ON2 ); assert( Vec_IntSize(p->vTemp) == 1 + KF_ADD_ON1 + KF_ADD_ON2 );
Kf_ObjSetCuts( p, i, p->vTemp ); Kf_ObjSetCuts( p, i, p->vTemp );
} }
else if ( Gia_ObjIsAnd(pObj) ) if ( p->pPars->nProcNumMax > 0 )
Kf_ManComputeCuts( p );
else
{
Gia_ManForEachAnd( p->pGia, pObj, i )
{ {
if ( p->pPars->fCutHashing ) if ( p->pPars->fCutHashing )
pCutBest = Kf_SetMerge( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin ); Kf_SetMerge( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
else else
pCutBest = Kf_SetMerge2( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin ); Kf_SetMerge2( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
Kf_ManSaveResults( p->pSett->ppCuts, p->pSett->nCuts, pCutBest, p->vTemp ); Kf_ManSaveResults( p->pSett->ppCuts, p->pSett->nCuts, p->pSett->pCutBest, p->vTemp );
Vec_IntWriteEntry( &p->vTime, i, pCutBest->Delay + 1 ); Vec_IntWriteEntry( &p->vTime, i, p->pSett->pCutBest->Delay + 1 );
Vec_FltWriteEntry( &p->vArea, i, (pCutBest->Area + 1)/Kf_ObjRefs(p, i) ); Vec_FltWriteEntry( &p->vArea, i, (p->pSett->pCutBest->Area + 1)/Kf_ObjRefs(p, i) );
if ( pCutBest->nLeaves > 1 ) if ( p->pSett->pCutBest->nLeaves > 1 )
Kf_ManStoreAddUnit( p->vTemp, i, Kf_ObjTime(p, i), Kf_ObjArea(p, i) ); Kf_ManStoreAddUnit( p->vTemp, i, Kf_ObjTime(p, i), Kf_ObjArea(p, i) );
Kf_ObjSetCuts( p, i, p->vTemp ); Kf_ObjSetCuts( p, i, p->vTemp );
// Gia_CutPrintSetPrint( Kf_ObjCuts(p, i) ); //Gia_CutSetPrint( Kf_ObjCuts(p, i) );
} }
} }
Kf_ManComputeRefs( p ); Kf_ManComputeRefs( p );
...@@ -867,7 +1030,7 @@ Kf_Man_t * Kf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars ) ...@@ -867,7 +1030,7 @@ Kf_Man_t * Kf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars )
p->vTemp = Vec_IntAlloc( 1000 ); p->vTemp = Vec_IntAlloc( 1000 );
pGia->pRefs = ABC_CALLOC( int, Gia_ManObjNum(pGia) ); pGia->pRefs = ABC_CALLOC( int, Gia_ManObjNum(pGia) );
// prepare cut sets // prepare cut sets
for ( i = 0; i < pPars->nProcNumMax; i++ ) for ( i = 0; i < Abc_MaxInt(1, pPars->nProcNumMax); i++ )
{ {
(p->pSett + i)->pMan = p; (p->pSett + i)->pMan = p;
(p->pSett + i)->nLutSize = (unsigned short)pPars->nLutSize; (p->pSett + i)->nLutSize = (unsigned short)pPars->nLutSize;
...@@ -943,7 +1106,7 @@ void Kf_ManSetDefaultPars( Jf_Par_t * pPars ) ...@@ -943,7 +1106,7 @@ void Kf_ManSetDefaultPars( Jf_Par_t * pPars )
pPars->fVeryVerbose = 0; pPars->fVeryVerbose = 0;
pPars->nLutSizeMax = KF_LEAF_MAX; pPars->nLutSizeMax = KF_LEAF_MAX;
pPars->nCutNumMax = KF_NUM_MAX; pPars->nCutNumMax = KF_NUM_MAX;
pPars->nProcNumMax = 1; pPars->nProcNumMax = 0;
} }
Gia_Man_t * Kf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) Gia_Man_t * Kf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
{ {
......
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