| /**CFile**************************************************************** |
| |
| FileName [fxuMatrix.c] |
| |
| PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] |
| |
| Synopsis [Procedures to manipulate the sparse matrix.] |
| |
| Author [MVSIS Group] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - February 1, 2003.] |
| |
| Revision [$Id: fxuMatrix.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "fxuInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Fxu_Matrix * Fxu_MatrixAllocate() |
| { |
| Fxu_Matrix * p; |
| p = ABC_ALLOC( Fxu_Matrix, 1 ); |
| memset( p, 0, sizeof(Fxu_Matrix) ); |
| p->nTableSize = Abc_PrimeCudd(10000); |
| p->pTable = ABC_ALLOC( Fxu_ListDouble, p->nTableSize ); |
| memset( p->pTable, 0, sizeof(Fxu_ListDouble) * p->nTableSize ); |
| #ifndef USE_SYSTEM_MEMORY_MANAGEMENT |
| { |
| // get the largest size in bytes for the following structures: |
| // Fxu_Cube, Fxu_Var, Fxu_Lit, Fxu_Pair, Fxu_Double, Fxu_Single |
| // (currently, Fxu_Var, Fxu_Pair, Fxu_Double take 10 machine words) |
| int nSizeMax, nSizeCur; |
| nSizeMax = -1; |
| nSizeCur = sizeof(Fxu_Cube); |
| if ( nSizeMax < nSizeCur ) |
| nSizeMax = nSizeCur; |
| nSizeCur = sizeof(Fxu_Var); |
| if ( nSizeMax < nSizeCur ) |
| nSizeMax = nSizeCur; |
| nSizeCur = sizeof(Fxu_Lit); |
| if ( nSizeMax < nSizeCur ) |
| nSizeMax = nSizeCur; |
| nSizeCur = sizeof(Fxu_Pair); |
| if ( nSizeMax < nSizeCur ) |
| nSizeMax = nSizeCur; |
| nSizeCur = sizeof(Fxu_Double); |
| if ( nSizeMax < nSizeCur ) |
| nSizeMax = nSizeCur; |
| nSizeCur = sizeof(Fxu_Single); |
| if ( nSizeMax < nSizeCur ) |
| nSizeMax = nSizeCur; |
| p->pMemMan = Extra_MmFixedStart( nSizeMax ); |
| } |
| #endif |
| p->pHeapDouble = Fxu_HeapDoubleStart(); |
| p->pHeapSingle = Fxu_HeapSingleStart(); |
| p->vPairs = Vec_PtrAlloc( 100 ); |
| return p; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_MatrixDelete( Fxu_Matrix * p ) |
| { |
| Fxu_HeapDoubleCheck( p->pHeapDouble ); |
| Fxu_HeapDoubleStop( p->pHeapDouble ); |
| Fxu_HeapSingleStop( p->pHeapSingle ); |
| |
| // delete other things |
| #ifdef USE_SYSTEM_MEMORY_MANAGEMENT |
| // this code is not needed when the custom memory manager is used |
| { |
| Fxu_Cube * pCube, * pCube2; |
| Fxu_Var * pVar, * pVar2; |
| Fxu_Lit * pLit, * pLit2; |
| Fxu_Double * pDiv, * pDiv2; |
| Fxu_Single * pSingle, * pSingle2; |
| Fxu_Pair * pPair, * pPair2; |
| int i; |
| // delete the divisors |
| Fxu_MatrixForEachDoubleSafe( p, pDiv, pDiv2, i ) |
| { |
| Fxu_DoubleForEachPairSafe( pDiv, pPair, pPair2 ) |
| MEM_FREE_FXU( p, Fxu_Pair, 1, pPair ); |
| MEM_FREE_FXU( p, Fxu_Double, 1, pDiv ); |
| } |
| Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 ) |
| MEM_FREE_FXU( p, Fxu_Single, 1, pSingle ); |
| // delete the entries |
| Fxu_MatrixForEachCube( p, pCube ) |
| Fxu_CubeForEachLiteralSafe( pCube, pLit, pLit2 ) |
| MEM_FREE_FXU( p, Fxu_Lit, 1, pLit ); |
| // delete the cubes |
| Fxu_MatrixForEachCubeSafe( p, pCube, pCube2 ) |
| MEM_FREE_FXU( p, Fxu_Cube, 1, pCube ); |
| // delete the vars |
| Fxu_MatrixForEachVariableSafe( p, pVar, pVar2 ) |
| MEM_FREE_FXU( p, Fxu_Var, 1, pVar ); |
| } |
| #else |
| Extra_MmFixedStop( p->pMemMan ); |
| #endif |
| |
| Vec_PtrFree( p->vPairs ); |
| ABC_FREE( p->pppPairs ); |
| ABC_FREE( p->ppPairs ); |
| // ABC_FREE( p->pPairsTemp ); |
| ABC_FREE( p->pTable ); |
| ABC_FREE( p->ppVars ); |
| ABC_FREE( p ); |
| } |
| |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Adds a variable to the matrix.] |
| |
| Description [This procedure always adds variables at the end of the matrix. |
| It assigns the var's node and number. It adds the var to the linked list of |
| all variables and to the table of all nodes.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p ) |
| { |
| Fxu_Var * pVar; |
| pVar = MEM_ALLOC_FXU( p, Fxu_Var, 1 ); |
| memset( pVar, 0, sizeof(Fxu_Var) ); |
| pVar->iVar = p->lVars.nItems; |
| p->ppVars[pVar->iVar] = pVar; |
| Fxu_ListMatrixAddVariable( p, pVar ); |
| return pVar; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Adds a literal to the matrix.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube ) |
| { |
| Fxu_Cube * pCube; |
| pCube = MEM_ALLOC_FXU( p, Fxu_Cube, 1 ); |
| memset( pCube, 0, sizeof(Fxu_Cube) ); |
| pCube->pVar = pVar; |
| pCube->iCube = iCube; |
| Fxu_ListMatrixAddCube( p, pCube ); |
| return pCube; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Adds a literal to the matrix.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar ) |
| { |
| Fxu_Lit * pLit; |
| pLit = MEM_ALLOC_FXU( p, Fxu_Lit, 1 ); |
| memset( pLit, 0, sizeof(Fxu_Lit) ); |
| // insert the literal into two linked lists |
| Fxu_ListCubeAddLiteral( pCube, pLit ); |
| Fxu_ListVarAddLiteral( pVar, pLit ); |
| // set the back pointers |
| pLit->pCube = pCube; |
| pLit->pVar = pVar; |
| pLit->iCube = pCube->iCube; |
| pLit->iVar = pVar->iVar; |
| // increment the literal counter |
| p->nEntries++; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Deletes the divisor from the matrix.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ) |
| { |
| // delete divisor from the table |
| Fxu_ListTableDelDivisor( p, pDiv ); |
| // recycle the divisor |
| MEM_FREE_FXU( p, Fxu_Double, 1, pDiv ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Deletes the literal fromthe matrix.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit ) |
| { |
| // delete the literal |
| Fxu_ListCubeDelLiteral( pLit->pCube, pLit ); |
| Fxu_ListVarDelLiteral( pLit->pVar, pLit ); |
| MEM_FREE_FXU( p, Fxu_Lit, 1, pLit ); |
| // increment the literal counter |
| p->nEntries--; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates and adds a single cube divisor.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight ) |
| { |
| Fxu_Single * pSingle; |
| assert( pVar1->iVar < pVar2->iVar ); |
| pSingle = MEM_ALLOC_FXU( p, Fxu_Single, 1 ); |
| memset( pSingle, 0, sizeof(Fxu_Single) ); |
| pSingle->Num = p->lSingles.nItems; |
| pSingle->Weight = Weight; |
| pSingle->HNum = 0; |
| pSingle->pVar1 = pVar1; |
| pSingle->pVar2 = pVar2; |
| Fxu_ListMatrixAddSingle( p, pSingle ); |
| // add to the heap |
| Fxu_HeapSingleInsert( p->pHeapSingle, pSingle ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ) |
| { |
| Fxu_Pair * pPair; |
| Fxu_Double * pDiv; |
| int nBase, nLits1, nLits2; |
| int fFound; |
| unsigned Key; |
| |
| // canonicize the pair |
| Fxu_PairCanonicize( &pCube1, &pCube2 ); |
| // compute the hash key |
| Key = Fxu_PairHashKey( p, pCube1, pCube2, &nBase, &nLits1, &nLits2 ); |
| |
| // create the cube pair |
| pPair = Fxu_PairAlloc( p, pCube1, pCube2 ); |
| pPair->nBase = nBase; |
| pPair->nLits1 = nLits1; |
| pPair->nLits2 = nLits2; |
| |
| // check if the divisor for this pair already exists |
| fFound = 0; |
| Key %= p->nTableSize; |
| Fxu_TableForEachDouble( p, Key, pDiv ) |
| { |
| if ( Fxu_PairCompare( pPair, pDiv->lPairs.pTail ) ) // they are equal |
| { |
| fFound = 1; |
| break; |
| } |
| } |
| |
| if ( !fFound ) |
| { // create the new divisor |
| pDiv = MEM_ALLOC_FXU( p, Fxu_Double, 1 ); |
| memset( pDiv, 0, sizeof(Fxu_Double) ); |
| pDiv->Key = Key; |
| // set the number of this divisor |
| pDiv->Num = p->nDivsTotal++; // p->nDivs; |
| // insert the divisor in the table |
| Fxu_ListTableAddDivisor( p, pDiv ); |
| // set the initial cost of the divisor |
| pDiv->Weight -= pPair->nLits1 + pPair->nLits2; |
| } |
| |
| // link the pair to the cubes |
| Fxu_PairAdd( pPair ); |
| // connect the pair and the divisor |
| pPair->pDiv = pDiv; |
| Fxu_ListDoubleAddPairLast( pDiv, pPair ); |
| // update the max number of pairs in a divisor |
| // if ( p->nPairsMax < pDiv->lPairs.nItems ) |
| // p->nPairsMax = pDiv->lPairs.nItems; |
| // update the divisor's weight |
| pDiv->Weight += pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase; |
| if ( fFound ) // update the divisor in the heap |
| Fxu_HeapDoubleUpdate( p->pHeapDouble, pDiv ); |
| else // add the new divisor to the heap |
| Fxu_HeapDoubleInsert( p->pHeapDouble, pDiv ); |
| } |
| |
| /* |
| { |
| int piVarsC1[100], piVarsC2[100], nVarsC1, nVarsC2; |
| Fxu_Double * pDivCur; |
| Fxu_MatrixGetDoubleVars( p, pDiv, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); |
| pDivCur = Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 ); |
| assert( pDivCur == pDiv ); |
| } |
| */ |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |