VIS

src/res/resSmartVarUse.c

Go to the documentation of this file.
00001 
00028 #include "resInt.h" 
00029 #include "var_set.h"
00030 
00031 static char rcsid[] UNUSED = "$Id: resSmartVarUse.c,v 1.15 2002/09/08 23:56:11 fabio Exp $";
00032 
00033 /*---------------------------------------------------------------------------*/
00034 /* Constant declarations                                                     */
00035 /*---------------------------------------------------------------------------*/
00036 
00037 #define DEFAULT_NUMBER_OF_VARIABLES (sizeof(int)*16)
00038 #define ELEMENTS_PER_WORD (sizeof(int)<<3)
00039 
00040 /*---------------------------------------------------------------------------*/
00041 /* Type declarations                                                         */
00042 /*---------------------------------------------------------------------------*/
00043 
00044 
00045 /*---------------------------------------------------------------------------*/
00046 /* Structure declarations                                                    */
00047 /*---------------------------------------------------------------------------*/
00048 
00049 
00050 /*---------------------------------------------------------------------------*/
00051 /* Variable declarations                                                     */
00052 /*---------------------------------------------------------------------------*/
00053 
00054 static var_set_t *idSet = NIL(var_set_t);
00055 static int numVarsInUse = 0;
00056 
00057 /*--------------------------------------------------------------------*/
00058 /* Macro declarations                                                        */
00059 /*---------------------------------------------------------------------------*/
00060 /* based on the fact that var set word size = ELEMENTS_PER_WORD */
00061 #define MaxSizeOfSet(set) ((set)->n_words * ELEMENTS_PER_WORD)
00062 
00065 /*---------------------------------------------------------------------------*/
00066 /* Static function prototypes                                                */
00067 /*---------------------------------------------------------------------------*/
00068 
00069 static var_set_t * InitializeVariableManager(int numOfVars);
00070 static void ResizeVariableManager(int newSize);
00071 
00075 /*---------------------------------------------------------------------------*/
00076 /* Definition of exported functions                                          */
00077 /*---------------------------------------------------------------------------*/
00078 
00079 /*---------------------------------------------------------------------------*/
00080 /* Definition of internal functions                                          */
00081 /*---------------------------------------------------------------------------*/
00082 
00100 void
00101 MddCreateVariables(mdd_manager *mgr,     
00102                    int numVarsToBeAdded) 
00103 {
00104     array_t *mvar_values;
00105     array_t *mvar_names = NIL(array_t);
00106     array_t *mvar_strides = NIL(array_t);
00107     int i, two_values;
00108 
00109     if (numVarsToBeAdded <= 0) return;
00110     
00111     /* Create 2 mvar values 0,1 */
00112     mvar_values = array_alloc(int, numVarsToBeAdded);    
00113 
00114     /* Assume we create only Bdd variables here */
00115     two_values = 2;
00116     for(i = 0; i < numVarsToBeAdded; i++) {
00117       array_insert(int, mvar_values, i, two_values);
00118     }
00119 
00120     /* creates the mdd variables and updates the mvar_list field */
00121     mdd_create_variables(mgr, mvar_values, mvar_names, mvar_strides);
00122     
00123     array_free(mvar_values);
00124 
00125 } /* End of MddCreateVariables */
00126 
00148 int *
00149 ResResidueVarAllocate(bdd_manager *ddManager,  
00150                          lsList orderList,   
00151                          array_t *newIdArray)
00152 {
00153   lsGen listGen;             /* generator to step through a list of nodes */
00154   Ntk_Node_t *nodePtr;       /* variable to store node pointer */
00155   int nodeId;                /* mdd id of a node */
00156   char *flagValue;           /* string to store flag value */
00157   int newVarsRequired;       /* number of new variables required by layer */
00158   int verbose;               /* verbosity value */
00159   var_set_t *assignedSet;    /* var_set of assigned  Ids in this layer */
00160   var_set_t *idsNotInList;   /* set of assigned Ids not in layer or fanin */
00161   var_set_t *notAssignedSet; /* var_set of Ids not in this layer */
00162   int *invPermArray;         /* inverse permutation array for shuffle */
00163   int invPermIndex, newIdIndex;  /* iterators */
00164   int i, j, id;              /* iterators */
00165   int holes;                  /* number of holes filled so far */
00166   int lastDdId;              /* last variable in dd manager before expansion */
00167   int numberOfFreeVars;      /* number of free variables */
00168 
00169   /* read verbosity flag */
00170   verbose = 0;
00171   flagValue = Cmd_FlagReadByName("residue_verbosity");
00172   if (flagValue != NIL(char)) {
00173     verbose = atoi(flagValue);
00174   }
00175   /* no work required */
00176   if (!lsLength(orderList)) {
00177     error_append("Something wrong order list is empty \n");
00178     return NIL(int);
00179   }
00180 
00181   /* if manager not yet initialized, initialize here */
00182   if (idSet == NIL(var_set_t)) {
00183     ResResidueInitializeVariableManager(lsLength(orderList));
00184   }
00185 
00186   /* number of nodes with unassigned Ids */
00187   newVarsRequired = 0;
00188 
00189   /* for output nodes list, ids are assigned, just set them in the
00190    * var set
00191    */
00192   if (var_set_is_empty(idSet)) {
00193     invPermArray = ALLOC(int, bdd_num_vars(ddManager));
00194     for (i = 0; (unsigned) i < bdd_num_vars(ddManager); i++) {
00195       invPermArray[i] = bdd_get_id_from_level(ddManager, i);
00196     }  
00197     invPermIndex = 0;
00198     lsForEachItem(orderList, listGen, nodePtr) {
00199       nodeId = Ntk_NodeReadMddId(nodePtr);
00200       assert(nodeId != NTK_UNASSIGNED_MDD_ID);
00201       /* mark output node mdd id as in use */
00202       var_set_set_elt(idSet, nodeId);
00203       /* increase number of variables in use */
00204       numVarsInUse++;
00205       invPermArray[invPermIndex] = nodeId;
00206       invPermArray[nodeId] = invPermIndex;
00207       invPermIndex++;
00208     }
00209     return(invPermArray);
00210   }
00211 
00212   /* create a set for already assigned Ids */
00213   assignedSet = var_set_new(MaxSizeOfSet(idSet));
00214 
00215   /* for each item in the list, check against the set if Id
00216    * is assigned. Also create a set to isolate assigned Ids
00217    * that are not in the list. If unassigned Id, increment
00218    * new variables
00219    */
00220   lsForEachItem(orderList, listGen, nodePtr) {
00221     nodeId = Ntk_NodeReadMddId(nodePtr);
00222     if (nodeId != NTK_UNASSIGNED_MDD_ID) {
00223       assert(var_set_get_elt(idSet, nodeId) == 1);
00224       /* create a var set with assigned ids in list */
00225       var_set_set_elt(assignedSet, nodeId);
00226     } else {
00227       newVarsRequired++;
00228     }
00229   }
00230   
00231   /* find out from the set, the assigned Ids which are not in
00232    * this list
00233    */
00234   idsNotInList = var_set_new(MaxSizeOfSet(idSet));
00235   
00236   /* do the operation idSet - assignedSet */
00237   notAssignedSet = var_set_new(MaxSizeOfSet(idSet));
00238   notAssignedSet = var_set_not(notAssignedSet, assignedSet);
00239   idsNotInList = var_set_and(idsNotInList, notAssignedSet, idSet);
00240   var_set_free(assignedSet);
00241   var_set_free(notAssignedSet);
00242   
00243   
00244   /* initialize return value */
00245   if (newVarsRequired) {
00246     
00247     if (verbose >= 3) {
00248       fprintf(vis_stdout, "Number of new variables to be assigned = %d\n",
00249               newVarsRequired);
00250     }
00251     /* compute number of free variables available in the manager */
00252     numberOfFreeVars = MaxSizeOfSet(idSet) - numVarsInUse;
00253 
00254     /* if too few free variables available, resize manager */
00255     if (numberOfFreeVars < newVarsRequired) {
00256       ResizeVariableManager(numVarsInUse + newVarsRequired);
00257     }
00258 
00259     invPermArray = ALLOC(int, bdd_num_vars(ddManager));
00260     /* fill the inverse permutation array */
00261     for (i = 0; (unsigned) i < bdd_num_vars(ddManager); i++) {
00262       invPermArray[i] = bdd_get_id_from_level(ddManager, i);
00263     }
00264     /* create the array of new ids ; assign them starting from the
00265      * top(in position) available ID
00266      */
00267     /* number of available ids in the variable manager */
00268     holes = 0;
00269     /* There could be two cases here: the number of new vars required
00270      * are filled by holes or new variables are required in the DD
00271      * manager to fill the requirement
00272      */
00273     
00274     /* assign as many new Ids as required by the list */
00275     for (i = 0; ((unsigned) i < bdd_num_vars(ddManager)) && (holes < newVarsRequired); i++) {
00276       /* done when holes fill the new variable requirements or when
00277        * new variables are needed in the ddManager
00278        */
00279       if (!var_set_get_elt(idSet, invPermArray[i])) {
00280         /* the number of holes filled above are the variables that exist in
00281          * the ddManager and are not in use
00282          */
00283         array_insert_last(int , newIdArray, invPermArray[i]);
00284         holes++;
00285       }
00286     }
00287     FREE(invPermArray);
00288     if (verbose >= 4) {
00289       if (holes) {
00290         fprintf(vis_stdout, "Holes filled are ids:");
00291         arrayForEachItem(int, newIdArray, i, nodeId) {
00292           fprintf(vis_stdout, "%d ", nodeId);
00293         }
00294         fprintf(vis_stdout, "\n");
00295       }
00296     }
00297 
00298     
00299     /* newVarsRequired-holes is the number of variables to be added to the
00300      * mdd manager
00301      */
00302     if (holes < newVarsRequired) {
00303       lastDdId = bdd_num_vars(ddManager);
00304       /* create mdd variables, dirty stuff needed to add to the mvar_list */
00305       MddCreateVariables((mdd_manager *)ddManager, newVarsRequired - holes);
00306       
00307       /* since all the variables were created in the end, use the ids
00308        * starting at the size of the manager
00309        */
00310       for(i = 0; i < (newVarsRequired-holes); i++) {
00311         array_insert_last(int, newIdArray, lastDdId+i);
00312       }
00313       if (verbose >= 4) {
00314         fprintf(vis_stdout, "New dd ids assigned are: ");
00315         for(i = 0; i < (newVarsRequired-holes); i++) {
00316           fprintf(vis_stdout, "%d ", array_fetch(int, newIdArray, holes+i));
00317         } 
00318         fprintf(vis_stdout, "\n");
00319       }
00320     } /* end of new vars needed to be assigned in the manager */
00321   } /* end of new vars need to be assigned to nodes */
00322 
00323   /* Create Inverse Permutation Array for the DD Manager */
00324   
00325   /* create inverse permutation array with nodes in list */ 
00326   invPermArray = ALLOC(int, bdd_num_vars(ddManager));
00327   invPermIndex = 0;
00328   newIdIndex = 0;
00329   if (verbose >= 4) {
00330     fprintf(vis_stdout, "Final order to shuffle heap is:\n");
00331   }
00332   lsForEachItem(orderList, listGen, nodePtr) {
00333     /* for nodes with assigned ids, get id from node */
00334     nodeId = Ntk_NodeReadMddId(nodePtr);
00335     if (nodeId == NTK_UNASSIGNED_MDD_ID) {
00336       /* for nodes with unassigned ids, get id from array */
00337       nodeId = array_fetch(int, newIdArray, newIdIndex);
00338       /* update var set with teh new ids added */
00339       var_set_set_elt(idSet, nodeId);
00340       numVarsInUse++;
00341       newIdIndex++;
00342     }
00343     invPermArray[invPermIndex] = nodeId;
00344     if (verbose >= 4) {
00345       fprintf(vis_stdout, "%d ", nodeId);
00346     }
00347     invPermIndex++;
00348   }
00349   /* all new ids been accounted for */
00350   assert(newIdIndex == array_n(newIdArray));
00351 
00352   /* push nodes  not in list with assigned Ids below those in list */
00353   /* fill inv Perm array with Ids that are not in the list
00354    * and not in the idsNotInList. These are ids in the
00355    * ddManager that are not in idSet. 
00356    */
00357   /* if the number of ids in use in residue verification is less
00358    * than that in the manager
00359    */
00360   if (((unsigned) invPermIndex < bdd_num_vars(ddManager)) ||
00361       (!var_set_is_empty(idsNotInList))) {
00362 
00363     /* collect the ids that are not in use in residue verification */
00364     for (j = 0; (unsigned) j < bdd_num_vars(ddManager); j++) {
00365       /* if not idSet, it means that it is not in use by
00366        * residue verification, hence add to the end of invpermArray.
00367        * Get id from the invPermArray that was filled in the
00368        * above lines(where invPermArray was copied in the manager).
00369        * Nodes already in the list will not get added since idSet
00370        * was updated as the list was read. The id is read from the
00371        * invPermArray so as to not disturb the relative order of
00372        * the ids not in use and those in the manager. The check
00373        * has the additional clause on the id <
00374        * MaxSizeOfSet(idsNotInList)since idsNotInList was created
00375        * before the additional variables were added to the manager.
00376        */
00377       id = bdd_get_id_from_level(ddManager, j);
00378       if ((!var_set_get_elt(idSet, id)) ||
00379            (((unsigned) id < MaxSizeOfSet(idsNotInList)) &&
00380             (var_set_get_elt(idsNotInList, id)))) {
00381         /* add to the inverse permutation array */
00382         invPermArray[invPermIndex] = id;
00383         if (verbose >= 4) {
00384           fprintf(vis_stdout, "%d ", id);
00385         }
00386         invPermIndex++;
00387       } /* end of if not in idSet */
00388     } /* end of iterating through the ids in the dd manager */
00389   } /* end of if */ 
00390   if (verbose >= 4) {
00391     fprintf(vis_stdout, "\n");
00392   }
00393 
00394   var_set_free(idsNotInList);
00395   assert(invPermIndex == bdd_num_vars(ddManager));
00396   
00397   return(invPermArray);
00398 }/* End of ResResidueVarAllocate */
00399 
00412 void
00413 ResResidueVarDeallocate(array_t *currentLayer)
00414 {
00415   int i=0;
00416   int nodeId;
00417   Ntk_Node_t *nodePtr;
00418   
00419   LayerForEachNode(currentLayer, i, nodePtr) {
00420     nodeId = Ntk_NodeReadMddId(nodePtr);
00421     var_set_clear_elt(idSet, nodeId);
00422     numVarsInUse--;
00423   }
00424 
00425   return;
00426 } /* End of Res_ResidueVarUseDeallocate */
00427 
00441 void
00442 ResResidueFreeVariableManager(void)
00443 {
00444 
00445   if (idSet == NIL(var_set_t)) {
00446     return;
00447   } /* End of if */
00448 
00449   numVarsInUse = 0;
00450   var_set_free(idSet);
00451 
00452   idSet = NIL(var_set_t);
00453 
00454   return;
00455 } /* End of ResResidueFreeVariableManager */
00456 
00466 void
00467 ResResidueInitializeVariableManager(int numOfVars)
00468 {
00469   idSet = InitializeVariableManager(numOfVars);
00470   return;
00471 } /* End of ResResidueInitializeVariableManager */
00472 
00473 
00474 /*---------------------------------------------------------------------------*/
00475 /* Definition of static functions                                            */
00476 /*---------------------------------------------------------------------------*/
00477 
00490 static var_set_t *
00491 InitializeVariableManager(int numOfVars)
00492 {
00493   if (numOfVars != 0) {
00494     if (numOfVars % ELEMENTS_PER_WORD != 0) {
00495       /* round up to the next word length */
00496       numOfVars = ((numOfVars/ELEMENTS_PER_WORD)+1)*ELEMENTS_PER_WORD;
00497     } 
00498   } else {
00499     numOfVars = DEFAULT_NUMBER_OF_VARIABLES;
00500   }
00501 
00502   /* default value of number of words = 2 */
00503   return var_set_new(numOfVars);
00504 
00505 } /* End of InitializeVariableManager */
00506 
00520 static void
00521 ResizeVariableManager(int newSize)
00522 {
00523   var_set_t *newSet;
00524   int i;
00525 
00526   /* resize only if the new size is larger than the previous size */
00527   assert(newSize > MaxSizeOfSet(idSet));
00528 
00529   /* create a new set with the new size */
00530   newSet = InitializeVariableManager(newSize);
00531   
00532   for (i=0; i < idSet->n_words; i++) {
00533     newSet->data[i] |= idSet->data[i];
00534   }
00535   /* free the old id set, not using ResResidueFreeVariableManager()
00536    * because it resets the numVarsInUse
00537    */
00538   var_set_free(idSet);
00539 
00540   idSet = newSet;
00541   return;
00542 } /* End of ResizeVariableManager */
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555