/**CFile**************************************************************** FileName [llb1Cluster.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [BDD based reachability.] Synopsis [Clustering algorithm.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: llb1Cluster.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "llbInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Llb_ManComputeCommonQuant( Llb_Mtr_t * p, int iCol1, int iCol2 ) { int iVar, Weight = 0; for ( iVar = 0; iVar < p->nRows - p->nFfs; iVar++ ) { // count each removed variable as 2 if ( p->pMatrix[iCol1][iVar] == 1 && p->pMatrix[iCol2][iVar] == 1 && p->pRowSums[iVar] == 2 ) Weight += 2; // count each added variale as -1 else if ( (p->pMatrix[iCol1][iVar] == 1 && p->pMatrix[iCol2][iVar] == 0) || (p->pMatrix[iCol1][iVar] == 0 && p->pMatrix[iCol2][iVar] == 1) ) Weight--; } return Weight; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Llb_ManComputeBestQuant( Llb_Mtr_t * p ) { int i, k, WeightBest = -100000, WeightCur, RetValue = -1; for ( i = 1; i < p->nCols-1; i++ ) for ( k = i+1; k < p->nCols-1; k++ ) { if ( p->pColSums[i] == 0 || p->pColSums[i] > p->pMan->pPars->nClusterMax ) continue; if ( p->pColSums[k] == 0 || p->pColSums[k] > p->pMan->pPars->nClusterMax ) continue; WeightCur = Llb_ManComputeCommonQuant( p, i, k ); if ( WeightCur <= 0 ) continue; if ( WeightBest < WeightCur ) { WeightBest = WeightCur; RetValue = (i << 16) | k; } } // printf( "Choosing best quant Weight %4d\n", WeightCur ); return RetValue; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float ** Llb_ManComputeQuant( Llb_Mtr_t * p ) { float ** pCosts; int i, k; // alloc and clean pCosts = (float **)Extra_ArrayAlloc( p->nCols, p->nCols, sizeof(float) ); for ( i = 0; i < p->nCols; i++ ) for ( k = 0; k < p->nCols; k++ ) pCosts[i][i] = 0.0; // fill up for ( i = 1; i < p->nCols-1; i++ ) for ( k = i+1; k < p->nCols-1; k++ ) pCosts[i][k] = pCosts[k][i] = Llb_ManComputeCommonQuant( p, i, k ); return pCosts; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float Llb_ManComputeCommonAttr( Llb_Mtr_t * p, int iCol1, int iCol2 ) { int iVar, CountComm = 0, CountDiff = 0; for ( iVar = 0; iVar < p->nRows - p->nFfs; iVar++ ) { if ( p->pMatrix[iCol1][iVar] == 1 && p->pMatrix[iCol2][iVar] == 1 ) CountComm++; else if ( p->pMatrix[iCol1][iVar] == 1 || p->pMatrix[iCol2][iVar] == 1 ) CountDiff++; } /* printf( "Attr cost for %4d and %4d: %4d %4d (%5.2f)\n", iCol1, iCol2, CountDiff, CountComm, -1.0 * CountDiff / ( CountComm + CountDiff ) ); */ return -1.0 * CountDiff / ( CountComm + CountDiff ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Llb_ManComputeBestAttr( Llb_Mtr_t * p ) { float WeightBest = -100000, WeightCur; int i, k, RetValue = -1; for ( i = 1; i < p->nCols-1; i++ ) for ( k = i+1; k < p->nCols-1; k++ ) { if ( p->pColSums[i] == 0 || p->pColSums[i] > p->pMan->pPars->nClusterMax ) continue; if ( p->pColSums[k] == 0 || p->pColSums[k] > p->pMan->pPars->nClusterMax ) continue; WeightCur = Llb_ManComputeCommonAttr( p, i, k ); if ( WeightBest < WeightCur ) { WeightBest = WeightCur; RetValue = (i << 16) | k; } } return RetValue; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float ** Llb_ManComputeAttr( Llb_Mtr_t * p ) { float ** pCosts; int i, k; // alloc and clean pCosts = (float **)Extra_ArrayAlloc( p->nCols, p->nCols, sizeof(float) ); for ( i = 0; i < p->nCols; i++ ) for ( k = 0; k < p->nCols; k++ ) pCosts[i][i] = 0.0; // fill up for ( i = 1; i < p->nCols-1; i++ ) for ( k = i+1; k < p->nCols-1; k++ ) pCosts[i][k] = pCosts[k][i] = Llb_ManComputeCommonAttr( p, i, k ); return pCosts; } /**Function************************************************************* Synopsis [Returns the number of variables that will be saved.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Llb_MtrCombineSelectedColumns( Llb_Mtr_t * p, int iGrp1, int iGrp2 ) { int iVar; assert( iGrp1 >= 1 && iGrp1 < p->nCols - 1 ); assert( iGrp2 >= 1 && iGrp2 < p->nCols - 1 ); assert( p->pColGrps[iGrp1] != NULL ); assert( p->pColGrps[iGrp2] != NULL ); for ( iVar = 0; iVar < p->nRows; iVar++ ) { if ( p->pMatrix[iGrp1][iVar] == 1 && p->pMatrix[iGrp2][iVar] == 1 ) p->pRowSums[iVar]--; if ( p->pMatrix[iGrp1][iVar] == 0 && p->pMatrix[iGrp2][iVar] == 1 ) { p->pMatrix[iGrp1][iVar] = 1; p->pColSums[iGrp1]++; } if ( p->pMatrix[iGrp2][iVar] == 1 ) p->pMatrix[iGrp2][iVar] = 0; } p->pColSums[iGrp2] = 0; } /**Function************************************************************* Synopsis [Combines one pair of columns.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Llb_ManClusterOne( Llb_Mtr_t * p, int iCol1, int iCol2 ) { int fVerbose = 0; Llb_Grp_t * pGrp; int iVar; if ( fVerbose ) { printf( "Combining %d and %d\n", iCol1, iCol2 ); for ( iVar = 0; iVar < p->nRows; iVar++ ) { if ( p->pMatrix[iCol1][iVar] == 0 && p->pMatrix[iCol2][iVar] == 0 ) continue; printf( "%3d : %c%c\n", iVar, p->pMatrix[iCol1][iVar]? '*':' ', p->pMatrix[iCol2][iVar]? '*':' ' ); } } pGrp = Llb_ManGroupsCombine( p->pColGrps[iCol1], p->pColGrps[iCol2] ); Llb_MtrCombineSelectedColumns( p, iCol1, iCol2 ); p->pColGrps[iCol1] = pGrp; p->pColGrps[iCol2] = NULL; } /**Function************************************************************* Synopsis [Removes empty columns.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Llb_ManClusterCompress( Llb_Mtr_t * p ) { int i, k = 0; for ( i = 0; i < p->nCols; i++ ) { if ( p->pColGrps[i] == NULL ) { assert( p->pColSums[i] == 0 ); assert( p->pMatrix[i] != NULL ); ABC_FREE( p->pMatrix[i] ); continue; } p->pMatrix[k] = p->pMatrix[i]; p->pColGrps[k] = p->pColGrps[i]; p->pColSums[k] = p->pColSums[i]; k++; } p->nCols = k; } /**Function************************************************************* Synopsis [Combines one pair of columns.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Llb_ManCluster( Llb_Mtr_t * p ) { int RetValue; do { do { RetValue = Llb_ManComputeBestQuant( p ); if ( RetValue > 0 ) Llb_ManClusterOne( p, RetValue >> 16, RetValue & 0xffff ); } while ( RetValue > 0 ); RetValue = Llb_ManComputeBestAttr( p ); if ( RetValue > 0 ) Llb_ManClusterOne( p, RetValue >> 16, RetValue & 0xffff ); Llb_MtrVerifyMatrix( p ); } while ( RetValue > 0 ); Llb_ManClusterCompress( p ); Llb_MtrVerifyMatrix( p ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END