summaryrefslogtreecommitdiffstats
path: root/src/aig/llb/llb2Flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/llb/llb2Flow.c')
-rw-r--r--src/aig/llb/llb2Flow.c1374
1 files changed, 0 insertions, 1374 deletions
diff --git a/src/aig/llb/llb2Flow.c b/src/aig/llb/llb2Flow.c
deleted file mode 100644
index 1b177807..00000000
--- a/src/aig/llb/llb2Flow.c
+++ /dev/null
@@ -1,1374 +0,0 @@
-/**CFile****************************************************************
-
- FileName [llb2Flow.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [BDD based reachability.]
-
- Synopsis [Flow computation.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: llb2Flow.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "llbInt.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-static inline int Llb_ObjSetPath( Aig_Obj_t * pObj, Aig_Obj_t * pNext ) { pObj->pData = (void *)pNext; return 1; }
-static inline Aig_Obj_t * Llb_ObjGetPath( Aig_Obj_t * pObj ) { return (Aig_Obj_t *)pObj->pData; }
-static inline Aig_Obj_t * Llb_ObjGetFanoutPath( Aig_Man_t * p, Aig_Obj_t * pObj )
-{
- Aig_Obj_t * pFanout;
- int i, iFanout;
- assert( Llb_ObjGetPath(pObj) );
- Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, i )
- if ( Llb_ObjGetPath(pFanout) == pObj )
- return pFanout;
- return NULL;
-}
-
-extern Vec_Ptr_t * Llb_ManCutSupp( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper );
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-
-/**Function*************************************************************
-
- Synopsis [For each cut, returns PIs that can be quantified.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManCutSupps( Aig_Man_t * p, Vec_Ptr_t * vResult )
-{
- Vec_Ptr_t * vSupps, * vOne, * vLower, * vUpper;
- int i;
- vSupps = Vec_PtrAlloc( 100 );
- Vec_PtrPush( vSupps, Vec_PtrAlloc(0) );
- vLower = (Vec_Ptr_t *)Vec_PtrEntry( vResult, 0 );
- Vec_PtrForEachEntryStart( Vec_Ptr_t *, vResult, vUpper, i, 1 )
- {
- vOne = Llb_ManCutSupp( p, vLower, vUpper );
- Vec_PtrPush( vSupps, vOne );
- vLower = vUpper;
- }
- assert( Vec_PtrSize(vSupps) == Vec_PtrSize(vResult) );
- return vSupps;
-}
-
-/**Function*************************************************************
-
- Synopsis [For each cut, returns PIs that can be quantified.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManCutMap( Aig_Man_t * p, Vec_Ptr_t * vResult, Vec_Ptr_t * vSupps )
-{
- int fShowMatrix = 1;
- Vec_Ptr_t * vMaps, * vOne;
- Vec_Int_t * vMap, * vPrev, * vNext;
- Aig_Obj_t * pObj;
- int * piFirst, * piLast;
- int i, k, CounterPlus, CounterMinus, Counter;
-
- vMaps = Vec_PtrAlloc( 100 );
- Vec_PtrForEachEntry( Vec_Ptr_t *, vResult, vOne, i )
- {
- vMap = Vec_IntStart( Aig_ManObjNumMax(p) );
- Vec_PtrForEachEntry( Aig_Obj_t *, vOne, pObj, k )
- {
- if ( !Saig_ObjIsPi(p, pObj) )
- Vec_IntWriteEntry( vMap, pObj->Id, 1 );
-// else
-//printf( "*" );
-//printf( "%d ", pObj->Id );
- }
- Vec_PtrPush( vMaps, vMap );
-//printf( "\n" );
- }
- Vec_PtrPush( vMaps, Vec_IntStart( Aig_ManObjNumMax(p) ) );
- assert( Vec_PtrSize(vMaps) == Vec_PtrSize(vResult)+1 );
-
- // collect the first and last PIs
- piFirst = ABC_ALLOC( int, Saig_ManPiNum(p) );
- piLast = ABC_ALLOC( int, Saig_ManPiNum(p) );
- Saig_ManForEachPi( p, pObj, i )
- piFirst[i] = piLast[i] = -1;
- Vec_PtrForEachEntry( Vec_Ptr_t *, vSupps, vOne, i )
- {
- Vec_PtrForEachEntry( Aig_Obj_t *, vOne, pObj, k )
- {
- if ( !Saig_ObjIsPi(p, pObj) )
- continue;
- if ( piFirst[Aig_ObjPioNum(pObj)] == -1 )
- piFirst[Aig_ObjPioNum(pObj)] = i;
- piLast[Aig_ObjPioNum(pObj)] = i;
- }
- }
- // PIs feeding into the flops should be extended to the last frame
- Saig_ManForEachLi( p, pObj, i )
- {
- if ( !Saig_ObjIsPi(p, Aig_ObjFanin0(pObj)) )
- continue;
- piLast[Aig_ObjPioNum(Aig_ObjFanin0(pObj))] = Vec_PtrSize(vMaps)-1;
- }
-
- // set the PI map
- Saig_ManForEachPi( p, pObj, i )
- {
- if ( piFirst[i] == -1 )
- continue;
- if ( piFirst[i] == piLast[i] )
- {
- vMap = (Vec_Int_t *)Vec_PtrEntry( vMaps, piFirst[i] );
- Vec_IntWriteEntry( vMap, pObj->Id, 2 );
- continue;
- }
-
- // set support for all in between
- for ( k = piFirst[i]; k <= piLast[i]; k++ )
- {
- vMap = (Vec_Int_t *)Vec_PtrEntry( vMaps, k );
- Vec_IntWriteEntry( vMap, pObj->Id, 1 );
- }
- }
- ABC_FREE( piFirst );
- ABC_FREE( piLast );
-
-
- // find all that will appear here
- Counter = Aig_ManRegNum(p);
- printf( "%d ", Counter );
- Vec_PtrForEachEntryStart( Vec_Int_t *, vMaps, vMap, i, 1 )
- {
- vPrev = (Vec_Int_t *)Vec_PtrEntry( vMaps, i-1 );
- vNext = (i == Vec_PtrSize(vMaps)-1)? NULL: (Vec_Int_t *)Vec_PtrEntry( vMaps, i+1 );
-
- CounterPlus = CounterMinus = 0;
- Aig_ManForEachObj( p, pObj, k )
- {
- if ( Saig_ObjIsPi(p, pObj) )
- {
- if ( Vec_IntEntry(vPrev, k) == 0 && Vec_IntEntry(vMap, k) == 1 )
- CounterPlus++;
- if ( Vec_IntEntry(vMap, k) == 1 && (vNext == NULL || Vec_IntEntry(vNext, k) == 0) )
- CounterMinus++;
- }
- else
- {
- if ( Vec_IntEntry(vPrev, k) == 0 && Vec_IntEntry(vMap, k) == 1 )
- CounterPlus++;
- if ( Vec_IntEntry(vPrev, k) == 1 && Vec_IntEntry(vMap, k) == 0 )
- CounterMinus++;
- }
- }
- Counter = Counter + CounterPlus - CounterMinus;
- printf( "%d=%d ", i, Counter );
- }
- printf( "\n" );
-
- if ( fShowMatrix )
- Aig_ManForEachObj( p, pObj, i )
- {
- if ( !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) )
- continue;
- Vec_PtrForEachEntry( Vec_Int_t *, vMaps, vMap, k )
- if ( Vec_IntEntry(vMap, i) )
- break;
- if ( k == Vec_PtrSize(vMaps) )
- continue;
- printf( "Obj = %4d : ", i );
- if ( Saig_ObjIsPi(p,pObj) )
- printf( "pi " );
- else if ( Saig_ObjIsLo(p,pObj) )
- printf( "lo " );
- else if ( Aig_ObjIsNode(pObj) )
- printf( "and " );
-
- Vec_PtrForEachEntry( Vec_Int_t *, vMaps, vMap, k )
- printf( "%d", Vec_IntEntry(vMap, i) );
- printf( "\n" );
- }
- return vMaps;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of PIs in the cut]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_ManCutPiNum( Aig_Man_t * p, Vec_Ptr_t * vMinCut )
-{
- Aig_Obj_t * pObj;
- int i, Counter = 0;
- Vec_PtrForEachEntry( Aig_Obj_t *, vMinCut, pObj, i )
- if ( Saig_ObjIsPi(p,pObj) )
- Counter++;
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of LOs in the cut]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_ManCutLoNum( Aig_Man_t * p, Vec_Ptr_t * vMinCut )
-{
- Aig_Obj_t * pObj;
- int i, Counter = 0;
- Vec_PtrForEachEntry( Aig_Obj_t *, vMinCut, pObj, i )
- if ( Saig_ObjIsLo(p,pObj) )
- Counter++;
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Counts the number of LIs in the cut]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_ManCutLiNum( Aig_Man_t * p, Vec_Ptr_t * vMinCut )
-{
- Aig_Obj_t * pFanout;
- Aig_Obj_t * pObj;
- int i, k, iFanout, Counter = 0;
- Vec_PtrForEachEntry( Aig_Obj_t *, vMinCut, pObj, i )
- {
- if ( Aig_ObjIsPi(pObj) )
- continue;
- Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k )
- {
- if ( Saig_ObjIsLi(p, pFanout) )
- {
- Counter++;
- break;
- }
- }
- }
- return Counter;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes volume of the cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_ManCutVolume_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
-{
- if ( Aig_ObjIsTravIdCurrent(p, pObj) )
- return 0;
- Aig_ObjSetTravIdCurrent(p, pObj);
- assert( Aig_ObjIsNode(pObj) );
- return 1 + Llb_ManCutVolume_rec(p, Aig_ObjFanin0(pObj)) +
- Llb_ManCutVolume_rec(p, Aig_ObjFanin1(pObj));
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes volume of the cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_ManCutVolume( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper )
-{
- Aig_Obj_t * pObj;
- int i, Counter = 0;
- // mark the lower cut with the traversal ID
- Aig_ManIncrementTravId(p);
- Vec_PtrForEachEntry( Aig_Obj_t *, vLower, pObj, i )
- Aig_ObjSetTravIdCurrent( p, pObj );
- // count the upper cut
- Vec_PtrForEachEntry( Aig_Obj_t *, vUpper, pObj, i )
- Counter += Llb_ManCutVolume_rec( p, pObj );
- return Counter;
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Computes volume of the cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManCutNodes_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
-{
- if ( Aig_ObjIsTravIdCurrent(p, pObj) )
- return;
- Aig_ObjSetTravIdCurrent(p, pObj);
- assert( Aig_ObjIsNode(pObj) );
- Llb_ManCutNodes_rec(p, Aig_ObjFanin0(pObj), vNodes);
- Llb_ManCutNodes_rec(p, Aig_ObjFanin1(pObj), vNodes);
- Vec_PtrPush( vNodes, pObj );
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes volume of the cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManCutNodes( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper )
-{
- Vec_Ptr_t * vNodes;
- Aig_Obj_t * pObj;
- int i;
- // mark the lower cut with the traversal ID
- Aig_ManIncrementTravId(p);
- Vec_PtrForEachEntry( Aig_Obj_t *, vLower, pObj, i )
- Aig_ObjSetTravIdCurrent( p, pObj );
- // count the upper cut
- vNodes = Vec_PtrAlloc( 100 );
- Vec_PtrForEachEntry( Aig_Obj_t *, vUpper, pObj, i )
- Llb_ManCutNodes_rec( p, pObj, vNodes );
- return vNodes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes volume of the cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManCutSupp( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper )
-{
- Vec_Ptr_t * vNodes, * vSupp;
- Aig_Obj_t * pObj;
- int i;
- vNodes = Llb_ManCutNodes( p, vLower, vUpper );
- // mark support of the nodes
- Aig_ManIncrementTravId(p);
- Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
- {
- assert( Aig_ObjIsNode(pObj) );
- Aig_ObjSetTravIdCurrent( p, Aig_ObjFanin0(pObj) );
- Aig_ObjSetTravIdCurrent( p, Aig_ObjFanin1(pObj) );
- }
- Vec_PtrFree( vNodes );
- // collect the support nodes
- vSupp = Vec_PtrAlloc( 100 );
- Vec_PtrForEachEntry( Aig_Obj_t *, vLower, pObj, i )
- if ( Aig_ObjIsTravIdCurrent(p, pObj) )
- Vec_PtrPush( vSupp, pObj );
- return vSupp;
-
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes volume of the cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManCutRange( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper )
-{
- Vec_Ptr_t * vRange;
- Aig_Obj_t * pObj;
- int i;
- // mark the lower cut with the traversal ID
- Aig_ManIncrementTravId(p);
- Vec_PtrForEachEntry( Aig_Obj_t *, vLower, pObj, i )
- Aig_ObjSetTravIdCurrent( p, pObj );
- // collect the upper ones that are not marked
- vRange = Vec_PtrAlloc( 100 );
- Vec_PtrForEachEntry( Aig_Obj_t *, vUpper, pObj, i )
- if ( !Aig_ObjIsTravIdCurrent(p, pObj) )
- Vec_PtrPush( vRange, pObj );
- return vRange;
-}
-
-
-
-
-/**Function*************************************************************
-
- Synopsis [Prints the given cluster.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManCutPrint( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper )
-{
- Vec_Ptr_t * vSupp, * vRange;
- int Pis, Ffs, And;
-
- Pis = Llb_ManCutPiNum(p, vLower);
- Ffs = Llb_ManCutLoNum(p, vLower);
- And = Vec_PtrSize(vLower) - Pis - Ffs;
- printf( "Leaf: %3d=%3d+%3d+%3d ", Vec_PtrSize(vLower), Pis, Ffs, And );
-
- Pis = Llb_ManCutPiNum(p, vUpper);
- Ffs = Llb_ManCutLiNum(p, vUpper);
- And = Vec_PtrSize(vUpper) - Pis - Ffs;
- printf( "Root: %3d=%3d+%3d+%3d ", Vec_PtrSize(vUpper), Pis, Ffs, And );
-
- vSupp = Llb_ManCutSupp( p, vLower, vUpper );
- Pis = Llb_ManCutPiNum(p, vSupp);
- Ffs = Llb_ManCutLoNum(p, vSupp);
- And = Vec_PtrSize(vSupp) - Pis - Ffs;
- printf( "Supp: %3d=%3d+%3d+%3d ", Vec_PtrSize(vSupp), Pis, Ffs, And );
-
- vRange = Llb_ManCutRange( p, vLower, vUpper );
- Pis = Llb_ManCutPiNum(p, vRange);
- Ffs = Llb_ManCutLiNum(p, vRange);
- And = Vec_PtrSize(vRange) - Pis - Ffs;
- printf( "Range: %3d=%3d+%3d+%3d ", Vec_PtrSize(vRange), Pis, Ffs, And );
-
- printf( "S =%3d. V =%3d.\n",
- Vec_PtrSize(vSupp)+Vec_PtrSize(vRange), Llb_ManCutVolume(p, vLower, vUpper) );
- Vec_PtrFree( vSupp );
- Vec_PtrFree( vRange );
-/*
- {
- Aig_Obj_t * pObj;
- int i;
- printf( "Lower: " );
- Vec_PtrForEachEntry( Aig_Obj_t *, vLower, pObj, i )
- printf( " %d", pObj->Id );
- printf( " " );
- printf( "Upper: " );
- Vec_PtrForEachEntry( Aig_Obj_t *, vUpper, pObj, i )
- printf( " %d", pObj->Id );
- printf( "\n" );
- }
-*/
-}
-
-/**Function*************************************************************
-
- Synopsis [Prints the given cluster.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManResultPrint( Aig_Man_t * p, Vec_Ptr_t * vResult )
-{
- Vec_Ptr_t * vLower, * vUpper;
- int i;
- Vec_PtrForEachEntryReverse( Vec_Ptr_t *, vResult, vLower, i )
- {
- if ( i < Vec_PtrSize(vResult) - 1 )
- Llb_ManCutPrint( p, vLower, vUpper );
- vUpper = vLower;
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Tries to find an augmenting path originating in this node.]
-
- Description [This procedure works for directed graphs only!]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_ManFlowBwdPath2_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
-{
- Aig_Obj_t * pFanout;
- assert( Aig_ObjIsNode(pObj) || Aig_ObjIsPi(pObj) || Aig_ObjIsConst1(pObj) );
- // skip visited nodes
- if ( Aig_ObjIsTravIdCurrent(p, pObj) )
- return 0;
- Aig_ObjSetTravIdCurrent(p, pObj);
- // process node without flow
- if ( !Llb_ObjGetPath(pObj) )
- {
- // start the path if we reached a terminal node
- if ( pObj->fMarkA )
- return Llb_ObjSetPath( pObj, (Aig_Obj_t *)1 );
- // explore the fanins
-// Abc_ObjForEachFanin( pObj, pFanin, i )
-// if ( Abc_NtkMaxFlowBwdPath2_rec(pFanin) )
-// return Abc_ObjSetPath( pObj, pFanin );
- if ( Aig_ObjIsNode(pObj) )
- {
- if ( Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin0(pObj) ) )
- return Llb_ObjSetPath( pObj, Aig_ObjFanin0(pObj) );
- if ( Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin1(pObj) ) )
- return Llb_ObjSetPath( pObj, Aig_ObjFanin1(pObj) );
- }
- return 0;
- }
- // pObj has flow - find the fanout with flow
- pFanout = Llb_ObjGetFanoutPath( p, pObj );
- if ( pFanout == NULL )
- return 0;
- // go through the fanins of the fanout with flow
-// Abc_ObjForEachFanin( pFanout, pFanin, i )
-// if ( Abc_NtkMaxFlowBwdPath2_rec( pFanin ) )
-// return Abc_ObjSetPath( pFanout, pFanin );
- assert( Aig_ObjIsNode(pFanout) );
- if ( Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin0(pFanout) ) )
- return Llb_ObjSetPath( pFanout, Aig_ObjFanin0(pFanout) );
- if ( Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin1(pFanout) ) )
- return Llb_ObjSetPath( pFanout, Aig_ObjFanin1(pFanout) );
- // try the fanout
- if ( Llb_ManFlowBwdPath2_rec( p, pFanout ) )
- return Llb_ObjSetPath( pFanout, NULL );
- return 0;
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Cleans markB.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowLabelTfi_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
-{
- if ( Aig_ObjIsTravIdCurrent(p, pObj) )
- return;
- Aig_ObjSetTravIdCurrent(p, pObj);
- if ( Aig_ObjIsPi(pObj) || Aig_ObjIsConst1(pObj) )
- return;
- assert( Aig_ObjIsNode(pObj) );
- Llb_ManFlowLabelTfi_rec( p, Aig_ObjFanin0(pObj) );
- Llb_ManFlowLabelTfi_rec( p, Aig_ObjFanin1(pObj) );
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowUpdateCut( Aig_Man_t * p, Vec_Ptr_t * vMinCut )
-{
- Aig_Obj_t * pObj;
- int i;
- // label the TFI of the cut nodes
- Aig_ManIncrementTravId(p);
- Vec_PtrForEachEntry( Aig_Obj_t *, vMinCut, pObj, i )
- Llb_ManFlowLabelTfi_rec( p, pObj );
- // collect labeled fanins of non-labeled nodes
- Vec_PtrClear( vMinCut );
- Aig_ManIncrementTravId(p);
- Aig_ManForEachObj( p, pObj, i )
- {
- if ( !Aig_ObjIsPo(pObj) && !Aig_ObjIsNode(pObj) )
- continue;
- if ( Aig_ObjIsTravIdCurrent(p, pObj) || Aig_ObjIsTravIdPrevious(p, pObj) )
- continue;
- if ( Aig_ObjIsTravIdPrevious(p, Aig_ObjFanin0(pObj)) )
- {
- Aig_ObjSetTravIdCurrent(p, Aig_ObjFanin0(pObj));
- Vec_PtrPush( vMinCut, Aig_ObjFanin0(pObj) );
- }
- if ( Aig_ObjIsNode(pObj) && Aig_ObjIsTravIdPrevious(p, Aig_ObjFanin1(pObj)) )
- {
- Aig_ObjSetTravIdCurrent(p, Aig_ObjFanin1(pObj));
- Vec_PtrPush( vMinCut, Aig_ObjFanin1(pObj) );
- }
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Find minimum-volume minumum cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManFlowMinCut( Aig_Man_t * p )
-{
- Vec_Ptr_t * vMinCut;
- Aig_Obj_t * pObj;
- int i;
- // collect the cut nodes
- vMinCut = Vec_PtrAlloc( Aig_ManRegNum(p) );
- Aig_ManForEachObj( p, pObj, i )
- {
- // node without flow is not a cut node
- if ( !Llb_ObjGetPath(pObj) )
- continue;
- // unvisited node is below the cut
- if ( !Aig_ObjIsTravIdCurrent(p, pObj) )
- continue;
- // add terminal with flow or node whose path is not visited
- if ( pObj->fMarkA || !Aig_ObjIsTravIdCurrent( p, Llb_ObjGetPath(pObj) ) )
- Vec_PtrPush( vMinCut, pObj );
- }
- return vMinCut;
-}
-
-/**Function*************************************************************
-
- Synopsis [Verifies the min-cut is indeed a cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_ManFlowVerifyCut_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
-{
- // skip visited nodes
- if ( Aig_ObjIsTravIdCurrent(p, pObj) )
- return 1;
- Aig_ObjSetTravIdCurrent(p, pObj);
- // visit the node
- if ( Aig_ObjIsConst1(pObj) )
- return 1;
- if ( Aig_ObjIsPi(pObj) )
- return 0;
- // explore the fanins
- assert( Aig_ObjIsNode(pObj) );
- if ( !Llb_ManFlowVerifyCut_rec(p, Aig_ObjFanin0(pObj)) )
- return 0;
- if ( !Llb_ManFlowVerifyCut_rec(p, Aig_ObjFanin1(pObj)) )
- return 0;
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Verifies the min-cut is indeed a cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_ManFlowVerifyCut( Aig_Man_t * p, Vec_Ptr_t * vMinCut )
-{
- Aig_Obj_t * pObj;
- int i;
- // mark the cut with the current traversal ID
- Aig_ManIncrementTravId(p);
- Vec_PtrForEachEntry( Aig_Obj_t *, vMinCut, pObj, i )
- Aig_ObjSetTravIdCurrent( p, pObj );
- // search from the latches for a path to the COs/CIs
- Saig_ManForEachLi( p, pObj, i )
- {
- if ( !Llb_ManFlowVerifyCut_rec( p, Aig_ObjFanin0(pObj) ) )
- return 0;
- }
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Implementation of max-flow/min-cut computation.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManFlow( Aig_Man_t * p, Vec_Ptr_t * vSources, int * pnFlow )
-{
- Vec_Ptr_t * vMinCut;
- Aig_Obj_t * pObj;
- int Flow, FlowCur, RetValue, i;
- // find the max-flow
- Flow = 0;
- Aig_ManCleanData( p );
- Aig_ManIncrementTravId(p);
- Vec_PtrForEachEntry( Aig_Obj_t *, vSources, pObj, i )
- {
- assert( !pObj->fMarkA && pObj->fMarkB );
- if ( !Aig_ObjFanin0(pObj)->fMarkB )
- {
- FlowCur = Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin0(pObj) );
- Flow += FlowCur;
- if ( FlowCur )
- Aig_ManIncrementTravId(p);
- }
- if ( Aig_ObjIsNode(pObj) && !Aig_ObjFanin1(pObj)->fMarkB )
- {
- FlowCur = Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin1(pObj) );
- Flow += FlowCur;
- if ( FlowCur )
- Aig_ManIncrementTravId(p);
- }
- }
- if ( pnFlow )
- *pnFlow = Flow;
-
- // mark the nodes reachable from the latches
- Aig_ManIncrementTravId(p);
- Vec_PtrForEachEntry( Aig_Obj_t *, vSources, pObj, i )
- {
- assert( !pObj->fMarkA && pObj->fMarkB );
- if ( !Aig_ObjFanin0(pObj)->fMarkB )
- {
- RetValue = Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin0(pObj) );
- assert( RetValue == 0 );
- }
- if ( Aig_ObjIsNode(pObj) && !Aig_ObjFanin1(pObj)->fMarkB )
- {
- RetValue = Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin1(pObj) );
- assert( RetValue == 0 );
- }
- }
-
- // find the min-cut with the smallest volume
- vMinCut = Llb_ManFlowMinCut( p );
- assert( Vec_PtrSize(vMinCut) == Flow );
- // verify the cut
- if ( !Llb_ManFlowVerifyCut(p, vMinCut) )
- printf( "Llb_ManFlow() error! The computed min-cut is not a cut!\n" );
-// Llb_ManFlowPrintCut( p, vMinCut );
- return vMinCut;
-}
-
-/**Function*************************************************************
-
- Synopsis [Implementation of max-flow/min-cut computation.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManFlowCompute( Aig_Man_t * p )
-{
- Vec_Ptr_t * vMinCut;
- Aig_Obj_t * pObj;
- int Flow, FlowCur, RetValue, i;
- // find the max-flow
- Flow = 0;
- Aig_ManCleanData( p );
- Aig_ManIncrementTravId(p);
- Aig_ManForEachObj( p, pObj, i )
- {
- if ( !pObj->fMarkB )
- continue;
- assert( !pObj->fMarkA );
- if ( !Aig_ObjFanin0(pObj)->fMarkB )
- {
-//printf( "%d ", Aig_ObjFanin0(pObj)->Id );
- FlowCur = Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin0(pObj) );
- Flow += FlowCur;
- if ( FlowCur )
- Aig_ManIncrementTravId(p);
- }
- if ( Aig_ObjIsNode(pObj) && !Aig_ObjFanin1(pObj)->fMarkB )
- {
-//printf( "%d ", Aig_ObjFanin1(pObj)->Id );
- FlowCur = Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin1(pObj) );
- Flow += FlowCur;
- if ( FlowCur )
- Aig_ManIncrementTravId(p);
- }
- }
-//printf( "\n" );
-
- // mark the nodes reachable from the latches
- Aig_ManIncrementTravId(p);
- Aig_ManForEachObj( p, pObj, i )
- {
- if ( !pObj->fMarkB )
- continue;
- assert( !pObj->fMarkA );
- if ( !Aig_ObjFanin0(pObj)->fMarkB )
- {
- RetValue = Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin0(pObj) );
- assert( RetValue == 0 );
- }
- if ( Aig_ObjIsNode(pObj) && !Aig_ObjFanin1(pObj)->fMarkB )
- {
- RetValue = Llb_ManFlowBwdPath2_rec( p, Aig_ObjFanin1(pObj) );
- assert( RetValue == 0 );
- }
- }
- // find the min-cut with the smallest volume
- vMinCut = Llb_ManFlowMinCut( p );
- assert( Vec_PtrSize(vMinCut) == Flow );
-//printf( "%d ", Vec_PtrSize(vMinCut) );
- Llb_ManFlowUpdateCut( p, vMinCut );
-//printf( "%d ", Vec_PtrSize(vMinCut) );
- // verify the cut
- if ( !Llb_ManFlowVerifyCut(p, vMinCut) )
- printf( "Llb_ManFlow() error! The computed min-cut is not a cut!\n" );
-// Llb_ManFlowPrintCut( p, vMinCut );
- return vMinCut;
-}
-
-
-
-
-/**Function*************************************************************
-
- Synopsis [Cleans markB.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowCleanMarkB_rec( Aig_Obj_t * pObj )
-{
- if ( pObj->fMarkB == 0 )
- return;
- pObj->fMarkB = 0;
- assert( Aig_ObjIsNode(pObj) );
- Llb_ManFlowCleanMarkB_rec( Aig_ObjFanin0(pObj) );
- Llb_ManFlowCleanMarkB_rec( Aig_ObjFanin1(pObj) );
-}
-
-/**Function*************************************************************
-
- Synopsis [Cleans markB.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowSetMarkA_rec( Aig_Obj_t * pObj )
-{
- if ( pObj->fMarkA )
- return;
- pObj->fMarkA = 1;
- if ( Aig_ObjIsPi(pObj) || Aig_ObjIsConst1(pObj) )
- return;
- assert( Aig_ObjIsNode(pObj) );
- Llb_ManFlowSetMarkA_rec( Aig_ObjFanin0(pObj) );
- Llb_ManFlowSetMarkA_rec( Aig_ObjFanin1(pObj) );
-}
-
-/**Function*************************************************************
-
- Synopsis [Prepares flow computation.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowPrepareCut( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper )
-{
- Aig_Obj_t * pObj;
- int i;
- // reset marks
- Aig_ManForEachObj( p, pObj, i )
- {
- pObj->fMarkA = 0;
- pObj->fMarkB = 1;
- }
- // clean PIs and const
- Aig_ManConst1(p)->fMarkB = 0;
- Aig_ManForEachPi( p, pObj, i )
- pObj->fMarkB = 0;
- // clean upper cut
-//printf( "Upper: ");
- Vec_PtrForEachEntry( Aig_Obj_t *, vUpper, pObj, i )
- {
- Llb_ManFlowCleanMarkB_rec( pObj );
-//printf( "%d ", pObj->Id );
- }
-//printf( "\n" );
- // set lower cut
-//printf( "Lower: ");
- Vec_PtrForEachEntry( Aig_Obj_t *, vLower, pObj, i )
- {
-//printf( "%d ", pObj->Id );
- assert( pObj->fMarkB == 0 );
- Llb_ManFlowSetMarkA_rec( pObj );
- }
-//printf( "\n" );
-}
-
-/**Function*************************************************************
-
- Synopsis [Prepares flow computation.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowUnmarkCone( Aig_Man_t * p, Vec_Ptr_t * vCone )
-{
- Aig_Obj_t * pObj;
- int i;
- Vec_PtrForEachEntry( Aig_Obj_t *, vCone, pObj, i )
- {
- assert( Aig_ObjIsNode(pObj) );
- assert( pObj->fMarkB == 1 );
- pObj->fMarkB = 0;
- }
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowCollectAndMarkCone_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vCone )
-{
- Aig_Obj_t * pFanout;
- int i, iFanout;
- if ( Saig_ObjIsLi(p, pObj) )
- return;
- if ( pObj->fMarkB )
- return;
- if ( pObj->fMarkA == 0 )
- {
- assert( Aig_ObjIsNode(pObj) );
- pObj->fMarkB = 1;
- if ( Aig_ObjIsNode(pObj) )
- Vec_PtrPush( vCone, pObj );
- }
- Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, i )
- Llb_ManFlowCollectAndMarkCone_rec( p, pFanout, vCone );
-}
-
-/**Function*************************************************************
-
- Synopsis [Collects the cone.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowCollectAndMarkCone( Aig_Man_t * p, Vec_Ptr_t * vStarts, Vec_Ptr_t * vCone )
-{
- Aig_Obj_t * pObj;
- int i;
- Vec_PtrClear( vCone );
- Vec_PtrForEachEntry( Aig_Obj_t *, vStarts, pObj, i )
- {
- assert( pObj->fMarkA && !pObj->fMarkB );
- Llb_ManFlowCollectAndMarkCone_rec( p, pObj, vCone );
- }
-}
-
-
-
-
-/**Function*************************************************************
-
- Synopsis [Finds balanced cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManComputeCutLo( Aig_Man_t * p )
-{
- Vec_Ptr_t * vMinCut;
- Aig_Obj_t * pObj;
- int i;
- vMinCut = Vec_PtrAlloc( 100 );
- Aig_ManForEachPi( p, pObj, i )
- Vec_PtrPush( vMinCut, pObj );
- return vMinCut;
-}
-
-/**Function*************************************************************
-
- Synopsis [Finds balanced cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManComputeCutLi( Aig_Man_t * p )
-{
- Vec_Ptr_t * vMinCut;
- Aig_Obj_t * pObj;
- int i;
- assert( Saig_ManPoNum(p) == 0 );
- vMinCut = Vec_PtrAlloc( 100 );
- Aig_ManIncrementTravId(p);
- Saig_ManForEachLi( p, pObj, i )
- {
- pObj = Aig_ObjFanin0(pObj);
- if ( Aig_ObjIsConst1(pObj) )
- continue;
- if ( Aig_ObjIsTravIdCurrent(p, pObj) )
- continue;
- Aig_ObjSetTravIdCurrent(p, pObj);
- Vec_PtrPush( vMinCut, pObj );
- }
- return vMinCut;
-}
-
-
-
-/**Function*************************************************************
-
- Synopsis [Finds balanced cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManFlowGetObjSet( Aig_Man_t * p, Vec_Ptr_t * vLower, int iStart, int nSize, Vec_Ptr_t * vSet )
-{
- Aig_Obj_t * pObj;
- int i;
- Vec_PtrClear( vSet );
- for ( i = 0; i < nSize; i++ )
- {
- pObj = (Aig_Obj_t *)Vec_PtrEntry( vLower, (iStart + i) % Vec_PtrSize(vLower) );
- Vec_PtrPush( vSet, pObj );
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Finds balanced cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManFlowFindBestCut( Aig_Man_t * p, Vec_Ptr_t * vLower, Vec_Ptr_t * vUpper, int Num )
-{
- int nVolMin = Aig_ManNodeNum(p) / Num / 2;
- Vec_Ptr_t * vMinCut;
- Vec_Ptr_t * vCone, * vSet;
- Aig_Obj_t * pObj;
- int i, s, Vol, VolLower, VolUpper, VolCmp;
- int iBest = -1, iMinCut = ABC_INFINITY, iVolBest = 0;
-
- Vol = Llb_ManCutVolume( p, vLower, vUpper );
- assert( Vol > nVolMin );
- VolCmp = ABC_MIN( nVolMin, Vol - nVolMin );
- vCone = Vec_PtrAlloc( 100 );
- vSet = Vec_PtrAlloc( 100 );
- Llb_ManFlowPrepareCut( p, vLower, vUpper );
- for ( s = 1; s < Aig_ManRegNum(p); s += 5 )
- {
- Vec_PtrForEachEntry( Aig_Obj_t *, vLower, pObj, i )
- {
- Llb_ManFlowGetObjSet( p, vLower, i, s, vSet );
- Llb_ManFlowCollectAndMarkCone( p, vSet, vCone );
- if ( Vec_PtrSize(vCone) == 0 )
- continue;
- vMinCut = Llb_ManFlowCompute( p );
- Llb_ManFlowUnmarkCone( p, vCone );
-
- VolLower = Llb_ManCutVolume( p, vLower, vMinCut );
- VolUpper = Llb_ManCutVolume( p, vMinCut, vUpper );
- Vol = ABC_MIN( VolLower, VolUpper );
- if ( Vol >= VolCmp && (iMinCut == -1 ||
- iMinCut > Vec_PtrSize(vMinCut) ||
- (iMinCut == Vec_PtrSize(vMinCut) && iVolBest < Vol)) )
- {
- iBest = i;
- iMinCut = Vec_PtrSize(vMinCut);
- iVolBest = Vol;
- }
- Vec_PtrFree( vMinCut );
- }
- if ( iBest >= 0 )
- break;
- }
- if ( iBest == -1 )
- {
- // cleanup
- Vec_PtrFree( vCone );
- Vec_PtrFree( vSet );
- return NULL;
- }
- // get the best cut
- assert( iBest >= 0 );
- Llb_ManFlowGetObjSet( p, vLower, iBest, s, vSet );
- Llb_ManFlowCollectAndMarkCone( p, vSet, vCone );
- vMinCut = Llb_ManFlowCompute( p );
- Llb_ManFlowUnmarkCone( p, vCone );
- // cleanup
- Vec_PtrFree( vCone );
- Vec_PtrFree( vSet );
- return vMinCut;
-}
-
-/**Function*************************************************************
-
- Synopsis [Finds balanced cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_ManComputeCuts( Aig_Man_t * p, int Num, int fVerbose, int fVeryVerbose )
-{
- int nVolMax = Aig_ManNodeNum(p) / Num;
- Vec_Ptr_t * vResult, * vMinCut, * vLower, * vUpper;
- int i, k, nVol, clk = clock();
- vResult = Vec_PtrAlloc( 100 );
- Vec_PtrPush( vResult, Llb_ManComputeCutLo(p) );
- Vec_PtrPush( vResult, Llb_ManComputeCutLi(p) );
- while ( 1 )
- {
- // find a place to insert new cut
- vLower = (Vec_Ptr_t *)Vec_PtrEntry( vResult, 0 );
- Vec_PtrForEachEntryStart( Vec_Ptr_t *, vResult, vUpper, i, 1 )
- {
- nVol = Llb_ManCutVolume( p, vLower, vUpper );
- if ( nVol <= nVolMax )
- {
- vLower = vUpper;
- continue;
- }
-
- if ( fVeryVerbose )
- Llb_ManCutPrint( p, vLower, vUpper );
- vMinCut = Llb_ManFlowFindBestCut( p, vLower, vUpper, Num );
- if ( vMinCut == NULL )
- {
- if ( fVeryVerbose )
- printf( "Could not break the cut.\n" );
- if ( fVeryVerbose )
- printf( "\n" );
- vLower = vUpper;
- continue;
- }
-
- if ( fVeryVerbose )
- Llb_ManCutPrint( p, vMinCut, vUpper );
- if ( fVeryVerbose )
- Llb_ManCutPrint( p, vLower, vMinCut );
- if ( fVeryVerbose )
- printf( "\n" );
-
- break;
- }
- if ( i == Vec_PtrSize(vResult) )
- break;
- // insert vMinCut before vUpper
- Vec_PtrPush( vResult, NULL );
- for ( k = Vec_PtrSize(vResult) - 1; k > i; k-- )
- Vec_PtrWriteEntry( vResult, k, Vec_PtrEntry(vResult, k-1) );
- Vec_PtrWriteEntry( vResult, i, vMinCut );
- }
- if ( fVerbose )
- {
- printf( "Finished computing %d partitions. ", Vec_PtrSize(vResult) - 1 );
- Abc_PrintTime( 1, "Time", clock() - clk );
- Llb_ManResultPrint( p, vResult );
- }
- return vResult;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_BddSetDefaultParams( Gia_ParLlb_t * p )
-{
- memset( p, 0, sizeof(Gia_ParLlb_t) );
- p->nBddMax = 1000000;
- p->nIterMax = 10000000;
- p->nClusterMax = 20;
- p->nHintDepth = 0;
- p->HintFirst = 0;
- p->fUseFlow = 0; // use flow
- p->nVolumeMax = 100; // max volume
- p->nVolumeMin = 30; // min volume
- p->fReorder = 1;
- p->fIndConstr = 0;
- p->fUsePivots = 0;
- p->fCluster = 0;
- p->fSchedule = 0;
- p->fVerbose = 0;
- p->fVeryVerbose = 0;
- p->fSilent = 0;
- p->TimeLimit = 0;
-// p->TimeLimit = 0;
- p->TimeLimitGlo = 0;
- p->TimeTarget = 0;
- p->iFrame = -1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Finds balanced cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_ManMinCutTest( Aig_Man_t * pAig, int Num )
-{
- extern void Llb_BddConstructTest( Aig_Man_t * p, Vec_Ptr_t * vResult );
- extern void Llb_BddExperiment( Aig_Man_t * pInit, Aig_Man_t * pAig, Gia_ParLlb_t * pPars, Vec_Ptr_t * vResult, Vec_Ptr_t * vMaps );
-
-
- int fVerbose = 1;
- Gia_ParLlb_t Pars, * pPars = &Pars;
- Vec_Ptr_t * vResult;//, * vSupps, * vMaps;
- Aig_Man_t * p;
-
- Llb_BddSetDefaultParams( pPars );
-
- p = Aig_ManDupFlopsOnly( pAig );
-//Aig_ManShow( p, 0, NULL );
- Aig_ManPrintStats( pAig );
- Aig_ManPrintStats( p );
- Aig_ManFanoutStart( p );
-
- vResult = Llb_ManComputeCuts( p, Num, 1, 0 );
-// vSupps = Llb_ManCutSupps( p, vResult );
-// vMaps = Llb_ManCutMap( p, vResult, vSupps );
-
-// Llb_BddExperiment( pAig, p, pPars, vResult, vMaps );
- Llb_CoreExperiment( pAig, p, pPars, vResult, 0 );
-
-// Vec_VecFree( (Vec_Vec_t *)vMaps );
-// Vec_VecFree( (Vec_Vec_t *)vSupps );
- Vec_VecFree( (Vec_Vec_t *)vResult );
-
- Aig_ManFanoutStop( p );
- Aig_ManCleanMarkAB( p );
- Aig_ManStop( p );
-}
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
-ABC_NAMESPACE_IMPL_END
-