abc/src/bdd/cudd/cuddSymmetry.c
/**Function********************************************************************

  Synopsis    [Symmetric sifting algorithm.]

  Description [Symmetric sifting algorithm.
  Assumes that no dead nodes are present.
    <ol>
    <li> Order all the variables according to the number of entries in
    each unique subtable.
    <li> Sift the variable up and down, remembering each time the total
    size of the DD heap and grouping variables that are symmetric.
    <li> Select the best permutation.
    <li> Repeat 3 and 4 for all variables.
    </ol>
  Returns 1 plus the number of symmetric variables if successful; 0
  otherwise.]

  SideEffects [None]

  SeeAlso     [cuddSymmSiftingConv]

******************************************************************************/
Function
Synopsis    [Symmetric sifting algorithm.]

Description [Symmetric sifting algorithm.
Assumes that no dead nodes are present.

 Order all the variables according to the number of entries in
each unique subtable.
 Sift the variable up and down, remembering each time the total
size of the DD heap and grouping variables that are symmetric.
 Select the best permutation.
 Repeat 3 and 4 for all variables.

Returns 1 plus the number of symmetric variables if successful; 0
otherwise.]




Function Synopsis [ Symmetric sifting algorithm . ] Description [ Symmetric sifting algorithm . Assumes that no dead nodes are present . Order all the variables according to the number of entries in each unique subtable . Sift the variable up and down remembering each time the total size of the DD heap and grouping variables that are symmetric . Select the best permutation . Repeat 3 and 4 for all variables . Returns 1 plus the number of symmetric variables if successful ; 0 otherwise . ]
int
cuddSymmSifting(
  DdManager * table,
  int  lower,
  int  upper)
{
    int         i;
    int         *var;
    int         size;
    int         x;
    int         result;
    int         symvars;
    int         symgroups;
#ifdef DD_STATS
    int         previousSize;
#endif
    size = table->size;
    var = NULL;
    entry = ABC_ALLOC(int,size);
    if (entry == NULL) {
        table->errorCode = CUDD_MEMORY_OUT;
        goto ddSymmSiftingOutOfMem;
    }
    var = ABC_ALLOC(int,size);
    if (var == NULL) {
        table->errorCode = CUDD_MEMORY_OUT;
        goto ddSymmSiftingOutOfMem;
    }
    for (i = 0; i < size; i++) {
        x = table->perm[i];
        entry[i] = table->subtables[x].keys;
        var[i] = i;
    }
    qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
    for (i = lower; i <= upper; i++) {
        table->subtables[i].next = i;
    }
    for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
        if (ddTotalNumberSwapping >= table->siftMaxSwap)
            break;
        if ( table->TimeStop && Abc_Clock() > table->TimeStop )
            break;
        x = table->perm[var[i]];
#ifdef DD_STATS
        previousSize = table->keys - table->isolated;
#endif
        if (x < lower || x > upper) continue;
        if (table->subtables[x].next == (unsigned) x) {
            result = ddSymmSiftingAux(table,x,lower,upper);
            if (!result) goto ddSymmSiftingOutOfMem;
#ifdef DD_STATS
            if (table->keys < (unsigned) previousSize + table->isolated) {
                (void) fprintf(table->out,"-");
            } else if (table->keys > (unsigned) previousSize +
                       table->isolated) {
                (void) fprintf(table->out,"+"); 
            } else {
                (void) fprintf(table->out,"=");
            }
            fflush(table->out);
#endif
        }
    }
    ABC_FREE(var);
    ABC_FREE(entry);
    ddSymmSummary(table, lower, upper, &symvars, &symgroups);
#ifdef DD_STATS
    (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
                   symvars);
    (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
                   symgroups);
#endif
    return(1+symvars);
ddSymmSiftingOutOfMem:
    if (entry != NULL) ABC_FREE(entry);
    if (var != NULL) ABC_FREE(var);
    return(0);
}
int cuddSymmSifting ( DdManager * table , int lower , int upper ) { int i ; int * var ; int size ; int x ; int result ; int symvars ; int symgroups ; #ifdef DD_STATS int previousSize ; #endif size = table -> size ; var = NULL ; entry = ABC_ALLOC ( int , size ) ; if ( entry == NULL ) { table -> errorCode = CUDD_MEMORY_OUT ; goto ddSymmSiftingOutOfMem ; } var = ABC_ALLOC ( int , size ) ; if ( var == NULL ) { table -> errorCode = CUDD_MEMORY_OUT ; goto ddSymmSiftingOutOfMem ; } for ( i = 0 ; i < size ; i ++ ) { x = table -> perm [ i ] ; entry [ i ] = table -> subtables [ x ] . keys ; var [ i ] = i ; } qsort ( ( void * ) var , size , sizeof ( int ) , ( DD_QSFP ) ddSymmUniqueCompare ) ; for ( i = lower ; i <= upper ; i ++ ) { table -> subtables [ i ] . next = i ; } for ( i = 0 ; i < ddMin ( table -> siftMaxVar , size ) ; i ++ ) { if ( ddTotalNumberSwapping >= table -> siftMaxSwap ) break ; if ( table -> TimeStop && Abc_Clock ( ) > table -> TimeStop ) break ; x = table -> perm [ var [ i ] ] ; #ifdef DD_STATS previousSize = table -> keys - table -> isolated ; #endif if ( x < lower || x > upper ) continue ; if ( table -> subtables [ x ] . next == ( unsigned ) x ) { result = ddSymmSiftingAux ( table , x , lower , upper ) ; if ( ! result ) goto ddSymmSiftingOutOfMem ; #ifdef DD_STATS if ( table -> keys < ( unsigned ) previousSize + table -> isolated ) { ( void ) fprintf ( table -> out , " " ) ; } else if ( table -> keys > ( unsigned ) previousSize + table -> isolated ) { ( void ) fprintf ( table -> out , " " ) ; } else { ( void ) fprintf ( table -> out , " " ) ; } fflush ( table -> out ) ; #endif } } ABC_FREE ( var ) ; ABC_FREE ( entry ) ; ddSymmSummary ( table , lower , upper , & symvars , & symgroups ) ; #ifdef DD_STATS ( void ) fprintf ( table -> out , " \n \n " , symvars ) ; ( void ) fprintf ( table -> out , " " , symgroups ) ; #endif return ( 1 + symvars ) ; ddSymmSiftingOutOfMem : if ( entry != NULL ) ABC_FREE ( entry ) ; if ( var != NULL ) ABC_FREE ( var ) ; return ( 0 ) ; }
Function
Synopsis    [Symmetric sifting algorithm.]
Function Synopsis [ Symmetric sifting algorithm . ]
/* Find order in which to sift variables. */ /* Initialize the symmetry of each subtable to itself. */ // enable timeout during variable reodering - alanmi 2/13/11 /* should never happen */