Merge pull request #249 from Yu-Maryland/master

AIG augmentation
This commit is contained in:
alanminko 2023-09-16 07:08:23 +08:00 committed by GitHub
commit 2800847a16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 484 additions and 4 deletions

View File

@ -164,6 +164,7 @@ static int Abc_CommandAllExact ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandTestExact ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMajGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandOrchestrate ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAIGAugmentation ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandComb ( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -920,6 +921,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Synthesis", "faultclasses", Abc_CommandFaultClasses, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "exact", Abc_CommandExact, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "orchestrate", Abc_CommandOrchestrate, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "aigaug", Abc_CommandAIGAugmentation, 1 );
Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_start", Abc_CommandBmsStart, 0 );
Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_stop", Abc_CommandBmsStop, 0 );
@ -7540,6 +7542,171 @@ usage:
}
/**Function*************************************************************
Synopsis []
Description [AIG RTL Augmentation]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAIGAugmentation( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup;
int c, RetValue;
int nNodeSizeMax;
int nConeSizeMax;
int fUpdateLevel;
int fUseZeros_rwr;
int fUseZeros_ref;
int fUseDcs;
int fVerbose;
int RS_CUT_MIN = 4;
int RS_CUT_MAX = 16;
int fPrecompute;
int fPlaceEnable;
int nNodesMax;
int nCutsMax;
int nLevelsOdc;
int fVeryVerbose;
int Rand_Seed;
//int sOpsOrder;
size_t NtkSize;
char *DecisionFile;
//FILE *maskFile;
extern void Rwr_Precompute();
extern int Abc_NtkOrchRand( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, Vec_Int_t **DecisionMask, char *DecisionFile, int Rand_Seed, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutsMax, int nNodesMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs );
// set defaults
nNodeSizeMax = 10;
nConeSizeMax = 16;
fUpdateLevel = 1;
fUseZeros_rwr = 0;
fUseZeros_ref = 0;
fUseDcs = 0;
fVerbose = 0;
fVeryVerbose = 0;
fPlaceEnable = 0;
fPrecompute = 0;
nCutsMax = 8;
nNodesMax = 1;
nLevelsOdc = 0;
Rand_Seed = 1;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "zZdsh" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
break;
case 'z':
fUseZeros_rwr ^= 1;
break;
case 'Z':
fUseZeros_ref ^= 1;
break;
case 'd':
if ( globalUtilOptind >= argc )
{
goto usage;
}
DecisionFile = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 's':
if ( globalUtilOptind >= argc )
{
goto usage;
}
Rand_Seed = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
}
}
if ( fPrecompute )
{
Rwr_Precompute();
return 0;
}
if ( pNtk == NULL )
{
Abc_Print( -1, "Empty network.\n" );
return 1;
}
if ( nCutsMax < RS_CUT_MIN || nCutsMax > RS_CUT_MAX )
{
Abc_Print( -1, "Can only compute cuts for %d <= K <= %d.\n", RS_CUT_MIN, RS_CUT_MAX );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
Abc_Print( -1, "This command can only be applied to an AIG (run \"strash\").\n" );
return 1;
}
if ( Abc_NtkGetChoiceNum(pNtk) )
{
Abc_Print( -1, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" );
return 1;
}
if ( nNodeSizeMax > 15 )
{
Abc_Print( -1, "The cone size cannot exceed 15.\n" );
return 1;
}
if ( fUseDcs && nNodeSizeMax >= nConeSizeMax )
{
Abc_Print( -1, "For don't-care to work, containing cone should be larger than collapsed node.\n" );
return 1;
}
NtkSize = Abc_NtkObjNumMax(pNtk);
Vec_Int_t *DecisionMask = Vec_IntAlloc(1);
for (int i=0; i<NtkSize;i++){
Vec_IntPush(DecisionMask, atoi("-1"));}
Vec_Int_t *pGain_rwr;
Vec_Int_t *pGain_res;
Vec_Int_t *pGain_ref;
// modify the current network
pDup = Abc_NtkDup( pNtk );
RetValue = Abc_NtkOrchRand( pNtk, &pGain_rwr, &pGain_res, &pGain_ref, &DecisionMask, DecisionFile, Rand_Seed, fUseZeros_rwr, fUseZeros_ref, fPlaceEnable, nCutsMax, nNodesMax, nLevelsOdc, fUpdateLevel, fVerbose, fVeryVerbose, nNodeSizeMax, nConeSizeMax, fUseDcs );
//printf("Vector check: %d %d\n", DecisionList->nSize, DecisionList->pArray[0]);
if ( RetValue == -1 )
{
Abc_FrameReplaceCurrentNetwork( pAbc, pDup );
printf( "An error occurred during computation. The original network is restored.\n" );
}
else
{
Abc_NtkDelete( pDup );
if ( RetValue == 0 )
{
Abc_Print( 0, "Orchestration evaluation for RL has failed.\n" );
return 1;
}
}
// Vec_IntPrint(pGain_rwr);
return 0;
usage:
Abc_Print( -2, "usage: aigaug [-s <num>] [-d <file>][-zZdsh]\n" );
Abc_Print( -2, "\t performs technology-independent AIG random synthesis (node level) for RTL augmentation\n" );
Abc_Print( -2, "\t-z : toggle using zero-cost replacements for rwr for aigaug [default = %s]\n", fUseZeros_rwr? "yes": "no" );
Abc_Print( -2, "\t-Z : toggle using zero-cost replacements for ref for aigaug [default = %s]\n", fUseZeros_ref? "yes": "no" );
Abc_Print( -2, "\t-d : record random synthesis decision made during augmentation [required filename; e.g., test.csv]\n");
Abc_Print( -2, "\t-s : set the random seed for random augmentation\n");
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\tExample : read i10.aig;st;aigaug -s 1 -d test.csv;write i10_arg_1.aig;cec i10.aig i10_arg_1.aig\n");
return 1;
}

View File

@ -198,7 +198,7 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk );
pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk);
nNodes = Abc_NtkObjNumMax(pNtk);
printf("nNodes: %d\n", nNodes);
//printf("nNodes: %d\n", nNodes);
if ( pGain_rw ) *pGain_rw = Vec_IntAlloc(1);
pProgress = Extra_ProgressBarStart( stdout, nNodes );
@ -489,7 +489,7 @@ int Abc_NtkRefactor3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_ref, int nNodeSizeMax,
Abc_NtkStartReverseLevels( pNtk, 0 );
pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk);
nNodes = Abc_NtkObjNumMax(pNtk);
printf("nNodes: %d\n", nNodes);
//printf("nNodes: %d\n", nNodes);
if (pGain_ref) *pGain_ref = Vec_IntAlloc(1);
pProgress = Extra_ProgressBarStart( stdout, nNodes );
@ -605,7 +605,7 @@ int Abc_NtkResubstitute3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_res, int nCutMax,
// resynthesize each node once
pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk);
nNodes = Abc_NtkObjNumMax(pNtk);
printf("nNodes: %d\n", nNodes);
//printf("nNodes: %d\n", nNodes);
if (pGain_res) *pGain_res = Vec_IntAlloc(1);
pProgress = Extra_ProgressBarStart( stdout, nNodes );
@ -2732,7 +2732,7 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk );
pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk);
nNodes = Abc_NtkObjNumMax(pNtk);
printf("nNodes: %d\n", nNodes);
//printf("nNodes: %d\n", nNodes);
if (pGain_res) *pGain_res = Vec_IntAlloc(1);
if (pGain_ref) *pGain_ref = Vec_IntAlloc(1);
if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1);
@ -5318,6 +5318,319 @@ s_ResubTime = Abc_Clock() - clkStart;
return 1;
}
// orchestration with sudo random decision list
int Abc_NtkOrchRand( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, Vec_Int_t **DecisionMask, char * DecisionFile, int Rand_Seed, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs )
{
extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
ProgressBar * pProgress;
// For resub
Abc_ManRes_t * pManRes;
Abc_ManCut_t * pManCutRes;
Odc_Man_t * pManOdc = NULL;
Dec_Graph_t * pFFormRes;
Vec_Ptr_t * vLeaves;
// For rewrite
Cut_Man_t * pManCutRwr;
Rwr_Man_t * pManRwr;
Dec_Graph_t * pGraph;
// For refactor
Abc_ManRef_t * pManRef;
Abc_ManCut_t * pManCutRef;
Dec_Graph_t * pFFormRef;
Vec_Ptr_t * vFanins;
Abc_Obj_t * pNode;
FILE *fpt;
abctime clk, clkStart = Abc_Clock();
int i, nNodes, nNodes_after, nGain, fCompl;
int RetValue = 1;
int ops_rwr = 0;
int ops_res = 0;
int ops_ref = 0;
int ops_null = 0;
int Valid_Len = 0;
//Vec_Int_t *Valid_Ops;
//clock_t begin= clock();
assert( Abc_NtkIsStrash(pNtk) );
// cleanup the AIG
Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc);
// start the managers resub
pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 );
pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX );
if ( nLevelsOdc > 0 )
pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose );
// start the managers refactor
pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 );
pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose );
pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef );
// start the managers rewrite
pManRwr = Rwr_ManStart( 0 );
if ( pManRwr == NULL )
return 0;
// compute the reverse levels if level update is requested
if ( fUpdateLevel )
Abc_NtkStartReverseLevels( pNtk, 0 );
// 'Resub only'
if ( Abc_NtkLatchNum(pNtk) ) {
Abc_NtkForEachLatch(pNtk, pNode, i)
pNode->pNext = (Abc_Obj_t *)pNode->pData;
}
// cut manager for rewrite
clk = Abc_Clock();
pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk );
Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk );
pNtk->pManCut = pManCutRwr;
if ( fVeryVerbose )
Rwr_ScoresClean( pManRwr );
// resynthesize each node once
// resub
pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk);
// rewrite
pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk);
// refactor
pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk);
//clock_t resyn_end=clock();
//double resyn_time_spent = (double)(resyn_end-begin)/CLOCKS_PER_SEC;
//printf("time %f\n", resyn_time_spent);
nNodes = Abc_NtkObjNumMax(pNtk);
//printf("nNodes: %d\n", nNodes);
//for(int i=0; i < nNodes; i++){printf("mask check: %d\n", (*DecisionMask)->pArray[i]);}
//printf("mask size:%d", (**DecisionMask).nSize);
if (pGain_res) *pGain_res = Vec_IntAlloc(1);
if (pGain_ref) *pGain_ref = Vec_IntAlloc(1);
if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1);
Vec_Int_t *Valid_Ops = Vec_IntAlloc(1);
pProgress = Extra_ProgressBarStart( stdout, nNodes );
fpt = fopen(DecisionFile, "w");
Abc_NtkForEachNode( pNtk, pNode, i )
{
//printf("Ochestration id: %d\n", pNode->Id);
int iterNode = pNode->Id;
Extra_ProgressBarUpdate( pProgress, i, NULL );
// skip the constant node
// if ( Abc_NodeIsConst(pNode) )
// continue;
// stop if all nodes have been tried once
if ( i >= nNodes )
break;
// skip persistant nodes
if ( Abc_NodeIsPersistant(pNode) )
{
//fprintf(fpt, "%d, %s, %d\n", pNode->Id, "None" , -99);
Vec_IntPush((*pGain_res), -99);
Vec_IntPush((*pGain_ref), -99);
Vec_IntPush((*pGain_rwr), -99);
continue;
}
// skip the nodes with many fanouts
if ( Abc_ObjFanoutNum(pNode) > 1000 )
{
//fprintf(fpt, "%d, %s, %d\n", pNode->Id,"None", -99);
Vec_IntPush((*pGain_res), -99);
Vec_IntPush((*pGain_ref), -99);
Vec_IntPush((*pGain_rwr), -99);
continue;
}
clk = Abc_Clock();
// Generate random operation
// check transformability of all three operations
Vec_IntPush( (Valid_Ops), -1);
nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable );
Vec_IntPush( (*pGain_rwr), nGain);
if (nGain > 0 || (nGain == 0 && fUseZeros_rwr))
{
Vec_IntPush( (Valid_Ops), 0);
}
vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 );
pManRes->timeCut += Abc_Clock() - clk;
if ( pManOdc )
{
clk = Abc_Clock();
Abc_NtkDontCareClear( pManOdc );
Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet );
pManRes->timeTruth += Abc_Clock() - clk;
}
clk = Abc_Clock();
pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose );
pManRes->timeRes += Abc_Clock() - clk;
Vec_IntPush((*pGain_res), pManRes->nLastGain);
if (pManRes->nLastGain > 0)
{
if ( pFFormRes != NULL ){
Vec_IntPush( (Valid_Ops), 1);
}
}
vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs );
pManRef->timeCut += Abc_Clock() - clk;
clk = Abc_Clock();
pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose );
pManRef->timeRes += Abc_Clock() - clk;
Vec_IntPush((*pGain_ref), pManRef->nLastGain);
if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref))
{
if ( pFFormRef != NULL ){
Vec_IntPush( (Valid_Ops), 2);
}
}
Valid_Len = (Valid_Ops)->nSize;
//printf("The length of valid operations: %d\n", Valid_Len);
//Pick a random operations from valid ones
if (Rand_Seed == -1)
{
srand(time(NULL));
}
else
{
srand(Rand_Seed);
}
int r = rand() % Valid_Len;
if ((Valid_Ops)->pArray[r] == -1){
(*DecisionMask)->pArray[iterNode] = -1;
ops_null++;
Vec_IntZero(Valid_Ops); // reset updates
continue;
}
else if ((Valid_Ops->pArray[r]) == 0){
// apply rewrite
pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr);
fCompl = Rwr_ManReadCompl(pManRwr);
if ( fPlaceEnable )
Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc );
if ( fCompl ) Dec_GraphComplement( pGraph );
clk = Abc_Clock();
Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk );
if ( fCompl ) Dec_GraphComplement( pGraph );
(*DecisionMask)->pArray[iterNode] = 0;
ops_rwr++;
Vec_IntZero(Valid_Ops); // reset updates
continue;
}
else if ((Valid_Ops->pArray[r] == 1)){
// apply res
pManRes->nTotalGain += pManRes->nLastGain;
clk = Abc_Clock();
Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain );
pManRes->timeNtk += Abc_Clock() - clk;
Dec_GraphFree( pFFormRes );
(*DecisionMask)->pArray[iterNode] = 1;
ops_res++;
Vec_IntZero(Valid_Ops); // reset updates
continue;
}
else if ((Valid_Ops->pArray[r] == 2)){
clk = Abc_Clock();
if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) )
{
Dec_GraphFree( pFFormRef );
RetValue = -1;
break;
}
pManRef->timeNtk += Abc_Clock() - clk;
Dec_GraphFree( pFFormRef );
(*DecisionMask)->pArray[iterNode] = 2;
ops_ref++;
Vec_IntZero(Valid_Ops); // reset updates
continue;
}
}
//fwrite((**DecisionMask).pArray, sizeof(int), sizeof((**DecisionMask).pArray), fpt);
for (int i = 0; i < (nNodes); i++){
fprintf(fpt, "%d\n", (*DecisionMask)->pArray[i]);}
fclose(fpt);
/*
printf("size of vector %d\n", Valid_Len);
printf("Nodes with rewrite: %d\n", ops_rwr);
printf("Nodes with resub: %d\n", ops_res);
printf("Nodes with refactor: %d\n", ops_ref);
printf("Nodes without updates: %d\n", ops_null);
*/
Extra_ProgressBarStop( pProgress );
// Rewrite
Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart );
pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk);
// Resub
pManRes->timeTotal = Abc_Clock() - clkStart;
pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk);
// Refactor
pManRef->timeTotal = Abc_Clock() - clkStart;
pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk);
// print statistics
if ( fVerbose ){
Abc_ManResubPrint( pManRes );
Rwr_ManPrintStats( pManRwr );
Abc_NtkManRefPrintStats_1( pManRef );
}
if ( fVeryVerbose )
Rwr_ScoresReport( pManRwr );
// delete the managers
// resub
Abc_ManResubStop( pManRes );
Abc_NtkManCutStop( pManCutRes );
// rewrite
Rwr_ManStop( pManRwr );
Cut_ManStop( pManCutRwr );
pNtk->pManCut = NULL;
// refactor
Abc_NtkManCutStop( pManCutRef );
Abc_NtkManRefStop_1( pManRef );
if ( pManOdc ) Abc_NtkDontCareFree( pManOdc );
// clean the data field
Abc_NtkForEachObj( pNtk, pNode, i )
pNode->pData = NULL;
if ( Abc_NtkLatchNum(pNtk) ) {
Abc_NtkForEachLatch(pNtk, pNode, i)
pNode->pData = pNode->pNext, pNode->pNext = NULL;
}
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
// fix the levels
if ( fUpdateLevel )
Abc_NtkStopReverseLevels( pNtk );
else
Abc_NtkLevel( pNtk );
// check
if ( !Abc_NtkCheck( pNtk ) )
{
printf( "Abc_NtkOchestraction: The network check has failed.\n" );
return 0;
}
nNodes_after = Abc_NtkObjNumMax(pNtk);
//printf("nNodes after optimization: %d\n", nNodes_after);
//s_ResubTime = Abc_Clock() - clkStart;
//clock_t end=clock();
//double time_spent = (double)(end-begin)/CLOCKS_PER_SEC;
//printf("time %f\n", time_spent);
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///