diff --git a/src/map/if/if.h b/src/map/if/if.h index 952359ced..e638b80da 100644 --- a/src/map/if/if.h +++ b/src/map/if/if.h @@ -285,6 +285,8 @@ struct If_Man_t_ int pDumpIns[16]; Vec_Str_t * vMarks; Vec_Int_t * vVisited2; + Vec_Int_t * vCuts; + Vec_Int_t * vCutCosts; // timing manager Tim_Man_t * pManTim; diff --git a/src/map/if/ifCore.c b/src/map/if/ifCore.c index eed6a55e8..58649b720 100644 --- a/src/map/if/ifCore.c +++ b/src/map/if/ifCore.c @@ -154,6 +154,10 @@ int If_ManPerformMappingComb( If_Man_t * p ) // area oriented mapping for ( i = 0; i < p->pPars->nAreaIters; i++ ) { + if ( p->pPars->fDumpFile && p->pPars->nLutSize <= 6 && i == p->pPars->nAreaIters-1 ) { + p->vCuts = Vec_IntAlloc( 1 << 20 ); + p->vCutCosts = Vec_IntAlloc( 1 << 16 ); + } If_ManPerformMappingRound( p, p->pPars->nCutsMax, 2, 0, 0, "Area" ); if ( p->pPars->fExpRed ) If_ManImproveMapping( p ); diff --git a/src/map/if/ifMan.c b/src/map/if/ifMan.c index 32dd124d4..a2fbf63d4 100644 --- a/src/map/if/ifMan.c +++ b/src/map/if/ifMan.c @@ -199,6 +199,121 @@ void If_ManRestart( If_Man_t * p ) p->nObjs[IF_CI] = p->nObjs[IF_CO] = p->nObjs[IF_AND] = 0; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void If_ManSimpleSort( int * pArray, int nSize ) +{ + int temp, i, j, best_i; + for ( i = 0; i < nSize-1; i++ ) { + best_i = i; + for ( j = i+1; j < nSize; j++ ) + if ( pArray[j] < pArray[best_i] ) + best_i = j; + temp = pArray[i]; + pArray[i] = pArray[best_i]; + pArray[best_i] = temp; + } +} +void If_ManDumpCut( If_Cut_t * pCut, int nLutSize, Vec_Int_t * vCuts ) +{ + int i; + for ( i = 0; i < pCut->nLeaves; i++ ) + Vec_IntPush( vCuts, pCut->pLeaves[i] ); + for ( ; i < nLutSize; i++ ) + Vec_IntPush( vCuts, 0 ); +} +void If_ManDumpCutsAndCost( If_Man_t * p, If_Obj_t * pObj, Vec_Int_t * vCuts, Vec_Int_t * vCutCosts ) +{ + If_Cut_t * pCut; int k, nCuts = 0; + while ( nCuts < p->pPars->nCutsMax ) { + If_ObjForEachCut( pObj, pCut, k ) { + If_ManDumpCut( pCut, p->pPars->nLutSize, vCuts ); + Vec_IntPush( vCutCosts, (int)pCut->Area ); + if ( ++nCuts == p->pPars->nCutsMax ) + break; + } + } +} +void If_ManDumpCutsAndCostAdd( int Obj, int nCutsMax, int nLutSize, Vec_Int_t * vCopy, Vec_Int_t * vCuts, Vec_Int_t * vCutCosts, Vec_Int_t * vCutsOut, Vec_Int_t * vCutCostsOut ) +{ + int i, * pCuts = Vec_IntEntryP( vCuts, Obj * nCutsMax * nLutSize ); + for ( i = 0; i < nCutsMax * nLutSize; i++ ) + pCuts[i] = Vec_IntEntry(vCopy, pCuts[i]); + for ( i = 0; i < nCutsMax; i++ ) + If_ManSimpleSort( pCuts + i*nLutSize, nLutSize ); + for ( i = 0; i < nCutsMax * nLutSize; i++ ) + Vec_IntPush( vCutsOut, pCuts[i] ); + for ( i = 0; i < nCutsMax; i++ ) + Vec_IntPush( vCutCostsOut, Vec_IntEntry( vCutCosts, Obj * nCutsMax + i ) ); +} +int If_ManDumpData( If_Man_t * p, FILE * pFile ) +{ + Vec_Int_t * vCopy = Vec_IntStartFull( If_ManObjNum(p) ); + Vec_Int_t * vCopy2 = Vec_IntAlloc( If_ManObjNum(p) ); + Vec_Int_t * vLevelLims = Vec_IntAlloc( p->nLevelMax + 1 ); + Vec_Int_t * vCuts = Vec_IntAlloc( 1 << 20 ); + Vec_Int_t * vFanins = Vec_IntAlloc( If_ManCoNum(p) ); + Vec_Int_t * vCutCosts = Vec_IntAlloc( 1 << 16 ); + Vec_Int_t * vLevel; If_Obj_t * pObj; + int i, k, Obj, nObjs = 0, nBytes = 0; + Vec_Wec_t * vLevels = Vec_WecStart( p->nLevelMax ); + If_ManForEachNode( p, pObj, i ) + Vec_WecPush( vLevels, pObj->Level, i ); + Vec_IntWriteEntry( vCopy, 0, nObjs++ ); + If_ManForEachCi( p, pObj, i ) + Vec_IntWriteEntry( vCopy, pObj->Id, nObjs++ ); + Vec_WecForEachLevelStart( vLevels, vLevel, i, 1 ) + Vec_IntForEachEntry( vLevel, Obj, k ) { + Vec_IntWriteEntry( vCopy, Obj, nObjs++ ); + Vec_IntPush( vCopy2, Obj - 1 - If_ManCiNum(p) ); + } + assert( Vec_IntSize(vCopy2) == If_ManAndNum(p) ); + assert( nObjs == 1 + If_ManCiNum(p) + If_ManAndNum(p) ); + nObjs = If_ManCiNum(p) + 1; + Vec_WecForEachLevelStart( vLevels, vLevel, i, 1 ) { + Vec_IntPush( vLevelLims, nObjs ); + nObjs += Vec_IntSize(vLevel); + } + Vec_IntPush( vLevelLims, nObjs ); + assert( Vec_IntSize(vLevelLims) == p->nLevelMax + 1 ); + Vec_IntForEachEntry( vCopy2, Obj, i ) + If_ManDumpCutsAndCostAdd( Obj, p->pPars->nCutsMax, p->pPars->nLutSize, vCopy, p->vCuts, p->vCutCosts, vCuts, vCutCosts ); + assert( Vec_IntSize(vCuts) == If_ManAndNum(p) * p->pPars->nCutsMax * p->pPars->nLutSize ); + assert( Vec_IntSize(vCutCosts) == If_ManAndNum(p) * p->pPars->nCutsMax ); + If_ManForEachCo( p, pObj, i ) + Vec_IntPush( vFanins, Vec_IntEntry(vCopy, pObj->pFanin0->Id) ); + nBytes += fwrite( Vec_IntArray(vCuts), 1, sizeof(int)*Vec_IntSize(vCuts), pFile ); + nBytes += fwrite( Vec_IntArray(vFanins), 1, sizeof(int)*Vec_IntSize(vFanins), pFile ); + nBytes += fwrite( Vec_IntArray(vLevelLims), 1, sizeof(int)*Vec_IntSize(vLevelLims), pFile ); + nBytes += fwrite( Vec_IntArray(vCutCosts), 1, sizeof(int)*Vec_IntSize(vCutCosts), pFile ); + if ( 0 ) { + Vec_WecPrint( vLevels, 0 ); + Vec_IntPrint( vCopy ); + Vec_IntPrint( vCopy2 ); + Vec_IntPrint( vLevelLims ); + Vec_IntPrint( vCuts ); + Vec_IntPrint( vFanins ); + Vec_IntPrint( vCutCosts ); + } + Vec_WecFree( vLevels ); + Vec_IntFree( vCopy ); + Vec_IntFree( vCopy2 ); + Vec_IntFree( vLevelLims ); + Vec_IntFree( vCuts ); + Vec_IntFree( vFanins ); + Vec_IntFree( vCutCosts ); + return nBytes; +} + /**Function************************************************************* Synopsis [] @@ -212,7 +327,26 @@ void If_ManRestart( If_Man_t * p ) ***********************************************************************/ void If_ManStop( If_Man_t * p ) { - if ( p->pPars->fDumpFile && p->pPars->fTruth ) + if ( p->pPars->fDumpFile && p->pPars->nLutSize <= 6 ) + { + char pFileName[1000] = {0}; + // "I15_O20_L32_N256_C16_K6__name.bin" + char * pName = Extra_FileNameGeneric(Extra_FileNameWithoutPath(p->pName)); + sprintf( pFileName, "I%d_O%d_L%d_N%d_C%d_K%d__%s.bin", If_ManCiNum(p), If_ManCoNum(p), p->nLevelMax, If_ManAndNum(p), p->pPars->nCutsMax, p->pPars->nLutSize, pName ); + ABC_FREE( pName ); + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + else { + int nBytes = If_ManDumpData( p, pFile ); + int nBytes2 = sizeof(int) * (If_ManAndNum(p) * p->pPars->nCutsMax * p->pPars->nLutSize + If_ManCoNum(p) + p->nLevelMax + 1); + nBytes2 += sizeof(int) * (If_ManAndNum(p) * p->pPars->nCutsMax); + assert( nBytes == nBytes2 ); + fclose( pFile ); + printf( "Finished writing cut information into file \"%s\" (%.3f MB).\n", pFileName, 1.0 * nBytes / (1<<20) ); + } + } + else if ( p->pPars->fDumpFile && p->pPars->fTruth ) { char pFileName[1000] = {0}, pBuffer[100]; int nUnique = 0, nChunks = 0, nChunkSize = 1 << 10, nBytes = 0; @@ -314,6 +448,8 @@ void If_ManStop( If_Man_t * p ) Vec_PtrFreeP( &p->vVisited ); Vec_StrFreeP( &p->vMarks ); Vec_IntFreeP( &p->vVisited2 ); + Vec_IntFreeP( &p->vCuts ); + Vec_IntFreeP( &p->vCutCosts ); if ( p->vPairHash ) Hash_IntManStop( p->vPairHash ); for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ ) diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c index d508afd9d..6cc5a0ab5 100644 --- a/src/map/if/ifMap.c +++ b/src/map/if/ifMap.c @@ -503,6 +503,10 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep if ( p->pPars->pFuncUser ) If_ObjForEachCut( pObj, pCut, i ) p->pPars->pFuncUser( p, pObj, pCut ); + if ( p->vCuts ) { + extern void If_ManDumpCutsAndCost( If_Man_t * p, If_Obj_t * pObj, Vec_Int_t * vCuts, Vec_Int_t * vCutCosts ); + If_ManDumpCutsAndCost( p, pObj, p->vCuts, p->vCutCosts ); + } // free the cuts If_ManDerefNodeCutSet( p, pObj ); }