Esempio n. 1
0
/**Function********************************************************************

  Synopsis    [Reads the variable group tree from a file.]

  Description [Reads the variable group tree from a file.
  Returns 1 if successful; 0 otherwise.]

  SideEffects [None]

  SeeAlso     []

*****************************************************************************/
static int
ntrReadTree(
  DdManager * dd,
  char * treefile,
  int  nvars)
{
    FILE *fp;
    MtrNode *root;

    if (treefile == NULL) {
	return(1);
    }

    if ((fp = fopen(treefile,"r")) == NULL) {
	(void) fprintf(stderr,"Unable to open %s\n",treefile);
	return(0);
    }

    root = Mtr_ReadGroups(fp,ddMax(Cudd_ReadSize(dd),nvars));
    if (root == NULL) {
	return(0);
    }

    Cudd_SetTree(dd,root);

    return(1);

} /* end of ntrReadTree */
Esempio n. 2
0
/**Function********************************************************************

  Synopsis    [Creates a new ZDD variable group.]

  Description [Creates a new ZDD variable group. The group starts at
  variable and contains size variables. The parameter low is the index
  of the first variable. If the variable already exists, its current
  position in the order is known to the manager. If the variable does
  not exist yet, the position is assumed to be the same as the index.
  The group tree is created if it does not exist yet.
  Returns a pointer to the group if successful; NULL otherwise.]

  SideEffects [The ZDD variable tree is changed.]

  SeeAlso     [Cudd_MakeTreeNode]

******************************************************************************/
MtrNode *
Cudd_MakeZddTreeNode(
  DdManager * dd /* manager */,
  unsigned int  low /* index of the first group variable */,
  unsigned int  size /* number of variables in the group */,
  unsigned int  type /* MTR_DEFAULT or MTR_FIXED */)
{
    MtrNode *group;
    MtrNode *tree;
    unsigned int level;

    /* If the variable does not exist yet, the position is assumed to be
    ** the same as the index. Therefore, applications that rely on
    ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new
    ** variables have to create the variables before they group them.
    */
    level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low;

    if (level + size - 1> (int) MTR_MAXHIGH)
	return(NULL);

    /* If the tree does not exist yet, create it. */
    tree = dd->treeZ;
    if (tree == NULL) {
	dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ);
	if (tree == NULL)
	    return(NULL);
	tree->index = dd->invpermZ[0];
    }

    /* Extend the upper bound of the tree if necessary. This allows the
    ** application to create groups even before the variables are created.
    */
    tree->size = ddMax(tree->size, level + size);

    /* Create the group. */
    group = Mtr_MakeGroup(tree, level, size, type);
    if (group == NULL)
	return(NULL);

    /* Initialize the index field to the index of the variable currently
    ** in position low. This field will be updated by the reordering
    ** procedure to provide a handle to the group once it has been moved.
    */
    group->index = (MtrHalfWord) low;

    return(group);

} /* end of Cudd_MakeZddTreeNode */
Esempio n. 3
0
/**Function********************************************************************

  Synopsis    [Reads in a matrix in the format of the Harwell-Boeing
  benchmark suite.]

  Description [Reads in a matrix in the format of the Harwell-Boeing
  benchmark suite. The variables are ordered as follows:
  <blockquote>
  x\[0\] y\[0\] x\[1\] y\[1\] ...
  </blockquote>
  0 is the most significant bit.  On input, nx and ny hold the numbers
  of row and column variables already in existence. On output, they
  hold the numbers of row and column variables actually used by the
  matrix.  m and n are set to the numbers of rows and columns of the
  matrix.  Their values on input are immaterial.  Returns 1 on
  success; 0 otherwise. The ADD for the sparse matrix is returned in
  E, and its reference count is > 0.]

  SideEffects [None]

  SeeAlso     [Cudd_addRead Cudd_bddRead]

******************************************************************************/
int
Cudd_addHarwell(
  FILE * fp /* pointer to the input file */,
  DdManager * dd /* DD manager */,
  DdNode ** E /* characteristic function of the graph */,
  DdNode *** x /* array of row variables */,
  DdNode *** y /* array of column variables */,
  DdNode *** xn /* array of complemented row variables */,
  DdNode *** yn_ /* array of complemented column variables */,
  int * nx /* number or row variables */,
  int * ny /* number or column variables */,
  int * m /* number of rows */,
  int * n /* number of columns */,
  int  bx /* first index of row variables */,
  int  sx /* step of row variables */,
  int  by /* first index of column variables */,
  int  sy /* step of column variables */,
  int  pr /* verbosity level */)
{
    DdNode *one, *zero;
    DdNode *w;
    DdNode *cubex, *cubey, *minterm1;
    int u, v, err, i, j, nv;
    double val;
    DdNode **lx, **ly, **lxn, **lyn;	/* local copies of x, y, xn, yn_ */
    int lnx, lny;			/* local copies of nx and ny */
    char title[73], key[9], mxtype[4], rhstyp[4];
    int totcrd, ptrcrd, indcrd, valcrd, rhscrd,
        nrow, ncol, nnzero, neltvl,
	nrhs, nrhsix;
    int *colptr, *rowind;
#if 0
    int nguess, nexact;
    int	*rhsptr, *rhsind;
#endif

    if (*nx < 0 || *ny < 0) return(0);

    one = DD_ONE(dd);
    zero = DD_ZERO(dd);

    /* Read the header */
    err = fscanf(fp, "%72c %8c", title, key);
    if (err == EOF) {
	return(0);
    } else if (err != 2) {
        return(0);
    }
    title[72] = (char) 0;
    key[8] = (char) 0;

    err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd,
    &valcrd, &rhscrd);
    if (err == EOF) {
	return(0);
    } else if (err != 5) {
        return(0);
    }

    err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol,
    &nnzero, &neltvl);
    if (err == EOF) {
	return(0);
    } else if (err != 5) {
        return(0);
    }

    /* Skip FORTRAN formats */
    if (rhscrd == 0) {
	err = fscanf(fp, "%*s %*s %*s \n");
    } else {
	err = fscanf(fp, "%*s %*s %*s %*s \n");
    }
    if (err == EOF) {
	return(0);
    } else if (err != 0) {
        return(0);
    }

    /* Print out some stuff if requested to be verbose */
    if (pr>0) {
	(void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key,
	mxtype, nrow, ncol, nnzero);
	if (pr>1) (void) fprintf(dd->out,"%s\n", title);
    }

    /* Check matrix type */
    if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') {
	(void) fprintf(dd->err,"%s: Illegal matrix type: %s\n",
		       key, mxtype);
	return(0);
    }
    if (neltvl != 0) return(0);

    /* Read optional 5-th line */
    if (rhscrd != 0) {
	err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix);
	if (err == EOF) {
	    return(0);
	} else if (err != 3) {
	    return(0);
	}
	rhstyp[3] = (char) 0;
	if (rhstyp[0] != 'F') {
	    (void) fprintf(dd->err,
	    "%s: Sparse right-hand side not yet supported\n", key);
	    return(0);
	}
	if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs);
    } else {
	nrhs = 0;
    }

    /* Compute the number of variables */

    /* row and column numbers start from 0 */
    u = nrow - 1;
    for (i=0; u > 0; i++) {
	u >>= 1;
    }
    lnx = i;
    if (nrhs == 0) {
	v = ncol - 1;
    } else {
	v = 2* (ddMax(ncol, nrhs) - 1);
    }
    for (i=0; v > 0; i++) {
	v >>= 1;
    }
    lny = i;

    /* Allocate or reallocate arrays for variables as needed */
    if (*nx == 0) {
	if (lnx > 0) {
	    *x = lx = ALLOC(DdNode *,lnx);
	    if (lx == NULL) {
		dd->errorCode = CUDD_MEMORY_OUT;
		return(0);
	    }
	    *xn = lxn =  ALLOC(DdNode *,lnx);
	    if (lxn == NULL) {
		dd->errorCode = CUDD_MEMORY_OUT;
		return(0);
	    }
	} else {
Esempio n. 4
0
File: reoCore.c Progetto: mrkj/abc
/**Function*************************************************************

  Synopsis    []

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
void reoReorderArray( reo_man * p, DdManager * dd, DdNode * Funcs[], DdNode * FuncsRes[], int nFuncs, int * pOrder )
{
	int Counter, i;

	// set the initial parameters
	p->dd     = dd;
	p->pOrder = pOrder;
	p->nTops  = nFuncs;
	// get the initial number of nodes
	p->nNodesBeg = Cudd_SharingSize( Funcs, nFuncs );     
	// resize the internal data structures of the manager if necessary
	reoResizeStructures( p, ddMax(dd->size,dd->sizeZ), p->nNodesBeg, nFuncs );
	// compute the support
	p->pSupp = Extra_VectorSupportArray( dd, Funcs, nFuncs, p->pSupp );
	// get the number of support variables
	p->nSupp = 0;
	for ( i = 0; i < dd->size; i++ )
		p->nSupp += p->pSupp[i];

	// if it is the constant function, no need to reorder
	if ( p->nSupp == 0 )
	{
		for ( i = 0; i < nFuncs; i++ )
		{
			FuncsRes[i] = Funcs[i]; Cudd_Ref( FuncsRes[i] );
		}
		return;
	}

	// create the internal variable maps
	// go through variable levels in the manager
	Counter = 0;
	for ( i = 0; i < dd->size; i++ )
		if ( p->pSupp[ dd->invperm[i] ] )
		{
			p->pMapToPlanes[ dd->invperm[i] ] = Counter;
			p->pMapToDdVarsOrig[Counter]      = dd->invperm[i];
			if ( !p->fRemapUp )
				p->pMapToDdVarsFinal[Counter] = dd->invperm[i];
			else
				p->pMapToDdVarsFinal[Counter] = dd->invperm[Counter];
			p->pOrderInt[Counter]        = Counter;
			Counter++;
		}

	// set the initial parameters
	p->nUnitsUsed = 0;
	p->nNodesCur  = 0;
	p->fThisIsAdd = 0;
	p->Signature++;
	// transfer the function from the CUDD package into REO"s internal data structure
	for ( i = 0; i < nFuncs; i++ )
		p->pTops[i] = reoTransferNodesToUnits_rec( p, Funcs[i] );
	assert( p->nNodesBeg == p->nNodesCur );

	if ( !p->fThisIsAdd && p->fMinWidth )
	{
		printf( "An important message from the REO reordering engine:\n" );
		printf( "The BDD given to the engine for reordering contains complemented edges.\n" );
		printf( "Currently, such BDDs cannot be reordered for the minimum width.\n" );
		printf( "Therefore, minimization for the number of BDD nodes is performed.\n" );
		fflush( stdout );
		p->fMinApl   = 0;
		p->fMinWidth = 0;
	}

	if ( p->fMinWidth )
		reoProfileWidthStart(p);
	else if ( p->fMinApl )
		reoProfileAplStart(p);
	else 
		reoProfileNodesStart(p);

	if ( p->fVerbose )
	{
		printf( "INITIAL: " );
		if ( p->fMinWidth )
			reoProfileWidthPrint(p);
		else if ( p->fMinApl )
			reoProfileAplPrint(p);
		else
			reoProfileNodesPrint(p);
	}
 
	///////////////////////////////////////////////////////////////////
	// performs the reordering
	p->nSwaps   = 0;
	p->nNISwaps = 0;
	for ( i = 0; i < p->nIters; i++ )
	{
		reoReorderSift( p );
		// print statistics after each iteration
		if ( p->fVerbose )
		{
			printf( "ITER #%d: ", i+1 );
			if ( p->fMinWidth )
				reoProfileWidthPrint(p);
			else if ( p->fMinApl )
				reoProfileAplPrint(p);
			else
				reoProfileNodesPrint(p);
		}
		// if the cost function did not change, stop iterating
		if ( p->fMinWidth )
		{
			p->nWidthEnd = p->nWidthCur;
			assert( p->nWidthEnd <= p->nWidthBeg );
			if ( p->nWidthEnd == p->nWidthBeg )
				break;
		}
		else if ( p->fMinApl )
		{
			p->nAplEnd = p->nAplCur;
			assert( p->nAplEnd <= p->nAplBeg );
			if ( p->nAplEnd == p->nAplBeg )
				break;
		}
		else
		{
			p->nNodesEnd = p->nNodesCur;
			assert( p->nNodesEnd <= p->nNodesBeg );
			if ( p->nNodesEnd == p->nNodesBeg )
				break;
		}
	}
	assert( reoCheckLevels( p ) );
	///////////////////////////////////////////////////////////////////

s_AplBefore = p->nAplBeg;
s_AplAfter  = p->nAplEnd;

	// set the initial parameters
	p->nRefNodes  = 0;
	p->nNodesCur  = 0;
	p->Signature++;
	// transfer the BDDs from REO's internal data structure to CUDD
	for ( i = 0; i < nFuncs; i++ )
	{
		FuncsRes[i] = reoTransferUnitsToNodes_rec( p, p->pTops[i] ); Cudd_Ref( FuncsRes[i] );
	}
	// undo the DDs referenced for storing in the cache
	for ( i = 0; i < p->nRefNodes; i++ )
		Cudd_RecursiveDeref( dd, p->pRefNodes[i] );
	// verify zero refs of the terminal nodes
	for ( i = 0; i < nFuncs; i++ )
	{
		assert( reoRecursiveDeref( p->pTops[i] ) );
	}
	assert( reoCheckZeroRefs( &(p->pPlanes[p->nSupp]) ) );

	// prepare the variable map to return to the user
	if ( p->pOrder )
	{
		// i is the current level in the planes data structure
		// p->pOrderInt[i] is the original level in the planes data structure
		// p->pMapToDdVarsOrig[i] is the variable, into which we remap when we construct the BDD from planes
		// p->pMapToDdVarsOrig[ p->pOrderInt[i] ] is the original BDD variable corresponding to this level
		// Therefore, p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ]
		// creates the permutation, which remaps the resulting BDD variable into the original BDD variable
		for ( i = 0; i < p->nSupp; i++ )
			p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ]; 
	}

	if ( p->fVerify )
	{
		int fVerification;
		DdNode * FuncRemapped;
		int * pOrder;

		if ( p->pOrder == NULL )
		{
			pOrder = ABC_ALLOC( int, p->nSupp );
			for ( i = 0; i < p->nSupp; i++ )
				pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ]; 
		}