VIS
|
00001 00036 #include "imgInt.h" 00037 #include "fsm.h" 00038 #include "heap.h" 00039 00040 static char rcsid[] UNUSED = "$Id: imgLinear.c,v 1.18 2010/04/10 00:37:06 fabio Exp $"; 00041 static char linearVarString[] = "TCNI"; 00042 00043 00044 /*---------------------------------------------------------------------------*/ 00045 /* Constant declarations */ 00046 /*---------------------------------------------------------------------------*/ 00047 00048 /*---------------------------------------------------------------------------*/ 00049 /* Type declarations */ 00050 /*---------------------------------------------------------------------------*/ 00051 00052 00053 /*---------------------------------------------------------------------------*/ 00054 /* Structure declarations */ 00055 /*---------------------------------------------------------------------------*/ 00056 00057 00058 /*---------------------------------------------------------------------------*/ 00059 /* Variable declarations */ 00060 /*---------------------------------------------------------------------------*/ 00061 00062 Cluster_t *__clu; 00063 00064 /*---------------------------------------------------------------------------*/ 00065 /* Macro declarations */ 00066 /*---------------------------------------------------------------------------*/ 00067 00068 #define BACKWARD_REDUCTION_RATE 0.5 00069 #define FORWARD_REDUCTION_RATE 0.5 00070 00073 /*---------------------------------------------------------------------------*/ 00074 /* Static function prototypes */ 00075 /*---------------------------------------------------------------------------*/ 00076 00077 static void ImgLinearUpdateVariableArrayWithId(Relation_t *head, int cindex, int id); 00078 static int ImgLinearQuantifyVariablesFromConjunct(Relation_t *head, Conjunct_t *conjunct, array_t *smoothVarBddArray, int *bModified); 00079 static void ImgLinearConjunctRefine(Relation_t *head, Conjunct_t *conjunct); 00080 static void ImgLinearVariableArrayQuit(Relation_t *head); 00081 static void ImgLinearConjunctQuit(Conjunct_t *conjunct); 00082 static Conjunct_t ** ImgLinearAddConjunctIntoArray(Conjunct_t **array, int *nArray, Conjunct_t *con); 00083 static void ImgLinearFindSameSupportConjuncts(Relation_t *head, int from, int to); 00084 static void ImgLinearClusterSameSupportSet(Relation_t *head); 00085 static void ImgLinearExpandSameSupportSet(Relation_t *head); 00086 static int ImgLinearIsSameConjunct(Relation_t *head, Conjunct_t *con1, Conjunct_t *con2); 00087 static bdd_t * ImgLinearClusteringSmooth(Relation_t *head, Cluster_t *clu, int **failureHistory, int andExistLimit, int bddLimit); 00088 static int ImgLinearClusterUsingHeap(Relation_t *head, double affinityLimit, int andExistLimit, int varLimit, Img_OptimizeType optDir, int rangeFlag, int (*compare_func)(const void *, const void *)); 00089 static void ImgLinearPrintTransitionInfo(Relation_t *head); 00090 static void ImgLinearComputeLifeTime(Relation_t *head, double *paal, double *patl); 00091 static void ImgLinearFreeSmoothArray(array_t *smoothVarBddArray); 00092 static void ImgLinearPrintMatrixFull(Relation_t *head, int matrixIndex); 00093 static void ImgLinearPrintMatrix(Relation_t *head); 00094 static void ImgLinearCAPOReadVariableOrder(Relation_t *head, char *baseName, int includeNS); 00095 static void ImgLinearCAPOInterfaceVariablePl(Relation_t *head, char *baseName, int includeNS); 00096 static void ImgLinearCAPOInterfaceVariableScl(Relation_t *head, char *baseName); 00097 static void ImgLinearCAPOInterfaceVariableNet(Relation_t *head, char *baseName, int includeNS); 00098 static void ImgLinearCAPOInterfaceVariableNodes(Relation_t *head, char *baseName, int includeNS); 00099 static void ImgLinearVariableOrder(Relation_t *head, char *baseName, int includeNS); 00100 static void ImgLinearCAPOReadConjunctOrder(Relation_t *head, char *baseName); 00101 static int ImgLinearCAPORun(char *capoExe, char *baseName, int brief); 00102 static void ImgLinearCAPOInterfaceAux(Relation_t *head, char *baseName); 00103 static void ImgLinearCAPOInterfaceConjunctPl(Relation_t *head, char *baseName); 00104 static void ImgLinearCAPOInterfaceConjunctScl(Relation_t *head, char *baseName); 00105 static void ImgLinearCAPOInterfaceConjunctNet(Relation_t *head, char *baseName); 00106 static void ImgLinearCAPOInterfaceConjunctNodes(Relation_t *head, char *baseName); 00107 static void ImgLinearConjunctionOrder(Relation_t *head, char *baseName, int refineFlag); 00108 static void ImgLinearConjunctOrderMain(Relation_t *head, int bRefineConjunctOrder); 00109 static void ImgLinearPrintDebugInfo(Relation_t *head); 00110 static void ImgLinearPrintVariableProfile(Relation_t *head, char *baseName); 00111 static void ImgLinearInsertClusterCandidate(Relation_t *head, int from, int to, int nDead, int nVar, double affinityLimit); 00112 static void ImgLinearInsertPairClusterCandidate(Relation_t *head, int from, double affinityLimit, int varLimit, int rangeFlag); 00113 static void ImgLinearBuildInitialCandidate(Relation_t *head, double affinityLimit, int varLimit, int rangeFlag, int (*compare_func)(const void *, const void *)); 00114 static bdd_t * ImgLinearClusteringPairSmooth(Relation_t *head, Cluster_t *clu, int **failureHistory, int andExistLimit, int bddLimit); 00115 static void ImgLinearVariableArrayInit(Relation_t *head); 00116 static void ImgLinearSetEffectiveNumberOfStateVariable(Relation_t *head, int *rangeId, int *domainId, int *existStateVariable) ; 00117 static void ImgLinearVariableLifeQuit(VarLife_t *var); 00118 static void ImgLinearAddNextStateCase(Relation_t *head); 00119 static void ImgLinearAddSingletonCase(Relation_t *head); 00120 00121 static int ImgLinearCompareDeadAffinityLive(const void *c1, const void *c2); 00122 static int ImgLinearCompareDeadLiveAffinity(const void *c1, const void *c2); 00123 static int ImgLinearCompareAffinityDeadLive(const void *c1, const void *c2); 00124 static int ImgLinearCompareLiveAffinityDead(const void *c1, const void *c2); 00125 static int ImgLinearHeapCompareDeadAffinityLive(const void *c1, const void *c2); 00126 static int ImgLinearHeapCompareDeadLiveAffinity(const void *c1, const void *c2); 00127 static int ImgLinearHeapCompareAffinityDeadLive(const void *c1, const void *c2); 00128 static int ImgLinearHeapCompareLiveAffinityDead(const void *c1, const void *c2); 00129 00130 static int ImgLinearCompareVarIndex(const void *c1, const void *c2); 00131 static int ImgLinearCompareVarSize(const void *c1, const void *c2); 00132 static int ImgLinearCompareVarEffFromSmall(const void *c1, const void *c2); 00133 static int ImgLinearCompareVarEffFromLarge(const void *c1, const void *c2); 00134 static int ImgLinearCompareConjunctDummy(const void *c1, const void *c2); 00135 static int ImgLinearCompareConjunctIndex(const void *c1, const void *c2); 00136 static int ImgLinearCompareConjunctSize(const void *c1, const void *c2); 00137 static int ImgLinearCompareConjunctRangeMinusDomain(const void *c1, const void *c2); 00138 static int ImgLinearCompareVarId(const void *c1, const void *c2); 00139 static int ImgCheckRangeTestAndOverapproximate(Relation_t *head); 00140 static void ImgCountOnsetDisjunctiveArray(Relation_t *head); 00141 static int linearCheckRange(const void *tc); 00142 00143 static void ImgLinearConjunctArrayRefine(Relation_t *head); 00147 /*---------------------------------------------------------------------------*/ 00148 /* Definition of exported functions */ 00149 /*---------------------------------------------------------------------------*/ 00150 void ImgLinearConjunctOrderMainCC(Relation_t *head, int refineFlag); 00151 int ImgLinearClustering(Relation_t *head, Img_OptimizeType optDir); 00152 int ImgLinearPropagateConstant(Relation_t *head, int nextStateFlag); 00153 int ImgLinearOptimizeStateVariables(Relation_t *head, Img_OptimizeType optDir); 00154 void ImgLinearExtractNextStateCase(Relation_t *head); 00155 void ImgLinearExtractSingletonCase(Relation_t *head); 00156 /*void ImgLinearClusterRelationArray(mdd_manager *mgr, ImgFunctionData_t *functionData, array_t *relationArray, Img_DirectionType direction, array_t **clusteredRelationArrayPtr, array_t **arraySmoothVarBddArrayPtr, array_t **optClusteredRelationArrayPtr, array_t **optArraySmoothVarBddArrayPtr, ImgTrmOption_t *option); 00157 */ 00158 void ImgLinearConnectedComponent(Relation_t *head); 00159 void ImgLinearBuildConjunctArrayWithQuotientCC(Relation_t *head); 00160 void ImgLinearFindConnectedComponent(Relation_t *head, Conjunct_t *conjunct, int cc_index); 00161 void ImgLinearAddConjunctIntoClusterArray(Conjunct_t *base, Conjunct_t *con); 00162 00163 00175 void 00176 ImgLinearClusterRelationArray(mdd_manager *mgr, 00177 ImgFunctionData_t *functionData, 00178 array_t *relationArray, 00179 Img_DirectionType direction, 00180 array_t **clusteredRelationArrayPtr, 00181 array_t **arraySmoothVarBddArrayPtr, 00182 array_t **optClusteredRelationArrayPtr, 00183 array_t **optArraySmoothVarBddArrayPtr, 00184 ImgTrmOption_t *option) 00185 { 00186 Img_OptimizeType optDir; 00187 int bGroupStateVariable; 00188 int bOrderVariable; 00189 00190 int includeCS; 00191 int includeNS; 00192 int quantifyCS; 00193 array_t *initRelationArray; 00194 int bOptimize; 00195 Relation_t *head; 00196 bdd_t **smoothCubeArr, **optSmoothCubeArr; 00197 array_t *optRelationArr, *optSmoothVarBddArr; 00198 array_t *relationArr, *smoothVarBddArr; 00199 00200 if(option->linearComputeRange) { 00201 option->linearIncludeCS = 0; 00202 option->linearIncludeNS = 0; 00203 option->linearQuantifyCS = 1; 00204 } 00205 00206 optRelationArr = relationArr = 0; 00207 optSmoothVarBddArr = smoothVarBddArr = 0; 00208 00209 includeCS = option->linearIncludeCS; 00210 includeNS = option->linearIncludeNS; 00211 quantifyCS = option->linearQuantifyCS; 00212 if(option->linearFineGrainFlag) includeNS = 1; 00213 optDir = option->linearOptimize; 00214 bOrderVariable = option->linearOrderVariable; 00215 bGroupStateVariable = option->linearGroupStateVariable; 00216 00217 head = ImgLinearRelationInit(mgr, relationArray, 00218 functionData->domainBddVars, functionData->rangeBddVars, 00219 functionData->quantifyBddVars, option); 00220 00221 if(head->verbosity >= 5) ImgLinearPrintDebugInfo(head); 00222 00223 ImgLinearOptimizeAll(head, Opt_None, 0); 00224 ImgLinearRefineRelation(head); 00225 initRelationArray = ImgLinearExtractRelationArrayT(head); 00226 00227 bOptimize = 0; 00228 00229 ImgLinearPrintMatrix(head); 00230 00231 if(bOrderVariable) 00232 ImgLinearVariableOrder(head, "VarOrder", !bGroupStateVariable); 00233 00234 if((direction==0) || (direction==2)) { 00235 ImgLinearPrintMatrix(head); 00236 00237 bOptimize |= ImgLinearOptimizeAll(head, optDir, 0); 00238 ImgLinearRefineRelation(head); 00239 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 00240 00241 ImgLinearConjunctOrderMainCC(head, 0); 00242 00243 ImgLinearPrintMatrix(head); 00244 00245 bOptimize |= ImgLinearClustering(head, optDir); 00246 00247 ImgLinearRefineRelation(head); 00248 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 00249 ImgLinearPrintTransitionInfo(head); 00250 00251 ImgLinearPrintMatrix(head); 00252 00253 ImgLinearPrintMatrixFull(head, 2); 00254 00255 if(bOptimize) { 00256 optRelationArr = ImgLinearExtractRelationArrayT(head); 00257 optSmoothCubeArr = ALLOC(bdd_t *, head->nSize+1); 00258 optSmoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, optSmoothCubeArr); 00259 } 00260 else { 00261 optRelationArr = ImgLinearExtractRelationArrayT(head); 00262 optSmoothCubeArr = ALLOC(bdd_t *, head->nSize+1); 00263 optSmoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, optSmoothCubeArr); 00264 relationArr = 0; 00265 smoothVarBddArr = 0; 00266 } 00267 ImgLinearPrintDebugInfo(head); 00268 ImgLinearRelationQuit(head); 00269 00270 if(bOptimize) { 00271 fprintf(vis_stdout, "Get Schedules without optimization\n"); 00272 head = ImgLinearRelationInit(mgr, initRelationArray, 00273 functionData->domainBddVars, functionData->rangeBddVars, 00274 functionData->quantifyBddVars, option); 00275 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 00276 ImgLinearConjunctOrderMainCC(head, 0); 00277 if(head->verbosity >= 5) 00278 ImgLinearPrintMatrix(head); 00279 ImgLinearClustering(head, Opt_None); 00280 00281 relationArr = ImgLinearExtractRelationArrayT(head); 00282 smoothCubeArr = ALLOC(bdd_t *, head->nSize+1); 00283 smoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, smoothCubeArr); 00284 00285 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 00286 ImgLinearPrintDebugInfo(head); 00287 ImgLinearPrintTransitionInfo(head); 00288 00289 ImgLinearRelationQuit(head); 00290 } 00291 00292 if(optClusteredRelationArrayPtr) 00293 *optClusteredRelationArrayPtr = optRelationArr; 00294 else 00295 mdd_array_free(optRelationArr); 00296 00297 if(optArraySmoothVarBddArrayPtr) 00298 *optArraySmoothVarBddArrayPtr = optSmoothVarBddArr; 00299 else if(optSmoothVarBddArr) 00300 ImgLinearFreeSmoothArray(optSmoothVarBddArr); 00301 00302 if(clusteredRelationArrayPtr) 00303 *clusteredRelationArrayPtr = relationArr; 00304 else 00305 mdd_array_free(relationArr); 00306 00307 if(arraySmoothVarBddArrayPtr) 00308 *arraySmoothVarBddArrayPtr = smoothVarBddArr; 00309 else if(smoothVarBddArr) 00310 ImgLinearFreeSmoothArray(smoothVarBddArr); 00311 } 00312 00313 if((direction==1) || (direction==2)) { 00314 } 00315 } 00316 00317 00329 Relation_t * 00330 ImgLinearRelationInit(mdd_manager *mgr, 00331 array_t *relationArray, 00332 array_t *domainBddVars, 00333 array_t *rangeBddVars, 00334 array_t *quantifyBddVars, 00335 ImgTrmOption_t *option) 00336 { 00337 Relation_t *head; 00338 Conjunct_t *conjunct, **conjunctArray; 00339 bdd_t *varBdd; 00340 int *domain2range, *range2domain; 00341 int *varArrayMap, *varType; 00342 bdd_t **constantCase, *relation; 00343 int i, j, id, tid, nSize; 00344 int *supList, listSize; 00345 char *flagValue; 00346 int *quantifyVars, nQuantify, *visited; 00347 00348 head = ALLOC(Relation_t, 1); 00349 memset(head, 0, sizeof(Relation_t)); 00350 head->mgr = mgr; 00351 head->nVar = bdd_num_vars(head->mgr); 00352 head->bddLimit = option->clusterSize; 00353 00354 head->verbosity = option->verbosity; 00355 flagValue = Cmd_FlagReadByName("linear_verbosity"); 00356 if(flagValue) { 00357 head->verbosity += atoi(flagValue); 00358 } 00359 00360 00361 head->includeCS = option->linearIncludeCS; 00362 head->includeNS = option->linearIncludeNS; 00363 head->quantifyCS = option->linearQuantifyCS; 00364 head->computeRange = option->linearComputeRange; 00365 00366 head->nInitRange = 0; 00367 head->nInitDomain = 0; 00368 head->nInitQuantify = 0; 00369 head->nEffRange = 0; 00370 head->nEffDomain = 0; 00371 head->nEffQuantify = 0; 00372 00373 head->clusterArray = 0; 00374 head->nClusterArray = 0; 00375 00376 head->nVarArray = 0; 00377 head->varArray = 0; 00378 00379 head->nSingletonArray = 0; 00380 head->singletonArray = 0; 00381 head->nNextStateArray = 0; 00382 head->nextStateArray = 0; 00383 00384 domain2range = ALLOC(int, head->nVar); 00385 head->domain2range = domain2range; 00386 memset(domain2range, -1, sizeof(int)*head->nVar); 00387 00388 range2domain = ALLOC(int, head->nVar); 00389 head->range2domain = range2domain; 00390 memset(range2domain, -1, sizeof(int)*head->nVar); 00391 00392 varType = ALLOC(int, head->nVar); 00393 head->varType = varType; 00394 memset(varType, 0, sizeof(int)*head->nVar); 00395 00396 head->nRange = array_n(rangeBddVars); 00397 head->nDomain = array_n(domainBddVars); 00398 00399 head->domainVars = ALLOC(int, head->nDomain); 00400 head->rangeVars = ALLOC(int, head->nRange); 00401 for(i=0; i<head->nDomain; i++) { 00402 varBdd = array_fetch(bdd_t *, domainBddVars, i); 00403 id = (int)bdd_top_var_id(varBdd); 00404 head->domainVars[i] = id; 00405 varType[id] = 1; 00406 00407 varBdd = array_fetch(bdd_t *, rangeBddVars, i); 00408 tid = (int)bdd_top_var_id(varBdd); 00409 head->rangeVars[i] = tid; 00410 varType[tid] = 2; 00411 00412 domain2range[id] = tid; 00413 range2domain[tid] = id; 00414 } 00415 00416 head->quantifyVars = quantifyVars = ALLOC(int, head->nVar); 00417 memset(quantifyVars, 0, sizeof(int)*head->nVar); 00418 for(nQuantify=0, i=0; i<array_n(quantifyBddVars); i++) { 00419 varBdd = array_fetch(bdd_t *, quantifyBddVars, i); 00420 id = (int)bdd_top_var_id(varBdd); 00421 quantifyVars[nQuantify++] = id; 00422 varType[id] = 3; 00423 } 00424 00425 varArrayMap = ALLOC(int, head->nVar); 00426 head->varArrayMap = varArrayMap; 00427 memset(varArrayMap, -1, sizeof(int)*head->nVar); 00428 00429 constantCase = ALLOC(bdd_t *, head->nVar); 00430 head->constantCase = constantCase; 00431 memset(constantCase, 0, sizeof(bdd_t *)*head->nVar); 00432 00433 00434 nSize = array_n(relationArray); 00435 conjunctArray = ALLOC(Conjunct_t *, nSize+1); 00436 head->nSize = nSize; 00437 head->conjunctArray = conjunctArray; 00438 00439 visited = ALLOC(int, head->nVar); 00440 memset(visited, 0, sizeof(int)*head->nVar); 00441 for(i=0; i<nSize; i++) { 00442 conjunct = ALLOC(Conjunct_t, 1); 00443 memset(conjunct, 0, sizeof(Conjunct_t)); 00444 conjunct->index = i; 00445 relation = array_fetch(bdd_t *, relationArray, i); 00446 00447 conjunct->relation = mdd_dup(relation); 00448 00449 supList = ImgLinearGetSupportBddId(head->mgr, relation, &listSize); 00450 conjunct->supList = supList; 00451 conjunct->nSize = listSize; 00452 for(j=0; j<listSize; j++) { 00453 id = supList[j]; 00454 if(varType[id] == 1) conjunct->nDomain++; 00455 else if(varType[id] == 2) conjunct->nRange++; 00456 else if(varType[id] == 3) conjunct->nQuantify++; 00457 else if(visited[id] == 0) { 00458 quantifyVars[nQuantify++] = id; 00459 visited[id] = 1; 00460 } 00461 } 00462 00463 conjunctArray[i] = conjunct; 00464 } 00465 conjunctArray[i] = 0; 00466 00467 head->nQuantify= nQuantify; 00468 free(visited); 00469 00470 ImgLinearVariableArrayInit(head); 00471 return(head); 00472 } 00473 00474 00486 int * 00487 ImgLinearGetSupportBddId(mdd_manager *mgr, bdd_t *f, int *nSize) 00488 { 00489 var_set_t *vset; 00490 array_t *bvar_list; 00491 int *supList, i, size; 00492 00493 bvar_list = mdd_ret_bvar_list(mgr); 00494 vset = bdd_get_support(f); 00495 size = 0; 00496 supList = ALLOC(int, size+1); 00497 supList[0] = -1; 00498 for(i=0; i<array_n(bvar_list); i++) { 00499 if(var_set_get_elt(vset, i) == 1) { 00500 supList = REALLOC(int, supList, size+2); 00501 supList[size++] = i; 00502 supList[size] = -1; 00503 } 00504 } 00505 var_set_free(vset); 00506 *nSize = size; 00507 if(size == 0) { 00508 free(supList); 00509 supList = 0; 00510 } 00511 return(supList); 00512 } 00513 00525 bdd_t ** 00526 ImgLinearExtractRelationArray(Relation_t *head) 00527 { 00528 int i; 00529 bdd_t **relationArray; 00530 Conjunct_t *conjunct; 00531 00532 relationArray = ALLOC(bdd_t *, head->nSize+1); 00533 for(i=0; i<head->nSize; i++) { 00534 conjunct = head->conjunctArray[i]; 00535 relationArray[i] = bdd_dup(conjunct->relation); 00536 } 00537 relationArray[i] = 0; 00538 return(relationArray); 00539 } 00551 array_t * 00552 ImgLinearExtractRelationArrayT(Relation_t *head) 00553 { 00554 int i; 00555 array_t *relationArray; 00556 Conjunct_t *conjunct; 00557 00558 relationArray = array_alloc(bdd_t *, head->nSize); 00559 for(i=0; i<head->nSize; i++) { 00560 conjunct = head->conjunctArray[i]; 00561 array_insert_last(bdd_t *, relationArray, bdd_dup(conjunct->relation)); 00562 } 00563 return(relationArray); 00564 } 00565 00566 00580 int 00581 ImgLinearOptimizeAll(Relation_t *head, Img_OptimizeType optDir, int constantNSOpt) 00582 { 00583 int bOptimize; 00584 00585 bOptimize = 0; 00586 bOptimize |= ImgLinearPropagateConstant(head, constantNSOpt); 00587 bOptimize |= ImgLinearOptimizeStateVariables(head, optDir); 00588 ImgLinearOptimizeInternalVariables(head); 00589 return(bOptimize); 00590 } 00602 int 00603 ImgLinearPropagateConstant(Relation_t *head, int nextStateFlag) 00604 { 00605 int nSize, i, j; 00606 int *supList; 00607 Conjunct_t **conjunctArray; 00608 Conjunct_t *conjunct; 00609 mdd_manager *mgr; 00610 bdd_t **constantCase; 00611 bdd_t *relation, *simpleRelation; 00612 int nConstantCase; 00613 int bOptimize; 00614 int id, cid, index; 00615 int *varType; 00616 int size; 00617 00618 bOptimize = 0; 00619 mgr = head->mgr; 00620 constantCase = head->constantCase; 00621 varType = head->varType; 00622 00623 conjunctArray = head->conjunctArray; 00624 nSize = head->nSize; 00625 nConstantCase = 0; 00626 for(index=0, i=0; i<nSize; i++) { 00627 conjunct = conjunctArray[i]; 00628 if(conjunct == 0) continue; 00629 if(conjunct->relation == 0) continue; 00630 00631 if(conjunct->nSize == 1) { 00632 id = conjunct->supList[0]; 00633 if(varType[id] == 2) { 00634 if(nextStateFlag) { 00635 cid = head->range2domain[id]; 00636 if(constantCase[cid] == 0) { 00637 constantCase[cid] = bdd_dup(conjunct->relation); 00638 if(head->verbosity >= 4) 00639 fprintf(vis_stdout, "Detect Constant Case %3d(%c)\n", cid, linearVarString[varType[cid]]); 00640 nConstantCase++; 00641 } 00642 } 00643 continue; 00644 } 00645 else { 00646 if(constantCase[id] == 0) { 00647 constantCase[id] = bdd_dup(conjunct->relation); 00648 if(head->verbosity >= 4) 00649 fprintf(vis_stdout, "Detect Constant Case %3d(%c)\n", id, linearVarString[varType[id]]); 00650 nConstantCase++; 00651 } 00652 continue; 00653 } 00654 } 00655 } 00656 00657 if(nConstantCase > 0) { 00658 for(i=0; i<head->nSize; i++) { 00659 conjunct = conjunctArray[i]; 00660 if(conjunct == 0) continue; 00661 if(conjunct->relation == 0) continue; 00662 relation = conjunct->relation; 00663 size = conjunct->nSize; 00664 supList = conjunct->supList; 00665 00666 for(j=0; j<size; j++) { 00667 id = supList[j]; 00668 if(constantCase[id] == 0) continue; 00669 00670 simpleRelation = bdd_cofactor(relation, constantCase[id]); 00671 if(bdd_equal(relation, simpleRelation)) { 00672 bdd_free(simpleRelation); 00673 continue; 00674 } 00675 if(varType[id] == 1) bOptimize++; 00676 bdd_free(conjunct->relation); 00677 conjunct->relation = simpleRelation; 00678 relation = conjunct->relation; 00679 conjunct->bModified = 1; 00680 head->bModified = 1; 00681 head->bRefineVarArray = 1; 00682 00683 00684 if(head->verbosity >= 2) 00685 fprintf(vis_stdout, "Constant propagation is applied %3d(%c) to %3d'th relation\n", id, linearVarString[varType[id]], i); 00686 } 00687 ImgLinearConjunctRefine(head, conjunct); 00688 } 00689 } 00690 00691 return(bOptimize); 00692 } 00693 00705 int 00706 ImgLinearOptimizeStateVariables(Relation_t *head, Img_OptimizeType optDir) 00707 { 00708 int *rangeId, *domainId, *existStateVar; 00709 int *domain2range; 00710 int *range2domain; 00711 bdd_t *oneBdd, *varBdd; 00712 VarLife_t **varArray, *var; 00713 array_t *smoothVarBddArray; 00714 Conjunct_t *conjunct; 00715 int i, id; 00716 int bOptimize; 00717 int rangeBound, domainBound; 00718 int nRangeReduced, nDomainReduced; 00719 00720 if(optDir == Opt_None) return(0); 00721 00722 id = 0; 00723 ImgLinearVariableArrayInit(head); 00724 00725 bOptimize = 0; 00726 rangeId = ALLOC(int, head->nRange+1); 00727 memset(rangeId, 0, sizeof(int)*(head->nRange+1)); 00728 domainId = ALLOC(int, head->nDomain+1); 00729 memset(domainId, 0, sizeof(int)*(head->nDomain+1)); 00730 existStateVar = ALLOC(int, head->nVar); 00731 memset(existStateVar, 0, sizeof(int)*head->nVar); 00732 ImgLinearSetEffectiveNumberOfStateVariable(head, rangeId, domainId, existStateVar); 00733 00734 rangeBound = (int)((double)head->nInitRange * BACKWARD_REDUCTION_RATE); 00735 domainBound = (int)((double)head->nInitDomain * FORWARD_REDUCTION_RATE); 00736 if(head->nEffDomain < domainBound) { 00737 if(optDir == Opt_Both) optDir = Opt_NS; 00738 else if(optDir == Opt_CS) optDir = Opt_None; 00739 } 00740 if(head->nEffRange < rangeBound) { 00741 if(optDir == Opt_Both) optDir = Opt_CS; 00742 else if(optDir == Opt_NS) optDir = Opt_None; 00743 } 00744 if(optDir == Opt_None) return(0); 00745 00746 oneBdd = bdd_one(head->mgr); 00747 domain2range = head->domain2range; 00748 range2domain = head->range2domain; 00749 varArray = head->varArray; 00750 00751 if(optDir == Opt_Both || optDir == Opt_CS) { 00752 smoothVarBddArray = array_alloc(bdd_t *, 0); 00753 nDomainReduced = 0; 00754 for(i=0; i<head->nEffDomain; i++) { 00755 id = domainId[i]; 00756 if(existStateVar[domain2range[id]]) continue; 00757 00758 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0; 00759 if(var) { 00760 if(head->nEffDomain-nDomainReduced < domainBound) break; 00761 if(var->nSize-head->includeCS == 1) { 00762 varBdd = bdd_get_variable(head->mgr, id); 00763 array_insert_last(bdd_t *, smoothVarBddArray, varBdd); 00764 nDomainReduced++; 00765 } 00766 } 00767 } 00768 00769 if(array_n(smoothVarBddArray)) { 00770 for(i=0; i<head->nSize; i++) { 00771 conjunct = head->conjunctArray[i]; 00772 if(conjunct->nDomain == 0) continue; 00773 if(ImgLinearQuantifyVariablesFromConjunct( 00774 head, conjunct, smoothVarBddArray, &bOptimize)) { 00775 fprintf(vis_stdout, "NOTICE : CS %3d quantified from %d'th relation\n", id, i); 00776 } 00777 } 00778 } 00779 mdd_array_free(smoothVarBddArray); 00780 } 00781 00782 if(optDir == Opt_Both || optDir == Opt_NS) { 00783 smoothVarBddArray = array_alloc(bdd_t *, 0); 00784 nRangeReduced = 0; 00785 for(i=0; i<head->nEffRange; i++) { 00786 id = rangeId[i]; 00787 if(existStateVar[range2domain[id]]) continue; 00788 00789 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 00790 0; 00791 if(var) { 00792 if(head->nEffRange-nRangeReduced < rangeBound) break; 00793 if(var->nSize-head->includeNS == 1) { 00794 varBdd = bdd_get_variable(head->mgr, id); 00795 array_insert_last(bdd_t *, smoothVarBddArray, varBdd); 00796 nRangeReduced++; 00797 } 00798 } 00799 } 00800 00801 if(array_n(smoothVarBddArray)) { 00802 for(i=0; i<head->nSize; i++) { 00803 conjunct = head->conjunctArray[i]; 00804 if(conjunct->nRange == 0) continue; 00805 if(ImgLinearQuantifyVariablesFromConjunct( 00806 head, conjunct, smoothVarBddArray, &bOptimize)) { 00807 fprintf(vis_stdout, "NOTICE : NS %3d quantified from %d'th relation\n", id, i); 00808 } 00809 } 00810 } 00811 mdd_array_free(smoothVarBddArray); 00812 } 00813 00814 bdd_free(oneBdd); 00815 free(rangeId); 00816 free(domainId); 00817 free(existStateVar); 00818 00819 ImgLinearVariableArrayInit(head); 00820 00821 return(bOptimize); 00822 } 00823 00835 void 00836 ImgLinearOptimizeInternalVariables(Relation_t *head) 00837 { 00838 bdd_t *oneBdd, *varBdd; 00839 VarLife_t **varArray, *var; 00840 Conjunct_t **conjunctArray; 00841 array_t *smoothVarBddArray; 00842 int *varType; 00843 int i, bModified; 00844 00845 oneBdd = bdd_one(head->mgr); 00846 while(1) { 00847 bModified = 0; 00848 varArray = head->varArray; 00849 varType = head->varType; 00850 conjunctArray = head->conjunctArray; 00851 for(i=0; i<head->nVarArray; i++) { 00852 var = head->varArray[i]; 00853 if(varType[var->id] == 2) 00854 continue; 00855 if(varType[var->id] == 1 && head->quantifyCS == 0) 00856 continue; 00857 if(var->from == var->to) { 00858 if(conjunctArray[var->from] == 0) continue; 00859 varBdd = bdd_get_variable(head->mgr, var->id); 00860 smoothVarBddArray = array_alloc(bdd_t *, 0); 00861 array_insert_last(bdd_t *, smoothVarBddArray, varBdd); 00862 ImgLinearQuantifyVariablesFromConjunct( 00863 head, head->conjunctArray[var->from], smoothVarBddArray, &bModified); 00864 mdd_array_free(smoothVarBddArray); 00865 } 00866 } 00867 if(bModified == 0) break; 00868 ImgLinearVariableArrayInit(head); 00869 } 00870 bdd_free(oneBdd); 00871 return; 00872 } 00873 00874 00875 00876 00888 void 00889 ImgLinearRefineRelation(Relation_t *head) 00890 { 00891 ImgLinearConjunctArrayRefine(head); 00892 ImgLinearVariableArrayInit(head); 00893 } 00894 00906 void 00907 ImgLinearConjunctOrderMainCC(Relation_t *head, int refineFlag) 00908 { 00909 Conjunct_t **connectedArray; 00910 int i, index; 00911 char baseName[1024]; 00912 00913 ImgLinearPrintMatrix(head); 00914 ImgLinearExtractNextStateCase(head); 00915 ImgLinearClusterSameSupportSet(head); 00916 ImgLinearRefineRelation(head); 00917 00918 ImgLinearExtractSingletonCase(head); 00919 ImgLinearRefineRelation(head); 00920 00921 ImgLinearConnectedComponent(head); 00922 00923 for(i=0; i<head->nConnectedComponent; i++) { 00924 connectedArray = head->connectedComponent[i]; 00925 for(index=0; (long)(connectedArray[index])>0; index++); 00926 head->conjunctArray = connectedArray; 00927 head->nSize = index; 00928 head->bModified = 1; 00929 head->bRefineVarArray = 1; 00930 qsort(head->conjunctArray, head->nSize, sizeof(Conjunct_t *), 00931 ImgLinearCompareConjunctSize); 00932 ImgLinearVariableArrayInit(head); 00933 00934 ImgLinearConjunctOrderMain(head, 0); 00935 fprintf(stdout, "NOTICE : %d'th connected component\n", i); 00936 head->connectedComponent[i] = head->conjunctArray; 00937 head->conjunctArray = 0; 00938 } 00939 00940 ImgLinearBuildConjunctArrayWithQuotientCC(head); 00941 00942 ImgLinearAddSingletonCase(head); 00943 ImgLinearAddNextStateCase(head); 00944 ImgLinearExpandSameSupportSet(head); 00945 ImgLinearRefineRelation(head); 00946 00947 ImgLinearRefineRelation(head); 00948 ImgLinearPrintMatrix(head); 00949 00950 sprintf(baseName, "profile"); 00951 ImgLinearPrintVariableProfile(head, baseName); 00952 ImgLinearPrintMatrixFull(head, 2); 00953 } 00965 void 00966 ImgLinearBuildConjunctArrayWithQuotientCC(Relation_t *head) 00967 { 00968 Conjunct_t *conjunct, *tConjunct; 00969 Conjunct_t **connectedArray; 00970 Conjunct_t **conjunctArray; 00971 Conjunct_t **newConjunctArray; 00972 st_table *table; 00973 int i, j, k, l; 00974 int index, id, size; 00975 int *varType, *supList; 00976 st_generator *gen; 00977 char baseName[1024]; 00978 00979 if(head->nConnectedComponent == 1) { 00980 size = 0; 00981 newConjunctArray = ALLOC(Conjunct_t *, size+1); 00982 connectedArray = head->connectedComponent[0]; 00983 for(j=0; (long)(connectedArray[j])>0; j++) { 00984 tConjunct = connectedArray[j]; 00985 newConjunctArray[size++] = tConjunct; 00986 newConjunctArray = REALLOC(Conjunct_t *, newConjunctArray, size+1); 00987 } 00988 free(head->conjunctArray); 00989 head->nSize = size; 00990 head->conjunctArray = newConjunctArray; 00991 head->bModified = 1; 00992 head->bRefineVarArray = 1; 00993 ImgLinearRefineRelation(head); 00994 return; 00995 } 00996 00997 head->includeCS = 1; 00998 head->includeNS = 1; 00999 varType = head->varType; 01000 conjunctArray = ALLOC(Conjunct_t *, head->nConnectedComponent); 01001 for(i=0; i<head->nConnectedComponent; i++) { 01002 connectedArray = head->connectedComponent[i]; 01003 01004 table = st_init_table(st_ptrcmp, st_ptrhash); 01005 for(j=0; (long)(connectedArray[j])>0; j++) { 01006 conjunct = connectedArray[j]; 01007 size = conjunct->nSize; 01008 supList = conjunct->supList; 01009 for(k=0; k<size; k++) { 01010 id = supList[k]; 01011 st_insert(table, (char *)(long)id, (char *)(long)id); 01012 } 01013 for(l=0; l<conjunct->nCluster; l++) { 01014 tConjunct = conjunct->clusterArray[l]; 01015 size = tConjunct->nSize; 01016 supList = tConjunct->supList; 01017 for(k=0; k<size; k++) { 01018 id = supList[k]; 01019 st_insert(table, (char *)(long)id, (char *)(long)id); 01020 } 01021 } 01022 } 01023 01024 conjunct = ALLOC(Conjunct_t, 1); 01025 memset(conjunct, 0, sizeof(Conjunct_t)); 01026 conjunct->index = i; 01027 conjunct->dummy = (long)connectedArray; 01028 supList = ALLOC(int, table->num_entries); 01029 index = 0; 01030 st_foreach_item(table, gen, &id, &id) { 01031 if(varType[id] == 1) conjunct->nDomain++; 01032 else if(varType[id] == 2) conjunct->nRange++; 01033 else if(varType[id] == 3) conjunct->nQuantify++; 01034 supList[index++] = id; 01035 } 01036 conjunct->supList = supList; 01037 conjunct->nSize = index; 01038 01039 conjunctArray[i] = conjunct; 01040 conjunct->index = i; 01041 conjunct->relation = bdd_zero(head->mgr); 01042 } 01043 01044 head->nSize = head->nConnectedComponent; 01045 head->conjunctArray = conjunctArray; 01046 head->bRefineVarArray = 1; 01047 ImgLinearVariableArrayInit(head); 01048 01049 sprintf(baseName, "TopCon"); 01050 ImgLinearCAPOInterfaceConjunctNodes(head, baseName); 01051 ImgLinearCAPOInterfaceConjunctNet(head, baseName); 01052 ImgLinearCAPOInterfaceConjunctScl(head, baseName); 01053 ImgLinearCAPOInterfaceConjunctPl(head, baseName); 01054 ImgLinearCAPOInterfaceAux(head, baseName); 01055 ImgLinearCAPORun("MetaPlacer", baseName, 0); 01056 ImgLinearCAPOReadConjunctOrder(head, baseName); 01057 01058 size = 0; 01059 newConjunctArray = ALLOC(Conjunct_t *, size+1); 01060 conjunctArray = head->conjunctArray; 01061 for(i=0; i<head->nSize; i++) { 01062 conjunct = head->conjunctArray[i]; 01063 connectedArray = (Conjunct_t **)conjunct->dummy; 01064 for(j=0; (long)(connectedArray[j])>0; j++) { 01065 tConjunct = connectedArray[j]; 01066 newConjunctArray[size++] = tConjunct; 01067 newConjunctArray = REALLOC(Conjunct_t *, newConjunctArray, size+1); 01068 } 01069 ImgLinearConjunctQuit(conjunct); 01070 } 01071 free(conjunctArray); 01072 head->conjunctArray = newConjunctArray; 01073 head->nSize = size; 01074 head->bModified = 1; 01075 head->bRefineVarArray = 1; 01076 ImgLinearRefineRelation(head); 01077 01078 } 01079 01080 01092 void 01093 ImgLinearConnectedComponent(Relation_t *head) 01094 { 01095 Conjunct_t *conjunct; 01096 Conjunct_t **connectedArray; 01097 int i, j, index, cc_index; 01098 int pre_index, pre_cc_index; 01099 01100 ImgLinearVariableArrayInit(head); 01101 01102 for(i=0; i<head->nSize; i++) { 01103 conjunct = head->conjunctArray[i]; 01104 conjunct->dummy = 0; 01105 } 01106 01107 cc_index = 0; 01108 for(i=0; i<head->nSize; i++) { 01109 conjunct = head->conjunctArray[i]; 01110 if(conjunct->dummy) continue; 01111 cc_index++; 01112 ImgLinearFindConnectedComponent(head, conjunct, cc_index); 01113 } 01114 qsort(head->conjunctArray, head->nSize, sizeof(Conjunct_t *), 01115 ImgLinearCompareConjunctDummy); 01116 01117 head->nConnectedComponent = 0; 01118 pre_index = 0; 01119 pre_cc_index = 1; 01120 for(i=0; i<head->nSize; i++) { 01121 conjunct = head->conjunctArray[i]; 01122 if(conjunct->dummy != pre_cc_index) { 01123 if((i-pre_index) == 1) { 01124 head->singletonArray = ImgLinearAddConjunctIntoArray( 01125 head->singletonArray, &(head->nSingletonArray), 01126 head->conjunctArray[i-1]); 01127 } 01128 else { 01129 if(head->nConnectedComponent) 01130 head->connectedComponent = REALLOC(Conjunct_t **, head->connectedComponent, head->nConnectedComponent+1); 01131 else 01132 head->connectedComponent = ALLOC(Conjunct_t **, head->nConnectedComponent+1); 01133 01134 connectedArray = ALLOC(Conjunct_t *, (i-pre_index+2)); 01135 head->connectedComponent[head->nConnectedComponent++] = connectedArray; 01136 for(index=0, j=pre_index; j<i; j++) 01137 connectedArray[index++] = head->conjunctArray[j]; 01138 connectedArray[index] = 0; 01139 } 01140 01141 pre_cc_index = conjunct->dummy; 01142 pre_index = i; 01143 } 01144 } 01145 01146 if((i-pre_index) == 1) { 01147 head->singletonArray = ImgLinearAddConjunctIntoArray( 01148 head->singletonArray, &(head->nSingletonArray), 01149 head->conjunctArray[i-1]); 01150 } 01151 else { 01152 if(head->nConnectedComponent) 01153 head->connectedComponent = REALLOC(Conjunct_t **, 01154 head->connectedComponent, head->nConnectedComponent+1); 01155 01156 else 01157 head->connectedComponent = ALLOC(Conjunct_t **, 01158 head->nConnectedComponent+1); 01159 01160 connectedArray = ALLOC(Conjunct_t *, (i-pre_index+2)); 01161 head->connectedComponent[head->nConnectedComponent++] = connectedArray; 01162 for(index=0, j=pre_index; j<i; j++) 01163 connectedArray[index++] = head->conjunctArray[j]; 01164 connectedArray[index] = 0; 01165 } 01166 free(head->conjunctArray); 01167 } 01168 01180 void 01181 ImgLinearFindConnectedComponent(Relation_t *head, 01182 Conjunct_t *conjunct, 01183 int cc_index) 01184 { 01185 VarLife_t *var; 01186 int *supList; 01187 int id, size; 01188 int index, i, j; 01189 int *relArr; 01190 Conjunct_t *tConjunct; 01191 01192 if(conjunct->dummy) return; 01193 supList = conjunct->supList; 01194 size = conjunct->nSize; 01195 conjunct->dummy = cc_index; 01196 for(i=0; i<size; i++) { 01197 id = supList[i]; 01198 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0; 01199 if(!var) continue; 01200 relArr = var->relArr; 01201 for(j=0; j<var->nSize; j++) { 01202 index = relArr[j]; 01203 if(index == MAXINT) continue; 01204 if(index == MAXINT-1) continue; 01205 tConjunct = head->conjunctArray[index]; 01206 if(tConjunct->dummy) continue; 01207 ImgLinearFindConnectedComponent(head, tConjunct, cc_index); 01208 } 01209 } 01210 } 01211 01212 01224 void 01225 ImgLinearExtractSingletonCase(Relation_t *head) 01226 { 01227 int i, j, k, id, index; 01228 VarLife_t **varArray, *var; 01229 int nSingleton; 01230 int *supList, *varType; 01231 Conjunct_t *conjunct, **newSingletonArray; 01232 int *singletonArray; 01233 01234 varType = head->varType; 01235 varArray = head->varArray; 01236 nSingleton = 0; 01237 singletonArray = ALLOC(int , nSingleton+1); 01238 for(i=0; i<head->nVarArray; i++) { 01239 var = varArray[i]; 01240 if(var->stateVar == 2) continue; 01241 if(var->stateVar == 1) { 01242 if(var->nSize - head->includeCS > 1) continue; 01243 } 01244 else { 01245 if(var->nSize > 1) continue; 01246 } 01247 01248 for(j=0; j<var->nSize; j++) { 01249 if(var->relArr[j] == MAXINT) continue; 01250 if(var->relArr[j] == MAXINT-1) continue; 01251 singletonArray[nSingleton++] = var->relArr[j]; 01252 singletonArray = REALLOC(int , singletonArray, nSingleton+1); 01253 } 01254 } 01255 01256 for(i=0; i<nSingleton; i++) { 01257 conjunct = head->conjunctArray[singletonArray[i]]; 01258 conjunct->bSingleton = 1; 01259 } 01260 01261 for(i=0; i<nSingleton; i++) { 01262 conjunct = head->conjunctArray[singletonArray[i]]; 01263 if(conjunct->nRange == conjunct->nSize-conjunct->nRange && 01264 conjunct->nSize-conjunct->nRange != 1) { 01265 conjunct->bSingleton = 0; 01266 continue; 01267 } 01268 01269 supList = conjunct->supList; 01270 for(j=0; j<conjunct->nSize; j++) { 01271 id = supList[j]; 01272 if(varType[id] == 2) continue; 01273 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0; 01274 if(!var) continue; 01275 01276 if(var->stateVar == 1) { 01277 if(var->nSize - head->includeCS == 1) continue; 01278 } 01279 else { 01280 if(var->nSize == 1) continue; 01281 } 01282 for(k=0; k<var->nSize; k++) { 01283 index = var->relArr[k]; 01284 if(index == MAXINT) continue; 01285 if(index == MAXINT-1) continue; 01286 (head->conjunctArray[index])->bSingleton = 0; 01287 } 01288 } 01289 } 01290 01291 newSingletonArray = ALLOC(Conjunct_t *, nSingleton); 01292 for(index=0, i=0; i<nSingleton; i++) { 01293 conjunct = head->conjunctArray[singletonArray[i]]; 01294 if(conjunct == 0) continue; 01295 if(conjunct->bSingleton) { 01296 newSingletonArray[index++] = conjunct; 01297 head->conjunctArray[singletonArray[i]] = 0; 01298 } 01299 } 01300 head->nSingletonArray = index; 01301 free(singletonArray); 01302 qsort(newSingletonArray, head->nSingletonArray, 01303 sizeof(Conjunct_t *), ImgLinearCompareConjunctRangeMinusDomain); 01304 head->singletonArray = newSingletonArray; 01305 01306 if(head->nSingletonArray) { 01307 head->bModified = 1; 01308 head->bRefineVarArray = 1; 01309 } 01310 } 01311 01323 void 01324 ImgLinearAddConjunctIntoClusterArray(Conjunct_t *base, Conjunct_t *con) 01325 { 01326 if(base->clusterArray == 0) { 01327 base->clusterArray = ALLOC(Conjunct_t *, base->nCluster+1); 01328 base->clusterArray[base->nCluster++] = con; 01329 } 01330 else { 01331 base->clusterArray = REALLOC(Conjunct_t *, base->clusterArray, base->nCluster+1); 01332 base->clusterArray[base->nCluster++] = con; 01333 } 01334 base->bClustered = 1; 01335 } 01336 01337 01338 01350 void 01351 ImgLinearExtractNextStateCase(Relation_t *head) 01352 { 01353 int i, index, flag; 01354 Conjunct_t *conjunct; 01355 Conjunct_t **nextStateArray; 01356 01357 index = 0; 01358 flag = 1; 01359 nextStateArray = ALLOC(Conjunct_t *, index+1); 01360 for(index=0, i=head->nSize-1; i>=0; i--) { 01361 conjunct = head->conjunctArray[i]; 01362 if(conjunct == 0) continue; 01363 if(conjunct->nSize == conjunct->nRange && flag == 0) { 01364 nextStateArray[index++] = conjunct; 01365 nextStateArray = REALLOC(Conjunct_t *, nextStateArray, index+1); 01366 head->conjunctArray[i] = 0; 01367 head->bModified = 1; 01368 } 01369 if(conjunct->nSize != conjunct->nRange) flag = 0; 01370 } 01371 head->nextStateArray = nextStateArray; 01372 head->nNextStateArray = index; 01373 01374 ImgLinearRefineRelation(head); 01375 } 01376 01388 void 01389 ImgLinearRelationQuit(Relation_t *head) 01390 { 01391 int i; 01392 Conjunct_t *conjunct; 01393 01394 if(head->varArray) ImgLinearVariableArrayQuit(head); 01395 if(head->rangeVars) free(head->rangeVars); 01396 if(head->domainVars) free(head->domainVars); 01397 if(head->quantifyVars) free(head->quantifyVars); 01398 if(head->varType) free(head->varType); 01399 if(head->varArrayMap) free(head->varArrayMap); 01400 01401 if(head->singletonArray) free(head->singletonArray); 01402 if(head->nextStateArray) free(head->nextStateArray); 01403 01404 if(head->constantCase) { 01405 for(i=0; i<head->nVar; i++) 01406 if(head->constantCase[i]) bdd_free(head->constantCase[i]); 01407 } 01408 01409 for(i=0; i<head->nSize; i++) { 01410 conjunct = head->conjunctArray[i]; 01411 ImgLinearConjunctQuit(conjunct); 01412 } 01413 free(head); 01414 } 01415 01416 01428 int 01429 ImgLinearClusteringIteratively(Relation_t *head, 01430 double affinityLimit, 01431 int andExistLimit, 01432 int varLimit, 01433 int includeZeroGain, 01434 int useFailureHistory, 01435 Img_OptimizeType optDir, 01436 int (*compare_func)(const void *, const void *)) 01437 { 01438 int bddLimit, gainLimit; 01439 int clusterLimit; 01440 int bOptimize; 01441 01442 if(head->nSize < 2) return(0); 01443 01444 bOptimize = 0; 01445 bddLimit = head->bddLimit; 01446 gainLimit = 50; 01447 01448 while(1) { 01449 if(head->nSize < 50)clusterLimit = head->nSize/2; 01450 else clusterLimit = head->nSize/3+1; 01451 if(clusterLimit > 50) clusterLimit = 50; 01457 ImgLinearClusteringByConstraints(head, includeZeroGain, varLimit, clusterLimit, 01458 gainLimit, affinityLimit, andExistLimit, 01459 bddLimit, useFailureHistory, compare_func); 01460 if(head->bModified) { 01461 ImgLinearRefineRelation(head); 01462 bOptimize |= ImgLinearOptimizeAll(head, optDir, 0); 01463 } 01464 else break; 01465 } 01466 return(bOptimize); 01467 } 01479 void 01480 ImgLinearClusteringByConstraints(Relation_t *head, 01481 int includeZeroGain, 01482 int varLimit, 01483 int clusterLimit, 01484 int gainLimit, 01485 double affinityLimit, 01486 int andExistLimit, 01487 int bddLimit, 01488 int useFailureHistory, 01489 int (*compare_func)(const void *, const void *)) 01490 { 01491 int size, begin, end; 01492 int **nDead, **nVar, **nFailure; 01493 int *dirtyBit; 01494 int i, j, k, l, index; 01495 int start, preGain; 01496 int nClusterArray; 01497 VarLife_t **varArray, *var; 01498 Cluster_t **clusterArray, *clu; 01499 Conjunct_t *conjunct; 01500 bdd_t *clusteredRelation; 01501 int fail_flag; 01502 int from, to, splitable; 01503 01504 varArray = head->varArray; 01505 size = head->nSize; 01506 01507 nDead = ALLOC(int *, size); 01508 nVar = ALLOC(int *, size); 01509 nFailure = 0; 01510 if(useFailureHistory) 01511 nFailure = ALLOC(int *, size); 01512 for(i=0; i<size; i++) { 01513 nDead[i] = ALLOC(int, size); 01514 nVar[i] = ALLOC(int, size); 01515 if(useFailureHistory) 01516 nFailure[i] = ALLOC(int, size); 01517 memset(nDead[i], 0, sizeof(int)*size); 01518 memset(nVar[i], 0, sizeof(int)*size); 01519 if(useFailureHistory) 01520 memset(nFailure[i], 0, sizeof(int)*size); 01521 } 01522 01523 index = 0; 01524 for(l=0; l<head->nVarArray; l++) { 01525 var = varArray[l]; 01526 begin = var->from; 01527 end = var->to; 01528 if(var->stateVar == 1) begin = -1; 01529 else if(var->stateVar == 2) end = size; 01530 01531 for(i=0; i<=begin; i++) 01532 for(j=end; j<size; j++) 01533 nDead[i][j]++; 01534 01535 for(i=0; i<=var->effTo; i++) { 01536 if(i > var->effFrom) { 01537 for(k=0; k<var->nSize; k++) { 01538 index = var->relArr[k]; 01539 if(index == MAXINT) continue; 01540 if(index == MAXINT-1) continue; 01541 if(index >= i) break; 01542 } 01543 if(index < i) start = var->effTo; 01544 else start = index; 01545 } 01546 else { 01547 start = var->effFrom; 01548 } 01549 01550 for(j=start; j<size; j++) 01551 nVar[i][j]++; 01552 } 01553 } 01554 01555 for(i=0; i<size; i++) { 01556 end = (size-1) < i+clusterLimit ? size-1 : i+clusterLimit; 01557 if(i==end) continue; 01558 if(nDead[i][end] == 0 && !includeZeroGain) continue; 01559 01560 preGain = -1; 01561 for(j=end; j>=i; j--) { 01562 if(varLimit < nVar[i][j]-nDead[i][j]) continue; 01563 if(gainLimit < nDead[i][j]) continue; 01564 01565 01566 if(preGain != -1) { 01567 if(nDead[i][j] < preGain && nDead[i][j] >= 0) { 01568 to = j+1; 01569 for(from=i; from < to; from++) { 01570 if(nDead[from+1][to] != nDead[from][to]) break; 01571 } 01572 if(from != i) continue; 01573 01574 splitable = 0; 01575 for(k=from; k<to; k++) { 01576 if(nDead[from][to] == (nDead[from][k] + nDead[k+1][to])) { 01577 splitable = 1; 01578 break; 01579 } 01580 } 01581 if(!splitable) 01582 ImgLinearInsertClusterCandidate(head, from, to, 01583 nDead[from][to], nVar[from][to], affinityLimit); 01584 } 01585 } 01586 01587 if(nDead[i][j] == 0) { 01588 if(includeZeroGain) 01589 ImgLinearInsertClusterCandidate(head, i, i+1, 01590 nDead[i][i+1], nVar[i][i+1], affinityLimit); 01591 break; 01592 } 01593 01594 preGain = nDead[i][j]; 01595 01596 } 01597 } 01598 01599 if(head->nClusterArray == 0) return; 01600 qsort(head->clusterArray, head->nClusterArray, sizeof(Cluster_t *), 01601 compare_func); 01602 01603 dirtyBit = ALLOC(int, size); 01604 memset(dirtyBit, 0, sizeof(int)*size); 01605 01606 clusterArray = head->clusterArray; 01607 nClusterArray = head->nClusterArray; 01608 for(i=0; i<nClusterArray; i++) { 01609 clu = clusterArray[i]; 01610 if(useFailureHistory) { 01611 if(nFailure[clu->from][clu->to] == 1) continue; 01612 } 01613 fail_flag = 0; 01614 for(j=clu->from; j<=clu->to; j++) { 01615 if(dirtyBit[j] == 1) { 01616 fail_flag = 1; 01617 continue; 01618 } 01619 } 01620 if(fail_flag) continue; 01621 01622 clusteredRelation = ImgLinearClusteringSmooth(head, clu, 01623 nFailure, andExistLimit, bddLimit); 01624 01625 conjunct = 0; 01626 if(clusteredRelation) { 01627 for(j=clu->from; j<=clu->to; j++) { 01628 conjunct = head->conjunctArray[j]; 01629 if(conjunct->relation) bdd_free(conjunct->relation); 01630 conjunct->relation = 0; 01631 } 01632 conjunct->relation = clusteredRelation; 01633 conjunct->bModified = 1; 01634 head->bModified = 1; 01635 for(j=clu->from; j<=clu->to; j++) dirtyBit[j] = 1; 01636 01637 if(head->verbosity >= 5) 01638 fprintf(stdout, "\tClustering Success : %4d -%4d G(%3d) V(%3d) A(%3d)\n", 01639 clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity); 01640 } 01641 fflush(stdout); 01642 } 01643 01644 for(i=0; i<nClusterArray; i++) 01645 free(clusterArray[i]); 01646 free(clusterArray); 01647 head->clusterArray = 0; 01648 head->nClusterArray = 0; 01649 01650 for(i=0; i<head->nSize; i++) { 01651 free(nDead[i]); 01652 free(nVar[i]); 01653 if(useFailureHistory) 01654 free(nFailure[i]); 01655 } 01656 free(nDead); 01657 free(nVar); 01658 if(useFailureHistory) 01659 free(nFailure); 01660 01661 return; 01662 } 01674 static void 01675 ImgLinearInsertClusterCandidate(Relation_t *head, 01676 int from, int to, 01677 int nDead, int nVar, 01678 double affinityLimit) 01679 { 01680 Conjunct_t *conjunct; 01681 Cluster_t *clu; 01682 int *varType, *supList; 01683 int i, j, id, size; 01684 st_table *table; 01685 double affinity, tAffinity; 01686 int preSize, postSize, curSize, overlap; 01687 01688 varType = head->varType; 01689 01690 conjunct = head->conjunctArray[from]; 01691 if(conjunct->relation == 0) { 01692 return; 01693 } 01694 01695 supList = conjunct->supList; 01696 size = conjunct->nSize; 01697 table = st_init_table(st_numcmp, st_numhash); 01698 for(i=0; i<size; i++) { 01699 id = supList[i]; 01700 if(varType[id] == 2) continue; 01701 st_insert(table, (char *)(long)id, (char *)(long)id); 01702 } 01703 01704 tAffinity = 0.0; 01705 for(i=from+1; i<=to; i++) { 01706 preSize = table->num_entries; 01707 01708 conjunct = head->conjunctArray[i]; 01709 if(conjunct->relation == 0) continue; 01710 supList = conjunct->supList; 01711 size = conjunct->nSize; 01712 curSize = 0; 01713 for(j=0; j<size; j++) { 01714 id = supList[j]; 01715 01716 if(varType[id] == 2) continue; 01717 curSize++; 01718 st_insert(table, (char *)(long)id, (char *)(long)id); 01719 } 01720 01721 postSize = table->num_entries; 01722 01723 overlap = curSize - (postSize-preSize); 01724 01725 if(curSize > preSize) affinity = (double)overlap/(double)preSize; 01726 else affinity = (double)overlap/(double)curSize; 01727 01734 tAffinity += affinity; 01735 } 01736 st_free_table(table); 01737 01738 tAffinity /= (double)(to-from); 01739 clu = ALLOC(Cluster_t, 1); 01740 clu->from = from; 01741 clu->to = to; 01742 clu->nVar = nVar; 01743 clu->nDead = nDead; 01744 clu->nAffinity = (int)(tAffinity * 100.0); 01745 01746 head->clusterArray = REALLOC(Cluster_t *, head->clusterArray, head->nClusterArray+1); 01747 head->clusterArray[head->nClusterArray++] = clu; 01748 if(head->verbosity >= 5) { 01749 fprintf(stdout, "Candidate Cluster : %4d-%4d G(%3d) V(%3d) A(%3d)\n", 01750 clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity); 01751 fflush(stdout); 01752 } 01753 01754 } 01755 01767 static bdd_t * 01768 ImgLinearClusteringSmooth(Relation_t *head, 01769 Cluster_t *clu, 01770 int **failureHistory, 01771 int andExistLimit, 01772 int bddLimit) 01773 { 01774 int *varType, *supList; 01775 array_t *smoothVarBddArray, *smoothArray; 01776 Conjunct_t *conjunct; 01777 bdd_t *relation, *totalRelation; 01778 bdd_t *varBdd, *tempRelation; 01779 int i, j, k, tempSize, failFlag; 01780 int id, tid; 01781 st_table *deadTable; 01782 VarLife_t *var; 01783 01784 varType = head->varType; 01785 01786 smoothVarBddArray = array_alloc(array_t *, 0); 01787 for(i=clu->from; i<=clu->to; i++) { 01788 smoothArray = array_alloc(bdd_t *, 0); 01789 array_insert_last(array_t *, smoothVarBddArray, smoothArray); 01790 } 01791 01792 deadTable = st_init_table(st_numcmp, st_numhash); 01793 for(i=clu->from; i<=clu->to; i++) { 01794 conjunct = head->conjunctArray[i]; 01795 if(conjunct == 0) continue; 01796 if(conjunct->relation == 0) continue; 01797 supList = conjunct->supList; 01798 for(j=0; j<conjunct->nSize; j++) { 01799 id = supList[j]; 01800 if(varType[id] == 1 || varType[id] == 2) continue; 01801 01802 if(st_lookup(deadTable, (char *)(long)id, &tid)) continue; 01803 01804 var = head->varArray[head->varArrayMap[id]]; 01805 01806 if(clu->from <= var->from && var->to <= clu->to) { 01807 st_insert(deadTable, (char *)(long)id, (char *)(long)id); 01808 smoothArray = array_fetch(array_t *, smoothVarBddArray, 01809 var->to-clu->from); 01810 varBdd = bdd_get_variable(head->mgr, var->id); 01811 array_insert_last(bdd_t *, smoothArray, varBdd); 01812 } 01813 } 01814 } 01815 st_free_table(deadTable); 01816 01817 01818 totalRelation = bdd_one(head->mgr); 01819 failFlag = 0; 01820 for(i=clu->from; i<=clu->to; i++) { 01821 conjunct = head->conjunctArray[i]; 01822 if(conjunct == 0) continue; 01823 if(conjunct->relation == 0) continue; 01824 relation = conjunct->relation; 01825 smoothArray = array_fetch(array_t *, smoothVarBddArray, i-clu->from); 01826 01827 tempRelation = bdd_and_smooth_with_limit(totalRelation, relation, 01828 smoothArray, andExistLimit); 01829 if(tempRelation) tempSize = bdd_size(tempRelation); 01830 else tempSize = MAXINT; 01831 01832 if(tempSize > bddLimit) { 01833 bdd_free(totalRelation); 01834 if(tempRelation) bdd_free(tempRelation); 01835 totalRelation = 0; 01836 01837 if(failureHistory) { 01838 for(j=0; j<=clu->from; j++) 01839 for(k=i; k<head->nSize; k++) 01840 failureHistory[j][k] = 1; 01841 } 01842 01843 if(head->verbosity >= 3) 01844 fprintf(stdout, "Clustering Failure : %4d-%4d G(%3d) V(%3d) A(%3d) At %3d S(%d)\n", 01845 clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity, i, tempSize); 01846 break; 01847 } 01848 01849 bdd_free(totalRelation); 01850 totalRelation = tempRelation; 01851 } 01852 ImgLinearFreeSmoothArray(smoothVarBddArray); 01853 01854 if(failFlag) return(0); 01855 else return(totalRelation); 01856 } 01857 01858 01870 static int 01871 ImgLinearClusterUsingHeap(Relation_t *head, 01872 double affinityLimit, 01873 int andExistLimit, 01874 int varLimit, 01875 Img_OptimizeType optDir, 01876 int rangeFlag, 01877 int (*compare_func)(const void *, const void *)) 01878 { 01879 Cluster_t *clu; 01880 int j; 01881 Conjunct_t *conjunct; 01882 bdd_t *clusteredRelation; 01883 Heap_t *heap; 01884 int bOptimize; 01885 long dummy; 01886 01887 bOptimize = 0; 01888 ImgLinearBuildInitialCandidate(head, affinityLimit, varLimit, rangeFlag, compare_func); 01890 heap = head->clusterHeap; 01891 while(Heap_HeapExtractMin(heap, &clu, &dummy)) { 01892 if(clu->flag) { 01893 free(clu); 01894 continue; 01895 } 01896 if(clu->to >= head->nSize) { 01897 free(clu); 01898 continue; 01899 } 01900 01901 clusteredRelation = ImgLinearClusteringPairSmooth(head, clu, 01902 0, andExistLimit, head->bddLimit); 01903 if(clusteredRelation) { 01904 if(head->verbosity >= 5) 01905 fprintf(stdout, "\tClustering Success : %4d -%4d G(%3d) V(%3d) A(%3d)\n", 01906 clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity); 01907 fflush(stdout); 01908 01909 for(j=clu->from+1; j<=clu->to; j++) { 01910 conjunct = head->conjunctArray[j]; 01911 if(conjunct == 0) continue; 01912 if(conjunct->relation == 0) continue; 01913 bdd_free(conjunct->relation); 01914 conjunct->relation = 0; 01915 } 01916 conjunct = head->conjunctArray[clu->from]; 01917 if(conjunct->relation) 01918 bdd_free(conjunct->relation); 01919 conjunct->relation = clusteredRelation; 01920 conjunct->bModified = 1; 01921 ImgLinearConjunctRefine(head, conjunct); 01922 head->bModified = 1; 01923 head->bRefineVarArray = 1; 01924 01925 Heap_HeapApplyForEachElement(heap, linearCheckRange); 01936 ImgLinearInsertPairClusterCandidate(head, clu->from, affinityLimit, varLimit, rangeFlag); 01937 ImgLinearInsertPairClusterCandidate(head, clu->from-1, affinityLimit, varLimit, rangeFlag); 01938 } 01939 if(clu->nDead && clusteredRelation) { 01940 ImgLinearVariableArrayInit(head); 01941 bOptimize |= ImgLinearOptimizeAll(head, optDir, 0); 01942 } 01943 free(clu); 01944 } 01945 Heap_HeapFree(heap); 01946 head->clusterHeap = 0; 01947 01948 if(head->bModified) { 01949 if(head->verbosity >= 5) 01950 ImgLinearPrintMatrix(head); 01951 01952 bOptimize |= ImgLinearOptimizeAll(head, optDir, 0); 01953 ImgLinearRefineRelation(head); 01954 01955 if(head->verbosity >= 5) 01956 ImgLinearPrintMatrix(head); 01957 } 01958 return(bOptimize); 01959 } 01960 01972 static int 01973 linearCheckRange(const void *tc) 01974 { 01975 Cluster_t *tclu; 01976 01977 tclu = (Cluster_t *)tc; 01978 if(tclu->from <= __clu->from && __clu->from <= tclu->to) 01979 tclu->flag = 1; 01980 if(tclu->from <= __clu->to && __clu->to <= tclu->to) 01981 tclu->flag = 1; 01982 01983 return(1); 01984 } 01985 01997 static bdd_t * 01998 ImgLinearClusteringPairSmooth(Relation_t *head, 01999 Cluster_t *clu, 02000 int **failureHistory, 02001 int andExistLimit, 02002 int bddLimit) 02003 { 02004 int *varType, *supList; 02005 array_t *smoothArray; 02006 Conjunct_t *conjunct; 02007 bdd_t *totalRelation; 02008 bdd_t *fromRelation, *toRelation; 02009 bdd_t *varBdd; 02010 int i, j, k, tempSize; 02011 int id, tid, effTo; 02012 st_table *deadTable; 02013 VarLife_t *var; 02014 02015 varType = head->varType; 02016 02017 smoothArray = array_alloc(bdd_t *, 0); 02018 02019 for(effTo = clu->to+1; effTo<head->nSize; effTo++) { 02020 conjunct = head->conjunctArray[effTo]; 02021 if(conjunct && conjunct->relation) break; 02022 } 02023 effTo--; 02024 02025 deadTable = st_init_table(st_numcmp, st_numhash); 02026 for(i=clu->from; i<=clu->to; i++) { 02027 conjunct = head->conjunctArray[i]; 02028 if(conjunct == 0) continue; 02029 if(conjunct->relation == 0) continue; 02030 supList = conjunct->supList; 02031 for(j=0; j<conjunct->nSize; j++) { 02032 id = supList[j]; 02033 if(varType[id] == 1 || varType[id] == 2) continue; 02034 02035 if(st_lookup(deadTable, (char *)(long)id, &tid)) continue; 02036 02037 var = head->varArray[head->varArrayMap[id]]; 02038 02039 if(clu->from <= var->from && var->to <= effTo) { 02040 st_insert(deadTable, (char *)(long)id, (char *)(long)id); 02041 varBdd = bdd_get_variable(head->mgr, var->id); 02042 array_insert_last(bdd_t *, smoothArray, varBdd); 02043 } 02044 } 02045 } 02046 st_free_table(deadTable); 02047 02048 conjunct = head->conjunctArray[clu->from]; 02049 fromRelation = conjunct->relation; 02050 toRelation = 0; 02051 for(i=clu->from+1; i<=clu->to; i++) { 02052 conjunct = head->conjunctArray[i]; 02053 if(conjunct == 0) continue; 02054 if(conjunct->relation == 0) continue; 02055 toRelation = conjunct->relation; 02056 break; 02057 } 02058 if(toRelation == 0) { 02059 mdd_array_free(smoothArray); 02060 return(0); 02061 } 02062 if(fromRelation == 0 && toRelation == 0) return(0); 02063 if(fromRelation == 0) { 02064 totalRelation = bdd_dup(toRelation); 02065 } 02066 else if(toRelation == 0) { 02067 totalRelation = bdd_dup(fromRelation); 02068 } 02069 else { 02070 totalRelation = bdd_and_smooth_with_limit(fromRelation, toRelation, 02071 smoothArray, andExistLimit); 02072 } 02073 if(totalRelation) tempSize = bdd_size(totalRelation); 02074 else tempSize = MAXINT; 02075 02076 if(tempSize > bddLimit) { 02077 if(totalRelation) bdd_free(totalRelation); 02078 totalRelation = 0; 02079 if(failureHistory) { 02080 for(j=0; j<=clu->from; j++) 02081 for(k=i; k<head->nSize; k++) 02082 failureHistory[j][k] = 1; 02083 } 02084 if(head->verbosity >= 3) 02085 fprintf(stdout, "Clustering Failure : %4d-%4d G(%3d) V(%3d) A(%3d) At %3d S(%d)\n", 02086 clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity, i, tempSize); 02087 } 02088 mdd_array_free(smoothArray); 02089 02090 return(totalRelation); 02091 } 02092 02093 02094 02107 static void 02108 ImgLinearBuildInitialCandidate(Relation_t *head, 02109 double affinityLimit, 02110 int varLimit, 02111 int rangeFlag, 02112 int (*compare_func)(const void *, const void *)) 02113 { 02114 int size, i; 02115 02116 head->clusterHeap = Heap_HeapInitCompare(head->nSize, compare_func); 02117 size = head->nSize; 02118 for(i=0; i<size; i++) { 02119 ImgLinearInsertPairClusterCandidate(head, i, affinityLimit, varLimit, rangeFlag); 02120 } 02121 02122 return; 02123 } 02135 static void 02136 ImgLinearInsertPairClusterCandidate(Relation_t *head, 02137 int from, 02138 double affinityLimit, 02139 int varLimit, 02140 int rangeFlag) 02141 { 02142 Conjunct_t *conjunct, *fromC, *toC; 02143 Cluster_t *clu; 02144 int *varType, *supList; 02145 st_table *table; 02146 double affinity; 02147 int preSize, postSize, curSize, overlap; 02148 int i, j, id, tid, size, nDead; 02149 int to, effTo; 02150 VarLife_t *var; 02151 02152 if(from < 0) return; 02153 if(from == head->nSize-1) return; 02154 02155 conjunct = head->conjunctArray[from]; 02156 if(conjunct == 0 || conjunct->relation == 0) { 02157 for(; from>=0; from--) { 02158 conjunct = head->conjunctArray[from]; 02159 if(conjunct == 0) continue; 02160 if(conjunct->relation == 0) continue; 02161 break; 02162 } 02163 } 02164 if(from < 0) return; 02165 02166 to = -1; 02167 for(i=from+1; i<head->nSize; i++) { 02168 conjunct = head->conjunctArray[i]; 02169 if(!conjunct) continue; 02170 if(conjunct->relation == 0) continue; 02171 to = i; 02172 break; 02173 } 02174 if(to == -1) return; 02175 for(effTo = to+1; effTo<head->nSize; effTo++) { 02176 conjunct = head->conjunctArray[effTo]; 02177 if(conjunct && conjunct->relation) break; 02178 } 02179 effTo--; 02180 02181 02182 varType = head->varType; 02183 02184 fromC = head->conjunctArray[from]; 02185 toC = head->conjunctArray[to]; 02186 02187 if(rangeFlag && 02188 (fromC->nSize == fromC->nRange || toC->nSize == toC->nRange)) 02189 return; 02190 02191 if(fromC->nSize == fromC->nRange && toC->nSize != toC->nRange) 02192 return; 02193 if(fromC->nSize != fromC->nRange && toC->nSize == toC->nRange) 02194 return; 02195 02196 nDead = 0; 02197 supList = fromC->supList; 02198 size = fromC->nSize; 02199 table = st_init_table(st_numcmp, st_numhash); 02200 for(i=0; i<size; i++) { 02201 id = supList[i]; 02202 if(varType[id] == 2) continue; 02203 preSize++; 02204 st_insert(table, (char *)(long)id, (char *)(long)id); 02205 var = head->varArray[head->varArrayMap[id]]; 02206 if(from <= var->from && var->to <= effTo) nDead++; 02207 } 02208 02209 preSize = table->num_entries; 02210 supList = toC->supList; 02211 size = toC->nSize; 02212 curSize = 0; 02213 for(j=0; j<size; j++) { 02214 id = supList[j]; 02215 if(varType[id] == 2) continue; 02216 curSize++; 02217 if(st_lookup(table, (char *)(long)id, &tid)) continue; 02218 st_insert(table, (char *)(long)id, (char *)(long)id); 02219 var = head->varArray[head->varArrayMap[id]]; 02220 if(from <= var->from && var->to <= effTo) nDead++; 02221 } 02222 02223 postSize = table->num_entries; 02224 overlap = curSize - (postSize-preSize); 02225 if(overlap == 0) affinity = 0.0; 02226 else { 02227 if(curSize > preSize)affinity = (double)overlap/(double)preSize; 02228 else affinity = (double)overlap/(double)curSize; 02229 } 02230 st_free_table(table); 02231 02232 if(affinity < affinityLimit) return; 02233 02234 if(affinity == 0.0 && postSize > 10 && 02235 (fromC->bSingleton || toC->bSingleton)) return; 02236 if(postSize-nDead > varLimit) return; 02237 02238 clu = ALLOC(Cluster_t, 1); 02239 memset(clu, 0, sizeof(Cluster_t)); 02240 clu->from = from; 02241 clu->to = to; 02242 clu->nVar = postSize; 02243 clu->nDead = nDead; 02244 clu->nAffinity = (int)(affinity * 100.0); 02245 02246 Heap_HeapInsertCompare(head->clusterHeap, (void *)clu, (long)clu); 02247 if(head->verbosity >= 5) { 02248 fprintf(stdout, "Candidate Cluster : %4d -%4d G(%3d) V(%3d) A(%3d)\n", 02249 clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity); 02250 fflush(stdout); 02251 } 02252 } 02253 02265 static void 02266 ImgLinearPrintDebugInfo(Relation_t *head) 02267 { 02268 int i, j, id; 02269 Conjunct_t *conjunct; 02270 int *supList; 02271 array_t *smoothVarBddArray; 02272 array_t *smoothArray; 02273 bdd_t *varBdd; 02274 int idPerLine; 02275 02276 idPerLine = 12; 02277 02278 fprintf(vis_stdout, "-----------------------------------------------------\n"); 02279 fprintf(vis_stdout, " Debug Information for Transition Relations\n"); 02280 fprintf(vis_stdout, "-----------------------------------------------------\n"); 02281 fprintf(vis_stdout, "List of Quantify Variables---------------------------\n"); 02282 for(i=0; i<head->nQuantify; i++) { 02283 if(i!=0 && i%idPerLine == 0) fprintf(vis_stdout, "\n"); 02284 fprintf(vis_stdout, "%3d ", head->quantifyVars[i]); 02285 } 02286 fprintf(vis_stdout, "\n"); 02287 02288 fprintf(vis_stdout, "List of Domain Variables-----------------------------\n"); 02289 for(i=0; i<head->nDomain; i++) { 02290 if(i!=0 && i%idPerLine == 0) fprintf(vis_stdout, "\n"); 02291 fprintf(vis_stdout, "%3d ", head->domainVars[i]); 02292 } 02293 fprintf(vis_stdout, "\n"); 02294 02295 fprintf(vis_stdout, "List of Range Variables------------------------------\n"); 02296 for(i=0; i<head->nRange; i++) { 02297 if(i!=0 && i%idPerLine == 0) fprintf(vis_stdout, "\n"); 02298 fprintf(vis_stdout, "%3d ", head->rangeVars[i]); 02299 } 02300 fprintf(vis_stdout, "\n"); 02301 02302 fprintf(vis_stdout, "Varibles in Each Transition Relation-----------------\n"); 02303 for(i=0; i<head->nSize; i++) { 02304 conjunct = head->conjunctArray[i]; 02305 supList = conjunct->supList; 02306 fprintf(vis_stdout, "%3d'th : ", i); 02307 for(j=0; j<conjunct->nSize; j++) { 02308 if(j!=0 && j%idPerLine == 0) fprintf(vis_stdout, "\n "); 02309 fprintf(vis_stdout, "%3d ", supList[j]); 02310 } 02311 fprintf(vis_stdout, "\n"); 02312 } 02313 02314 smoothVarBddArray = ImgLinearMakeSmoothVarBdd(head, 0); 02315 fprintf(vis_stdout, "Quantified Schedule----------------------------------\n"); 02316 for(i=0; i<=head->nSize; i++) { 02317 fprintf(vis_stdout, "%3d'th : ", i); 02318 smoothArray = array_fetch(array_t *, smoothVarBddArray, i); 02319 for(j=0; j<array_n(smoothArray); j++) { 02320 varBdd = array_fetch(bdd_t *, smoothArray, j); 02321 id = bdd_top_var_id(varBdd); 02322 if(j!=0 && j%idPerLine == 0) fprintf(vis_stdout, "\n "); 02323 fprintf(vis_stdout, "%3d ", id); 02324 } 02325 fprintf(vis_stdout, "\n"); 02326 } 02327 ImgLinearFreeSmoothArray(smoothVarBddArray); 02328 } 02329 02341 static void 02342 ImgLinearConjunctOrderMain(Relation_t *head, int bRefineConjunctOrder) 02343 { 02344 double aal, atl; 02345 02362 ImgLinearConjunctionOrder(head, "SecondCon", bRefineConjunctOrder); 02363 ImgLinearComputeLifeTime(head, &aal, &atl); 02364 ImgLinearPrintMatrixFull(head, 1); 02365 fprintf(stdout, "NOTICE : aal %.3f atl %.3f\n", aal, atl); 02366 ImgLinearPrintMatrix(head); 02367 02386 } 02387 02399 static void 02400 ImgLinearConjunctionOrder(Relation_t *head, char *baseName, int refineFlag) 02401 { 02402 Conjunct_t *conjunct; 02403 int i, j; 02404 02405 02406 if(head->nSize < 2) return; 02407 for(i=0; i<head->nSize; i++) { 02408 conjunct = head->conjunctArray[i]; 02409 conjunct->dummy = 0; 02410 for(j=0; j<conjunct->nSize; j++) 02411 conjunct->dummy += conjunct->supList[j]; 02412 } 02413 qsort(head->conjunctArray, head->nSize, sizeof(Conjunct_t *), 02414 ImgLinearCompareConjunctSize); 02415 head->bRefineVarArray = 1; 02416 ImgLinearRefineRelation(head); 02417 02418 ImgLinearCAPOInterfaceConjunctNodes(head, baseName); 02419 ImgLinearCAPOInterfaceConjunctNet(head, baseName); 02420 ImgLinearCAPOInterfaceConjunctScl(head, baseName); 02421 ImgLinearCAPOInterfaceConjunctPl(head, baseName); 02422 ImgLinearCAPOInterfaceAux(head, baseName); 02423 ImgLinearCAPORun("MetaPlacer", baseName, 0); 02424 ImgLinearCAPOReadConjunctOrder(head, baseName); 02425 } 02426 02427 02439 static void 02440 ImgLinearCAPOInterfaceConjunctNodes(Relation_t *head, char *baseName) 02441 { 02442 char filename[1024]; 02443 FILE *fout; 02444 int i; 02445 02446 sprintf(filename, "%s.nodes", baseName); 02447 fout = fopen(filename, "w"); 02448 fprintf(fout, "UCLA nodes 1.0\n"); 02449 if(head->includeNS) { 02450 if(head->includeCS) { 02451 fprintf(fout, "NumNodes : %d\n", head->nSize+2); 02452 fprintf(fout, "NumTerminals : 2\n"); 02453 } 02454 else { 02455 fprintf(fout, "NumNodes : %d\n", head->nSize+1); 02456 fprintf(fout, "NumTerminals : 1\n"); 02457 } 02458 } 02459 else if(head->includeCS) { 02460 fprintf(fout, "NumNodes : %d\n", head->nSize+1); 02461 fprintf(fout, "NumTerminals : 1\n"); 02462 } 02463 else { 02464 fprintf(fout, "NumNodes : %d\n", head->nSize); 02465 fprintf(fout, "NumTerminals : 0\n"); 02466 } 02467 02468 for(i=0; i<head->nSize; i++) 02469 fprintf(fout, "C%d 1 1\n", i); 02470 02471 if(head->includeCS) 02472 fprintf(fout, "C%d 1 1 terminal\n", MAXINT-1); 02473 02474 if(head->includeNS) 02475 fprintf(fout, "C%d 1 1 terminal\n", MAXINT); 02476 02477 fclose(fout); 02478 } 02479 02491 static void 02492 ImgLinearCAPOInterfaceConjunctNet(Relation_t *head, char *baseName) 02493 { 02494 char filename[1024]; 02495 FILE *fout; 02496 VarLife_t **varArray, *var; 02497 int i, j, nPin; 02498 02499 varArray = head->varArray; 02500 sprintf(filename, "%s.nets", baseName); 02501 fout = fopen(filename, "w"); 02502 fprintf(fout, "UCLA nets 1.0\n"); 02503 fprintf(fout, "#NumNets : %d\n", head->nVarArray); 02504 02505 qsort(head->varArray, head->nVarArray, sizeof(VarLife_t *), ImgLinearCompareVarId); 02506 nPin = 0; 02507 for(i=0; i<head->nVarArray; i++) { 02508 var = varArray[i]; 02509 if(var->nSize == 1) nPin += 2; 02510 else nPin += var->nSize; 02511 } 02512 fprintf(fout, "NumPins : %d\n", nPin); 02513 02514 for(i=0; i<head->nVarArray; i++) { 02515 var = varArray[i]; 02516 if(var->nSize == 1) 02517 fprintf(fout, "NetDegree : %d S%d\n", var->nSize+1, var->id); 02518 else 02519 fprintf(fout, "NetDegree : %d S%d\n", var->nSize, var->id); 02520 02521 for(j=0; j<var->nSize; j++) 02522 fprintf(fout, "C%d B\n", var->relArr[j]); 02523 02524 if(var->nSize == 1) 02525 fprintf(fout, "C%d B\n", var->relArr[0]); 02526 } 02527 fclose(fout); 02528 } 02529 02530 02542 static void 02543 ImgLinearCAPOInterfaceConjunctScl(Relation_t *head, char *baseName) 02544 { 02545 char filename[1024]; 02546 FILE *fout; 02547 02548 sprintf(filename, "%s.scl", baseName); 02549 fout = fopen(filename, "w"); 02550 fprintf(fout, "UCLA scl 1.0\n"); 02551 fprintf(fout, "Numrows : 1\n"); 02552 fprintf(fout, "CoreRow Horizontal\n"); 02553 fprintf(fout, " Coordinate : 1\n"); 02554 fprintf(fout, " Height : 1\n"); 02555 fprintf(fout, " Sitewidth : 1\n"); 02556 fprintf(fout, " Sitespacing : 1\n"); 02557 fprintf(fout, " Siteorient : N\n"); 02558 fprintf(fout, " Sitesymmetry : Y\n"); 02559 fprintf(fout, " SubrowOrigin : 0\n"); 02560 fprintf(fout, " Numsites : %d\n", head->nSize*2+2); 02561 fprintf(fout, "End\n"); 02562 fclose(fout); 02563 } 02564 02576 static void 02577 ImgLinearCAPOInterfaceConjunctPl(Relation_t *head, char *baseName) 02578 { 02579 char filename[1024]; 02580 FILE *fout; 02581 int i; 02582 02583 sprintf(filename, "%s.pl", baseName); 02584 fout = fopen(filename, "w"); 02585 02586 fprintf(fout, "UCLA pl 1.0\n"); 02587 for(i=0; i<head->nSize; i++) 02588 fprintf(fout, "C%d %d 1\n", i, (i+2)*2+1); 02589 02590 if(head->includeCS) 02591 fprintf(fout, "C%d 0 1 / N / FIXED\n", MAXINT-1); 02592 02593 if(head->includeNS) 02594 fprintf(fout, "C%d %d 1 / N / FIXED\n", MAXINT, (head->nSize+2)*2+1); 02595 02596 fclose(fout); 02597 } 02598 02610 static void 02611 ImgLinearCAPOInterfaceAux(Relation_t *head, char *baseName) 02612 { 02613 char filename[1024]; 02614 FILE *fout; 02615 02616 sprintf(filename, "%s.aux", baseName); 02617 fout = fopen(filename, "w"); 02618 fprintf(fout, "RowBasedPlacement : "); 02619 fprintf(fout, "%s.nodes %s.nets %s.pl %s.scl\n", 02620 baseName, baseName, baseName, baseName); 02621 fclose(fout); 02622 } 02623 02635 static int 02636 ImgLinearCAPORun(char *capoExe, char *baseName, int brief) 02637 { 02638 char logFile[1024]; 02639 char capoOption[1024]; 02640 char command[1024]; 02641 char cpCommand[1024]; 02642 FILE *fout; 02643 int cmdStatus; 02644 02645 fout = fopen("seeds.in", "w"); 02646 fprintf(fout, "0\n"); 02647 fprintf(fout, "460427264\n"); 02648 fclose(fout); 02649 02650 02651 if(brief) 02652 sprintf(capoOption, "-replaceSmallBlocks Never -noRowIroning -save -saveXorder"); 02653 else 02654 sprintf(capoOption, "-save -saveXorder -clust CutOpt"); 02655 02656 sprintf(logFile, "%s.log", baseName); 02657 sprintf(command, "%s -f %s.aux %s > %s", 02658 capoExe, baseName, capoOption, logFile); 02659 cmdStatus = system(command); 02660 sprintf(cpCommand, "cp left2right.ord %s.ord", baseName); 02661 cmdStatus |= system(cpCommand); 02662 02663 unlink("seeds.out"); 02664 unlink("left2right.ord"); 02665 return (cmdStatus == 0); 02666 } 02667 02668 02680 static void 02681 ImgLinearCAPOReadConjunctOrder(Relation_t *head, char *baseName) 02682 { 02683 char ordFile[1024]; 02684 char line[1024]; 02685 int index, id; 02686 char *next; 02687 FILE *fin; 02688 Conjunct_t *conjunct; 02689 02690 sprintf(ordFile, "%s.ord", baseName); 02691 if(!(fin = fopen(ordFile, "r"))) { 02692 fprintf(stdout, "Can't open order file %s\n", ordFile); 02693 exit(0); 02694 } 02695 index = 0; 02696 while(fgets(line, 1024, fin)){ 02697 next = strchr(line, 'C'); 02698 next++; 02699 sscanf(next, "%d", &id); 02700 if(id == MAXINT) continue; 02701 if(id == MAXINT-1) continue; 02702 conjunct = head->conjunctArray[id]; 02703 conjunct->index = index; 02704 index++; 02705 } 02706 fclose(fin); 02707 02708 qsort(head->conjunctArray, head->nSize, sizeof(Conjunct_t *), ImgLinearCompareConjunctIndex); 02709 02710 head->bModified = 1; 02711 head->bRefineVarArray = 1; 02712 ImgLinearRefineRelation(head); 02713 } 02714 02726 static void 02727 ImgLinearVariableOrder(Relation_t *head, char *baseName, int includeNS) 02728 { 02729 ImgLinearCAPOInterfaceVariableNodes(head, baseName, includeNS); 02730 ImgLinearCAPOInterfaceVariableNet(head, baseName, includeNS); 02731 ImgLinearCAPOInterfaceVariableScl(head, baseName); 02732 ImgLinearCAPOInterfaceVariablePl(head, baseName, includeNS); 02733 ImgLinearCAPOInterfaceAux(head, baseName); 02734 ImgLinearCAPORun("MetaPlacer", baseName, 0); 02735 ImgLinearCAPOReadVariableOrder(head, baseName, includeNS); 02736 } 02737 02749 void 02750 ImgLinearCAPOInterfaceVariableNodes(Relation_t *head, char *baseName, int includeNS) 02751 { 02752 int i, size; 02753 VarLife_t **varArray, *var; 02754 int *varType; 02755 char filename[1024]; 02756 FILE *fout; 02757 int numUnused; 02758 02759 varArray = head->varArray; 02760 varType = head->varType; 02761 sprintf(filename, "%s.nodes", baseName); 02762 fout = fopen(filename, "w"); 02763 02764 fprintf(fout, "UCLA nodes 1.0\n"); 02765 02766 size = 0; 02767 if(includeNS) size = head->nVarArray; 02768 else { 02769 for(i=0; i<head->nVarArray; i++) { 02770 if(varType[varArray[i]->id] == 2) continue; 02771 size++; 02772 } 02773 } 02774 02775 numUnused = 0; 02776 for(i=0; i<head->nVar; i++) { 02777 if(varType[i] != 1) continue; /* if it is not domain variable **/ 02778 var = head->varArrayMap[i] >=0 ? head->varArray[head->varArrayMap[i]] : 0; 02779 if(var) continue; 02780 numUnused++; 02781 } 02782 if(includeNS) { 02783 for(i=0; i<head->nVar; i++) { 02784 if(varType[i] != 2) continue; /* if it is not range variable **/ 02785 var = head->varArrayMap[i] >=0 ? head->varArray[head->varArrayMap[i]] : 0; 02786 if(var) continue; 02787 numUnused++; 02788 } 02789 } 02790 02791 fprintf(fout, "NumNodes : %d\n", size+numUnused); 02792 fprintf(fout, "NumTerminals : 0\n"); 02793 for(i=0; i<head->nVarArray; i++) { 02794 var = varArray[i]; 02795 if(includeNS == 0 && varType[var->id] == 2) continue; 02796 fprintf(fout, "C%d 1 1\n", var->id); 02797 } 02798 02799 for(i=0; i<head->nVar; i++) { 02800 if(varType[i] != 1) continue; /* if it is not domain variable **/ 02801 var = head->varArrayMap[i] >=0 ? head->varArray[head->varArrayMap[i]] : 0; 02802 if(var) continue; 02803 fprintf(fout, "C%d 1 1\n", i); 02804 } 02805 if(includeNS) { 02806 for(i=0; i<head->nVar; i++) { 02807 if(varType[i] != 2) continue; /* if it is not range variable **/ 02808 var = head->varArrayMap[i] >=0 ? head->varArray[head->varArrayMap[i]] : 0; 02809 if(var) continue; 02810 fprintf(fout, "C%d 1 1\n", i); 02811 } 02812 } 02813 fclose(fout); 02814 } 02815 02827 static void 02828 ImgLinearCAPOInterfaceVariableNet(Relation_t *head, 02829 char *baseName, 02830 int includeNS) 02831 { 02832 int nPin, i, j; 02833 int id, size; 02834 Conjunct_t *conjunct; 02835 bdd_t *relation; 02836 int *supList, *varType; 02837 char filename[1024]; 02838 FILE *fout; 02839 02840 nPin = 0; 02841 for(i=0; i<head->nSize; i++) { 02842 conjunct = head->conjunctArray[i]; 02843 relation = conjunct->relation; 02844 if(relation == (mdd_t *)(MAXINT-1)) continue; 02845 supList = conjunct->supList; 02846 if(includeNS) { 02847 if(conjunct->nSize == 1) nPin += 2; 02848 else nPin += conjunct->nSize-conjunct->nRange; 02849 } 02850 else { 02851 if(conjunct->nSize-conjunct->nRange == 1) nPin += 2; 02852 else nPin += conjunct->nSize-conjunct->nRange; 02853 } 02854 } 02855 nPin += head->nDomain; 02856 if(includeNS) 02857 nPin += head->nRange; 02858 02859 varType = head->varType; 02860 sprintf(filename, "%s.nets", baseName); 02861 fout = fopen(filename, "w"); 02862 fprintf(fout, "UCLA nets 1.0\n"); 02863 fprintf(fout, "#NumNets : %d\n", head->nSize); 02864 fprintf(fout, "NumPins : %d\n", nPin); 02865 for(i=0; i<head->nSize; i++) { 02866 conjunct = head->conjunctArray[i]; 02867 relation = conjunct->relation; 02868 if(relation == (mdd_t *)(MAXINT-1)) continue; 02869 02870 supList = conjunct->supList; 02871 if(includeNS) size = conjunct->nSize; 02872 else size = conjunct->nSize - conjunct->nRange; 02873 02874 if(size == 1) fprintf(fout, "NetDegree : %d \n", 2); 02875 else fprintf(fout, "NetDegree : %d \n", size); 02876 02877 id = 0; 02878 if(includeNS) { 02879 for(j=0; j<conjunct->nSize; j++) { 02880 id = supList[j]; 02881 fprintf(fout, "C%d B\n", id); 02882 } 02883 } 02884 else { 02885 for(j=0; j<conjunct->nSize; j++) { 02886 id = supList[j]; 02887 if(varType[id] == 2) continue; 02888 fprintf(fout, "C%d B\n", id); 02889 } 02890 } 02891 if(size == 1) 02892 fprintf(fout, "C%d B\n", id); 02893 } 02894 fprintf(fout, "NetDegree : %d \n", head->nDomain); 02895 for(i=0; i<head->nVar; i++) { 02896 if(varType[i] == 1) 02897 fprintf(fout, "C%d B\n", i); 02898 } 02899 if(includeNS) { 02900 fprintf(fout, "NetDegree : %d \n", head->nRange); 02901 for(i=0; i<head->nVar; i++) { 02902 if(varType[i] == 2) 02903 fprintf(fout, "C%d B\n", i); 02904 } 02905 } 02906 fclose(fout); 02907 } 02908 02920 static void 02921 ImgLinearCAPOInterfaceVariableScl(Relation_t *head, char *baseName) 02922 { 02923 char filename[1024]; 02924 FILE *fout; 02925 02926 sprintf(filename, "%s.scl", baseName); 02927 fout = fopen(filename, "w"); 02928 fprintf(fout, "UCLA scl 1.0\n"); 02929 fprintf(fout, "Numrows : 1\n"); 02930 fprintf(fout, "CoreRow Horizontal\n"); 02931 fprintf(fout, " Coordinate : 1\n"); 02932 fprintf(fout, " Height : 1\n"); 02933 fprintf(fout, " Sitewidth : 1\n"); 02934 fprintf(fout, " Sitespacing : 1\n"); 02935 fprintf(fout, " Siteorient : N\n"); 02936 fprintf(fout, " Sitesymmetry : Y\n"); 02937 fprintf(fout, " SubrowOrigin : 0\n"); 02938 fprintf(fout, " Numsites : %d\n", head->nVarArray*2+2); 02939 fprintf(fout, "End\n"); 02940 fclose(fout); 02941 } 02942 02943 02955 static void 02956 ImgLinearCAPOInterfaceVariablePl(Relation_t *head, char *baseName, int includeNS) 02957 { 02958 char filename[1024]; 02959 FILE *fout; 02960 VarLife_t *var, **varArray; 02961 int i, index, *varType; 02962 02963 varType = head->varType; 02964 sprintf(filename, "%s.pl", baseName); 02965 fout = fopen(filename, "w"); 02966 fprintf(fout, "UCLA pl 1.0\n"); 02967 varArray = head->varArray; 02968 for(index=0, i=0; i<head->nVarArray; i++) { 02969 var = varArray[i]; 02970 if(includeNS == 0 && varType[var->id] == 2) continue; 02971 fprintf(fout, "C%d %d 1\n", var->id, (index+1)*2+1); 02972 index++; 02973 } 02974 fclose(fout); 02975 } 02976 02977 02978 02990 static void 02991 ImgLinearCAPOReadVariableOrder(Relation_t *head, char *baseName, int includeNS) 02992 { 02993 char ordFile[1024], line[1024]; 02994 FILE *fin; 02995 char *next; 02996 int i, id, index, *permutation, *exist; 02997 02998 sprintf(ordFile, "%s.ord", baseName); 02999 if(!(fin = fopen(ordFile, "r"))) { 03000 fprintf(stdout, "Can't open order file %s\n", ordFile); 03001 exit(0); 03002 } 03003 03004 permutation = ALLOC(int, head->nVar); 03005 exist = ALLOC(int, head->nVar); 03006 memset(exist, 0, sizeof(int)*head->nVar); 03007 03008 index = 0; 03009 while(fgets(line, 1024, fin)){ 03010 next = strchr(line, 'C'); 03011 next++; 03012 sscanf(next, "%d", &id); 03013 permutation[index++] = id; 03014 exist[id] = 1; 03015 if(includeNS == 0 && head->varType[id] == 1) { 03016 permutation[index++] = head->domain2range[id]; 03017 exist[head->domain2range[id]] = 1; 03018 } 03019 } 03020 fclose(fin); 03021 03022 for(i=0; i<head->nVar; i++) 03023 if(exist[i] == 0) 03024 permutation[index++] = i; 03025 03026 free(exist); 03027 03028 bdd_shuffle_heap(head->mgr, permutation); 03029 03030 free(permutation); 03031 } 03032 03044 static void 03045 ImgLinearPrintVariableProfile(Relation_t *head, char *baseName) 03046 { 03047 double aal, atl; 03048 char filename[1024]; 03049 FILE *fout; 03050 st_table *cutSet; 03051 int i, j, nDead, id; 03052 int *varType; 03053 int *supList; 03054 Conjunct_t *conjunct; 03055 VarLife_t *var; 03056 st_generator *gen; 03057 03058 ImgLinearVariableArrayInit(head); 03059 varType = head->varType; 03060 03061 sprintf(filename, "%s.data", baseName); 03062 fout = fopen(filename, "w"); 03063 03064 cutSet = st_init_table(st_numcmp, st_numhash); 03065 for(i=0; i<head->nVar; i++) { 03066 if(varType[i] == 1) 03067 st_insert(cutSet, (char *)(long)i, (char *)(long)i); 03068 } 03069 03070 for(i=0; i<head->nSize; i++) { 03071 conjunct = head->conjunctArray[i]; 03072 supList = conjunct->supList; 03073 for(j=0; j<conjunct->nSize; j++) 03074 st_insert(cutSet, (char *)(long)supList[j], (char *)(long)supList[j]); 03075 03076 nDead = 0; 03077 st_foreach_item(cutSet, gen, &id, &id) { 03078 if(varType[id] == 2) continue; 03079 03080 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 03081 0; 03082 if(!var) continue; 03083 03084 if(var->to <= i) { 03085 nDead++; 03086 st_delete(cutSet, (&id), NULL); 03087 } 03088 } 03089 fprintf(fout, "%d %d %d\n", i, cutSet->num_entries, cutSet->num_entries+nDead); 03090 } 03091 fclose(fout); 03092 03093 ImgLinearComputeLifeTime(head, &aal, &atl); 03094 03095 sprintf(filename, "%s.gnu", baseName); 03096 fout = fopen(filename, "w"); 03097 fprintf(fout, "set terminal postscript \n"); 03098 fprintf(fout, "set output \"%s.ps\"\n", baseName); 03099 fprintf(fout, "set title \"profile of live variable aal %.3f atl %.3f\"\n", 03100 aal, atl); 03101 fprintf(fout, "plot \"%s.data\" using 1:2 title \"%s\" with lines, \\\n", baseName, "cut"); 03102 fprintf(fout, " \"%s.data\" using 1:3 title \"%s\" with lines\n", baseName, "cut+dead"); 03103 fclose(fout); 03104 } 03105 03117 void 03118 ImgLinearPrintMatrix(Relation_t *head) 03119 { 03120 int i, j, id, index; 03121 int *mapArray; 03122 VarLife_t **varArray, *var; 03123 VarLife_t **auxArr, **sortArr; 03124 int nAuxArr, nSortArr; 03125 array_t *smoothVarBddArr, *smoothArray; 03126 bdd_t *varBdd; 03127 Conjunct_t *conjunct; 03128 bdd_t *relation; 03129 int *supList, *varType; 03130 char *buffer; 03131 int maxIndex; 03132 03133 if(head->verbosity < 5) return; 03134 03135 ImgLinearVariableArrayInit(head); 03136 03137 mapArray = ALLOC(int, head->nVar); 03138 memset(mapArray, -1, sizeof(int)*head->nVar); 03139 03140 varArray = head->varArray; 03141 03142 smoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, 0); 03143 for(index=0, i=0; i<array_n(smoothVarBddArr); i++) { 03144 smoothArray = array_fetch(array_t *, smoothVarBddArr, i); 03145 nAuxArr = 0; 03146 auxArr = ALLOC(VarLife_t *, nAuxArr+1); 03147 for(j=0; j<array_n(smoothArray); j++) { 03148 varBdd = array_fetch(bdd_t *, smoothArray, j); 03149 id = (int)bdd_top_var_id(varBdd); 03150 03151 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 03152 0; 03153 if(var) { 03154 auxArr[nAuxArr++] = var; 03155 auxArr = REALLOC(VarLife_t *, auxArr, nAuxArr+1); 03156 } 03157 } 03158 qsort(auxArr, nAuxArr, sizeof(VarLife_t *), ImgLinearCompareVarIndex); 03159 for(j=0; j<nAuxArr; j++) 03160 mapArray[auxArr[j]->id] = index++; 03161 free(auxArr); 03162 } 03163 03164 varArray = head->varArray; 03165 nSortArr = 0; 03166 sortArr = ALLOC(VarLife_t *, nSortArr+1); 03167 for(i=0; i<head->nVarArray; i++) { 03168 var = varArray[i]; 03169 if(var->stateVar == 2) continue; 03170 if(mapArray[var->id] >= 0) { 03171 var->index = mapArray[var->id]; 03172 sortArr[nSortArr++] = var; 03173 sortArr = REALLOC(VarLife_t *, sortArr, nSortArr+1); 03174 } 03175 else { 03176 var->index = (double)MAXINT; 03177 } 03178 } 03179 qsort(sortArr, nSortArr, sizeof(VarLife_t *), ImgLinearCompareVarIndex); 03180 03181 fprintf(stdout, " "); 03182 for(i=0; i<nSortArr; i++) fprintf(stdout, "%d", (i/10)%10); 03183 fprintf(stdout, "\n"); 03184 03185 fprintf(stdout, " "); 03186 for(i=0; i<nSortArr; i++) fprintf(stdout, "%d", i%10); 03187 fprintf(stdout, "\n"); 03188 03189 buffer = ALLOC(char , nSortArr+1); 03190 for(i=0; i<nSortArr; i++) { 03191 var = sortArr[i]; 03192 var->index = (double)i; 03193 if(var->stateVar == 1) buffer[i] = 'C'; 03194 else buffer[i] = 'T'; 03195 } 03196 buffer[i] = '\0'; 03197 free(sortArr); 03198 fprintf(stdout, " %s\n", buffer); 03199 03200 maxIndex = i; 03201 for(i=0; i<maxIndex; i++) buffer[i] = '.'; 03202 buffer[i] = '\0'; 03203 03204 varType = head->varType; 03205 for(index=0,i=head->nSize-1;i>=0; i--) { 03206 conjunct = head->conjunctArray[i]; 03207 if(conjunct == 0) continue; 03208 if(conjunct->relation == 0) continue; 03209 relation = conjunct->relation; 03210 if(relation == (mdd_t *)(MAXINT-1)) continue; 03211 if(relation == 0) continue; 03212 supList = conjunct->supList; 03213 for(j=0; j<conjunct->nSize; j++) { 03214 id = supList[j]; 03215 if(varType[id] == 2) continue; 03216 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 03217 0; 03218 if(!var) continue; 03219 if((int)var->index == MAXINT) continue; 03220 buffer[(int)var->index] = '1'; 03221 } 03222 index++; 03223 fprintf(stdout, "%4d %s %d %d\n", i, buffer, conjunct->nRange, bdd_size(relation)); 03224 fflush(stdout); 03225 for(j=0; j<maxIndex; j++) buffer[j] = '.'; 03226 buffer[j] = '\0'; 03227 } 03228 free(buffer); 03229 } 03241 void 03242 ImgLinearPrintMatrixFull(Relation_t *head, int matrixIndex) 03243 { 03244 int i, j, id, index; 03245 int *mapArray; 03246 VarLife_t **varArray, *var; 03247 VarLife_t **auxArr, **sortArr; 03248 int nAuxArr, nSortArr; 03249 array_t *smoothVarBddArr, *smoothArray; 03250 FILE *fout; 03251 int min, max; 03252 bdd_t *varBdd; 03253 char filename[1024]; 03254 Conjunct_t *conjunct; 03255 bdd_t *relation; 03256 int *supList; 03257 03258 ImgLinearVariableArrayInit(head); 03259 03260 mapArray = ALLOC(int, head->nVar); 03261 memset(mapArray, -1, sizeof(int)*head->nVar); 03262 varArray = head->varArray; 03263 03264 smoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, 0); 03265 for(index=0, i=0; i<array_n(smoothVarBddArr); i++) { 03266 smoothArray = array_fetch(array_t *, smoothVarBddArr, i); 03267 nAuxArr = 0; 03268 auxArr = ALLOC(VarLife_t *, nAuxArr+1); 03269 for(j=0; j<array_n(smoothArray); j++) { 03270 varBdd = array_fetch(bdd_t *, smoothArray, j); 03271 id = (int)bdd_top_var_id(varBdd); 03272 03273 var = head->varArrayMap[id] >=0 ? varArray[head->varArrayMap[id]] : 0; 03274 if(var) { 03275 auxArr[nAuxArr++] = var; 03276 auxArr = REALLOC(VarLife_t *, auxArr, nAuxArr+1); 03277 } 03278 } 03279 qsort(auxArr, nAuxArr, sizeof(VarLife_t *), ImgLinearCompareVarIndex); 03280 for(j=0; j<nAuxArr; j++) 03281 mapArray[auxArr[j]->id] = index++; 03282 free(auxArr); 03283 } 03284 03285 nSortArr = 0; 03286 sortArr = ALLOC(VarLife_t *, nSortArr+1); 03287 for(i=0; i<head->nVarArray; i++) { 03288 var = varArray[i]; 03289 if(var->stateVar == 2) continue; 03290 if(mapArray[var->id] >= 0) { 03291 var->index = mapArray[var->id]; 03292 sortArr[nSortArr++] = var; 03293 sortArr = REALLOC(VarLife_t *, sortArr, nSortArr+1); 03294 } 03295 else { 03296 var->index = (double)MAXINT; 03297 } 03298 } 03299 03300 qsort(sortArr, nSortArr, sizeof(VarLife_t *), ImgLinearCompareVarIndex); 03301 free(mapArray); 03302 03303 sprintf(filename, "fullmatrix%d.data", matrixIndex); 03304 fout = fopen(filename, "w"); 03305 min = 0; 03306 max = head->nSize+1; 03307 for(i=0; i<nSortArr; i++) { 03308 var = sortArr[i]; 03309 if(var->stateVar == 1) 03310 fprintf(fout, "%d %d\n", (int)var->index, min); 03311 } 03312 free(sortArr); 03313 03314 for(index=0, i=0; i<head->nSize; i++) { 03315 conjunct = head->conjunctArray[i]; 03316 relation = conjunct->relation; 03317 if(relation == (mdd_t *)(MAXINT-1)) continue; 03318 if(relation == 0) continue; 03319 supList = conjunct->supList; 03320 for(j=0; j<conjunct->nSize; j++) { 03321 id = supList[j]; 03322 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0; 03323 if(!var) continue; 03324 if(var->stateVar == 2) 03325 if((int)var->index == MAXINT) continue; 03326 fprintf(fout, "%d %d\n", (int)var->index, index+1); 03327 } 03328 index++; 03329 } 03330 fclose(fout); 03331 03332 sprintf(filename, "fullmatrix%d.gnu", matrixIndex); 03333 fout = fopen(filename, "w"); 03334 fprintf(fout, "set terminal postscript \n"); 03335 fprintf(fout, "set output \"fullmatrix%d.ps\"\n", matrixIndex); 03336 fprintf(fout, "set title \"profile of live variable\"\n"); 03337 fprintf(fout, "set yrange [-1:%d]\n", head->nSize+2); 03338 fprintf(fout, "plot \"fullmatrix%d.data\" using 1:2 title \"%d\" with point\n", 03339 matrixIndex, matrixIndex); 03340 fclose(fout); 03341 03342 ImgLinearFreeSmoothArray(smoothVarBddArr); 03343 } 03344 03356 void 03357 ImgLinearFreeSmoothArray(array_t *smoothVarBddArray) 03358 { 03359 int i; 03360 array_t *smoothArray; 03361 03362 for(i=0; i<array_n(smoothVarBddArray); i++) { 03363 smoothArray = array_fetch(array_t *, smoothVarBddArray, i); 03364 mdd_array_free(smoothArray); 03365 } 03366 array_free(smoothVarBddArray); 03367 } 03368 03380 void 03381 ImgLinearComputeLifeTime(Relation_t *head, double *paal, double *patl) 03382 { 03383 double aal, atl; 03384 int i; 03385 VarLife_t **varArray, *var; 03386 03387 aal = atl = 0.0; 03388 varArray = head->varArray; 03389 for(i=0; i<head->nVarArray; i++) { 03390 var = varArray[i]; 03391 aal += var->effTo - var->effFrom; 03392 if(var->stateVar == 1) atl += var->to+1; 03393 else if(var->stateVar == 2) atl += head->nSize+1 - var->from; 03394 else atl += var->to - var->from; 03395 } 03396 atl = atl / (double)(head->nVarArray * head->nSize); 03397 aal = aal / (double)(head->nVarArray * head->nSize); 03398 03399 *paal = aal; 03400 *patl = atl; 03401 } 03402 03414 static void 03415 ImgLinearPrintTransitionInfo(Relation_t *head) 03416 { 03417 double aal, atl; 03418 03419 fprintf(stdout, "SUMMARY : domain variables %d -> %d -> %d\n", 03420 head->nDomain, head->nInitDomain, head->nEffDomain); 03421 fprintf(stdout, "SUMMARY : range variables %d -> %d -> %d\n", 03422 head->nRange, head->nInitRange, head->nEffRange); 03423 fprintf(stdout, "SUMMARY : quantify variables %d -> %d -> %d\n", 03424 head->nQuantify, head->nInitQuantify, head->nEffQuantify); 03425 fprintf(stdout, "SUMMARY : number of transition relation %d\n", 03426 head->nSize); 03427 ImgLinearComputeLifeTime(head, &aal, &atl); 03428 fprintf(stdout, "Active Life Time : %g\n", aal); 03429 fprintf(stdout, "Average Life Time : %g\n", atl); 03430 } 03431 03432 03433 03445 array_t * 03446 ImgLinearMakeSmoothVarBdd(Relation_t *head, bdd_t **smoothCubeArr) 03447 { 03448 array_t *smoothVarBddArray; 03449 array_t *smoothArray; 03450 VarLife_t **varArray; 03451 int i, j, id; 03452 VarLife_t *var; 03453 bdd_t *varBdd, *cube, *newCube; 03454 03455 smoothVarBddArray = array_alloc(array_t *, 0); 03456 for(i=0; i<=head->nSize; i++) { 03457 smoothArray = array_alloc(bdd_t *, 0); 03458 array_insert_last(array_t *, smoothVarBddArray, smoothArray); 03459 } 03460 03461 varArray = head->varArray; 03462 for(i=0; i<head->nVarArray; i++) { 03463 var = varArray[i]; 03464 if(var->stateVar == 2) continue; 03465 smoothArray = array_fetch(array_t *, smoothVarBddArray, var->to+1); 03466 varBdd = bdd_get_variable(head->mgr, var->id); 03467 array_insert_last(bdd_t *, smoothArray, varBdd); 03468 } 03469 03470 smoothArray = array_fetch(array_t *, smoothVarBddArray, 0); 03471 for(i=0; i<head->nDomain; i++) { 03472 id = head->domainVars[i]; 03473 var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0; 03474 if(var) continue; 03475 varBdd = bdd_get_variable(head->mgr, id); 03476 array_insert_last(bdd_t *, smoothArray, varBdd); 03477 } 03478 03479 if(smoothCubeArr) { 03480 for(i=0; i<=head->nSize; i++) { 03481 smoothArray = array_fetch(array_t *, smoothVarBddArray, i); 03482 cube = bdd_one(head->mgr); 03483 for(j=0; j<array_n(smoothArray); j++) { 03484 varBdd = array_fetch(bdd_t *, smoothArray, j); 03485 newCube = bdd_and(varBdd, cube, 1, 1); 03486 bdd_free(cube); 03487 cube = newCube; 03488 } 03489 smoothCubeArr[i] = cube; 03490 } 03491 } 03492 03493 return(smoothVarBddArray); 03494 } 03495 03507 static int 03508 ImgLinearCompareVarEffFromSmall(const void *c1, const void *c2) 03509 { 03510 VarLife_t *con1, *con2; 03511 03512 con1 = *(VarLife_t **)c1; 03513 con2 = *(VarLife_t **)c2; 03514 return(con1->effFrom > con2->effFrom); 03515 } 03516 03528 static int 03529 ImgLinearCompareVarDummyLarge(const void *c1, const void *c2) 03530 { 03531 VarLife_t *con1, *con2; 03532 03533 con1 = *(VarLife_t **)c1; 03534 con2 = *(VarLife_t **)c2; 03535 return(con1->dummy < con2->dummy); 03536 } 03537 03549 static int 03550 ImgLinearCompareVarEffFromLarge(const void *c1, const void *c2) 03551 { 03552 VarLife_t *con1, *con2; 03553 03554 con1 = *(VarLife_t **)c1; 03555 con2 = *(VarLife_t **)c2; 03556 return(con1->effFrom < con2->effFrom); 03557 } 03558 03570 static int 03571 ImgLinearCompareVarId(const void *c1, const void *c2) 03572 { 03573 VarLife_t *con1, *con2; 03574 03575 con1 = *(VarLife_t **)c1; 03576 con2 = *(VarLife_t **)c2; 03577 return(con1->id < con2->id); 03578 } 03579 03591 static int 03592 ImgLinearCompareVarSize(const void *c1, const void *c2) 03593 { 03594 VarLife_t *con1, *con2; 03595 03596 con1 = *(VarLife_t **)c1; 03597 con2 = *(VarLife_t **)c2; 03598 return(con1->nSize > con2->nSize); 03599 } 03600 03612 static int 03613 ImgLinearCompareConjunctRangeMinusDomain(const void *c1, const void *c2) 03614 { 03615 Conjunct_t *con1, *con2; 03616 03617 con1 = *(Conjunct_t **)c1; 03618 con2 = *(Conjunct_t **)c2; 03619 return(con1->nRange-con1->nDomain > con2->nRange-con2->nDomain); 03620 } 03621 03633 static int 03634 ImgLinearCompareConjunctDummy(const void *c1, const void *c2) 03635 { 03636 Conjunct_t *con1, *con2; 03637 03638 con1 = *(Conjunct_t **)c1; 03639 con2 = *(Conjunct_t **)c2; 03640 return(con1->dummy > con2->dummy); 03641 } 03642 03654 static int 03655 ImgLinearCompareConjunctIndex(const void *c1, const void *c2) 03656 { 03657 Conjunct_t *con1, *con2; 03658 03659 con1 = *(Conjunct_t **)c1; 03660 con2 = *(Conjunct_t **)c2; 03661 03662 return(con1->index > con2->index); 03663 } 03664 03676 static int 03677 ImgLinearCompareConjunctSize(const void *c1, const void *c2) 03678 { 03679 Conjunct_t *con1, *con2; 03680 03681 con1 = *(Conjunct_t **)c1; 03682 con2 = *(Conjunct_t **)c2; 03683 03684 if(con1->nSize == con2->nSize) 03685 return(con1->dummy < con2->dummy); 03686 return(con1->nSize < con2->nSize); 03687 } 03688 03700 static int 03701 ImgLinearCompareVarIndex(const void *c1, const void *c2) 03702 { 03703 VarLife_t *v1, *v2; 03704 03705 v1 = *(VarLife_t **)c1; 03706 v2 = *(VarLife_t **)c2; 03707 03708 return(v1->index < v2->index); 03709 } 03710 03722 static int 03723 ImgLinearCompareDeadAffinityLive(const void *c1, const void *c2) 03724 { 03725 Cluster_t *clu1, *clu2; 03726 03727 clu1 = *(Cluster_t **)c1; 03728 clu2 = *(Cluster_t **)c2; 03729 if(clu1->nDead == clu2->nDead) { 03730 if(clu1->nAffinity == clu2->nAffinity) { 03731 return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 03732 } 03733 return(clu1->nAffinity < clu2->nAffinity); 03734 } 03735 return(clu1->nDead < clu2->nDead); 03736 } 03737 03749 static int 03750 ImgLinearCompareDeadLiveAffinity(const void *c1, const void *c2) 03751 { 03752 Cluster_t *clu1, *clu2; 03753 03754 clu1 = *(Cluster_t **)c1; 03755 clu2 = *(Cluster_t **)c2; 03756 if(clu1->nDead == clu2->nDead) { 03757 if(clu1->nVar-clu1->nDead == clu2->nVar-clu2->nDead) { 03758 return(clu1->nAffinity < clu2->nAffinity); 03759 } 03760 return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 03761 } 03762 return(clu1->nDead < clu2->nDead); 03763 } 03764 03776 static int 03777 ImgLinearCompareAffinityDeadLive(const void *c1, const void *c2) 03778 { 03779 Cluster_t *clu1, *clu2; 03780 03781 clu1 = *(Cluster_t **)c1; 03782 clu2 = *(Cluster_t **)c2; 03783 if(clu1->nAffinity == clu2->nAffinity) { 03784 if(clu1->nDead == clu2->nDead) { 03785 return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 03786 } 03787 return(clu1->nDead < clu2->nDead); 03788 } 03789 return(clu1->nAffinity < clu2->nAffinity); 03790 } 03791 03803 static int 03804 ImgLinearCompareLiveAffinityDead(const void *c1, const void *c2) 03805 { 03806 Cluster_t *clu1, *clu2; 03807 03808 clu1 = *(Cluster_t **)c1; 03809 clu2 = *(Cluster_t **)c2; 03810 if(clu1->nVar-clu1->nDead == clu2->nVar-clu2->nDead) { 03811 if(clu1->nAffinity == clu2->nAffinity) { 03812 return(clu1->nDead < clu2->nDead); 03813 } 03814 return(clu1->nAffinity < clu2->nAffinity); 03815 } 03816 return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 03817 } 03818 03830 static int 03831 ImgLinearHeapCompareDeadAffinityLive(const void *c1, const void *c2) 03832 { 03833 Cluster_t *clu1, *clu2; 03834 03835 clu1 = (Cluster_t *)c1; 03836 clu2 = (Cluster_t *)c2; 03837 if(clu1->nDead == clu2->nDead) { 03838 if(clu1->nAffinity == clu2->nAffinity) { 03839 return((clu1->nVar-clu1->nDead) > (clu2->nVar-clu2->nDead)); 03840 } 03841 return(clu1->nAffinity < clu2->nAffinity); 03842 } 03843 return(clu1->nDead < clu2->nDead); 03844 } 03845 03857 static int 03858 ImgLinearHeapCompareDeadLiveAffinity(const void *c1, const void *c2) 03859 { 03860 Cluster_t *clu1, *clu2; 03861 03862 clu1 = (Cluster_t *)c1; 03863 clu2 = (Cluster_t *)c2; 03864 if(clu1->nDead == clu2->nDead) { 03865 if((clu1->nVar-clu1->nDead) == (clu2->nVar-clu2->nDead)) { 03866 return(clu1->nAffinity < clu2->nAffinity); 03867 } 03868 return((clu1->nVar-clu1->nDead) > (clu2->nVar-clu2->nDead)); 03869 } 03870 return(clu1->nDead < clu2->nDead); 03871 } 03872 03884 static int 03885 ImgLinearHeapCompareAffinityDeadLive(const void *c1, const void *c2) 03886 { 03887 Cluster_t *clu1, *clu2; 03888 03889 clu1 = (Cluster_t *)c1; 03890 clu2 = (Cluster_t *)c2; 03891 if(clu1->nAffinity == clu2->nAffinity) { 03892 if(clu1->nDead == clu2->nDead) { 03893 return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 03894 } 03895 return(clu1->nDead < clu2->nDead); 03896 } 03897 return(clu1->nAffinity < clu2->nAffinity); 03898 } 03899 03911 static int 03912 ImgLinearHeapCompareLiveAffinityDead(const void *c1, const void *c2) 03913 { 03914 Cluster_t *clu1, *clu2; 03915 03916 clu1 = (Cluster_t *)c1; 03917 clu2 = (Cluster_t *)c2; 03918 if(clu1->nVar-clu1->nDead == clu2->nVar-clu2->nDead) { 03919 if(clu1->nAffinity == clu2->nAffinity) { 03920 return(clu1->nDead < clu2->nDead); 03921 } 03922 return(clu1->nAffinity < clu2->nAffinity); 03923 } 03924 return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 03925 } 03926 03938 static void 03939 ImgLinearVariableArrayInit(Relation_t *head) 03940 { 03941 mdd_manager *mgr; 03942 Conjunct_t **conjunctArray, *conjunct; 03943 Conjunct_t *tConjunct; 03944 bdd_t *relation, *bddOne; 03945 VarLife_t **varArray; 03946 int *supList, listSize; 03947 int *varType, *varArrayMap; 03948 int i, j, k, id, nVarArray; 03949 int nSize, newNum; 03950 03951 03952 if(head->bRefineVarArray) { 03953 ImgLinearVariableArrayQuit(head); 03954 } 03955 03956 if(head->varArray) return; 03957 03958 mgr = head->mgr; 03959 03960 if(head->nVar != (int)(bdd_num_vars(mgr))) { 03961 newNum = bdd_num_vars(head->mgr); 03962 head->domain2range = REALLOC(int, head->domain2range, newNum); 03963 head->range2domain = REALLOC(int, head->range2domain, newNum); 03964 head->varType = REALLOC(int, head->varType, newNum); 03965 head->varArrayMap = REALLOC(int, head->varArrayMap, newNum); 03966 head->constantCase = REALLOC(bdd_t *, head->constantCase, newNum); 03967 head->quantifyVars = REALLOC(int, head->quantifyVars, newNum); 03968 03969 for(i=head->nVar; i<newNum; i++) { 03970 head->domain2range[i] = -1; 03971 head->range2domain[i] = -1; 03972 head->varType[i] = 0; 03973 head->varArrayMap[i] = -1; 03974 head->constantCase[i] = 0; 03975 head->quantifyVars[i] = 0; 03976 } 03977 head->nVar = bdd_num_vars(head->mgr); 03978 } 03979 03980 nSize = head->nSize; 03981 conjunctArray = head->conjunctArray; 03982 varArrayMap = head->varArrayMap; 03983 03984 id = 0; 03985 nVarArray = 0; 03986 varArray = ALLOC(VarLife_t *, nVarArray+1); 03987 head->varArray = varArray; 03988 head->nVarArray = nVarArray; 03989 bddOne = bdd_one(head->mgr); 03990 03991 varType = head->varType; 03992 for(i=0; i<nSize; i++) { 03993 conjunct = conjunctArray[i]; 03994 if(conjunct == 0) continue; 03995 relation = conjunct->relation; 03996 if(relation == 0) continue; 03997 if(bdd_equal(bddOne, relation)) continue; 03998 supList = conjunct->supList; 03999 listSize = conjunct->nSize; 04000 for(j=0; j<listSize; j++) { 04001 id = supList[j]; 04002 ImgLinearUpdateVariableArrayWithId(head, i, id); 04003 } 04004 04005 for(k=0; k<conjunct->nCluster; k++) { 04006 tConjunct = conjunct->clusterArray[k]; 04007 supList = tConjunct->supList; 04008 listSize = tConjunct->nSize; 04009 for(j=0; j<listSize; j++) { 04010 ImgLinearUpdateVariableArrayWithId(head, i, id); 04011 } 04012 } 04013 } 04014 bdd_free(bddOne); 04015 head->bRefineVarArray = 0; 04016 } 04017 04029 static void 04030 ImgLinearUpdateVariableArrayWithId(Relation_t *head, 04031 int cindex, 04032 int id) 04033 { 04034 VarLife_t *var; 04035 int *varType; 04036 int *varArrayMap; 04037 int nVarArray; 04038 VarLife_t **varArray; 04039 04040 varType = head->varType; 04041 varArrayMap = head->varArrayMap; 04042 varArray = head->varArray; 04043 nVarArray = head->nVarArray; 04044 04045 if(varArrayMap[id] == -1) { 04046 var = ALLOC(VarLife_t, 1); 04047 var->id = id; 04048 var->from = cindex; 04049 var->to = cindex; 04050 var->effFrom = cindex; 04051 var->effTo = cindex; 04052 var->stateVar = 0; 04053 var->relArr = ALLOC(int, 1); 04054 var->nSize = 0; 04055 var->index = 0.0; 04056 varArrayMap[id] = nVarArray; 04057 varArray[nVarArray++] = var; 04058 varArray = REALLOC(VarLife_t *, varArray, nVarArray+1); 04059 04060 if(varType[id] == 1) { 04061 var->stateVar = 1; 04062 if(head->includeCS && !head->quantifyCS) { 04063 var->relArr = REALLOC(int, var->relArr, var->nSize+1); 04064 var->relArr[var->nSize++] = MAXINT-1; 04065 var->from = -1; 04066 } 04067 } 04068 else if(varType[id] == 2) { 04069 var->stateVar = 2; 04070 if(head->includeNS) { 04071 var->relArr = REALLOC(int, var->relArr, var->nSize+1); 04072 var->relArr[var->nSize++] = MAXINT; 04073 var->to = head->nSize; 04074 } 04075 } 04076 } 04077 else { 04078 var = varArray[varArrayMap[id]]; 04079 } 04080 04081 if(var->to < cindex) var->to = cindex; 04082 if(var->from > cindex) var->from = cindex; 04083 04084 if(var->effTo < cindex) var->effTo = cindex; 04085 if(var->effFrom > cindex) var->effFrom = cindex; 04086 04087 var->relArr = REALLOC(int, var->relArr, var->nSize+1); 04088 var->relArr[var->nSize++] = cindex; 04089 head->varArray = varArray; 04090 head->nVarArray = nVarArray; 04091 } 04103 static int 04104 ImgLinearQuantifyVariablesFromConjunct(Relation_t *head, 04105 Conjunct_t *conjunct, 04106 array_t *smoothVarBddArray, 04107 int *bModified) 04108 { 04109 bdd_t *relation, *simpleRelation; 04110 04111 if(conjunct == 0) return 1; 04112 relation = conjunct->relation; 04113 if(relation == 0) return 1; 04114 04115 simpleRelation = bdd_smooth(relation, smoothVarBddArray); 04116 if(bdd_equal(relation, simpleRelation)) { 04117 bdd_free(simpleRelation); 04118 return 0; 04119 } 04120 bdd_free(relation); 04121 04122 (*bModified)++; 04123 conjunct->relation = simpleRelation; 04124 conjunct->bModified = 1; 04125 head->bModified = 1; 04126 head->bRefineVarArray = 1; 04127 ImgLinearConjunctRefine(head, conjunct); 04128 return 1; 04129 } 04130 04142 static void 04143 ImgLinearConjunctRefine(Relation_t *head, Conjunct_t *conjunct) 04144 { 04145 int i, id, listSize, *supList; 04146 int *varType; 04147 04148 if(conjunct->relation == 0) { 04149 if(conjunct->supList) free(conjunct->supList); 04150 conjunct->supList = 0; 04151 return; 04152 } 04153 if(!conjunct->bModified) return; 04154 04155 if(conjunct->supList) { 04156 free(conjunct->supList); 04157 conjunct->supList = 0; 04158 } 04159 04160 supList = ImgLinearGetSupportBddId(head->mgr, conjunct->relation, &listSize); 04161 if(listSize == 0) { 04162 conjunct->relation = 0; 04163 if(conjunct->supList) { 04164 free(conjunct->supList); 04165 conjunct->supList = 0; 04166 } 04167 return; 04168 } 04169 else { 04170 varType = head->varType; 04171 conjunct->supList = supList; 04172 conjunct->nSize = listSize; 04173 conjunct->bModified = 0; 04174 conjunct->nDomain = 0; 04175 conjunct->nRange = 0; 04176 conjunct->nQuantify = 0; 04177 conjunct->from = 0; 04178 conjunct->to = 0; 04179 conjunct->dummy = 0; 04180 for(i=0; i<listSize; i++) { 04181 id = supList[i]; 04182 if(varType[id] == 1) conjunct->nDomain++; 04183 else if(varType[id] == 2) conjunct->nRange++; 04184 else if(varType[id] == 3) conjunct->nQuantify++; 04185 } 04186 head->bModified = 1; 04187 } 04188 return; 04189 } 04201 static void 04202 ImgLinearConjunctArrayRefine(Relation_t *head) 04203 { 04204 int nSize, i; 04205 int index; 04206 Conjunct_t **conjunctArray, **newConjunctArray; 04207 Conjunct_t *conjunct; 04208 04209 if(head->bModified == 0) return; 04210 04211 conjunctArray = head->conjunctArray; 04212 newConjunctArray = ALLOC(Conjunct_t *, head->nSize+1); 04213 nSize = head->nSize; 04214 for(index=0, i=0; i<nSize; i++) { 04215 conjunct = conjunctArray[i]; 04216 if(conjunct == 0) { 04217 head->bRefineVarArray = 1; 04218 continue; 04219 } 04220 if(conjunct->relation == 0) { 04221 ImgLinearConjunctQuit(conjunct); 04222 head->bRefineVarArray = 1; 04223 continue; 04224 } 04225 04226 if(conjunct->bModified) { 04227 ImgLinearConjunctRefine(head, conjunct); 04228 head->bRefineVarArray = 1; 04229 } 04230 04231 if(conjunct == 0) continue; 04232 if(conjunct->relation == 0) { 04233 ImgLinearConjunctQuit(conjunct); 04234 continue; 04235 } 04236 04237 newConjunctArray[index] = conjunct; 04238 conjunct->index = index++; 04239 } 04240 newConjunctArray[index] = 0; 04241 free(conjunctArray); 04242 head->conjunctArray = newConjunctArray; 04243 head->nSize = index; 04244 head->bModified = 0; 04245 return; 04246 } 04247 04259 static void 04260 ImgLinearSetEffectiveNumberOfStateVariable(Relation_t *head, 04261 int *rangeId, 04262 int *domainId, 04263 int *existStateVariable) 04264 { 04265 VarLife_t **varArray, *var; 04266 int *varType; 04267 int nRange, nDomain, nQuantify; 04268 int i; 04269 04270 varArray = head->varArray; 04271 varType = head->varType; 04272 nRange = nDomain = nQuantify = 0; 04273 04274 for(i=0; i<head->nVarArray; i++) { 04275 var = varArray[i]; 04276 if(varType[var->id] == 1) { 04277 if(domainId) domainId[nDomain] = var->id; 04278 nDomain++; 04279 if(existStateVariable) existStateVariable[var->id] = 1; 04280 } 04281 else if(varType[var->id] == 2) { 04282 if(rangeId) rangeId[nRange] = var->id; 04283 nRange++; 04284 if(existStateVariable) existStateVariable[var->id] = 1; 04285 } 04286 else if(varType[var->id] == 3) { 04287 nQuantify++; 04288 } 04289 else 04290 nQuantify++; 04291 04292 } 04293 if(domainId) domainId[nDomain] = -1; 04294 if(rangeId) rangeId[nRange] = -1; 04295 04296 head->nEffRange = nRange; 04297 head->nEffDomain = nDomain; 04298 head->nEffQuantify = nQuantify; 04299 04300 if(head->nInitRange == 0 && head->nInitDomain == 0 && head->nInitQuantify == 0) { 04301 head->nInitRange = nRange; 04302 head->nInitDomain = nDomain; 04303 head->nInitQuantify = nQuantify; 04304 } 04305 } 04306 04318 static void 04319 ImgLinearAddSingletonCase(Relation_t *head) 04320 { 04321 Conjunct_t **newConjunctArray; 04322 Conjunct_t **singletonArray; 04323 Conjunct_t *conjunct; 04324 int i, j, index; 04325 int nSingletonArray; 04326 int putFlag; 04327 04328 nSingletonArray = head->nSingletonArray; 04329 singletonArray = head->singletonArray; 04330 04331 if(nSingletonArray == 0) return; 04332 fprintf(stdout, "NOTICE : %d singleton case will be added\n", nSingletonArray); 04333 04334 qsort(singletonArray, nSingletonArray, sizeof(Conjunct_t *), ImgLinearCompareConjunctRangeMinusDomain); 04335 04336 index = 0; 04337 newConjunctArray = ALLOC(Conjunct_t *, head->nSize + nSingletonArray); 04338 putFlag = 0; 04339 for(i=0; i<nSingletonArray; i++) { 04340 conjunct = singletonArray[i]; 04341 if(putFlag == 0 && conjunct->nRange > conjunct->nSize-conjunct->nRange) { 04342 putFlag = 1; 04343 for(j=0; j<head->nSize; j++) 04344 newConjunctArray[index++] = head->conjunctArray[j]; 04345 } 04346 newConjunctArray[index++] = singletonArray[i]; 04347 } 04348 if(putFlag == 0) { 04349 for(j=0; j<head->nSize; j++) 04350 newConjunctArray[index++] = head->conjunctArray[j]; 04351 } 04352 04353 head->nSize = index; 04354 head->bModified = 1; 04355 head->bRefineVarArray = 1; 04356 free(head->conjunctArray); 04357 head->conjunctArray = newConjunctArray; 04358 free(singletonArray); 04359 head->singletonArray = 0; 04360 head->nSingletonArray = 0; 04361 } 04362 04363 04375 static void 04376 ImgLinearExpandSameSupportSet(Relation_t *head) 04377 { 04378 int index, i, j; 04379 Conjunct_t **newConjunctArray; 04380 Conjunct_t *conjunct; 04381 04382 newConjunctArray = ALLOC(Conjunct_t *, head->nSize); 04383 for(index=0, i=0; i<head->nSize; i++) { 04384 if(index >= head->nSize) 04385 newConjunctArray = REALLOC(Conjunct_t *, newConjunctArray, index+1); 04386 conjunct = head->conjunctArray[i]; 04387 newConjunctArray[index++] = conjunct; 04388 if(conjunct->nCluster) { 04389 for(j=0; j<conjunct->nCluster; j++) { 04390 if(index >= head->nSize) 04391 newConjunctArray = REALLOC(Conjunct_t *, newConjunctArray, index+1); 04392 newConjunctArray[index++] = conjunct->clusterArray[j]; 04393 } 04394 head->bModified = 1; 04395 head->bRefineVarArray = 1; 04396 conjunct->nCluster = 0; 04397 if(conjunct->clusterArray) { 04398 free(conjunct->clusterArray); 04399 conjunct->clusterArray = 0; 04400 } 04401 } 04402 } 04403 free(head->conjunctArray); 04404 head->conjunctArray = newConjunctArray; 04405 head->nSize = index; 04406 } 04407 04408 04420 static void 04421 ImgLinearClusterSameSupportSet(Relation_t *head) 04422 { 04423 int i, j, index, id; 04424 int *supList; 04425 Conjunct_t *conjunct, *base; 04426 int *varType; 04427 Conjunct_t **conjunctArray, **newConjunctArray; 04428 04429 head->nTotalCluster = 0; 04430 varType = head->varType; 04431 conjunctArray = head->conjunctArray; 04432 04433 for(i=0; i<head->nSize; i++) { 04434 conjunct = head->conjunctArray[i]; 04435 supList = conjunct->supList; 04436 conjunct->dummy = 0; 04437 for(j=0; j<conjunct->nSize; j++) { 04438 id = supList[j]; 04439 if(varType[id] == 2) continue; 04440 conjunct->dummy += id; 04441 } 04442 conjunct->dummy *= (conjunct->nSize-conjunct->nRange); 04443 conjunct->dummy -= conjunct->nDomain; 04444 } 04445 qsort(conjunctArray, head->nSize, sizeof(Conjunct_t *), 04446 ImgLinearCompareConjunctDummy); 04447 04448 for(i=0; i<head->nSize; i++) { 04449 base = head->conjunctArray[i]; 04450 for(j=i+1; j<head->nSize; j++) { 04451 conjunct = head->conjunctArray[j]; 04452 if(base->dummy != conjunct->dummy) { 04453 if(j == i+1) break; 04454 ImgLinearFindSameSupportConjuncts(head, i, j-1); 04455 i = j-1; 04456 break; 04457 } 04458 } 04459 } 04460 04461 if(head->bModified) { 04462 conjunctArray = head->conjunctArray; 04463 newConjunctArray = ALLOC(Conjunct_t *, head->nSize); 04464 for(index=0, i=0; i<head->nSize; i++) { 04465 conjunct = conjunctArray[i]; 04466 if(conjunct == 0) continue; 04467 newConjunctArray[index++] = conjunct; 04468 } 04469 free(conjunctArray); 04470 head->conjunctArray = newConjunctArray; 04471 head->nSize = index; 04472 head->bModified = 1; 04473 head->bRefineVarArray = 1; 04474 } 04475 04476 conjunctArray = head->conjunctArray; 04477 qsort(conjunctArray, head->nSize, sizeof(Conjunct_t *), ImgLinearCompareConjunctIndex); 04478 if(head->bModified) { 04479 conjunctArray = head->conjunctArray; 04480 for(i=0; i<head->nSize; i++) { 04481 conjunct = conjunctArray[i]; 04482 if(conjunct == 0) continue; 04483 conjunct->index = i; 04484 } 04485 } 04486 fprintf(stdout, "NOTICE : %d conjunct clustered\n", head->nTotalCluster); 04487 head->nTotalCluster = 0; 04488 04489 } 04501 static void 04502 ImgLinearFindSameSupportConjuncts(Relation_t *head, int from, int to) 04503 { 04504 Conjunct_t *con1, *con2; 04505 int i, j; 04506 04507 for(i=from; i<=to; i++) { 04508 con1 = head->conjunctArray[i]; 04509 if(con1 == 0) continue; 04510 04511 for(j=from; j<=to; j++) { 04512 if(i == j) continue; 04513 con2 = head->conjunctArray[j]; 04514 if(con2 == 0) continue; 04515 if(ImgLinearIsSameConjunct(head, con1, con2)) { 04516 ImgLinearAddConjunctIntoClusterArray(con1, con2); 04517 head->conjunctArray[j] = 0; 04518 04519 head->bModified = 1; 04520 head->bRefineVarArray = 1; 04521 head->nTotalCluster++; 04522 } 04523 } 04524 } 04525 } 04526 04538 static int 04539 ImgLinearIsSameConjunct(Relation_t *head, Conjunct_t *con1, Conjunct_t *con2) 04540 { 04541 int i, j; 04542 int *sup1, *sup2; 04543 int id1, id2; 04544 int *varType; 04545 04546 if(con1->nDomain != con2->nDomain) return(0); 04547 if(con1->nSize-con1->nRange != con2->nSize-con2->nRange) return(0); 04548 sup1 = con1->supList; 04549 sup2 = con2->supList; 04550 04551 varType = head->varType; 04552 04553 for(j=0, i=0; i<con1->nSize; i++) { 04554 id1 = sup1[i]; 04555 if(varType[id1] == 2)continue; 04556 while(1) { 04557 id2 = sup2[j]; 04558 if(varType[id2] == 2) { 04559 j++; 04560 continue; 04561 } 04562 if(id1 != id2) return(0); 04563 j++; 04564 break; 04565 } 04566 } 04567 return(1); 04568 } 04569 04581 static Conjunct_t ** 04582 ImgLinearAddConjunctIntoArray(Conjunct_t **array, int *nArray, Conjunct_t *con) 04583 { 04584 if(array) 04585 array = REALLOC(Conjunct_t *, array, (*nArray)+1); 04586 else 04587 array = ALLOC(Conjunct_t *, (*nArray)+1); 04588 array[(*nArray)++] = con; 04589 return(array); 04590 04591 } 04592 04604 static void 04605 ImgLinearConjunctQuit(Conjunct_t *conjunct) 04606 { 04607 if(conjunct->supList) { 04608 free(conjunct->supList); 04609 conjunct->supList = 0; 04610 } 04611 if(conjunct->relation) { 04612 bdd_free(conjunct->relation); 04613 conjunct->relation = 0; 04614 } 04615 free(conjunct); 04616 } 04617 04618 04630 static void 04631 ImgLinearVariableArrayQuit(Relation_t *head) 04632 { 04633 int i; 04634 VarLife_t **varArray; 04635 04636 04637 varArray = head->varArray; 04638 for(i=0; i<head->nVarArray; i++) 04639 ImgLinearVariableLifeQuit(varArray[i]); 04640 04641 free(varArray); 04642 head->varArray = 0; 04643 head->nVarArray = 0; 04644 memset(head->varArrayMap, -1, sizeof(int)*head->nVar); 04645 } 04646 04647 04659 static void 04660 ImgLinearVariableLifeQuit(VarLife_t *var) 04661 { 04662 if(var->relArr) free(var->relArr); 04663 free(var); 04664 } 04665 04677 int 04678 ImgLinearClustering(Relation_t *head, Img_OptimizeType optDir) 04679 { 04680 int andExistLimit; 04681 int useFailureHistory; 04682 int includeZeroGain; 04683 double affinityLimit; 04684 int bOptimize; 04685 int varLimit; 04686 04687 bOptimize = 0; 04688 04689 affinityLimit = 0.99; 04690 andExistLimit = 10; 04691 varLimit = 200; 04692 fprintf(stdout, "Heap DAL affinity %3f, andExist %d\n", 04693 affinityLimit, andExistLimit); 04694 bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit, 04695 varLimit, optDir, 0, 04696 ImgLinearHeapCompareDeadAffinityLive); 04697 ImgLinearRefineRelation(head); 04698 if(head->verbosity >= 5) 04699 ImgLinearPrintMatrix(head); 04700 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 04701 ImgLinearPrintTransitionInfo(head); 04702 04703 includeZeroGain = 0; 04704 affinityLimit = 0.3; 04705 andExistLimit = 5000; 04706 varLimit = 50; 04707 useFailureHistory = 0; 04708 if(head->computeRange) { 04709 varLimit = 50; 04710 affinityLimit = 0.8; 04711 andExistLimit = 5000; 04712 fprintf(stdout, "Heap DAL affinity %3f, andExist %d\n", 04713 affinityLimit, andExistLimit); 04714 bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit, 04715 varLimit, optDir, 0, 04716 ImgLinearHeapCompareDeadAffinityLive); 04717 04718 ImgLinearRefineRelation(head); 04719 ImgLinearExtractNextStateCase(head); 04720 ImgLinearExtractSingletonCase(head); 04721 ImgLinearRefineRelation(head); 04722 ImgLinearAddSingletonCase(head); 04723 ImgLinearRefineRelation(head); 04724 ImgLinearAddNextStateCase(head); 04725 ImgLinearRefineRelation(head); 04726 } 04727 else 04728 { 04729 fprintf(stdout, "Gain DAL affinity %3f, andExist %d\n", 04730 affinityLimit, andExistLimit); 04731 bOptimize |= ImgLinearClusteringIteratively(head, affinityLimit, 04732 andExistLimit, varLimit, 04733 includeZeroGain, useFailureHistory, optDir, 04734 ImgLinearCompareDeadAffinityLive); 04735 ImgLinearRefineRelation(head); 04736 ImgLinearExtractNextStateCase(head); 04737 ImgLinearExtractSingletonCase(head); 04738 ImgLinearRefineRelation(head); 04739 ImgLinearAddSingletonCase(head); 04740 ImgLinearRefineRelation(head); 04741 ImgLinearAddNextStateCase(head); 04742 ImgLinearRefineRelation(head); 04743 } 04744 04745 includeZeroGain = 1; 04746 varLimit = 200; 04747 affinityLimit = 0.7; 04748 andExistLimit = 5000; 04749 fprintf(stdout, "Heap DAL affinity %3f, andExist %d\n", 04750 affinityLimit, andExistLimit); 04751 bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit, 04752 varLimit, optDir, 0, 04753 ImgLinearHeapCompareDeadAffinityLive); 04754 04755 ImgLinearRefineRelation(head); 04756 ImgLinearExtractNextStateCase(head); 04757 ImgLinearExtractSingletonCase(head); 04758 ImgLinearRefineRelation(head); 04759 ImgLinearAddSingletonCase(head); 04760 ImgLinearRefineRelation(head); 04761 ImgLinearAddNextStateCase(head); 04762 ImgLinearRefineRelation(head); 04763 04764 if(head->verbosity >= 5) 04765 ImgLinearPrintMatrix(head); 04766 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 04767 ImgLinearPrintTransitionInfo(head); 04768 04769 includeZeroGain = 1; 04770 affinityLimit = 0.4; 04771 andExistLimit = 5000; 04772 fprintf(stdout, "Heap DAL affinity %3f, andExist %d\n", 04773 affinityLimit, andExistLimit); 04774 bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit, 04775 varLimit, optDir, 0, 04776 ImgLinearHeapCompareDeadAffinityLive); 04777 ImgLinearRefineRelation(head); 04778 ImgLinearExtractNextStateCase(head); 04779 ImgLinearExtractSingletonCase(head); 04780 ImgLinearRefineRelation(head); 04781 ImgLinearAddSingletonCase(head); 04782 ImgLinearRefineRelation(head); 04783 ImgLinearAddNextStateCase(head); 04784 ImgLinearRefineRelation(head); 04785 04786 if(head->verbosity >= 5) 04787 ImgLinearPrintMatrix(head); 04788 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 04789 ImgLinearPrintTransitionInfo(head); 04790 04791 affinityLimit = 0.0; 04792 andExistLimit = 5000; 04793 fprintf(stdout, "Heap DLA affinity %3f, andExist %d\n", 04794 affinityLimit, andExistLimit); 04795 bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit, 04796 varLimit, optDir, 0, 04797 ImgLinearHeapCompareDeadLiveAffinity); 04798 ImgLinearRefineRelation(head); 04799 ImgLinearExtractNextStateCase(head); 04800 ImgLinearRefineRelation(head); 04801 ImgLinearAddNextStateCase(head); 04802 ImgLinearRefineRelation(head); 04803 if(head->verbosity >= 5) 04804 ImgLinearPrintMatrix(head); 04805 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 04806 ImgLinearPrintTransitionInfo(head); 04807 04808 if(head->computeRange) { 04809 includeZeroGain = 0; 04810 affinityLimit = 0.0; 04811 andExistLimit = andExistLimit; 04812 varLimit = MAXINT; 04813 head->bddLimit = head->bddLimit * 2; 04814 fprintf(stdout, "Heap DLA affinity %3f, andExist %d\n", 04815 affinityLimit, andExistLimit); 04816 while(1) { 04817 bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit, 04818 varLimit, optDir, 1, 04819 ImgLinearHeapCompareDeadLiveAffinity); 04820 ImgLinearRefineRelation(head); 04821 04822 if(ImgCheckRangeTestAndOverapproximate(head)) break; 04823 } 04824 04825 ImgCountOnsetDisjunctiveArray(head); 04826 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 04827 ImgLinearPrintTransitionInfo(head); 04828 04829 } 04830 04831 return(bOptimize); 04832 } 04833 04845 static void 04846 ImgCountOnsetDisjunctiveArray(Relation_t *head) 04847 { 04848 EpDouble tepd; 04849 char strValue[1024]; 04850 bdd_t *varBdd; 04851 mdd_manager *mgr; 04852 array_t *bddVarArray; 04853 Conjunct_t *conjunct; 04854 int count, i, j, id; 04855 double onSet; 04856 04857 mgr = head->mgr; 04858 count = 0; 04859 EpdConvert((double)1.0, &tepd); 04860 for(i=0; i<head->nSize; i++) { 04861 conjunct = head->conjunctArray[i]; 04862 bddVarArray = array_alloc(bdd_t *, 0); 04863 for(j=0; j<conjunct->nSize; j++) { 04864 id = conjunct->supList[j]; 04865 varBdd = bdd_get_variable(mgr, id); 04866 array_insert_last(bdd_t *, bddVarArray, varBdd); 04867 } 04872 onSet = bdd_count_onset(conjunct->relation, bddVarArray); 04873 EpdMultiply(&tepd, onSet); 04874 count += conjunct->nSize; 04875 mdd_array_free(bddVarArray); 04876 } 04877 04878 if(count < head->nRange) { 04879 EpdMultiply(&tepd, pow(2, (double)(head->nRange-count))); 04880 } 04881 EpdGetString(&tepd, strValue); 04882 (void) fprintf(vis_stdout, "%-20s%10s\n", "range =", strValue); 04883 04884 } 04885 04897 static int 04898 ImgCheckRangeTestAndOverapproximate(Relation_t *head) 04899 { 04900 Conjunct_t *conjunct; 04901 VarLife_t **varArray, *var; 04902 int nVarArray, i, k, count; 04903 int index; 04904 int *varType; 04905 int allRangeFlag; 04906 bdd_t *relation, *simpleRelation, *varBdd; 04907 04908 04909 allRangeFlag = 1; 04910 for(i=0; i<head->nSize; i++) { 04911 conjunct = head->conjunctArray[i]; 04912 if(conjunct->nRange != conjunct->nSize) { 04913 allRangeFlag = 0; 04914 break; 04915 } 04916 } 04917 04918 if(allRangeFlag == 1) return(1); 04919 04920 varArray = head->varArray; 04921 varType = head->varType; 04922 nVarArray = head->nVarArray; 04937 count = head->nEffDomain + head->nEffQuantify; 04938 if(count == 0) return(1); 04939 04940 varArray = ALLOC(VarLife_t *, head->nVarArray); 04941 memcpy(varArray, head->varArray, sizeof(VarLife_t *)*head->nVarArray); 04942 qsort(varArray, head->nVarArray, sizeof(VarLife_t *), ImgLinearCompareVarSize); 04943 04944 if(count != 0) { 04945 count = (count / 10); 04946 if(count == 0) count = 1; 04947 } 04948 k=0; 04949 index = 0; 04950 while(1) { 04951 if(index >= count) break; 04952 var = varArray[k++]; 04953 if(var->stateVar == 2) continue; 04954 index++; 04955 varBdd = bdd_get_variable(head->mgr, var->id); 04956 for(i=0; i<var->nSize; i++) { 04957 conjunct = head->conjunctArray[var->relArr[i]]; 04958 relation = conjunct->relation; 04959 simpleRelation = bdd_smooth_with_cube(relation, varBdd); 04960 if(bdd_equal(relation, simpleRelation)) { 04961 bdd_free(simpleRelation); 04962 continue; 04963 } 04964 bdd_free(relation); 04965 04966 conjunct->relation = simpleRelation; 04967 conjunct->bModified = 1; 04968 head->bModified = 1; 04969 head->bRefineVarArray = 1; 04970 ImgLinearConjunctRefine(head, conjunct); 04971 } 04972 } 04973 free(varArray); 04974 04975 ImgLinearRefineRelation(head); 04976 ImgLinearConjunctOrderMainCC(head, 0); 04977 ImgLinearRefineRelation(head); 04978 04979 ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0); 04980 ImgLinearPrintTransitionInfo(head); 04981 04982 return(0); 04983 } 04984 04996 static void 04997 ImgLinearAddNextStateCase(Relation_t *head) 04998 { 04999 Conjunct_t **newConjunctArray; 05000 int i, j, index; 05001 05002 index = 0; 05003 if(head->nNextStateArray) { 05004 newConjunctArray = ALLOC(Conjunct_t *, head->nSize + head->nNextStateArray); 05005 for(j=0; j<head->nSize; j++) 05006 newConjunctArray[index++] = head->conjunctArray[j]; 05007 05008 for(i=0; i<head->nNextStateArray; i++) 05009 newConjunctArray[index++] = head->nextStateArray[i]; 05010 05011 head->nSize = index; 05012 head->bModified = 1; 05013 head->bRefineVarArray = 1; 05014 free(head->conjunctArray); 05015 head->conjunctArray = newConjunctArray; 05016 05017 if(head->nextStateArray) free(head->nextStateArray); 05018 head->nextStateArray = 0; 05019 } 05020 } 05021