summaryrefslogtreecommitdiffstats
path: root/src/aig/nwk/nwkMerge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/nwk/nwkMerge.c')
-rw-r--r--src/aig/nwk/nwkMerge.c1044
1 files changed, 0 insertions, 1044 deletions
diff --git a/src/aig/nwk/nwkMerge.c b/src/aig/nwk/nwkMerge.c
deleted file mode 100644
index 9a4f2f8c..00000000
--- a/src/aig/nwk/nwkMerge.c
+++ /dev/null
@@ -1,1044 +0,0 @@
-/**CFile****************************************************************
-
- FileName [nwkMerge.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Netlist representation.]
-
- Synopsis [LUT merging algorithm.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: nwkMerge.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "nwk.h"
-#include "nwkMerge.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis [Allocates the graph.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Nwk_Grf_t * Nwk_ManGraphAlloc( int nVertsMax )
-{
- Nwk_Grf_t * p;
- p = ABC_ALLOC( Nwk_Grf_t, 1 );
- memset( p, 0, sizeof(Nwk_Grf_t) );
- p->nVertsMax = nVertsMax;
- p->nEdgeHash = Aig_PrimeCudd( 3 * nVertsMax );
- p->pEdgeHash = ABC_CALLOC( Nwk_Edg_t *, p->nEdgeHash );
- p->pMemEdges = Aig_MmFixedStart( sizeof(Nwk_Edg_t), p->nEdgeHash );
- p->vPairs = Vec_IntAlloc( 1000 );
- return p;
-}
-
-/**Function*************************************************************
-
- Synopsis [Deallocates the graph.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManGraphFree( Nwk_Grf_t * p )
-{
- if ( p->vPairs ) Vec_IntFree( p->vPairs );
- if ( p->pMemEdges ) Aig_MmFixedStop( p->pMemEdges, 0 );
- if ( p->pMemVerts ) Aig_MmFlexStop( p->pMemVerts, 0 );
- ABC_FREE( p->pVerts );
- ABC_FREE( p->pEdgeHash );
- ABC_FREE( p->pMapLut2Id );
- ABC_FREE( p->pMapId2Lut );
- ABC_FREE( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Prepares the graph for solving the problem.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManGraphReportMemoryUsage( Nwk_Grf_t * p )
-{
- p->nMemBytes1 =
- sizeof(Nwk_Grf_t) +
- sizeof(void *) * p->nEdgeHash +
- sizeof(int) * (p->nObjs + p->nVertsMax) +
- sizeof(Nwk_Edg_t) * p->nEdges;
- p->nMemBytes2 =
- sizeof(Nwk_Vrt_t) * p->nVerts +
- sizeof(int) * 2 * p->nEdges;
- printf( "Memory usage stats: Preprocessing = %.2f Mb. Solving = %.2f Mb.\n",
- 1.0 * p->nMemBytes1 / (1<<20), 1.0 * p->nMemBytes2 / (1<<20) );
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Finds or adds the edge to the graph.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManGraphHashEdge( Nwk_Grf_t * p, int iLut1, int iLut2 )
-{
- Nwk_Edg_t * pEntry;
- unsigned Key;
- if ( iLut1 == iLut2 )
- return;
- if ( iLut1 > iLut2 )
- {
- Key = iLut1;
- iLut1 = iLut2;
- iLut2 = Key;
- }
- assert( iLut1 < iLut2 );
- if ( p->nObjs < iLut2 )
- p->nObjs = iLut2;
- Key = (unsigned)(741457 * iLut1 + 4256249 * iLut2) % p->nEdgeHash;
- for ( pEntry = p->pEdgeHash[Key]; pEntry; pEntry = pEntry->pNext )
- if ( pEntry->iNode1 == iLut1 && pEntry->iNode2 == iLut2 )
- return;
- pEntry = (Nwk_Edg_t *)Aig_MmFixedEntryFetch( p->pMemEdges );
- pEntry->iNode1 = iLut1;
- pEntry->iNode2 = iLut2;
- pEntry->pNext = p->pEdgeHash[Key];
- p->pEdgeHash[Key] = pEntry;
- p->nEdges++;
-}
-
-/**Function*************************************************************
-
- Synopsis [Adds one entry to the list.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-static inline void Nwk_ManGraphListAdd( Nwk_Grf_t * p, int * pList, Nwk_Vrt_t * pVertex )
-{
- if ( *pList )
- {
- Nwk_Vrt_t * pHead;
- pHead = p->pVerts[*pList];
- pVertex->iPrev = 0;
- pVertex->iNext = pHead->Id;
- pHead->iPrev = pVertex->Id;
- }
- *pList = pVertex->Id;
-}
-
-/**Function*************************************************************
-
- Synopsis [Deletes one entry from the list.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-static inline void Nwk_ManGraphListDelete( Nwk_Grf_t * p, int * pList, Nwk_Vrt_t * pVertex )
-{
- assert( *pList );
- if ( pVertex->iPrev )
- {
-// assert( p->pVerts[pVertex->iPrev]->iNext == pVertex->Id );
- p->pVerts[pVertex->iPrev]->iNext = pVertex->iNext;
- }
- if ( pVertex->iNext )
- {
-// assert( p->pVerts[pVertex->iNext]->iPrev == pVertex->Id );
- p->pVerts[pVertex->iNext]->iPrev = pVertex->iPrev;
- }
- if ( *pList == pVertex->Id )
- *pList = pVertex->iNext;
- pVertex->iPrev = pVertex->iNext = 0;
-}
-
-/**Function*************************************************************
-
- Synopsis [Inserts the edge into one of the linked lists.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-static inline void Nwk_ManGraphListInsert( Nwk_Grf_t * p, Nwk_Vrt_t * pVertex )
-{
- Nwk_Vrt_t * pNext;
- assert( pVertex->nEdges > 0 );
-
- if ( pVertex->nEdges == 1 )
- {
- pNext = p->pVerts[ pVertex->pEdges[0] ];
- if ( pNext->nEdges >= NWK_MAX_LIST )
- Nwk_ManGraphListAdd( p, p->pLists1 + NWK_MAX_LIST, pVertex );
- else
- Nwk_ManGraphListAdd( p, p->pLists1 + pNext->nEdges, pVertex );
- }
- else
- {
- if ( pVertex->nEdges >= NWK_MAX_LIST )
- Nwk_ManGraphListAdd( p, p->pLists2 + NWK_MAX_LIST, pVertex );
- else
- Nwk_ManGraphListAdd( p, p->pLists2 + pVertex->nEdges, pVertex );
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Extracts the edge from one of the linked lists.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-static inline void Nwk_ManGraphListExtract( Nwk_Grf_t * p, Nwk_Vrt_t * pVertex )
-{
- Nwk_Vrt_t * pNext;
- assert( pVertex->nEdges > 0 );
-
- if ( pVertex->nEdges == 1 )
- {
- pNext = p->pVerts[ pVertex->pEdges[0] ];
- if ( pNext->nEdges >= NWK_MAX_LIST )
- Nwk_ManGraphListDelete( p, p->pLists1 + NWK_MAX_LIST, pVertex );
- else
- Nwk_ManGraphListDelete( p, p->pLists1 + pNext->nEdges, pVertex );
- }
- else
- {
- if ( pVertex->nEdges >= NWK_MAX_LIST )
- Nwk_ManGraphListDelete( p, p->pLists2 + NWK_MAX_LIST, pVertex );
- else
- Nwk_ManGraphListDelete( p, p->pLists2 + pVertex->nEdges, pVertex );
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Prepares the graph for solving the problem.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManGraphPrepare( Nwk_Grf_t * p )
-{
- Nwk_Edg_t * pEntry;
- Nwk_Vrt_t * pVertex;
- int * pnEdges, nBytes, i;
- // allocate memory for the present objects
- p->pMapLut2Id = ABC_ALLOC( int, p->nObjs+1 );
- p->pMapId2Lut = ABC_ALLOC( int, p->nVertsMax+1 );
- memset( p->pMapLut2Id, 0xff, sizeof(int) * (p->nObjs+1) );
- memset( p->pMapId2Lut, 0xff, sizeof(int) * (p->nVertsMax+1) );
- // mark present objects
- Nwk_GraphForEachEdge( p, pEntry, i )
- {
- assert( pEntry->iNode1 <= p->nObjs );
- assert( pEntry->iNode2 <= p->nObjs );
- p->pMapLut2Id[ pEntry->iNode1 ] = 0;
- p->pMapLut2Id[ pEntry->iNode2 ] = 0;
- }
- // map objects
- p->nVerts = 0;
- for ( i = 0; i <= p->nObjs; i++ )
- {
- if ( p->pMapLut2Id[i] == 0 )
- {
- p->pMapLut2Id[i] = ++p->nVerts;
- p->pMapId2Lut[p->nVerts] = i;
- }
- }
- // count the edges and mark present objects
- pnEdges = ABC_CALLOC( int, p->nVerts+1 );
- Nwk_GraphForEachEdge( p, pEntry, i )
- {
- // translate into vertices
- assert( pEntry->iNode1 <= p->nObjs );
- assert( pEntry->iNode2 <= p->nObjs );
- pEntry->iNode1 = p->pMapLut2Id[pEntry->iNode1];
- pEntry->iNode2 = p->pMapLut2Id[pEntry->iNode2];
- // count the edges
- assert( pEntry->iNode1 <= p->nVerts );
- assert( pEntry->iNode2 <= p->nVerts );
- pnEdges[pEntry->iNode1]++;
- pnEdges[pEntry->iNode2]++;
- }
- // allocate the real graph
- p->pMemVerts = Aig_MmFlexStart();
- p->pVerts = ABC_ALLOC( Nwk_Vrt_t *, p->nVerts + 1 );
- p->pVerts[0] = NULL;
- for ( i = 1; i <= p->nVerts; i++ )
- {
- assert( pnEdges[i] > 0 );
- nBytes = sizeof(Nwk_Vrt_t) + sizeof(int) * pnEdges[i];
- p->pVerts[i] = (Nwk_Vrt_t *)Aig_MmFlexEntryFetch( p->pMemVerts, nBytes );
- memset( p->pVerts[i], 0, nBytes );
- p->pVerts[i]->Id = i;
- }
- // add edges to the real graph
- Nwk_GraphForEachEdge( p, pEntry, i )
- {
- pVertex = p->pVerts[pEntry->iNode1];
- pVertex->pEdges[ pVertex->nEdges++ ] = pEntry->iNode2;
- pVertex = p->pVerts[pEntry->iNode2];
- pVertex->pEdges[ pVertex->nEdges++ ] = pEntry->iNode1;
- }
- // put vertices into the data structure
- for ( i = 1; i <= p->nVerts; i++ )
- {
- assert( p->pVerts[i]->nEdges == pnEdges[i] );
- Nwk_ManGraphListInsert( p, p->pVerts[i] );
- }
- // clean up
- Aig_MmFixedStop( p->pMemEdges, 0 ); p->pMemEdges = NULL;
- ABC_FREE( p->pEdgeHash );
-// p->nEdgeHash = 0;
- ABC_FREE( pnEdges );
-}
-
-/**Function*************************************************************
-
- Synopsis [Sort pairs by the first vertex in the topological order.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManGraphSortPairs( Nwk_Grf_t * p )
-{
- int nSize = Vec_IntSize(p->vPairs);
- int * pIdToPair, i;
- // allocate storage
- pIdToPair = ABC_ALLOC( int, p->nObjs+1 );
- for ( i = 0; i <= p->nObjs; i++ )
- pIdToPair[i] = -1;
- // create mapping
- for ( i = 0; i < p->vPairs->nSize; i += 2 )
- {
- assert( pIdToPair[ p->vPairs->pArray[i] ] == -1 );
- pIdToPair[ p->vPairs->pArray[i] ] = p->vPairs->pArray[i+1];
- }
- // recreate pairs
- Vec_IntClear( p->vPairs );
- for ( i = 0; i <= p->nObjs; i++ )
- if ( pIdToPair[i] >= 0 )
- {
- assert( i < pIdToPair[i] );
- Vec_IntPush( p->vPairs, i );
- Vec_IntPush( p->vPairs, pIdToPair[i] );
- }
- assert( nSize == Vec_IntSize(p->vPairs) );
- ABC_FREE( pIdToPair );
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Updates the problem after pulling out one edge.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManGraphCheckLists( Nwk_Grf_t * p )
-{
- Nwk_Vrt_t * pVertex, * pNext;
- int i, j;
- assert( p->pLists1[0] == 0 );
- for ( i = 1; i <= NWK_MAX_LIST; i++ )
- if ( p->pLists1[i] )
- {
- pVertex = p->pVerts[ p->pLists1[i] ];
- assert( pVertex->nEdges == 1 );
- pNext = p->pVerts[ pVertex->pEdges[0] ];
- assert( pNext->nEdges == i || pNext->nEdges > NWK_MAX_LIST );
- }
- // find the next vertext to extract
- assert( p->pLists2[0] == 0 );
- assert( p->pLists2[1] == 0 );
- for ( j = 2; j <= NWK_MAX_LIST; j++ )
- if ( p->pLists2[j] )
- {
- pVertex = p->pVerts[ p->pLists2[j] ];
- assert( pVertex->nEdges == j || pVertex->nEdges > NWK_MAX_LIST );
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Extracts the edge from one of the linked lists.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-static inline void Nwk_ManGraphVertexRemoveEdge( Nwk_Vrt_t * pThis, Nwk_Vrt_t * pNext )
-{
- int k;
- for ( k = 0; k < pThis->nEdges; k++ )
- if ( pThis->pEdges[k] == pNext->Id )
- break;
- assert( k < pThis->nEdges );
- pThis->nEdges--;
- for ( ; k < pThis->nEdges; k++ )
- pThis->pEdges[k] = pThis->pEdges[k+1];
-}
-
-/**Function*************************************************************
-
- Synopsis [Updates the problem after pulling out one edge.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManGraphUpdate( Nwk_Grf_t * p, Nwk_Vrt_t * pVertex, Nwk_Vrt_t * pNext )
-{
- Nwk_Vrt_t * pChanged, * pOther;
- int i, k;
-// Nwk_ManGraphCheckLists( p );
- Nwk_ManGraphListExtract( p, pVertex );
- Nwk_ManGraphListExtract( p, pNext );
- // update neihbors of pVertex
- Nwk_VertexForEachAdjacent( p, pVertex, pChanged, i )
- {
- if ( pChanged == pNext )
- continue;
- Nwk_ManGraphListExtract( p, pChanged );
- // move those that use this one
- if ( pChanged->nEdges > 1 )
- Nwk_VertexForEachAdjacent( p, pChanged, pOther, k )
- {
- if ( pOther == pVertex || pOther->nEdges > 1 )
- continue;
- assert( pOther->nEdges == 1 );
- Nwk_ManGraphListExtract( p, pOther );
- pChanged->nEdges--;
- Nwk_ManGraphListInsert( p, pOther );
- pChanged->nEdges++;
- }
- // remove the edge
- Nwk_ManGraphVertexRemoveEdge( pChanged, pVertex );
- // add the changed vertex back
- if ( pChanged->nEdges > 0 )
- Nwk_ManGraphListInsert( p, pChanged );
- }
- // update neihbors of pNext
- Nwk_VertexForEachAdjacent( p, pNext, pChanged, i )
- {
- if ( pChanged == pVertex )
- continue;
- Nwk_ManGraphListExtract( p, pChanged );
- // move those that use this one
- if ( pChanged->nEdges > 1 )
- Nwk_VertexForEachAdjacent( p, pChanged, pOther, k )
- {
- if ( pOther == pNext || pOther->nEdges > 1 )
- continue;
- assert( pOther->nEdges == 1 );
- Nwk_ManGraphListExtract( p, pOther );
- pChanged->nEdges--;
- Nwk_ManGraphListInsert( p, pOther );
- pChanged->nEdges++;
- }
- // remove the edge
- Nwk_ManGraphVertexRemoveEdge( pChanged, pNext );
- // add the changed vertex back
- if ( pChanged->nEdges > 0 )
- Nwk_ManGraphListInsert( p, pChanged );
- }
- // add to the result
- if ( pVertex->Id < pNext->Id )
- {
- Vec_IntPush( p->vPairs, p->pMapId2Lut[pVertex->Id] );
- Vec_IntPush( p->vPairs, p->pMapId2Lut[pNext->Id] );
- }
- else
- {
- Vec_IntPush( p->vPairs, p->pMapId2Lut[pNext->Id] );
- Vec_IntPush( p->vPairs, p->pMapId2Lut[pVertex->Id] );
- }
-// Nwk_ManGraphCheckLists( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of entries in the list.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Nwk_ManGraphListLength( Nwk_Grf_t * p, int List )
-{
- Nwk_Vrt_t * pThis;
- int fVerbose = 0;
- int Counter = 0;
- Nwk_ListForEachVertex( p, List, pThis )
- {
- if ( fVerbose && Counter < 20 )
- printf( "%d ", p->pVerts[pThis->pEdges[0]]->nEdges );
- Counter++;
- }
- if ( fVerbose )
- printf( "\n" );
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Returns the adjacent vertex with the mininum number of edges.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Nwk_Vrt_t * Nwk_ManGraphListFindMinEdge( Nwk_Grf_t * p, Nwk_Vrt_t * pVert )
-{
- Nwk_Vrt_t * pThis, * pMinCost = NULL;
- int k;
- Nwk_VertexForEachAdjacent( p, pVert, pThis, k )
- {
- if ( pMinCost == NULL || pMinCost->nEdges > pThis->nEdges )
- pMinCost = pThis;
- }
- return pMinCost;
-}
-
-/**Function*************************************************************
-
- Synopsis [Finds the best vertext in the list.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Nwk_Vrt_t * Nwk_ManGraphListFindMin( Nwk_Grf_t * p, int List )
-{
- Nwk_Vrt_t * pThis, * pMinCost = NULL;
- int k, Counter = 10000, BestCost = 1000000;
- Nwk_ListForEachVertex( p, List, pThis )
- {
- for ( k = 0; k < pThis->nEdges; k++ )
- {
- if ( pMinCost == NULL || BestCost > p->pVerts[pThis->pEdges[k]]->nEdges )
- {
- BestCost = p->pVerts[pThis->pEdges[k]]->nEdges;
- pMinCost = pThis;
- }
- }
- if ( --Counter == 0 )
- break;
- }
- return pMinCost;
-}
-
-/**Function*************************************************************
-
- Synopsis [Solves the problem by extracting one edge at a time.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManGraphSolve( Nwk_Grf_t * p )
-{
- Nwk_Vrt_t * pVertex, * pNext;
- int i, j;
- Nwk_ManGraphPrepare( p );
- while ( 1 )
- {
- // find the next vertex to extract
- assert( p->pLists1[0] == 0 );
- for ( i = 1; i <= NWK_MAX_LIST; i++ )
- if ( p->pLists1[i] )
- {
-// printf( "%d ", i );
-// printf( "ListA = %2d. Length = %5d.\n", i, Nwk_ManGraphListLength(p,p->pLists1[i]) );
- pVertex = p->pVerts[ p->pLists1[i] ];
- assert( pVertex->nEdges == 1 );
- pNext = p->pVerts[ pVertex->pEdges[0] ];
- Nwk_ManGraphUpdate( p, pVertex, pNext );
- break;
- }
- if ( i < NWK_MAX_LIST + 1 )
- continue;
- // find the next vertex to extract
- assert( p->pLists2[0] == 0 );
- assert( p->pLists2[1] == 0 );
- for ( j = 2; j <= NWK_MAX_LIST; j++ )
- if ( p->pLists2[j] )
- {
-// printf( "***%d ", j );
-// printf( "ListB = %2d. Length = %5d.\n", j, Nwk_ManGraphListLength(p,p->pLists2[j]) );
- pVertex = Nwk_ManGraphListFindMin( p, p->pLists2[j] );
- assert( pVertex->nEdges == j || j == NWK_MAX_LIST );
- pNext = Nwk_ManGraphListFindMinEdge( p, pVertex );
- Nwk_ManGraphUpdate( p, pVertex, pNext );
- break;
- }
- if ( j == NWK_MAX_LIST + 1 )
- break;
- }
- Nwk_ManGraphSortPairs( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Reads graph from file.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Nwk_Grf_t * Nwk_ManLutMergeReadGraph( char * pFileName )
-{
- Nwk_Grf_t * p;
- FILE * pFile;
- char Buffer[100];
- int nNodes, nEdges, iNode1, iNode2;
- pFile = fopen( pFileName, "r" );
- fscanf( pFile, "%s %d", Buffer, &nNodes );
- fscanf( pFile, "%s %d", Buffer, &nEdges );
- p = Nwk_ManGraphAlloc( nNodes );
- while ( fscanf( pFile, "%s %d %d", Buffer, &iNode1, &iNode2 ) == 3 )
- Nwk_ManGraphHashEdge( p, iNode1, iNode2 );
- assert( p->nEdges == nEdges );
- fclose( pFile );
- return p;
-}
-
-/**Function*************************************************************
-
- Synopsis [Solves the graph coming from file.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Nwk_ManLutMergeGraphTest( char * pFileName )
-{
- int nPairs;
- Nwk_Grf_t * p;
- int clk = clock();
- p = Nwk_ManLutMergeReadGraph( pFileName );
- ABC_PRT( "Reading", clock() - clk );
- clk = clock();
- Nwk_ManGraphSolve( p );
- printf( "GRAPH: Nodes = %6d. Edges = %6d. Pairs = %6d. ",
- p->nVerts, p->nEdges, Vec_IntSize(p->vPairs)/2 );
- ABC_PRT( "Solving", clock() - clk );
- nPairs = Vec_IntSize(p->vPairs)/2;
- Nwk_ManGraphReportMemoryUsage( p );
- Nwk_ManGraphFree( p );
- return nPairs;
-}
-
-
-
-
-/**Function*************************************************************
-
- Synopsis [Marks the fanins of the node with the current trav ID.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManMarkFanins_rec( Nwk_Obj_t * pLut, int nLevMin )
-{
- Nwk_Obj_t * pNext;
- int i;
- if ( !Nwk_ObjIsNode(pLut) )
- return;
- if ( Nwk_ObjIsTravIdCurrent( pLut ) )
- return;
- Nwk_ObjSetTravIdCurrent( pLut );
- if ( Nwk_ObjLevel(pLut) < nLevMin )
- return;
- Nwk_ObjForEachFanin( pLut, pNext, i )
- Nwk_ManMarkFanins_rec( pNext, nLevMin );
-}
-
-/**Function*************************************************************
-
- Synopsis [Marks the fanouts of the node with the current trav ID.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManMarkFanouts_rec( Nwk_Obj_t * pLut, int nLevMax, int nFanMax )
-{
- Nwk_Obj_t * pNext;
- int i;
- if ( !Nwk_ObjIsNode(pLut) )
- return;
- if ( Nwk_ObjIsTravIdCurrent( pLut ) )
- return;
- Nwk_ObjSetTravIdCurrent( pLut );
- if ( Nwk_ObjLevel(pLut) > nLevMax )
- return;
- if ( Nwk_ObjFanoutNum(pLut) > nFanMax )
- return;
- Nwk_ObjForEachFanout( pLut, pNext, i )
- Nwk_ManMarkFanouts_rec( pNext, nLevMax, nFanMax );
-}
-
-/**Function*************************************************************
-
- Synopsis [Collects the circle of nodes around the given set.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManCollectCircle( Vec_Ptr_t * vStart, Vec_Ptr_t * vNext, int nFanMax )
-{
- Nwk_Obj_t * pObj, * pNext;
- int i, k;
- Vec_PtrClear( vNext );
- Vec_PtrForEachEntry( Nwk_Obj_t *, vStart, pObj, i )
- {
- Nwk_ObjForEachFanin( pObj, pNext, k )
- {
- if ( !Nwk_ObjIsNode(pNext) )
- continue;
- if ( Nwk_ObjIsTravIdCurrent( pNext ) )
- continue;
- Nwk_ObjSetTravIdCurrent( pNext );
- Vec_PtrPush( vNext, pNext );
- }
- Nwk_ObjForEachFanout( pObj, pNext, k )
- {
- if ( !Nwk_ObjIsNode(pNext) )
- continue;
- if ( Nwk_ObjIsTravIdCurrent( pNext ) )
- continue;
- Nwk_ObjSetTravIdCurrent( pNext );
- if ( Nwk_ObjFanoutNum(pNext) > nFanMax )
- continue;
- Vec_PtrPush( vNext, pNext );
- }
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Collects the circle of nodes removes from the given one.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManCollectNonOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vStart, Vec_Ptr_t * vNext, Vec_Ptr_t * vCands, Nwk_LMPars_t * pPars )
-{
- Vec_Ptr_t * vTemp;
- Nwk_Obj_t * pObj;
- int i, k;
- Vec_PtrClear( vCands );
- if ( pPars->nMaxSuppSize - Nwk_ObjFaninNum(pLut) <= 1 )
- return;
-
- // collect nodes removed by this distance
- assert( pPars->nMaxDistance > 0 );
- Vec_PtrClear( vStart );
- Vec_PtrPush( vStart, pLut );
- Nwk_ManIncrementTravId( pLut->pMan );
- Nwk_ObjSetTravIdCurrent( pLut );
- for ( i = 1; i <= pPars->nMaxDistance; i++ )
- {
- Nwk_ManCollectCircle( vStart, vNext, pPars->nMaxFanout );
- vTemp = vStart;
- vStart = vNext;
- vNext = vTemp;
- // collect the nodes in vStart
- Vec_PtrForEachEntry( Nwk_Obj_t *, vStart, pObj, k )
- Vec_PtrPush( vCands, pObj );
- }
-
- // mark the TFI/TFO nodes
- Nwk_ManIncrementTravId( pLut->pMan );
- if ( pPars->fUseTfiTfo )
- Nwk_ObjSetTravIdCurrent( pLut );
- else
- {
- Nwk_ObjSetTravIdPrevious( pLut );
- Nwk_ManMarkFanins_rec( pLut, Nwk_ObjLevel(pLut) - pPars->nMaxDistance );
- Nwk_ObjSetTravIdPrevious( pLut );
- Nwk_ManMarkFanouts_rec( pLut, Nwk_ObjLevel(pLut) + pPars->nMaxDistance, pPars->nMaxFanout );
- }
-
- // collect nodes satisfying the following conditions:
- // - they are close enough in terms of distance
- // - they are not in the TFI/TFO of the LUT
- // - they have no more than the given number of fanins
- // - they have no more than the given diff in delay
- k = 0;
- Vec_PtrForEachEntry( Nwk_Obj_t *, vCands, pObj, i )
- {
- if ( Nwk_ObjIsTravIdCurrent(pObj) )
- continue;
- if ( Nwk_ObjFaninNum(pLut) + Nwk_ObjFaninNum(pObj) > pPars->nMaxSuppSize )
- continue;
- if ( Nwk_ObjLevel(pLut) - Nwk_ObjLevel(pObj) > pPars->nMaxLevelDiff ||
- Nwk_ObjLevel(pObj) - Nwk_ObjLevel(pLut) > pPars->nMaxLevelDiff )
- continue;
- Vec_PtrWriteEntry( vCands, k++, pObj );
- }
- Vec_PtrShrink( vCands, k );
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Count the total number of fanins.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Nwk_ManCountTotalFanins( Nwk_Obj_t * pLut, Nwk_Obj_t * pCand )
-{
- Nwk_Obj_t * pFanin;
- int i, nCounter = Nwk_ObjFaninNum(pLut);
- Nwk_ObjForEachFanin( pCand, pFanin, i )
- nCounter += !pFanin->MarkC;
- return nCounter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Collects overlapping candidates.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Nwk_ManCollectOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vCands, Nwk_LMPars_t * pPars )
-{
- Nwk_Obj_t * pFanin, * pObj;
- int i, k;
- // mark fanins of pLut
- Nwk_ObjForEachFanin( pLut, pFanin, i )
- pFanin->MarkC = 1;
- // collect the matching fanouts of each fanin of the node
- Vec_PtrClear( vCands );
- Nwk_ManIncrementTravId( pLut->pMan );
- Nwk_ObjSetTravIdCurrent( pLut );
- Nwk_ObjForEachFanin( pLut, pFanin, i )
- {
- if ( !Nwk_ObjIsNode(pFanin) )
- continue;
- if ( Nwk_ObjFanoutNum(pFanin) > pPars->nMaxFanout )
- continue;
- Nwk_ObjForEachFanout( pFanin, pObj, k )
- {
- if ( !Nwk_ObjIsNode(pObj) )
- continue;
- if ( Nwk_ObjIsTravIdCurrent( pObj ) )
- continue;
- Nwk_ObjSetTravIdCurrent( pObj );
- // check the difference in delay
- if ( Nwk_ObjLevel(pLut) - Nwk_ObjLevel(pObj) > pPars->nMaxLevelDiff ||
- Nwk_ObjLevel(pObj) - Nwk_ObjLevel(pLut) > pPars->nMaxLevelDiff )
- continue;
- // check the total number of fanins of the node
- if ( Nwk_ManCountTotalFanins(pLut, pObj) > pPars->nMaxSuppSize )
- continue;
- Vec_PtrPush( vCands, pObj );
- }
- }
- // unmark fanins of pLut
- Nwk_ObjForEachFanin( pLut, pFanin, i )
- pFanin->MarkC = 0;
-}
-
-/**Function*************************************************************
-
- Synopsis [Performs LUT merging with parameters.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * pNtk, void * pParsInit )
-{
- Nwk_LMPars_t * pPars = (Nwk_LMPars_t *)pParsInit;
- Nwk_Grf_t * p;
- Vec_Int_t * vResult;
- Vec_Ptr_t * vStart, * vNext, * vCands1, * vCands2;
- Nwk_Obj_t * pLut, * pCand;
- int i, k, nVertsMax, nCands, clk = clock();
- // count the number of vertices
- nVertsMax = 0;
- Nwk_ManForEachNode( pNtk, pLut, i )
- nVertsMax += (int)(Nwk_ObjFaninNum(pLut) <= pPars->nMaxLutSize);
- p = Nwk_ManGraphAlloc( nVertsMax );
- // create graph
- vStart = Vec_PtrAlloc( 1000 );
- vNext = Vec_PtrAlloc( 1000 );
- vCands1 = Vec_PtrAlloc( 1000 );
- vCands2 = Vec_PtrAlloc( 1000 );
- nCands = 0;
- Nwk_ManForEachNode( pNtk, pLut, i )
- {
- if ( Nwk_ObjFaninNum(pLut) > pPars->nMaxLutSize )
- continue;
- Nwk_ManCollectOverlapCands( pLut, vCands1, pPars );
- if ( pPars->fUseDiffSupp )
- Nwk_ManCollectNonOverlapCands( pLut, vStart, vNext, vCands2, pPars );
- if ( Vec_PtrSize(vCands1) == 0 && Vec_PtrSize(vCands2) == 0 )
- continue;
- nCands += Vec_PtrSize(vCands1) + Vec_PtrSize(vCands2);
- // save candidates
- Vec_PtrForEachEntry( Nwk_Obj_t *, vCands1, pCand, k )
- Nwk_ManGraphHashEdge( p, Nwk_ObjId(pLut), Nwk_ObjId(pCand) );
- Vec_PtrForEachEntry( Nwk_Obj_t *, vCands2, pCand, k )
- Nwk_ManGraphHashEdge( p, Nwk_ObjId(pLut), Nwk_ObjId(pCand) );
- // print statistics about this node
- if ( pPars->fVeryVerbose )
- printf( "Node %6d : Fanins = %d. Fanouts = %3d. Cand1 = %3d. Cand2 = %3d.\n",
- Nwk_ObjId(pLut), Nwk_ObjFaninNum(pLut), Nwk_ObjFaninNum(pLut),
- Vec_PtrSize(vCands1), Vec_PtrSize(vCands2) );
- }
- Vec_PtrFree( vStart );
- Vec_PtrFree( vNext );
- Vec_PtrFree( vCands1 );
- Vec_PtrFree( vCands2 );
- if ( pPars->fVerbose )
- {
- printf( "Mergable LUTs = %6d. Total cands = %6d. ", p->nVertsMax, nCands );
- ABC_PRT( "Deriving graph", clock() - clk );
- }
- // solve the graph problem
- clk = clock();
- Nwk_ManGraphSolve( p );
- if ( pPars->fVerbose )
- {
- printf( "GRAPH: Nodes = %6d. Edges = %6d. Pairs = %6d. ",
- p->nVerts, p->nEdges, Vec_IntSize(p->vPairs)/2 );
- ABC_PRT( "Solving", clock() - clk );
- Nwk_ManGraphReportMemoryUsage( p );
- }
- vResult = p->vPairs; p->vPairs = NULL;
-/*
- for ( i = 0; i < vResult->nSize; i += 2 )
- printf( "(%d,%d) ", vResult->pArray[i], vResult->pArray[i+1] );
- printf( "\n" );
-*/
- Nwk_ManGraphFree( p );
- return vResult;
-}
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
-ABC_NAMESPACE_IMPL_END
-