VIS
|
00001 00032 #include "ordInt.h" 00033 00034 static char rcsid[] UNUSED = "$Id: ordPerm.c,v 1.9 2005/04/16 06:15:25 fabio Exp $"; 00035 00036 /*---------------------------------------------------------------------------*/ 00037 /* Structure declarations */ 00038 /*---------------------------------------------------------------------------*/ 00039 00040 typedef struct proc_pair { 00041 long proc_no; 00042 long var_no; 00043 } pair; 00044 00045 typedef struct proc_struct { 00046 int num_loc_vars; 00047 array_t *o_list; /* of pair */ 00048 array_t *i_list; /* of pair */ 00049 } proc_struct; 00050 00051 typedef struct Proc_Com_Graph { 00052 int num_vars; 00053 int num_proc; 00054 int *width_list; 00055 proc_struct *proc_list; 00056 int *locations; /* Array of length num_proc used as temporary storage by some 00057 functions */ 00058 int *variables; /* Array of length num_vars used as temporary storage by some 00059 functions */ 00060 00061 } Proc_Com_Graph; 00062 00063 00064 /*---------------------------------------------------------------------------*/ 00065 /* Variable declarations */ 00066 /*---------------------------------------------------------------------------*/ 00081 static int number_of_calls; 00082 00083 00084 /*---------------------------------------------------------------------------*/ 00085 /* Macro declarations */ 00086 /*---------------------------------------------------------------------------*/ 00087 00088 00091 /*---------------------------------------------------------------------------*/ 00092 /* Static function prototypes */ 00093 /*---------------------------------------------------------------------------*/ 00094 00095 static lsList NetworkComputeLatchOrder(Ntk_Network_t * network, int verbose); 00096 static int * LatchPermutationCompute(Proc_Com_Graph *PCG, int choice, int verbose); 00097 static double rev_fac(int num_rev_bits); 00098 static double cost_for_cut(Proc_Com_Graph * PCG, int * perm, int end_of_set1); 00099 static void append_best(int * opt_perm, int loc, Proc_Com_Graph * PCG); 00100 static double cost_2(int * opt_perm, int loc, Proc_Com_Graph * PCG); 00101 static long int cost_touati_2(int * opt_perm, int loc, Proc_Com_Graph * PCG); 00102 static void swap(int * opt_perm, int i, int j); 00103 static void append_best_2(int * opt_perm, int loc, Proc_Com_Graph * PCG); 00104 static void append_touati_2(int * opt_perm, int loc, Proc_Com_Graph * PCG); 00105 static void init_heur(Proc_Com_Graph * PCG, int * opt_perm); 00106 static void heur_2(Proc_Com_Graph * PCG, int * opt_perm); 00107 static void heur_touati_la2(Proc_Com_Graph * PCG, int * opt_perm); 00108 static int * opt_proc_order(Proc_Com_Graph * PCG); 00109 static int * opt_touati_order(Proc_Com_Graph * PCG); 00110 static double cost_total(Proc_Com_Graph * PCG, int * perm); 00111 static int * random_permutation(int seed, int n_elts); 00112 00116 /*---------------------------------------------------------------------------*/ 00117 /* Definition of exported functions */ 00118 /*---------------------------------------------------------------------------*/ 00119 00120 00121 /*---------------------------------------------------------------------------*/ 00122 /* Definition of internal functions */ 00123 /*---------------------------------------------------------------------------*/ 00124 00141 lsList 00142 OrdNetworkOrderRootsByPerm( 00143 Ntk_Network_t *network, 00144 int verbose) 00145 { 00146 lsGen gen; 00147 Ntk_Node_t *node; 00148 lsList dataInputs; 00149 st_table *processedTable = st_init_table(st_ptrcmp, st_ptrhash); 00150 lsList otherCombOuts = lsCreate(); 00151 00152 /* 00153 * Create a list of all combinational outputs that are not data inputs to 00154 * latches. A node can drive more than one latch data input, latch initial 00155 * input, or primary output. Use a hash table to ensure that no node appears 00156 * twice in the list. 00157 */ 00158 Ntk_NetworkForEachCombOutput(network, gen, node) { 00159 if (!Ntk_NodeTestIsLatchDataInput(node)) { 00160 OrdNodeAddToList(otherCombOuts, processedTable, node); 00161 } 00162 } 00163 st_free_table(processedTable); 00164 00165 /* Compute depth of all roots in otherCombOuts. */ 00166 OrdNetworkComputeNodeDepths(network, otherCombOuts); 00167 00168 /* Sort otherCombOuts based on depth. */ 00169 lsSort(otherCombOuts, OrdNodesFromListCompareDepth); 00170 00171 /* Compute order on dataInputs roots using the permutation method. */ 00172 dataInputs = NetworkComputeLatchOrder(network, verbose); 00173 00174 /* Add the otherCombOuts list to the end of the dataInputs list. */ 00175 Ord_ListAppendList(dataInputs, otherCombOuts); 00176 (void) lsDestroy(otherCombOuts, (void (*) (lsGeneric)) NULL); 00177 00178 return dataInputs; 00179 } 00180 00181 00182 /*---------------------------------------------------------------------------*/ 00183 /* Definition of static functions */ 00184 /*---------------------------------------------------------------------------*/ 00185 00200 static lsList 00201 NetworkComputeLatchOrder( 00202 Ntk_Network_t * network, 00203 int verbose) 00204 { 00205 int i, j; 00206 lsGen listGen; 00207 st_generator *stGen; 00208 Ntk_Node_t *latch; 00209 lsList tfoLatchList; 00210 int *latchOrderArray; 00211 long count = 0L; 00212 st_table *idToLatch = st_init_table(st_numcmp, st_numhash); 00213 int numLatches = Ntk_NetworkReadNumLatches(network); 00214 st_table *latchDependencies = Ntk_NetworkComputeLatchDependencies(network); 00215 lsList latchOrderList = lsCreate(); 00216 int latchOrderingMode = 1; /* FIX: make an option */ 00217 double convConstant = log10(2.0); 00218 Proc_Com_Graph *PCG; 00219 pair *cur_pair; 00220 00221 /* 00222 * Assign unique integer between 0 and numLatches-1 to each latch. Store 00223 * this correspondance in the idToLatch hash table. 00224 * (NOTE: may be sensitive to ordering in memory.) 00225 */ 00226 Ntk_NetworkForEachLatch(network, listGen, latch) { 00227 Ntk_NodeSetUndef(latch, (void *) count); 00228 st_insert(idToLatch, (char *) count, (char *) latch); 00229 count++; 00230 } 00231 00232 /* Create a Proc_Com_Graph and write the communications 00233 * structure of the network into it 00234 */ 00235 00236 PCG = ALLOC(Proc_Com_Graph, 1); 00237 PCG->num_proc = numLatches; /* SER (void) fprintf(pcgFile, "%d\n", numLatches); */ 00238 PCG->num_vars = numLatches; /* SER (void) fprintf(pcgFile, "%d\n", numLatches); */ 00239 00240 PCG->proc_list = ALLOC(proc_struct, PCG->num_proc); 00241 PCG->width_list= ALLOC(int, PCG->num_vars); 00242 PCG->locations = ALLOC(int, PCG->num_proc); 00243 PCG->variables = ALLOC(int, PCG->num_vars); 00244 00245 for(i=0;i< PCG->num_proc ; i++) { 00246 PCG->proc_list[i].o_list= array_alloc(pair *, 0); 00247 PCG->proc_list[i].i_list= array_alloc(pair *, 0); 00248 }; 00249 00250 /* 00251 * For each latch/tfoLatchList pair, write information about the latch, and 00252 * write the latches to which the latch fanouts. Finish the entry with "%%". 00253 * Here is the general format for a process: 00254 * process # list of local vars to process # 00255 * fanout-latch : local-var-fanning-to width-of-local-var / 00256 * .... 00257 * fanout-latch : local-var-fanning-to width-of-local-var / %% 00258 * 00259 * When this format is specialized to case where each process is a single 00260 * latch, then the format looks like: 00261 * latch # latch # 00262 * fanout-latch : latch width-of-latch / 00263 * .... 00264 * fanout-latch : latch width-of-latch / %% 00265 */ 00266 st_foreach_item(latchDependencies, stGen, &latch, &tfoLatchList) { 00267 Ntk_Node_t *tfoLatch; 00268 int varWidth; 00269 long var_no, fr_no, to_no; 00270 00271 00272 /* 00273 * Write the latch id and the cardinality of the latch variable 00274 * domain. 00275 */ 00276 fr_no = (long) Ntk_NodeReadUndef(latch); 00277 PCG->proc_list[fr_no].num_loc_vars = 1; 00278 00279 00280 /* 00281 * For each transitive fanout latch, write the tfoLatch id, the latch 00282 * id, and the width of the latch variable (assumes minimum 00283 * encoding). Width is ceiling(log2(number of values in domain)). 00284 */ 00285 varWidth = (int) ceil(log10 00286 ((double)Var_VariableReadNumValues(Ntk_NodeReadVariable(latch))) 00287 / convConstant); 00288 lsForEachItem(tfoLatchList, listGen, tfoLatch) { 00289 to_no = (long) Ntk_NodeReadUndef(tfoLatch); 00290 var_no = (long) Ntk_NodeReadUndef(latch); 00291 00292 cur_pair = ALLOC(pair,1); 00293 cur_pair->proc_no = to_no; 00294 cur_pair->var_no = var_no; 00295 array_insert_last(pair *, PCG->proc_list[fr_no].o_list, cur_pair); 00296 00297 cur_pair = ALLOC(pair,1); 00298 cur_pair->proc_no = fr_no; 00299 cur_pair->var_no = var_no; 00300 array_insert_last(pair *, PCG->proc_list[to_no].i_list, cur_pair); 00301 00302 PCG->width_list[var_no] = varWidth; 00303 } 00304 } 00305 00306 /* 00307 * We don't need the latchDependencies table anymore. Free the list stored 00308 * at each value, and then free the table itself. 00309 */ 00310 st_foreach_item(latchDependencies, stGen, &latch, &tfoLatchList) { 00311 (void) lsDestroy(tfoLatchList, (void (*) (lsGeneric)) NULL); 00312 } 00313 st_free_table(latchDependencies); 00314 00315 /* 00316 * Compute the order on the latches. This is returned as an array of 00317 * integers, where the latch whose id is latchOrderArray[i] is ordered in 00318 * the ith position of latchOrderList. Note that the returned list actually 00319 * contains the latch data inputs, not the latches themselves. 00320 */ 00321 latchOrderArray = LatchPermutationCompute(PCG, latchOrderingMode, verbose); 00322 00323 for (i=0; i < PCG->num_proc; i++) { 00324 for (j=0; j<array_n(PCG->proc_list[i].o_list); j++) { 00325 cur_pair = array_fetch(pair *, PCG->proc_list[i].o_list, j); 00326 FREE(cur_pair); 00327 } 00328 00329 for (j=0; j<array_n(PCG->proc_list[i].i_list); j++) { 00330 cur_pair = array_fetch(pair *, PCG->proc_list[i].i_list, j); 00331 FREE(cur_pair); 00332 } 00333 00334 array_free(PCG->proc_list[i].o_list); 00335 array_free(PCG->proc_list[i].i_list); 00336 } 00337 00338 FREE(PCG->proc_list); 00339 FREE(PCG->width_list); 00340 FREE(PCG->variables); 00341 FREE(PCG->locations); 00342 FREE(PCG); 00343 00344 for (i = 0; i < numLatches; i++) { 00345 int status UNUSED = st_lookup(idToLatch, 00346 (char *) (long) (latchOrderArray[i]), 00347 &latch); 00348 assert(status); 00349 (void) lsNewEnd(latchOrderList, (lsGeneric) Ntk_LatchReadDataInput(latch), LS_NH); 00350 } 00351 00352 /* 00353 * We are done with idToLatch and latchOrderArray. 00354 */ 00355 st_free_table(idToLatch); 00356 FREE(latchOrderArray); 00357 00358 return (latchOrderList); 00359 } 00360 00361 00373 static int * 00374 LatchPermutationCompute( 00375 Proc_Com_Graph *PCG, 00376 int choice, 00377 int verbose) 00378 { 00379 int *opt_perm; 00380 00381 if (choice == 0) { 00382 opt_perm = opt_proc_order(PCG); 00383 } 00384 else if (choice == 1) { 00385 opt_perm = ALLOC(int, PCG->num_proc); 00386 init_heur(PCG, opt_perm); 00387 } 00388 else if (choice == 2) { 00389 opt_perm = opt_touati_order(PCG); 00390 } 00391 else if (choice == 3) { 00392 opt_perm = random_permutation(7,PCG->num_vars); 00393 } 00394 else { 00395 fail("Unknown Option for Computing Latch Permutation"); 00396 } 00397 00398 if (verbose > 1) { 00399 (void) fprintf(vis_stdout, "TOTAL COST= %e \n",cost_total(PCG,opt_perm)); 00400 } 00401 00402 return opt_perm; 00403 } 00404 00405 00417 static double 00418 rev_fac( 00419 int num_rev_bits) 00420 { 00421 double result; 00422 00423 result = pow( ((double) 2.0),((double) num_rev_bits) ); 00424 00425 return result; 00426 } 00427 00428 00441 static double 00442 cost_for_cut( 00443 Proc_Com_Graph * PCG, 00444 int * perm, 00445 int end_of_set1) 00446 { 00447 int i, j; 00448 double result; 00449 int forw = 0, rev = 0; 00450 pair *cur_pair; 00451 00452 for (i=0; i<=end_of_set1; i++) { 00453 PCG->locations[perm[i]]=1; 00454 } 00455 00456 for (i=end_of_set1+1; i<PCG->num_proc; i++) { 00457 PCG->locations[perm[i]]=2; 00458 } 00459 00460 for (i=0; i<PCG->num_vars; i++) { 00461 PCG->variables[i]=0; 00462 } 00463 00464 /* Count the # of forward crossing bits */ 00465 /* for (i=0; i<=end_of_set1; i++) { 00466 st_foreach_item(PCG->proc_list[perm[i]].o_list, 00467 gen,(char **)&bit_no,(char **)&to_proc) { 00468 if (PCG->locations[to_proc] ==2) { 00469 PCG->variables[bit_no]++ ; 00470 } 00471 } 00472 } 00473 */ 00474 for (i=0; i<=end_of_set1; i++) 00475 for (j=0; j<array_n(PCG->proc_list[perm[i]].o_list); j++) { 00476 cur_pair = array_fetch(pair *, PCG->proc_list[perm[i]].o_list, j); 00477 if (PCG->locations[cur_pair->proc_no] ==2) { 00478 PCG->variables[cur_pair->var_no]++ ; 00479 } 00480 } 00481 00482 00483 for (i=0; i<PCG->num_vars; i++) { 00484 if (PCG->variables[i] > 0) { 00485 ++forw ; 00486 } 00487 } 00488 00489 for (i=0; i<PCG->num_vars; i++) { 00490 PCG->variables[i]=0; 00491 } 00492 00493 /* Count the # of reverse crossing bits */ 00494 /* for (i=end_of_set1+1; i<PCG->num_proc; i++) { 00495 st_foreach_item(PCG->proc_list[perm[i]].o_list, 00496 gen,(char **)&bit_no,(char **)&to_proc) { 00497 if (PCG->locations[to_proc] ==1) { 00498 PCG->variables[bit_no]++; 00499 } 00500 } 00501 } 00502 */ 00503 for (i=end_of_set1+1; i<PCG->num_proc; i++) 00504 for (j=0; j<array_n(PCG->proc_list[perm[i]].o_list); j++) { 00505 cur_pair = array_fetch(pair *, PCG->proc_list[perm[i]].o_list, j); 00506 if (PCG->locations[cur_pair->proc_no] ==1) { 00507 PCG->variables[cur_pair->var_no]++ ; 00508 } 00509 } 00510 00511 00512 for (i=0; i<PCG->num_vars; i++) { 00513 if (PCG->variables[i] > 0) { 00514 ++rev; 00515 } 00516 } 00517 00518 { 00519 double rev_cost = rev_fac(rev); 00520 result = ((double) forw) + rev_cost; 00521 number_of_calls++; 00522 } 00523 return result; 00524 } 00525 00526 00539 static void 00540 append_best( 00541 int * opt_perm, 00542 int loc, 00543 Proc_Com_Graph * PCG) 00544 { 00545 int i, temp, bestswap, cur_fanout, best_fanout; 00546 double cur_cost, best_cost; 00547 int j; 00548 pair *cur_pair; 00549 00550 best_cost = cost_for_cut(PCG, opt_perm, loc); 00551 cur_cost = best_cost; 00552 bestswap = loc; 00553 00554 best_fanout = 100000; 00555 for(i=loc+1; i<PCG->num_proc; i++) { 00556 temp = opt_perm[loc]; 00557 opt_perm[loc] = opt_perm[i]; 00558 opt_perm[i] = temp; 00559 00560 cur_cost = cost_for_cut(PCG, opt_perm, loc); 00561 00562 if ( cur_cost == best_cost ) { 00563 cur_fanout = 0; 00564 00565 for ( j = 0 ; j <= loc ; j++ ) { 00566 PCG->locations[opt_perm[j]] = 1; 00567 } 00568 00569 for ( j = loc + 1 ; j < PCG->num_proc ; j++ ) { 00570 PCG->locations[opt_perm[j]] = 2; 00571 } 00572 00573 /* st_foreach_item( PCG->proc_list[opt_perm[i]].o_list, 00574 stgen, ( char ** ) &bit_no, ( char ** ) &to_proc ) { 00575 if ( PCG->locations[to_proc] == 2 ) { 00576 cur_fanout++; 00577 } 00578 } 00579 */ 00580 for (j=0; j<array_n(PCG->proc_list[opt_perm[i]].o_list); j++) { 00581 cur_pair = array_fetch(pair *, PCG->proc_list[opt_perm[i]].o_list, j); 00582 if (PCG->locations[cur_pair->proc_no] ==2) 00583 cur_fanout++; 00584 } 00585 00586 00587 00588 00589 if ( cur_fanout < best_fanout ) { 00590 best_fanout = cur_fanout; 00591 bestswap = i; 00592 } 00593 } 00594 00595 if (cur_cost < best_cost) { 00596 best_cost = cur_cost; 00597 bestswap = i; 00598 } 00599 00600 temp = opt_perm[loc]; 00601 opt_perm[loc] = opt_perm[i]; 00602 opt_perm[i] = temp; 00603 } 00604 00605 temp = opt_perm[loc]; 00606 opt_perm[loc] = opt_perm[bestswap]; 00607 opt_perm[bestswap] = temp; 00608 } 00609 00610 00622 static double 00623 cost_2( 00624 int * opt_perm, 00625 int loc, 00626 Proc_Com_Graph * PCG) 00627 { 00628 00629 double cost_0 = cost_for_cut(PCG, opt_perm, loc); 00630 double cost_1 = cost_for_cut(PCG, opt_perm, loc+1); 00631 double result = cost_0 + cost_1; 00632 00633 return result; 00634 00635 } 00636 00637 00649 static long int 00650 cost_touati_2( 00651 int * opt_perm, 00652 int loc, 00653 Proc_Com_Graph * PCG) 00654 { 00655 int i, j; 00656 long int result; 00657 pair *cur_pair; 00658 00659 00660 for (i=0; i<loc; i++) { 00661 PCG->locations[opt_perm[i]]=1; 00662 } 00663 00664 for (i=loc+1; i<PCG->num_proc; i++) { 00665 PCG->locations[opt_perm[i]]=0; 00666 } 00667 00668 for (i=0; i<PCG->num_vars; i++) 00669 PCG->variables[i]=0; 00670 00671 /* st_foreach_item(PCG->proc_list[opt_perm[loc]].i_list, 00672 gen,(char **)&bit_no,(char **)&from_proc) { 00673 if (PCG->locations[from_proc] == 0) { 00674 PCG->variables[bit_no]++ ; 00675 } 00676 } 00677 */ 00678 00679 for (j=0; j<array_n(PCG->proc_list[opt_perm[loc]].i_list); j++) { 00680 cur_pair = array_fetch(pair *, PCG->proc_list[opt_perm[loc]].i_list, j); 00681 if (PCG->locations[cur_pair->proc_no] ==0) { 00682 PCG->variables[cur_pair->var_no]++ ; 00683 } 00684 } 00685 00686 result = 0; 00687 for (i=0; i<PCG->num_vars; i++) { 00688 if (PCG->variables[i] != 0) { 00689 result++; 00690 } 00691 } 00692 00693 for (i=0; i<PCG->num_vars; i++) 00694 PCG->variables[i]=0; 00695 00696 /* st_foreach_item(PCG->proc_list[opt_perm[loc+1]].i_list, 00697 gen,(char **)&bit_no,(char **)&from_proc) { 00698 if (PCG->locations[from_proc] == 0) { 00699 PCG->variables[bit_no]++ ; 00700 } 00701 } 00702 */ 00703 00704 for (j=0; j<array_n(PCG->proc_list[opt_perm[loc+1]].i_list); j++) { 00705 cur_pair = array_fetch(pair *, PCG->proc_list[opt_perm[loc+1]].i_list, j); 00706 if (PCG->locations[cur_pair->proc_no] ==0) { 00707 PCG->variables[cur_pair->var_no]++ ; 00708 } 00709 } 00710 00711 for (i=0; i<PCG->num_vars; i++) { 00712 if (PCG->variables[i] != 0) { 00713 result++; 00714 } 00715 } 00716 00717 return result; 00718 } 00719 00720 00732 static void 00733 swap( 00734 int * opt_perm, 00735 int i, 00736 int j) 00737 { 00738 int temp; 00739 00740 temp = opt_perm[i]; 00741 opt_perm[i] = opt_perm[j]; 00742 opt_perm[j] = temp; 00743 } 00744 00745 00757 static void 00758 append_best_2( 00759 int * opt_perm, 00760 int loc, 00761 Proc_Com_Graph * PCG) 00762 { 00763 double best_cost, cur_cost; 00764 int i,j; 00765 int best[2]; 00766 00767 00768 best_cost = cost_2(opt_perm, loc, PCG); 00769 cur_cost = best_cost; 00770 best[0] = loc; 00771 best[1] = loc+1; 00772 00773 for(i=loc; i<PCG->num_proc; i++) { 00774 swap(opt_perm,loc,i); 00775 for(j=loc+1; j<PCG->num_proc; j++) { 00776 swap(opt_perm,loc+1,j); 00777 cur_cost = cost_2(opt_perm, loc, PCG); 00778 if (cur_cost < best_cost) { 00779 best_cost = cur_cost; 00780 best[0] = i; 00781 best[1] = j; 00782 }; 00783 swap(opt_perm,loc+1,j); 00784 } 00785 swap(opt_perm,loc,i); 00786 }; 00787 00788 swap(opt_perm,loc,best[0]); 00789 swap(opt_perm,loc+1,best[1]); 00790 } 00791 00792 00804 static void 00805 append_touati_2( 00806 int * opt_perm, 00807 int loc, 00808 Proc_Com_Graph * PCG) 00809 { 00810 long int best_cost, cur_cost; 00811 int i,j; 00812 int best[2]; 00813 00814 /* 00815 * FIX: this is the same function as append_best_2, except that 00816 * cost_touati_2 is used rather than cost_2; just pass the cost function in 00817 * as a parameter. 00818 */ 00819 00820 best_cost = cost_touati_2(opt_perm, loc, PCG); 00821 cur_cost = best_cost; 00822 best[0] = loc; 00823 best[1] = loc+1; 00824 00825 for(i=loc; i<PCG->num_proc; i++) { 00826 swap(opt_perm,loc,i); 00827 for(j=loc+1; j<PCG->num_proc; j++) { 00828 swap(opt_perm,loc+1,j); 00829 cur_cost = cost_touati_2(opt_perm, loc, PCG); 00830 if (cur_cost < best_cost) { 00831 best_cost = cur_cost; 00832 best[0] = i; 00833 best[1] = j; 00834 }; 00835 swap(opt_perm,loc+1,j); 00836 } 00837 swap(opt_perm,loc,i); 00838 }; 00839 00840 swap(opt_perm,loc,best[0]); 00841 swap(opt_perm,loc+1,best[1]); 00842 } 00843 00844 00859 static void 00860 init_heur( 00861 Proc_Com_Graph * PCG, 00862 int * opt_perm) 00863 { 00864 int i; 00865 00866 for(i=0; i<PCG->num_proc; i++) { 00867 opt_perm[i] = i; 00868 } 00869 00870 00871 00872 /*printf("\nEntering ordering code:\n");*/ 00873 for(i=0; i<PCG->num_proc; i++) { 00874 /*printf("Iteration\t:\t%d(%d)\n", i, PCG->num_proc );*/ 00875 append_best(opt_perm, i, PCG); 00876 } 00877 /*printf("\n\t--- Total number of calls = %d ---\n", number_of_calls );*/ 00878 } 00879 00880 00892 static void 00893 heur_2( 00894 Proc_Com_Graph * PCG, 00895 int * opt_perm) 00896 { 00897 00898 int i; 00899 00900 for(i=0; i<PCG->num_proc; i++) { 00901 opt_perm[i] = i; 00902 } 00903 00904 for(i=0; i<(2*floor(((double)PCG->num_proc) / 2.0 )); i = i+2) { 00905 /*printf("Iteration\t:\t%d(%d)\n", i, PCG->num_proc );*/ 00906 append_best_2(opt_perm,i,PCG); 00907 } 00908 } 00909 00910 00922 static void 00923 heur_touati_la2( 00924 Proc_Com_Graph * PCG, 00925 int * opt_perm) 00926 { 00927 int i; 00928 00929 for(i=0; i<PCG->num_proc; i++) { 00930 opt_perm[i] = i; 00931 } 00932 00933 for(i=0; i<(2*floor(((double)PCG->num_proc) / 2.0 )); i = i+2) { 00934 /*printf("Iteration\t:\t%d(%d)\n", i, PCG->num_proc );*/ 00935 append_touati_2(opt_perm,i,PCG); 00936 } 00937 } 00938 00939 00951 static int * 00952 opt_proc_order( 00953 Proc_Com_Graph * PCG) 00954 { 00955 int *cur_opt; 00956 00957 00958 cur_opt = ALLOC(int, PCG->num_proc); 00959 heur_2(PCG, cur_opt); 00960 00961 /*for (i=0;i<PCG->num_proc; i++) printf(" %d ",cur_opt[i]+1);*/ 00962 00963 return cur_opt; 00964 } 00965 00966 00978 static int * 00979 opt_touati_order( 00980 Proc_Com_Graph * PCG) 00981 { 00982 int *cur_opt; 00983 00984 00985 /* 00986 * FIX: same function as opt_proc_order except for heuristic call. 00987 */ 00988 00989 cur_opt = ALLOC(int, PCG->num_proc); 00990 heur_touati_la2(PCG, cur_opt); 00991 00992 /*for (i=0;i<PCG->num_proc; i++) printf(" %d ",cur_opt[i]+1);*/ 00993 00994 return cur_opt; 00995 } 00996 01008 static double 01009 cost_total( 01010 Proc_Com_Graph * PCG, 01011 int * perm) 01012 { 01013 int i; 01014 01015 double cost=0; 01016 01017 for(i=0; i<PCG->num_proc-1; i++) { 01018 cost += cost_for_cut(PCG, perm, i); 01019 } 01020 01021 return cost; 01022 } 01023 01024 01036 static int * 01037 random_permutation( 01038 int seed, 01039 int n_elts) 01040 { 01041 int i, j; 01042 int *permutation; 01043 int *remaining; 01044 int next_entry; 01045 int next_value; 01046 int n_entries; 01047 01048 if (n_elts <= 0) { 01049 return NIL(int); 01050 } 01051 01052 n_entries = n_elts; 01053 permutation = ALLOC(int, n_entries); 01054 remaining = ALLOC(int, n_entries); 01055 for (i = 0; i < n_entries; i++) { 01056 remaining[i] = i; 01057 } 01058 01059 util_srandom((long) seed); 01060 01061 next_entry = 0; 01062 for (; n_entries > 0; n_entries--) { 01063 next_value = util_random() % n_entries; 01064 permutation[next_entry++] = remaining[next_value]; 01065 for (j = next_value; j < n_entries - 1; j++) { 01066 remaining[j] = remaining[j + 1]; 01067 } 01068 } 01069 FREE(remaining); 01070 return permutation; 01071 }