src/opt/fxu/fxuCreate.c File Reference

#include "abc.h"
#include "fxuInt.h"
#include "fxu.h"
Include dependency graph for fxuCreate.c:

Go to the source code of this file.

Functions

static void Fxu_CreateMatrixAddCube (Fxu_Matrix *p, Fxu_Cube *pCube, char *pSopCube, Vec_Int_t *vFanins, int *pOrder)
static int Fxu_CreateMatrixLitCompare (int *ptrX, int *ptrY)
static void Fxu_CreateCoversNode (Fxu_Matrix *p, Fxu_Data_t *pData, int iNode, Fxu_Cube *pCubeFirst, Fxu_Cube *pCubeNext)
static Fxu_CubeFxu_CreateCoversFirstCube (Fxu_Matrix *p, Fxu_Data_t *pData, int iNode)
int Fxu_PreprocessCubePairs (Fxu_Matrix *p, Vec_Ptr_t *vCovers, int nPairsTotal, int nPairsMax)
Fxu_MatrixFxu_CreateMatrix (Fxu_Data_t *pData)
void Fxu_CreateCovers (Fxu_Matrix *p, Fxu_Data_t *pData)

Variables

static int * s_pLits

Function Documentation

void Fxu_CreateCovers ( Fxu_Matrix p,
Fxu_Data_t pData 
)

Function*************************************************************

Synopsis [Creates the new array of Sop covers from the sparse matrix.]

Description []

SideEffects []

SeeAlso []

Definition at line 264 of file fxuCreate.c.

00265 {
00266     Fxu_Cube * pCube, * pCubeFirst, * pCubeNext;
00267     char * pSopCover;
00268     int iNode, n;
00269 
00270     // get the first cube of the first internal node 
00271     pCubeFirst = Fxu_CreateCoversFirstCube( p, pData, 0 );
00272 
00273     // go through the internal nodes
00274     for ( n = 0; n < pData->nNodesOld; n++ )
00275     if ( pSopCover = pData->vSops->pArray[n] )
00276     {
00277         // get the number of this node
00278         iNode = n;
00279         // get the next first cube
00280         pCubeNext = Fxu_CreateCoversFirstCube(  p, pData, iNode + 1 );
00281         // check if there any new variables in these cubes
00282         for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
00283             if ( pCube->lLits.pTail && pCube->lLits.pTail->iVar >= 2 * pData->nNodesOld )
00284                 break;
00285         if ( pCube != pCubeNext )
00286             Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext );
00287         // update the first cube
00288         pCubeFirst = pCubeNext;
00289     }
00290 
00291     // add the covers for the extracted nodes
00292     for ( n = 0; n < pData->nNodesNew; n++ )
00293     {
00294         // get the number of this node
00295         iNode = pData->nNodesOld + n;
00296         // get the next first cube
00297         pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 );
00298         // the node should be added
00299         Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext );
00300         // update the first cube
00301         pCubeFirst = pCubeNext;
00302     }
00303 }

Fxu_Cube * Fxu_CreateCoversFirstCube ( Fxu_Matrix p,
Fxu_Data_t pData,
int  iVar 
) [static]

Function*************************************************************

Synopsis [Adds the var to storage.]

Description []

SideEffects []

SeeAlso []

Definition at line 404 of file fxuCreate.c.

00405 {
00406     int v;
00407     for ( v = iVar; v < pData->nNodesOld + pData->nNodesNew; v++ )
00408         if ( p->ppVars[ 2*v + 1 ]->pFirst )
00409             return p->ppVars[ 2*v + 1 ]->pFirst;
00410     return NULL;
00411 }

void Fxu_CreateCoversNode ( Fxu_Matrix p,
Fxu_Data_t pData,
int  iNode,
Fxu_Cube pCubeFirst,
Fxu_Cube pCubeNext 
) [static]

Function*************************************************************

Synopsis [Create Sop covers for one node that has changed.]

Description []

SideEffects []

SeeAlso []

Definition at line 316 of file fxuCreate.c.

00317 {
00318     Vec_Int_t * vInputsNew;
00319     char * pSopCover, * pSopCube;
00320     Fxu_Var * pVar;
00321     Fxu_Cube * pCube;
00322     Fxu_Lit * pLit;
00323     int iNum, nCubes, v;
00324 
00325     // collect positive polarity variable in the cubes between pCubeFirst and pCubeNext
00326     Fxu_MatrixRingVarsStart( p );
00327     for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
00328         for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext )
00329         {
00330             pVar = p->ppVars[ 2 * (pLit->pVar->iVar/2) + 1 ];
00331             if ( pVar->pOrder == NULL )
00332                 Fxu_MatrixRingVarsAdd( p, pVar );
00333         }
00334     Fxu_MatrixRingVarsStop( p );
00335 
00336     // collect the variable numbers
00337     vInputsNew = Vec_IntAlloc( 4 );
00338     Fxu_MatrixForEachVarInRing( p, pVar )
00339         Vec_IntPush( vInputsNew, pVar->iVar / 2 );
00340     Fxu_MatrixRingVarsUnmark( p );
00341 
00342     // sort the vars by their number
00343     Vec_IntSort( vInputsNew, 0 );
00344 
00345     // mark the vars with their numbers in the sorted array
00346     for ( v = 0; v < vInputsNew->nSize; v++ )
00347     {
00348         p->ppVars[ 2 * vInputsNew->pArray[v] + 0 ]->lLits.nItems = v; // hack - reuse lLits.nItems
00349         p->ppVars[ 2 * vInputsNew->pArray[v] + 1 ]->lLits.nItems = v; // hack - reuse lLits.nItems
00350     }
00351 
00352     // count the number of cubes
00353     nCubes = 0;
00354     for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
00355         if ( pCube->lLits.nItems )
00356             nCubes++;
00357 
00358     // allocate room for the new cover
00359     pSopCover = Abc_SopStart( pData->pManSop, nCubes, vInputsNew->nSize );
00360     // set the correct polarity of the cover
00361     if ( iNode < pData->nNodesOld && Abc_SopGetPhase( pData->vSops->pArray[iNode] ) == 0 )
00362         Abc_SopComplement( pSopCover );
00363 
00364     // add the cubes
00365     nCubes = 0;
00366     for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
00367     {
00368         if ( pCube->lLits.nItems == 0 )
00369             continue;
00370         // get hold of the SOP cube
00371         pSopCube = pSopCover + nCubes * (vInputsNew->nSize + 3);
00372         // insert literals
00373         for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext )
00374         {
00375             iNum = pLit->pVar->lLits.nItems; // hack - reuse lLits.nItems
00376             assert( iNum < vInputsNew->nSize );
00377             if ( pLit->pVar->iVar / 2 < pData->nNodesOld )
00378                 pSopCube[iNum] = (pLit->pVar->iVar & 1)? '0' : '1';   // reverse CST
00379             else
00380                 pSopCube[iNum] = (pLit->pVar->iVar & 1)? '1' : '0';   // no CST
00381         }
00382         // count the cube
00383         nCubes++;
00384     }
00385     assert( nCubes == Abc_SopGetCubeNum(pSopCover) );
00386 
00387     // set the new cover and the array of fanins
00388     pData->vSopsNew->pArray[iNode]   = pSopCover;
00389     pData->vFaninsNew->pArray[iNode] = vInputsNew;
00390 }

Fxu_Matrix* Fxu_CreateMatrix ( Fxu_Data_t pData  ) 

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [Creates the sparse matrix from the array of SOPs.]

Description []

SideEffects []

SeeAlso []

Definition at line 50 of file fxuCreate.c.

00051 {
00052     Fxu_Matrix * p;
00053     Fxu_Var * pVar;
00054     Fxu_Cube * pCubeFirst, * pCubeNew;
00055     Fxu_Cube * pCube1, * pCube2;
00056     Vec_Int_t * vFanins;
00057     char * pSopCover;
00058     char * pSopCube;
00059     int * pOrder, nBitsMax;
00060     int i, v, c;
00061     int nCubesTotal;
00062     int nPairsTotal;
00063     int nPairsStore;
00064     int nCubes;
00065     int iCube, iPair;
00066     int nFanins;
00067 
00068     // collect all sorts of statistics
00069     nCubesTotal =  0;
00070     nPairsTotal =  0;
00071     nPairsStore =  0;
00072     nBitsMax    = -1; 
00073     for ( i = 0; i < pData->nNodesOld; i++ )
00074         if ( pSopCover = pData->vSops->pArray[i] )
00075         {
00076             nCubes       = Abc_SopGetCubeNum( pSopCover );
00077             nFanins      = Abc_SopGetVarNum( pSopCover );
00078             assert( nFanins > 1 && nCubes > 0 );
00079 
00080             nCubesTotal += nCubes;
00081             nPairsTotal += nCubes * (nCubes - 1) / 2;
00082             nPairsStore += nCubes * nCubes;
00083             if ( nBitsMax < nFanins )
00084                 nBitsMax = nFanins;
00085         }
00086     if ( nBitsMax <= 0 )
00087     {
00088         printf( "The current network does not have SOPs to perform extraction.\n" );
00089         return NULL;
00090     }
00091 
00092     if ( nPairsStore > 50000000 )
00093     {
00094         printf( "The problem is too large to be solved by \"fxu\" (%d cubes and %d cube pairs)\n", nCubesTotal, nPairsStore );
00095         return NULL;
00096     }
00097 
00098     // start the matrix
00099         p = Fxu_MatrixAllocate();
00100     // create the column labels 
00101     p->ppVars = ALLOC( Fxu_Var *, 2 * (pData->nNodesOld + pData->nNodesExt) );
00102     for ( i = 0; i < 2 * pData->nNodesOld; i++ )
00103         p->ppVars[i] = Fxu_MatrixAddVar( p );
00104 
00105     // allocate storage for all cube pairs at once
00106     p->pppPairs = ALLOC( Fxu_Pair **, nCubesTotal + 100 );
00107     p->ppPairs  = ALLOC( Fxu_Pair *,  nPairsStore + 100 );
00108     memset( p->ppPairs, 0, sizeof(Fxu_Pair *) * nPairsStore );
00109     iCube = 0;
00110     iPair = 0;
00111     for ( i = 0; i < pData->nNodesOld; i++ )
00112         if ( pSopCover = pData->vSops->pArray[i] )
00113         {
00114             // get the number of cubes
00115             nCubes = Abc_SopGetCubeNum( pSopCover );
00116             // get the new var in the matrix
00117             pVar = p->ppVars[2*i+1];
00118             // assign the pair storage
00119             pVar->nCubes     = nCubes;
00120             if ( nCubes > 0 )
00121             {
00122                 pVar->ppPairs    = p->pppPairs + iCube;
00123                 pVar->ppPairs[0] = p->ppPairs  + iPair;
00124                 for ( v = 1; v < nCubes; v++ )
00125                     pVar->ppPairs[v] = pVar->ppPairs[v-1] + nCubes;
00126             }
00127             // update
00128             iCube += nCubes;
00129             iPair += nCubes * nCubes;
00130         }
00131     assert( iCube == nCubesTotal );
00132     assert( iPair == nPairsStore );
00133 
00134 
00135     // allocate room for the reordered literals
00136     pOrder = ALLOC( int, nBitsMax );
00137     // create the rows
00138     for ( i = 0; i < pData->nNodesOld; i++ )
00139     if ( pSopCover = pData->vSops->pArray[i] )
00140     {
00141         // get the new var in the matrix
00142         pVar = p->ppVars[2*i+1];
00143         // here we sort the literals of the cover
00144         // in the increasing order of the numbers of the corresponding nodes
00145         // because literals should be added to the matrix in this order
00146         vFanins = pData->vFanins->pArray[i];
00147         s_pLits = vFanins->pArray;
00148         // start the variable order
00149         nFanins = Abc_SopGetVarNum( pSopCover );
00150         for ( v = 0; v < nFanins; v++ )
00151             pOrder[v] = v;
00152         // reorder the fanins
00153         qsort( (void *)pOrder, nFanins, sizeof(int),(int (*)(const void *, const void *))Fxu_CreateMatrixLitCompare);
00154         assert( s_pLits[ pOrder[0] ] < s_pLits[ pOrder[nFanins-1] ] );
00155         // create the corresponding cubes in the matrix
00156         pCubeFirst = NULL;
00157         c = 0;
00158         Abc_SopForEachCube( pSopCover, nFanins, pSopCube )
00159         {
00160             // create the cube
00161                 pCubeNew = Fxu_MatrixAddCube( p, pVar, c++ );
00162             Fxu_CreateMatrixAddCube( p, pCubeNew, pSopCube, vFanins, pOrder );
00163             if ( pCubeFirst == NULL )
00164                 pCubeFirst = pCubeNew;
00165             pCubeNew->pFirst = pCubeFirst;
00166         }
00167         // set the first cube of this var
00168         pVar->pFirst = pCubeFirst;
00169         // create the divisors without preprocessing
00170         if ( nPairsTotal <= pData->nPairsMax )
00171         {
00172                     for ( pCube1 = pCubeFirst; pCube1; pCube1 = pCube1->pNext )
00173                             for ( pCube2 = pCube1? pCube1->pNext: NULL; pCube2; pCube2 = pCube2->pNext )
00174                                     Fxu_MatrixAddDivisor( p, pCube1, pCube2 );
00175         }
00176     }
00177     FREE( pOrder );
00178 
00179     // consider the case when cube pairs should be preprocessed
00180     // before adding them to the set of divisors
00181 //    if ( pData->fVerbose )
00182 //        printf( "The total number of cube pairs is %d.\n", nPairsTotal );
00183     if ( nPairsTotal > 10000000 )
00184     {
00185         printf( "The total number of cube pairs of the network is more than 10,000,000.\n" );
00186         printf( "Command \"fx\" takes a long time to run in such cases. It is suggested\n" );
00187         printf( "that the user changes the network by reducing the size of logic node and\n" );
00188         printf( "consequently the number of cube pairs to be processed by this command.\n" );
00189         printf( "One way to achieve this is to run the commands \"st; multi -m -F <num>\"\n" );
00190         printf( "as a proprocessing step, while selecting <num> as approapriate.\n" );
00191         return NULL;
00192     }
00193     if ( nPairsTotal > pData->nPairsMax )
00194         if ( !Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax ) )
00195             return NULL;
00196 //    if ( pData->fVerbose )
00197 //        printf( "Only %d best cube pairs will be used by the fast extract command.\n", pData->nPairsMax );
00198 
00199     // add the var pairs to the heap
00200     Fxu_MatrixComputeSingles( p, pData->fUse0, pData->nSingleMax );
00201 
00202     // print stats
00203     if ( pData->fVerbose )
00204     {
00205         double Density;
00206         Density = ((double)p->nEntries) / p->lVars.nItems / p->lCubes.nItems;
00207             fprintf( stdout, "Matrix: [vars x cubes] = [%d x %d]  ",
00208             p->lVars.nItems, p->lCubes.nItems );
00209             fprintf( stdout, "Lits = %d  Density = %.5f%%\n", 
00210             p->nEntries, Density );
00211             fprintf( stdout, "1-cube divs = %6d. (Total = %6d)  ",  p->lSingles.nItems, p->nSingleTotal );
00212             fprintf( stdout, "2-cube divs = %6d. (Total = %6d)",  p->nDivsTotal, nPairsTotal );
00213             fprintf( stdout, "\n" );
00214     }
00215 //    Fxu_MatrixPrint( stdout, p );
00216     return p;
00217 }

void Fxu_CreateMatrixAddCube ( Fxu_Matrix p,
Fxu_Cube pCube,
char *  pSopCube,
Vec_Int_t vFanins,
int *  pOrder 
) [static]

CFile****************************************************************

FileName [fxuCreate.c]

PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]

Synopsis [Create matrix from covers and covers from matrix.]

Author [MVSIS Group]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - February 1, 2003.]

Revision [

Id
fxuCreate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp

] DECLARATIONS ///

Function*************************************************************

Synopsis [Adds one cube with literals to the matrix.]

Description [Create the cube and literals in the matrix corresponding to the given cube in the SOP cover. Co-singleton transform is performed here.]

SideEffects []

SeeAlso []

Definition at line 231 of file fxuCreate.c.

00232 {
00233         Fxu_Var * pVar;
00234     int Value, i;
00235     // add literals to the matrix
00236     Abc_CubeForEachVar( pSopCube, Value, i )
00237     {
00238         Value = pSopCube[pOrder[i]];
00239         if ( Value == '0' )
00240         {
00241             pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] + 1 ];  // CST
00242                     Fxu_MatrixAddLiteral( p, pCube, pVar );
00243         }
00244         else if ( Value == '1' )
00245         {
00246             pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] ];  // CST
00247                     Fxu_MatrixAddLiteral( p, pCube, pVar );
00248         }
00249     }
00250 }

int Fxu_CreateMatrixLitCompare ( int *  ptrX,
int *  ptrY 
) [static]

Function*************************************************************

Synopsis [Compares the vars by their number.]

Description []

SideEffects []

SeeAlso []

Definition at line 424 of file fxuCreate.c.

00425 {
00426     return s_pLits[*ptrX] - s_pLits[*ptrY];
00427 } 

int Fxu_PreprocessCubePairs ( Fxu_Matrix p,
Vec_Ptr_t vCovers,
int  nPairsTotal,
int  nPairsMax 
)

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [Precomputes the pairs to use for creating two-cube divisors.]

Description [This procedure takes the matrix with variables and cubes allocated (p), the original covers of the nodes (i-sets) and their number (ppCovers,nCovers). The maximum number of pairs to compute and the total number of pairs in existence. This procedure adds to the storage of divisors exactly the given number of pairs (nPairsMax) while taking first those pairs that have the smallest number of literals in their cube-free form.]

SideEffects []

SeeAlso []

Definition at line 50 of file fxuReduce.c.

00051 {
00052     unsigned char * pnLitsDiff;   // storage for the counters of diff literals
00053     int * pnPairCounters;         // the counters of pairs for each number of diff literals
00054     Fxu_Cube * pCubeFirst, * pCubeLast;
00055     Fxu_Cube * pCube1, * pCube2;
00056     Fxu_Var * pVar;
00057     int nCubes, nBitsMax, nSum;
00058     int CutOffNum, CutOffQuant;
00059     int iPair, iQuant, k, c;
00060     int clk = clock();
00061     char * pSopCover;
00062     int nFanins;
00063 
00064     assert( nPairsMax < nPairsTotal );
00065 
00066     // allocate storage for counter of diffs
00067     pnLitsDiff = ALLOC( unsigned char, nPairsTotal );
00068     // go through the covers and precompute the distances between the pairs
00069     iPair    =  0;
00070     nBitsMax = -1;
00071     for ( c = 0; c < vCovers->nSize; c++ )
00072         if ( pSopCover = vCovers->pArray[c] )
00073         {
00074             nFanins = Abc_SopGetVarNum(pSopCover);
00075             // precompute the differences
00076             Fxu_CountPairDiffs( pSopCover, pnLitsDiff + iPair );
00077             // update the counter
00078             nCubes = Abc_SopGetCubeNum( pSopCover );
00079             iPair += nCubes * (nCubes - 1) / 2;
00080             if ( nBitsMax < nFanins )
00081                 nBitsMax = nFanins;
00082         }
00083     assert( iPair == nPairsTotal );
00084 
00085     // allocate storage for counters of cube pairs by difference
00086     pnPairCounters = ALLOC( int, 2 * nBitsMax );
00087     memset( pnPairCounters, 0, sizeof(int) * 2 * nBitsMax );
00088     // count the number of different pairs
00089     for ( k = 0; k < nPairsTotal; k++ )
00090         pnPairCounters[ pnLitsDiff[k] ]++;
00091     // determine what pairs to take starting from the lower
00092     // so that there would be exactly pPairsMax pairs
00093     if ( pnPairCounters[0] != 0 )
00094     {
00095         printf( "The SOPs of the nodes are not cube-free. Run \"bdd; sop\" before \"fx\".\n" );
00096         return 0;
00097     }
00098     if ( pnPairCounters[1] != 0 )
00099     {
00100         printf( "The SOPs of the nodes are not SCC-free. Run \"bdd; sop\" before \"fx\".\n" );
00101         return 0;
00102     }
00103     assert( pnPairCounters[0] == 0 ); // otherwise, covers are not dup-free
00104     assert( pnPairCounters[1] == 0 ); // otherwise, covers are not SCC-free
00105     nSum = 0;
00106     for ( k = 0; k < 2 * nBitsMax; k++ )
00107     {
00108         nSum += pnPairCounters[k];
00109         if ( nSum >= nPairsMax )
00110         {
00111             CutOffNum   = k;
00112             CutOffQuant = pnPairCounters[k] - (nSum - nPairsMax);
00113             break;
00114         }
00115     }
00116     FREE( pnPairCounters );
00117 
00118     // set to 0 all the pairs above the cut-off number and quantity
00119     iQuant = 0;
00120     iPair  = 0;
00121     for ( k = 0; k < nPairsTotal; k++ )
00122         if ( pnLitsDiff[k] > CutOffNum ) 
00123             pnLitsDiff[k] = 0;
00124         else if ( pnLitsDiff[k] == CutOffNum )
00125         {
00126             if ( iQuant++ >= CutOffQuant )
00127                 pnLitsDiff[k] = 0;
00128             else
00129                 iPair++;
00130         }
00131         else
00132             iPair++;
00133     assert( iPair == nPairsMax );
00134 
00135     // collect the corresponding pairs and add the divisors
00136     iPair = 0;
00137     for ( c = 0; c < vCovers->nSize; c++ )
00138         if ( pSopCover = vCovers->pArray[c] )
00139         {
00140             // get the var
00141             pVar = p->ppVars[2*c+1];
00142             // get the first cube
00143             pCubeFirst = pVar->pFirst;
00144             // get the last cube
00145             pCubeLast = pCubeFirst;
00146             for ( k = 0; k < pVar->nCubes; k++ )
00147                 pCubeLast = pCubeLast->pNext;
00148             assert( pCubeLast == NULL || pCubeLast->pVar != pVar );
00149 
00150             // go through the cube pairs
00151                     for ( pCube1 = pCubeFirst; pCube1 != pCubeLast; pCube1 = pCube1->pNext )
00152                             for ( pCube2 = pCube1->pNext; pCube2 != pCubeLast; pCube2 = pCube2->pNext )
00153                     if ( pnLitsDiff[iPair++] )
00154                     {   // create the divisors for this pair
00155                             Fxu_MatrixAddDivisor( p, pCube1, pCube2 );
00156                     }
00157         }
00158     assert( iPair == nPairsTotal );
00159     FREE( pnLitsDiff );
00160 //PRT( "Preprocess", clock() - clk );
00161     return 1;
00162 }


Variable Documentation

int* s_pLits [static]

Definition at line 31 of file fxuCreate.c.


Generated on Tue Jan 5 12:19:25 2010 for abc70930 by  doxygen 1.6.1