blob: d032f7cd702d8608da5427e48fd0c09624efadec [file] [log] [blame]
/**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