/**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