You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1365 lines
42 KiB
1365 lines
42 KiB
/**
|
|
@file
|
|
|
|
@ingroup nanotrav
|
|
|
|
@brief Main program for the nanotrav program.
|
|
|
|
@author Fabio Somenzi
|
|
|
|
@copyright@parblock
|
|
Copyright (c) 1995-2015, Regents of the University of Colorado
|
|
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
Neither the name of the University of Colorado nor the names of its
|
|
contributors may be used to endorse or promote products derived from
|
|
this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
@endparblock
|
|
|
|
*/
|
|
|
|
#include "cuddInt.h"
|
|
#include "ntr.h"
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Constant declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#define NTR_VERSION "Nanotrav Version #0.13, Release date 2015/7/15"
|
|
|
|
#define BUFLENGTH 8192
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Stucture declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Type declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Variable declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
static char buffer[BUFLENGTH];
|
|
#ifdef DD_DEBUG
|
|
extern st_table *checkMinterms (BnetNetwork *net, DdManager *dd, st_table *previous);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Macro declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** \cond */
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Static function prototypes */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
static NtrOptions * mainInit ();
|
|
static void ntrReadOptions (int argc, char **argv, NtrOptions *option);
|
|
static void ntrReadOptionsFile (char *name, char ***argv, int *argc);
|
|
static char* readLine (FILE *fp);
|
|
static FILE * open_file (char *filename, const char *mode);
|
|
static int reorder (BnetNetwork *net, DdManager *dd, NtrOptions *option);
|
|
static void freeOption (NtrOptions *option);
|
|
static DdManager * startCudd (NtrOptions *option, int nvars);
|
|
static int ntrReadTree (DdManager *dd, char *treefile, int nvars);
|
|
|
|
/** \endcond */
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of exported functions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
@brief Main program for ntr.
|
|
|
|
@details Performs initialization. Reads command line options and
|
|
network(s). Builds BDDs with reordering, and optionally does
|
|
reachability analysis. Prints stats.
|
|
|
|
@sideeffect None
|
|
|
|
*/
|
|
int
|
|
main(
|
|
int argc,
|
|
char ** argv)
|
|
{
|
|
NtrOptions *option; /* options */
|
|
FILE *fp1; /* first network file pointer */
|
|
BnetNetwork *net1 = NULL; /* first network */
|
|
FILE *fp2; /* second network file pointer */
|
|
BnetNetwork *net2 = NULL; /* second network */
|
|
DdManager *dd; /* pointer to DD manager */
|
|
int exitval; /* return value of Cudd_CheckZeroRef */
|
|
int ok; /* overall return value from main() */
|
|
int result; /* stores the return value of functions */
|
|
BnetNode *node; /* auxiliary pointer to network node */
|
|
int i; /* loop index */
|
|
int j; /* loop index */
|
|
double *signatures; /* array of signatures */
|
|
int pr; /* verbosity level */
|
|
int reencoded; /* linear transformations attempted */
|
|
|
|
/* Initialize. */
|
|
#if defined(_WIN32) && defined(_TWO_DIGIT_EXPONENT)
|
|
(void) _set_output_format(_TWO_DIGIT_EXPONENT);
|
|
#endif
|
|
option = mainInit();
|
|
ntrReadOptions(argc,argv,option);
|
|
pr = option->verb;
|
|
reencoded = option->reordering == CUDD_REORDER_LINEAR ||
|
|
option->reordering == CUDD_REORDER_LINEAR_CONVERGE ||
|
|
option->autoMethod == CUDD_REORDER_LINEAR ||
|
|
option->autoMethod == CUDD_REORDER_LINEAR_CONVERGE;
|
|
/* Currently traversal requires global BDDs. Override whatever
|
|
** was specified for locGlob.
|
|
*/
|
|
if (option->traverse == TRUE || option->envelope == TRUE ||
|
|
option->scc == TRUE) {
|
|
option->locGlob = BNET_GLOBAL_DD;
|
|
}
|
|
|
|
/* Read the first network... */
|
|
fp1 = open_file(option->file1, "r");
|
|
net1 = Bnet_ReadNetwork(fp1,pr);
|
|
(void) fclose(fp1);
|
|
if (net1 == NULL) {
|
|
(void) fprintf(stderr,"Syntax error in %s.\n",option->file1);
|
|
exit(2);
|
|
}
|
|
/* ... and optionally echo it to the standard output. */
|
|
if (pr > 2) {
|
|
Bnet_PrintNetwork(net1);
|
|
}
|
|
|
|
/* Read the second network... */
|
|
if (option->verify == TRUE || option->second == TRUE ||
|
|
option->clip > 0.0 || option->dontcares) {
|
|
fp2 = open_file(option->file2, "r");
|
|
net2 = Bnet_ReadNetwork(fp2,pr);
|
|
(void) fclose(fp2);
|
|
if (net2 == NULL) {
|
|
(void) fprintf(stderr,"Syntax error in %s.\n",option->file2);
|
|
exit(2);
|
|
}
|
|
/* ... and optionally echo it to the standard output. */
|
|
if (pr > 2) {
|
|
Bnet_PrintNetwork(net2);
|
|
}
|
|
}
|
|
|
|
/* Initialize manager. We start with 0 variables, because
|
|
** Ntr_buildDDs will create new variables rather than using
|
|
** whatever already exists.
|
|
*/
|
|
dd = startCudd(option,net1->ninputs);
|
|
if (dd == NULL) { exit(2); }
|
|
|
|
/* Build the BDDs for the nodes of the first network. */
|
|
result = Ntr_buildDDs(net1,dd,option,NULL);
|
|
if (result == 0) { exit(2); }
|
|
|
|
/* Build the BDDs for the nodes of the second network if requested. */
|
|
if (option->verify == TRUE || option->second == TRUE ||
|
|
option->clip > 0.0 || option->dontcares == TRUE) {
|
|
char *nodesave = option->node;
|
|
option->node = NULL;
|
|
result = Ntr_buildDDs(net2,dd,option,net1);
|
|
option->node = nodesave;
|
|
if (result == 0) { exit(2); }
|
|
}
|
|
|
|
if (option->noBuild == TRUE) {
|
|
Bnet_FreeNetwork(net1);
|
|
if (option->verify == TRUE || option->second == TRUE ||
|
|
option->clip > 0.0) {
|
|
Bnet_FreeNetwork(net2);
|
|
}
|
|
freeOption(option);
|
|
exit(0);
|
|
}
|
|
if (option->locGlob != BNET_LOCAL_DD) {
|
|
/* Print the order before the final reordering. */
|
|
(void) printf("Order before final reordering\n");
|
|
result = Bnet_PrintOrder(net1,dd);
|
|
if (result == 0) exit(2);
|
|
}
|
|
|
|
/* Perform final reordering */
|
|
if (option->zddtest == FALSE) {
|
|
result = reorder(net1,dd,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Print final order. */
|
|
if ((option->reordering != CUDD_REORDER_NONE || option->gaOnOff) &&
|
|
option->locGlob != BNET_LOCAL_DD) {
|
|
(void) printf("New order\n");
|
|
result = Bnet_PrintOrder(net1,dd);
|
|
if (result == 0) exit(2);
|
|
}
|
|
|
|
/* Print the re-encoded inputs. */
|
|
if (pr >= 1 && reencoded == 1) {
|
|
for (i = 0; i < net1->npis; i++) {
|
|
if (!st_lookup(net1->hash,net1->inputs[i],(void **)&node)) {
|
|
exit(2);
|
|
}
|
|
(void) fprintf(stdout,"%s ",node->name);
|
|
Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr);
|
|
}
|
|
for (i = 0; i < net1->nlatches; i++) {
|
|
if (!st_lookup(net1->hash,net1->latches[i][1],(void **)&node)) {
|
|
exit(2);
|
|
}
|
|
(void) fprintf(stdout,"%s ",node->name);
|
|
Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr);
|
|
}
|
|
if (pr >= 3) {
|
|
result = Cudd_PrintLinear(dd);
|
|
if (result == 0) exit(2);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Verify (combinational) equivalence. */
|
|
if (option->verify == TRUE) {
|
|
result = Ntr_VerifyEquivalence(dd,net1,net2,option);
|
|
if (result == 0) {
|
|
(void) printf("Verification abnormally terminated\n");
|
|
exit(2);
|
|
} else if (result == -1) {
|
|
(void) printf("Combinational verification failed\n");
|
|
} else {
|
|
(void) printf("Verification succeeded\n");
|
|
}
|
|
}
|
|
|
|
/* Traverse if requested and if the circuit is sequential. */
|
|
result = Ntr_Trav(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Traverse with trasitive closure. */
|
|
result = Ntr_ClosureTrav(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Compute outer envelope if requested and if the circuit is sequential. */
|
|
if (option->envelope == TRUE && net1->nlatches > 0) {
|
|
NtrPartTR *T;
|
|
T = Ntr_buildTR(dd,net1,option,option->image);
|
|
result = Ntr_Envelope(dd,T,NULL,option);
|
|
if (result == 0) exit(2);
|
|
Ntr_freeTR(dd,T);
|
|
}
|
|
|
|
/* Compute SCCs if requested and if the circuit is sequential. */
|
|
result = Ntr_SCC(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test Constrain Decomposition. */
|
|
if (option->partition == TRUE && net1->nlatches > 0) {
|
|
NtrPartTR *T;
|
|
DdNode *product;
|
|
DdNode **decomp;
|
|
int sharingSize;
|
|
T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO);
|
|
decomp = Cudd_bddConstrainDecomp(dd,T->part[0]);
|
|
if (decomp == NULL) exit(2);
|
|
sharingSize = Cudd_SharingSize(decomp, Cudd_ReadSize(dd));
|
|
(void) fprintf(stdout, "Decomposition Size: %d components %d nodes\n",
|
|
Cudd_ReadSize(dd), sharingSize);
|
|
product = Cudd_ReadOne(dd);
|
|
Cudd_Ref(product);
|
|
for (i = 0; i < Cudd_ReadSize(dd); i++) {
|
|
DdNode *intermediate = Cudd_bddAnd(dd, product, decomp[i]);
|
|
if (intermediate == NULL) {
|
|
exit(2);
|
|
}
|
|
Cudd_Ref(intermediate);
|
|
Cudd_IterDerefBdd(dd, product);
|
|
product = intermediate;
|
|
}
|
|
if (product != T->part[0])
|
|
exit(2);
|
|
Cudd_IterDerefBdd(dd, product);
|
|
for (i = 0; i < Cudd_ReadSize(dd); i++) {
|
|
Cudd_IterDerefBdd(dd, decomp[i]);
|
|
}
|
|
FREE(decomp);
|
|
Ntr_freeTR(dd,T);
|
|
}
|
|
|
|
/* Test char-to-vect conversion. */
|
|
result = Ntr_TestCharToVect(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test extraction of two-literal clauses. */
|
|
result = Ntr_TestTwoLiteralClauses(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test BDD minimization functions. */
|
|
result = Ntr_TestMinimization(dd,net1,net2,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test density-related functions. */
|
|
result = Ntr_TestDensity(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test decomposition functions. */
|
|
result = Ntr_TestDecomp(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test cofactor estimation functions. */
|
|
result = Ntr_TestCofactorEstimate(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test BDD clipping functions. */
|
|
result = Ntr_TestClipping(dd,net1,net2,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test BDD equivalence and containment under DC functions. */
|
|
result = Ntr_TestEquivAndContain(dd,net1,net2,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test BDD Cudd_bddClosestCube. */
|
|
result = Ntr_TestClosestCube(dd,net1,option);
|
|
if (result == 0) exit(2);
|
|
|
|
/* Test ZDDs if requested. */
|
|
if (option->stateOnly == FALSE && option->zddtest == TRUE) {
|
|
result = Ntr_testZDD(dd,net1,option);
|
|
if (result == 0)
|
|
(void) fprintf(stdout,"ZDD test failed.\n");
|
|
result = Ntr_testISOP(dd,net1,option);
|
|
if (result == 0)
|
|
(void) fprintf(stdout,"ISOP test failed.\n");
|
|
}
|
|
|
|
/* Compute maximum flow if requested and if the circuit is sequential. */
|
|
if (option->maxflow == TRUE && net1->nlatches > 0) {
|
|
result = Ntr_maxflow(dd,net1,option);
|
|
if (result == 0)
|
|
(void) fprintf(stdout,"Maxflow computation failed.\n");
|
|
}
|
|
|
|
/* Compute shortest paths if requested and if the circuit is sequential. */
|
|
if (option->shortPath != NTR_SHORT_NONE && net1->nlatches > 0) {
|
|
result = Ntr_ShortestPaths(dd,net1,option);
|
|
if (result == 0)
|
|
(void) fprintf(stdout,"Shortest paths computation failed.\n");
|
|
}
|
|
|
|
/* Compute output signatures if so requested. */
|
|
if (option->signatures) {
|
|
(void) printf("Positive cofactor measures\n");
|
|
for (i = 0; i < net1->noutputs; i++) {
|
|
if (!st_lookup(net1->hash,net1->outputs[i],(void **)&node)) {
|
|
exit(2);
|
|
}
|
|
signatures = Cudd_CofMinterm(dd, node->dd);
|
|
if (signatures) {
|
|
(void) printf("%s:\n", node->name);
|
|
for (j = 0; j < Cudd_ReadSize(dd); j++) {
|
|
if((j%5 == 0)&&i) (void) printf("\n");
|
|
(void) printf("%5d: %-#8.4g ", j, signatures[j]);
|
|
}
|
|
(void) printf("\n");
|
|
FREE(signatures);
|
|
} else {
|
|
(void) printf("Signature computation failed.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Dump BDDs if so requested. */
|
|
if (option->bdddump && option->second == FALSE &&
|
|
option->density == FALSE && option->decomp == FALSE &&
|
|
option->cofest == FALSE && option->clip < 0.0 &&
|
|
option->scc == FALSE) {
|
|
(void) printf("Dumping BDDs to %s\n", option->dumpfile);
|
|
if (option->node != NULL) {
|
|
if (!st_lookup(net1->hash,option->node,(void **)&node)) {
|
|
exit(2);
|
|
}
|
|
result = Bnet_bddArrayDump(dd,net1,option->dumpfile,&(node->dd),
|
|
&(node->name),1,option->dumpFmt);
|
|
} else {
|
|
result = Bnet_bddDump(dd, net1, option->dumpfile,
|
|
option->dumpFmt, reencoded);
|
|
}
|
|
if (result != 1) {
|
|
(void) printf("BDD dump failed.\n");
|
|
}
|
|
}
|
|
|
|
/* Print stats and clean up. */
|
|
if (pr >= 0) {
|
|
result = Cudd_PrintInfo(dd,stdout);
|
|
if (result != 1) {
|
|
(void) printf("Cudd_PrintInfo failed.\n");
|
|
}
|
|
}
|
|
|
|
#if defined(DD_DEBUG) && !defined(DD_NO_DEATH_ROW)
|
|
(void) fprintf(dd->err,"%d empty slots in death row\n",
|
|
cuddTimesInDeathRow(dd,NULL));
|
|
#endif
|
|
(void) printf("Final size: %ld\n", Cudd_ReadNodeCount(dd));
|
|
|
|
/* Dispose of node BDDs. */
|
|
node = net1->nodes;
|
|
while (node != NULL) {
|
|
if (node->dd != NULL &&
|
|
node->type != BNET_INPUT_NODE &&
|
|
node->type != BNET_PRESENT_STATE_NODE) {
|
|
Cudd_IterDerefBdd(dd,node->dd);
|
|
node->dd = NULL;
|
|
}
|
|
node = node->next;
|
|
}
|
|
/* Dispose of network. */
|
|
Bnet_FreeNetwork(net1);
|
|
/* Do the same cleanup for the second network if it was created. */
|
|
if (option->verify == TRUE || option->second == TRUE ||
|
|
option->clip > 0.0 || option->dontcares == TRUE) {
|
|
/* Since option->second is TRUE and reading the second network
|
|
* didn't result in a failure, we know net2 is not NULL. */
|
|
assert(net2 != NULL);
|
|
node = net2->nodes;
|
|
while (node != NULL) {
|
|
if (node->dd != NULL &&
|
|
node->type != BNET_INPUT_NODE &&
|
|
node->type != BNET_PRESENT_STATE_NODE) {
|
|
Cudd_IterDerefBdd(dd,node->dd);
|
|
node->dd = NULL;
|
|
}
|
|
node = node->next;
|
|
}
|
|
Bnet_FreeNetwork(net2);
|
|
}
|
|
|
|
/* Check reference counts: At this point we should have dereferenced
|
|
** everything we had, except in the case of re-encoding.
|
|
*/
|
|
if (reencoded == CUDD_FALSE) {
|
|
exitval = Cudd_CheckZeroRef(dd);
|
|
ok = exitval != 0; /* ok == 0 means O.K. */
|
|
if (exitval != 0) {
|
|
(void) fflush(stdout);
|
|
(void) fprintf(stderr,
|
|
"%d non-zero DD reference counts after dereferencing\n", exitval);
|
|
}
|
|
} else {
|
|
ok = 0;
|
|
}
|
|
|
|
#ifdef DD_DEBUG
|
|
Cudd_CheckKeys(dd);
|
|
#endif
|
|
|
|
Cudd_Quit(dd);
|
|
|
|
if (pr >= 0) (void) printf("total time = %s\n",
|
|
util_print_time(util_cpu_time() - option->initialTime));
|
|
freeOption(option);
|
|
if (pr >= 0) util_print_cpu_stats(stdout);
|
|
|
|
exit(ok);
|
|
|
|
} /* end of main */
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of internal functions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of static functions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/**
|
|
@brief Allocates the option structure and initializes it.
|
|
|
|
@sideeffect none
|
|
|
|
@see ntrReadOptions
|
|
|
|
*/
|
|
static NtrOptions *
|
|
mainInit(
|
|
)
|
|
{
|
|
NtrOptions *option;
|
|
|
|
/* Initialize option structure. */
|
|
option = ALLOC(NtrOptions,1);
|
|
option->initialTime = util_cpu_time();
|
|
option->verify = FALSE;
|
|
option->second = FALSE;
|
|
option->file1 = NULL;
|
|
option->file2 = NULL;
|
|
option->traverse = FALSE;
|
|
option->depend = FALSE;
|
|
option->image = NTR_IMAGE_MONO;
|
|
option->imageClip = 1.0;
|
|
option->approx = NTR_UNDER_APPROX;
|
|
option->threshold = -1;
|
|
option->from = NTR_FROM_NEW;
|
|
option->groupnsps = NTR_GROUP_NONE;
|
|
option->closure = FALSE;
|
|
option->closureClip = 1.0;
|
|
option->envelope = FALSE;
|
|
option->scc = FALSE;
|
|
option->maxflow = FALSE;
|
|
option->shortPath = NTR_SHORT_NONE;
|
|
option->selectiveTrace = FALSE;
|
|
option->zddtest = FALSE;
|
|
option->printcover = FALSE;
|
|
option->sinkfile = NULL;
|
|
option->partition = FALSE;
|
|
option->char2vect = FALSE;
|
|
option->density = FALSE;
|
|
option->quality = 1.0;
|
|
option->decomp = FALSE;
|
|
option->cofest = FALSE;
|
|
option->clip = -1.0;
|
|
option->dontcares = FALSE;
|
|
option->closestCube = FALSE;
|
|
option->clauses = FALSE;
|
|
option->noBuild = FALSE;
|
|
option->stateOnly = FALSE;
|
|
option->node = NULL;
|
|
option->locGlob = BNET_GLOBAL_DD;
|
|
option->progress = FALSE;
|
|
option->cacheSize = 32768;
|
|
option->maxMemory = 0; /* set automatically */
|
|
option->maxMemHard = 0; /* don't set */
|
|
option->maxLive = ~0U; /* very large number */
|
|
option->slots = CUDD_UNIQUE_SLOTS;
|
|
option->ordering = PI_PS_FROM_FILE;
|
|
option->orderPiPs = NULL;
|
|
option->reordering = CUDD_REORDER_NONE;
|
|
option->autoMethod = CUDD_REORDER_SIFT;
|
|
option->autoDyn = 0;
|
|
option->treefile = NULL;
|
|
option->firstReorder = DD_FIRST_REORDER;
|
|
option->countDead = FALSE;
|
|
option->maxGrowth = 20;
|
|
option->groupcheck = CUDD_GROUP_CHECK7;
|
|
option->arcviolation = 10;
|
|
option->symmviolation = 10;
|
|
option->recomb = DD_DEFAULT_RECOMB;
|
|
option->nodrop = TRUE;
|
|
option->signatures = FALSE;
|
|
option->verb = 0;
|
|
option->gaOnOff = 0;
|
|
option->populationSize = 0; /* use default */
|
|
option->numberXovers = 0; /* use default */
|
|
option->bdddump = FALSE;
|
|
option->dumpFmt = 0; /* dot */
|
|
option->dumpfile = NULL;
|
|
option->store = -1; /* do not store */
|
|
option->storefile = NULL;
|
|
option->load = FALSE;
|
|
option->loadfile = NULL;
|
|
option->seed = 1;
|
|
|
|
return(option);
|
|
|
|
} /* end of mainInit */
|
|
|
|
|
|
/**
|
|
@brief Reads the command line options.
|
|
|
|
@details Scans the command line one argument at a time and performs
|
|
a switch on each arguement it hits. Some arguemnts also read in the
|
|
following arg from the list (i.e., -f also gets the filename which
|
|
should folow.) Gives a usage message and exits if any unrecognized
|
|
args are found.
|
|
|
|
@sideeffect May initialize the random number generator.
|
|
|
|
@see mainInit ntrReadOptionsFile
|
|
|
|
*/
|
|
static void
|
|
ntrReadOptions(
|
|
int argc,
|
|
char ** argv,
|
|
NtrOptions * option)
|
|
{
|
|
int i = 0;
|
|
|
|
if (argc < 2) goto usage;
|
|
|
|
if (STRING_EQUAL(argv[1],"-f")) {
|
|
ntrReadOptionsFile(argv[2],&argv,&argc);
|
|
}
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
if (argv[i][0] != '-' ) {
|
|
if (option->file1 == NULL) {
|
|
option->file1 = util_strsav(argv[i]);
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-second")) {
|
|
i++;
|
|
option->file2 = util_strsav(argv[i]);
|
|
option->second = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-verify")) {
|
|
i++;
|
|
option->file2 = util_strsav(argv[i]);
|
|
option->verify = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-trav")) {
|
|
option->traverse = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-depend")) {
|
|
option->traverse = TRUE;
|
|
option->depend = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-image")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"part")) {
|
|
option->image = NTR_IMAGE_PART;
|
|
} else if (STRING_EQUAL(argv[i],"clip")) {
|
|
option->image = NTR_IMAGE_CLIP;
|
|
} else if (STRING_EQUAL(argv[i],"depend")) {
|
|
option->image = NTR_IMAGE_DEPEND;
|
|
} else if (STRING_EQUAL(argv[i],"mono")) {
|
|
option->image = NTR_IMAGE_MONO;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-depth")) {
|
|
i++;
|
|
option->imageClip = (double) atof(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-cdepth")) {
|
|
i++;
|
|
option->closureClip = (double) atof(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-approx")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"under")) {
|
|
option->approx = NTR_UNDER_APPROX;
|
|
} else if (STRING_EQUAL(argv[i],"over")) {
|
|
option->approx = NTR_OVER_APPROX;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-threshold")) {
|
|
i++;
|
|
option->threshold = (int) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-from")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"new")) {
|
|
option->from = NTR_FROM_NEW;
|
|
} else if (STRING_EQUAL(argv[i],"reached")) {
|
|
option->from = NTR_FROM_REACHED;
|
|
} else if (STRING_EQUAL(argv[i],"restrict")) {
|
|
option->from = NTR_FROM_RESTRICT;
|
|
} else if (STRING_EQUAL(argv[i],"compact")) {
|
|
option->from = NTR_FROM_COMPACT;
|
|
} else if (STRING_EQUAL(argv[i],"squeeze")) {
|
|
option->from = NTR_FROM_SQUEEZE;
|
|
} else if (STRING_EQUAL(argv[i],"subset")) {
|
|
option->from = NTR_FROM_UNDERAPPROX;
|
|
} else if (STRING_EQUAL(argv[i],"superset")) {
|
|
option->from = NTR_FROM_OVERAPPROX;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-groupnsps")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"none")) {
|
|
option->groupnsps = NTR_GROUP_NONE;
|
|
} else if (STRING_EQUAL(argv[i],"default")) {
|
|
option->groupnsps = NTR_GROUP_DEFAULT;
|
|
} else if (STRING_EQUAL(argv[i],"fixed")) {
|
|
option->groupnsps = NTR_GROUP_FIXED;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-closure")) {
|
|
option->closure = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-envelope")) {
|
|
option->envelope = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-scc")) {
|
|
option->scc = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-maxflow")) {
|
|
option->maxflow = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-shortpaths")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"none")) {
|
|
option->shortPath = NTR_SHORT_NONE;
|
|
} else if (STRING_EQUAL(argv[i],"bellman")) {
|
|
option->shortPath = NTR_SHORT_BELLMAN;
|
|
} else if (STRING_EQUAL(argv[i],"floyd")) {
|
|
option->shortPath = NTR_SHORT_FLOYD;
|
|
} else if (STRING_EQUAL(argv[i],"square")) {
|
|
option->shortPath = NTR_SHORT_SQUARE;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-selective")) {
|
|
option->selectiveTrace = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-zdd")) {
|
|
option->zddtest = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-cover")) {
|
|
option->zddtest = TRUE;
|
|
option->printcover = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-sink")) {
|
|
i++;
|
|
option->maxflow = TRUE;
|
|
option->sinkfile = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-part")) {
|
|
option->partition = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-char2vect")) {
|
|
option->char2vect = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-density")) {
|
|
option->density = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-quality")) {
|
|
i++;
|
|
option->quality = (double) atof(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-decomp")) {
|
|
option->decomp = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-cofest")) {
|
|
option->cofest = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-clip")) {
|
|
i++;
|
|
option->clip = (double) atof(argv[i]);
|
|
i++;
|
|
option->file2 = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-dctest")) {
|
|
option->dontcares = TRUE;
|
|
i++;
|
|
option->file2 = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-closest")) {
|
|
option->closestCube = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-clauses")) {
|
|
option->clauses = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-nobuild")) {
|
|
option->noBuild = TRUE;
|
|
option->reordering = CUDD_REORDER_NONE;
|
|
} else if (STRING_EQUAL(argv[i],"-delta")) {
|
|
option->stateOnly = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-node")) {
|
|
i++;
|
|
option->node = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-local")) {
|
|
option->locGlob = BNET_LOCAL_DD;
|
|
} else if (STRING_EQUAL(argv[i],"-progress")) {
|
|
option->progress = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-cache")) {
|
|
i++;
|
|
option->cacheSize = (int) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-maxmem")) {
|
|
i++;
|
|
option->maxMemory = 1048576 * (int) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-memhard")) {
|
|
i++;
|
|
option->maxMemHard = 1048576 * (int) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-maxlive")) {
|
|
i++;
|
|
option->maxLive = (unsigned int) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-slots")) {
|
|
i++;
|
|
option->slots = (int) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-ordering")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"dfs")) {
|
|
option->ordering = PI_PS_DFS;
|
|
} else if (STRING_EQUAL(argv[i],"hw")) {
|
|
option->ordering = PI_PS_FROM_FILE;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-order")) {
|
|
i++;
|
|
option->ordering = PI_PS_GIVEN;
|
|
option->orderPiPs = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-reordering")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"none")) {
|
|
option->reordering = CUDD_REORDER_NONE;
|
|
} else if (STRING_EQUAL(argv[i],"random")) {
|
|
option->reordering = CUDD_REORDER_RANDOM;
|
|
} else if (STRING_EQUAL(argv[i],"bernard") ||
|
|
STRING_EQUAL(argv[i],"pivot")) {
|
|
option->reordering = CUDD_REORDER_RANDOM_PIVOT;
|
|
} else if (STRING_EQUAL(argv[i],"sifting")) {
|
|
option->reordering = CUDD_REORDER_SIFT;
|
|
} else if (STRING_EQUAL(argv[i],"converge")) {
|
|
option->reordering = CUDD_REORDER_SIFT_CONVERGE;
|
|
} else if (STRING_EQUAL(argv[i],"symm")) {
|
|
option->reordering = CUDD_REORDER_SYMM_SIFT;
|
|
} else if (STRING_EQUAL(argv[i],"cosymm")) {
|
|
option->reordering = CUDD_REORDER_SYMM_SIFT_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"tree") ||
|
|
STRING_EQUAL(argv[i],"group")) {
|
|
option->reordering = CUDD_REORDER_GROUP_SIFT;
|
|
} else if (STRING_EQUAL(argv[i],"cotree") ||
|
|
STRING_EQUAL(argv[i],"cogroup")) {
|
|
option->reordering = CUDD_REORDER_GROUP_SIFT_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"win2")) {
|
|
option->reordering = CUDD_REORDER_WINDOW2;
|
|
} else if (STRING_EQUAL(argv[i],"win3")) {
|
|
option->reordering = CUDD_REORDER_WINDOW3;
|
|
} else if (STRING_EQUAL(argv[i],"win4")) {
|
|
option->reordering = CUDD_REORDER_WINDOW4;
|
|
} else if (STRING_EQUAL(argv[i],"win2conv")) {
|
|
option->reordering = CUDD_REORDER_WINDOW2_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"win3conv")) {
|
|
option->reordering = CUDD_REORDER_WINDOW3_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"win4conv")) {
|
|
option->reordering = CUDD_REORDER_WINDOW4_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"annealing")) {
|
|
option->reordering = CUDD_REORDER_ANNEALING;
|
|
} else if (STRING_EQUAL(argv[i],"genetic")) {
|
|
option->reordering = CUDD_REORDER_GENETIC;
|
|
} else if (STRING_EQUAL(argv[i],"linear")) {
|
|
option->reordering = CUDD_REORDER_LINEAR;
|
|
} else if (STRING_EQUAL(argv[i],"linconv")) {
|
|
option->reordering = CUDD_REORDER_LINEAR_CONVERGE;
|
|
} else if (STRING_EQUAL(argv[i],"exact")) {
|
|
option->reordering = CUDD_REORDER_EXACT;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-autodyn")) {
|
|
option->autoDyn = 3;
|
|
} else if (STRING_EQUAL(argv[i],"-autodynB")) {
|
|
option->autoDyn |= 1;
|
|
} else if (STRING_EQUAL(argv[i],"-autodynZ")) {
|
|
option->autoDyn |= 2;
|
|
} else if (STRING_EQUAL(argv[i],"-automethod")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"none")) {
|
|
option->autoMethod = CUDD_REORDER_NONE;
|
|
} else if (STRING_EQUAL(argv[i],"random")) {
|
|
option->autoMethod = CUDD_REORDER_RANDOM;
|
|
} else if (STRING_EQUAL(argv[i],"bernard") ||
|
|
STRING_EQUAL(argv[i],"pivot")) {
|
|
option->autoMethod = CUDD_REORDER_RANDOM_PIVOT;
|
|
} else if (STRING_EQUAL(argv[i],"sifting")) {
|
|
option->autoMethod = CUDD_REORDER_SIFT;
|
|
} else if (STRING_EQUAL(argv[i],"converge")) {
|
|
option->autoMethod = CUDD_REORDER_SIFT_CONVERGE;
|
|
} else if (STRING_EQUAL(argv[i],"symm")) {
|
|
option->autoMethod = CUDD_REORDER_SYMM_SIFT;
|
|
} else if (STRING_EQUAL(argv[i],"cosymm")) {
|
|
option->autoMethod = CUDD_REORDER_SYMM_SIFT_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"tree") ||
|
|
STRING_EQUAL(argv[i],"group")) {
|
|
option->autoMethod = CUDD_REORDER_GROUP_SIFT;
|
|
} else if (STRING_EQUAL(argv[i],"cotree") ||
|
|
STRING_EQUAL(argv[i],"cogroup")) {
|
|
option->autoMethod = CUDD_REORDER_GROUP_SIFT_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"win2")) {
|
|
option->autoMethod = CUDD_REORDER_WINDOW2;
|
|
} else if (STRING_EQUAL(argv[i],"win3")) {
|
|
option->autoMethod = CUDD_REORDER_WINDOW3;
|
|
} else if (STRING_EQUAL(argv[i],"win4")) {
|
|
option->autoMethod = CUDD_REORDER_WINDOW4;
|
|
} else if (STRING_EQUAL(argv[i],"win2conv")) {
|
|
option->autoMethod = CUDD_REORDER_WINDOW2_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"win3conv")) {
|
|
option->autoMethod = CUDD_REORDER_WINDOW3_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"win4conv")) {
|
|
option->autoMethod = CUDD_REORDER_WINDOW4_CONV;
|
|
} else if (STRING_EQUAL(argv[i],"annealing")) {
|
|
option->autoMethod = CUDD_REORDER_ANNEALING;
|
|
} else if (STRING_EQUAL(argv[i],"genetic")) {
|
|
option->autoMethod = CUDD_REORDER_GENETIC;
|
|
} else if (STRING_EQUAL(argv[i],"linear")) {
|
|
option->autoMethod = CUDD_REORDER_LINEAR;
|
|
} else if (STRING_EQUAL(argv[i],"linconv")) {
|
|
option->autoMethod = CUDD_REORDER_LINEAR_CONVERGE;
|
|
} else if (STRING_EQUAL(argv[i],"exact")) {
|
|
option->autoMethod = CUDD_REORDER_EXACT;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-tree")) {
|
|
i++;
|
|
option->treefile = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-first")) {
|
|
i++;
|
|
option->firstReorder = (int)atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-countdead")) {
|
|
option->countDead = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-growth")) {
|
|
i++;
|
|
option->maxGrowth = (int)atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-groupcheck")) {
|
|
i++;
|
|
if (STRING_EQUAL(argv[i],"check")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK;
|
|
} else if (STRING_EQUAL(argv[i],"nocheck")) {
|
|
option->groupcheck = CUDD_NO_CHECK;
|
|
} else if (STRING_EQUAL(argv[i],"check2")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK2;
|
|
} else if (STRING_EQUAL(argv[i],"check3")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK3;
|
|
} else if (STRING_EQUAL(argv[i],"check4")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK4;
|
|
} else if (STRING_EQUAL(argv[i],"check5")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK5;
|
|
} else if (STRING_EQUAL(argv[i],"check6")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK6;
|
|
} else if (STRING_EQUAL(argv[i],"check7")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK7;
|
|
} else if (STRING_EQUAL(argv[i],"check8")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK8;
|
|
} else if (STRING_EQUAL(argv[i],"check9")) {
|
|
option->groupcheck = CUDD_GROUP_CHECK9;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
} else if (STRING_EQUAL(argv[i],"-arcviolation")) {
|
|
i++;
|
|
option->arcviolation = (int)atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-symmviolation")) {
|
|
i++;
|
|
option->symmviolation = (int)atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-recomb")) {
|
|
i++;
|
|
option->recomb = (int)atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-drop")) {
|
|
option->nodrop = FALSE;
|
|
} else if (STRING_EQUAL(argv[i],"-sign")) {
|
|
option->signatures = TRUE;
|
|
} else if (STRING_EQUAL(argv[i],"-genetic")) {
|
|
option->gaOnOff = 1;
|
|
} else if (STRING_EQUAL(argv[i],"-genepop")) {
|
|
option->gaOnOff = 1;
|
|
i++;
|
|
option->populationSize = (int)atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-genexover")) {
|
|
option->gaOnOff = 1;
|
|
i++;
|
|
option->numberXovers = (int) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-seed")) {
|
|
i++;
|
|
option->seed = (int32_t) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-dumpfile")) {
|
|
i++;
|
|
option->bdddump = TRUE;
|
|
option->dumpfile = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-dumpblif")) {
|
|
option->dumpFmt = 1; /* blif */
|
|
} else if (STRING_EQUAL(argv[i],"-dumpdaVinci")) {
|
|
option->dumpFmt = 2; /* daVinci */
|
|
} else if (STRING_EQUAL(argv[i],"-dumpddcal")) {
|
|
option->dumpFmt = 3; /* DDcal */
|
|
} else if (STRING_EQUAL(argv[i],"-dumpfact")) {
|
|
option->dumpFmt = 4; /* factored form */
|
|
} else if (STRING_EQUAL(argv[i],"-dumpmv")) {
|
|
option->dumpFmt = 5; /* blif-MV */
|
|
} else if (STRING_EQUAL(argv[i],"-store")) {
|
|
i++;
|
|
option->store = (int) atoi(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-storefile")) {
|
|
i++;
|
|
option->storefile = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-loadfile")) {
|
|
i++;
|
|
option->load = 1;
|
|
option->loadfile = util_strsav(argv[i]);
|
|
} else if (STRING_EQUAL(argv[i],"-p")) {
|
|
i++;
|
|
option->verb = (int) atoi(argv[i]);
|
|
} else {
|
|
goto usage;
|
|
}
|
|
}
|
|
|
|
if (option->store >= 0 && option->storefile == NULL) {
|
|
(void) fprintf(stdout,"-storefile mandatory with -store\n");
|
|
exit(-1);
|
|
}
|
|
|
|
if (option->verb >= 0) {
|
|
(void) printf("# %s\n", NTR_VERSION);
|
|
/* echo command line and arguments */
|
|
(void) printf("#");
|
|
for (i = 0; i < argc; i++) {
|
|
(void) printf(" %s", argv[i]);
|
|
}
|
|
(void) printf("\n");
|
|
(void) printf("# CUDD Version ");
|
|
Cudd_PrintVersion(stdout);
|
|
(void) fflush(stdout);
|
|
}
|
|
|
|
return;
|
|
|
|
usage: /* convenient goto */
|
|
printf("Usage: please read man page\n");
|
|
if (i == 0) {
|
|
(void) fprintf(stdout,"too few arguments\n");
|
|
} else {
|
|
(void) fprintf(stdout,"option: %s is not defined\n",argv[i]);
|
|
}
|
|
exit(-1);
|
|
|
|
} /* end of ntrReadOptions */
|
|
|
|
|
|
/**
|
|
@brief Reads the program options from a file.
|
|
|
|
@details Opens file. Reads the command line from the otpions file
|
|
using the read_line func. Scans the line looking for spaces, each
|
|
space is a searator and demarks a new option. When a space is
|
|
found, it is changed to a \0 to terminate that string; then the next
|
|
value of slot points to the next non-space character. There is a
|
|
limit of 1024 options. Should produce an error (presently doesn't)
|
|
on overrun of options, but this is very unlikely to happen.
|
|
|
|
@sideeffect none
|
|
|
|
*/
|
|
static void
|
|
ntrReadOptionsFile(
|
|
char * name,
|
|
char *** argv,
|
|
int * argc)
|
|
{
|
|
char **slot;
|
|
char *line;
|
|
char c;
|
|
int index,flag;
|
|
FILE *fp;
|
|
|
|
if ((fp = fopen(name,"r")) == NULL) {
|
|
fprintf(stderr,"Error: can not find cmd file %s\n",name);
|
|
exit(-1);
|
|
}
|
|
|
|
slot = ALLOC(char *,1024);
|
|
index = 1;
|
|
line = readLine(fp);
|
|
flag = TRUE;
|
|
|
|
do {
|
|
c = *line;
|
|
if ( c == ' ') {
|
|
flag = TRUE;
|
|
*line = '\0';
|
|
} else if ( c != ' ' && flag == TRUE) {
|
|
flag = FALSE;
|
|
slot[index] = line;
|
|
index++;
|
|
}
|
|
line++;
|
|
} while ( *line != '\0');
|
|
|
|
|
|
*argv = slot;
|
|
*argc = index;
|
|
|
|
fclose(fp);
|
|
|
|
} /* end of ntrReadOptionsFile */
|
|
|
|
|
|
/**
|
|
@brief Reads a line from the option file.
|
|
|
|
@sideeffect none
|
|
|
|
*/
|
|
static char*
|
|
readLine(
|
|
FILE * fp)
|
|
{
|
|
int c;
|
|
char *pbuffer;
|
|
|
|
pbuffer = buffer;
|
|
|
|
/* Strip white space from beginning of line. */
|
|
for(;;) {
|
|
c = getc(fp);
|
|
if ( c == EOF) return(NULL);
|
|
if ( c == '\n') {
|
|
*pbuffer = '\0';
|
|
return(buffer); /* got a blank line */
|
|
}
|
|
if ( c != ' ') break;
|
|
}
|
|
do {
|
|
if ( c == '\\' ) { /* if we have a continuation character.. */
|
|
do { /* scan to end of line */
|
|
c = getc(fp);
|
|
if ( c == '\n' ) break;
|
|
} while ( c != EOF);
|
|
if ( c != EOF) {
|
|
*pbuffer = ' ';
|
|
pbuffer++;
|
|
} else return( buffer);
|
|
c = getc(fp);
|
|
continue;
|
|
}
|
|
*pbuffer = (char) c;
|
|
pbuffer++;
|
|
c = getc(fp);
|
|
} while( c != '\n' && c != EOF);
|
|
*pbuffer = '\0';
|
|
return(buffer);
|
|
|
|
} /* end of readLine */
|
|
|
|
|
|
/**
|
|
@brief Opens a file.
|
|
|
|
@details Opens a file, or fails with an error message and exits.
|
|
Allows '-' as a synonym for standard input.
|
|
|
|
@sideeffect None
|
|
|
|
*/
|
|
static FILE *
|
|
open_file(
|
|
char * filename,
|
|
const char * mode)
|
|
{
|
|
FILE *fp;
|
|
|
|
if (strcmp(filename, "-") == 0) {
|
|
return mode[0] == 'r' ? stdin : stdout;
|
|
} else if ((fp = fopen(filename, mode)) == NULL) {
|
|
perror(filename);
|
|
exit(1);
|
|
}
|
|
return(fp);
|
|
|
|
} /* end of open_file */
|
|
|
|
|
|
/**
|
|
@brief Explicitly applies reordering to the DDs.
|
|
|
|
@return 1 if successful; 0 otherwise.
|
|
|
|
@sideeffect None
|
|
|
|
*/
|
|
static int
|
|
reorder(
|
|
BnetNetwork * net,
|
|
DdManager * dd,
|
|
NtrOptions * option)
|
|
{
|
|
#ifdef DD_DEBUG
|
|
st_table *mintermTable; /* minterm counts for each output */
|
|
#endif
|
|
int result; /* return value from functions */
|
|
|
|
(void) printf("Number of inputs = %d\n",net->ninputs);
|
|
|
|
/* Perform the final reordering */
|
|
if (option->reordering != CUDD_REORDER_NONE) {
|
|
#ifdef DD_DEBUG
|
|
result = Cudd_DebugCheck(dd);
|
|
if (result != 0) {
|
|
(void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n");
|
|
return(0);
|
|
}
|
|
result = Cudd_CheckKeys(dd);
|
|
if (result != 0) {
|
|
(void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n");
|
|
return(0);
|
|
}
|
|
mintermTable = checkMinterms(net,dd,NULL);
|
|
if (mintermTable == NULL) exit(2);
|
|
#endif
|
|
|
|
dd->siftMaxVar = 1000000;
|
|
dd->siftMaxSwap = 1000000000;
|
|
result = Cudd_ReduceHeap(dd,option->reordering,1);
|
|
if (result == 0) return(0);
|
|
#ifdef DD_DEBUG
|
|
result = Cudd_DebugCheck(dd);
|
|
if (result != 0) {
|
|
(void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n");
|
|
return(0);
|
|
}
|
|
result = Cudd_CheckKeys(dd);
|
|
if (result != 0) {
|
|
(void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n");
|
|
return(0);
|
|
}
|
|
mintermTable = checkMinterms(net,dd,mintermTable);
|
|
if (mintermTable != NULL) {
|
|
(void) fprintf(stderr,"Error in checkMinterms\n");
|
|
return(0);
|
|
}
|
|
#endif
|
|
|
|
/* Print symmetry stats if pertinent */
|
|
if (dd->tree == NULL &&
|
|
(option->reordering == CUDD_REORDER_SYMM_SIFT ||
|
|
option->reordering == CUDD_REORDER_SYMM_SIFT_CONV))
|
|
Cudd_SymmProfile(dd,0,dd->size - 1);
|
|
}
|
|
|
|
if (option->gaOnOff) {
|
|
result = Cudd_ReduceHeap(dd,CUDD_REORDER_GENETIC,1);
|
|
if (result == 0) {
|
|
(void) printf("Something went wrong in cuddGa\n");
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
return(1);
|
|
|
|
} /* end of reorder */
|
|
|
|
|
|
/**
|
|
@brief Frees the option structure and its appendages.
|
|
|
|
@sideeffect None
|
|
|
|
*/
|
|
static void
|
|
freeOption(
|
|
NtrOptions * option)
|
|
{
|
|
if (option->file1 != NULL) FREE(option->file1);
|
|
if (option->file2 != NULL) FREE(option->file2);
|
|
if (option->orderPiPs != NULL) FREE(option->orderPiPs);
|
|
if (option->treefile != NULL) FREE(option->treefile);
|
|
if (option->sinkfile != NULL) FREE(option->sinkfile);
|
|
if (option->dumpfile != NULL) FREE(option->dumpfile);
|
|
if (option->loadfile != NULL) FREE(option->loadfile);
|
|
if (option->storefile != NULL) FREE(option->storefile);
|
|
if (option->node != NULL) FREE(option->node);
|
|
FREE(option);
|
|
|
|
} /* end of freeOption */
|
|
|
|
|
|
/**
|
|
@brief Starts the CUDD manager with the desired options.
|
|
|
|
@details Starts with 0 variables, because Ntr_buildDDs will create
|
|
new variables rather than using whatever already exists.
|
|
|
|
@sideeffect None
|
|
|
|
*/
|
|
static DdManager *
|
|
startCudd(
|
|
NtrOptions * option,
|
|
int nvars)
|
|
{
|
|
DdManager *dd;
|
|
int result;
|
|
|
|
dd = Cudd_Init(0, 0, option->slots, option->cacheSize, option->maxMemory);
|
|
if (dd == NULL) return(NULL);
|
|
|
|
Cudd_Srandom(dd, option->seed);
|
|
if (option->maxMemHard != 0) {
|
|
Cudd_SetMaxMemory(dd,option->maxMemHard);
|
|
}
|
|
Cudd_SetMaxLive(dd,option->maxLive);
|
|
Cudd_SetGroupcheck(dd,option->groupcheck);
|
|
if (option->autoDyn & 1) {
|
|
Cudd_AutodynEnable(dd,option->autoMethod);
|
|
}
|
|
dd->nextDyn = option->firstReorder;
|
|
dd->countDead = (option->countDead == FALSE) ? ~0 : 0;
|
|
dd->maxGrowth = 1.0 + ((float) option->maxGrowth / 100.0);
|
|
dd->recomb = option->recomb;
|
|
dd->arcviolation = option->arcviolation;
|
|
dd->symmviolation = option->symmviolation;
|
|
dd->populationSize = option->populationSize;
|
|
dd->numberXovers = option->numberXovers;
|
|
result = ntrReadTree(dd,option->treefile,nvars);
|
|
if (result == 0) {
|
|
Cudd_Quit(dd);
|
|
return(NULL);
|
|
}
|
|
#ifndef DD_STATS
|
|
result = Cudd_EnableReorderingReporting(dd);
|
|
if (result == 0) {
|
|
(void) fprintf(stderr,
|
|
"Error reported by Cudd_EnableReorderingReporting\n");
|
|
Cudd_Quit(dd);
|
|
return(NULL);
|
|
}
|
|
#endif
|
|
|
|
return(dd);
|
|
|
|
} /* end of startCudd */
|
|
|
|
|
|
/**
|
|
@brief Reads the variable group tree from a file.
|
|
|
|
@return 1 if successful; 0 otherwise.
|
|
|
|
@sideeffect None
|
|
|
|
*/
|
|
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 */
|