00001 #include <float.h>
00002 #include <stdlib.h>
00003 #include <stdio.h>
00004 #include <math.h>
00005 #include <assert.h>
00006 #include "tm_tree.h"
00007 #include "tm_timings.h"
00008 #include "tm_bucket.h"
00009
00010 #if __CHARMC__
00011 #include "converse.h"
00012 #else
00013 #define CmiLog2 log2
00014 #endif
00015
00016 #define MIN(a,b) ((a)<(b)?(a):(b))
00017 #define MAX(a,b) ((a)>(b)?(a):(b))
00018 #undef DEBUG
00019
00020
00021 void free_list_child(tree_t *tree){
00022 int i;
00023 if(tree){
00024 for(i=0;i<tree->arity;i++){
00025 free_list_child(tree->child[i]);
00026 }
00027 }
00028 free(tree->child);
00029 if(tree->dumb)
00030 free(tree);
00031 }
00032
00033
00034
00035
00036 void free_tab_child(tree_t *tree){
00037 if(tree){
00038 free_tab_child(tree->tab_child);
00039 free(tree->tab_child);
00040 }
00041 }
00042
00043
00044
00045 void free_tree(tree_t *tree){
00046
00047 free_list_child(tree);
00048 free_tab_child(tree);
00049 free(tree);
00050 }
00051
00052 long int choose (long n,long k){
00053
00054 double res=1;
00055 int i;
00056 for(i=0;i<k;i++)
00057 res*=(double)(n-i)/(double)(k-i);
00058
00059 return (long int)res;
00060 }
00061
00062 void set_node(tree_t *node,tree_t ** child, int arity,tree_t *parent,int id,double val,tree_t *tab_child){
00063 static int uniq=0;
00064 node->child=child;
00065 node->arity=arity;
00066 node->tab_child=NULL;
00067 node->parent=parent;
00068 node->id=id;
00069 node->val=val;
00070 node->uniq=uniq++;
00071 node->dumb=0;
00072 }
00073
00074 void display_node(tree_t *node){
00075 printf("child : %p\narity : %d\nparent : %p\nid : %d\nval : %f\nuniq : %d\n\n" ,
00076 node->child,node->arity,node->parent,node->id,node->val,node->uniq);
00077 }
00078 void clone_tree(tree_t *new,tree_t *old){
00079 int i;
00080 new->child=old->child;
00081 new->arity=old->arity;
00082 new->parent=old->parent;
00083
00084 new->id=old->id;
00085 new->val=old->val;
00086 new->uniq=old->uniq;
00087 new->dumb=old->dumb;
00088 for(i=0;i<new->arity;i++)
00089 new->child[i]->parent=new;
00090 }
00091
00092
00093
00094 double *aggregate_obj_weight(tree_t *new_tab_node, double *tab, int M){
00095 int i,i1,id1;
00096 double *res;
00097
00098 if(!tab)
00099 return NULL;
00100
00101 res=(double*)malloc(M*sizeof(double));
00102
00103 for(i=0;i<M;i++){
00104 res[i]=0.0;
00105 for(i1=0;i1<new_tab_node[i].arity;i1++){
00106 id1=new_tab_node[i].child[i1]->id;
00107 res[i]+=tab[id1];
00108 }
00109 }
00110
00111 return res;
00112
00113 }
00114
00115
00116 double **aggregate_com_mat(tree_t *new_tab_node, double **tab, int M){
00117 int i,j,i1,j1,id1,id2;
00118 double **res;
00119
00120
00121
00122 res=(double**)malloc(M*sizeof(double*));
00123 for(i=0;i<M;i++)
00124 res[i]=(double*)malloc(M*sizeof(double));
00125
00126 for(i=0;i<M;i++){
00127 for(j=0;j<M;j++){
00128 if(i==j)
00129 res[i][j]=0;
00130 else{
00131 res[i][j]=0;
00132 for(i1=0;i1<new_tab_node[i].arity;i1++){
00133 id1=new_tab_node[i].child[i1]->id;
00134 for(j1=0;j1<new_tab_node[j].arity;j1++){
00135 id2=new_tab_node[j].child[j1]->id;
00136 res[i][j]+=tab[id1][id2];
00137
00138 }
00139 }
00140 }
00141 }
00142 }
00143
00144 return res;
00145
00146 }
00147
00148 void free_tab_double(double**tab,int N){
00149 int i;
00150 for(i=0;i<N;i++){
00151 free(tab[i]);
00152 }
00153 free(tab);
00154 }
00155
00156 void free_tab_int(int**tab,int N){
00157 int i;
00158 for(i=0;i<N;i++){
00159 free(tab[i]);
00160 }
00161 free(tab);
00162 }
00163
00164 void display_tab(double **tab,int N){
00165 int i,j;
00166 double line,total=0;;
00167 for(i=0;i<N;i++){
00168 line=0;
00169 for(j=0;j<N;j++){
00170 printf("%g ",tab[i][j]);
00171 line+=tab[i][j];
00172 }
00173 total+=line;
00174
00175 printf("\n");
00176 }
00177 printf("Total: %.2f\n",total);
00178 }
00179
00180
00181 double eval_grouping(double **tab,tree_t **cur_group,int arity,int N){
00182 double res=0;
00183 int i,k,j,id,id1,id2;
00184
00185
00186
00187 for(i=0;i<arity;i++){
00188 id=cur_group[i]->id;
00189
00190 for(k=0;k<N;k++){
00191
00192 res+=tab[k][id];
00193 }
00194 }
00195
00196 for(i=0;i<arity;i++){
00197 id1=cur_group[i]->id;
00198 for(j=0;j<arity;j++){
00199 id2=cur_group[j]->id;
00200
00201 res-=tab[id1][id2];
00202 }
00203 }
00204
00205 return res;
00206 }
00207
00208
00209
00210 group_list_t *new_group_list(tree_t **tab,double val,group_list_t *next){
00211 group_list_t *res;
00212 res=(group_list_t *)malloc(sizeof(group_list_t));
00213 res->tab=tab;
00214 res->val=val;
00215 res->next=next;
00216 res->sum_neighbour=0;
00217 return res;
00218 }
00219
00220
00221 void add_to_list(group_list_t *list,tree_t **cur_group, int arity, double val){
00222
00223 group_list_t *elem;
00224 int i;
00225 tree_t **tab;
00226
00227 tab=(tree_t **)malloc(sizeof(tree_t *)*arity);
00228
00229 for(i=0;i<arity;i++){
00230 tab[i]=cur_group[i];
00231
00232 }
00233
00234
00235 elem=new_group_list(tab,val,list->next);
00236 list->next=elem;
00237 list->val++;
00238 }
00239
00240
00241
00242 void list_all_possible_groups(double **tab,tree_t *tab_node,int id,int arity, int depth,
00243 tree_t **cur_group,int N,group_list_t *list){
00244 double val;
00245 int i;
00246
00247
00248
00249 if(depth==arity){
00250 val=eval_grouping(tab,cur_group,arity,N);
00251 add_to_list(list,cur_group,arity,val);
00252 return;
00253 }else if(N+depth>=arity+id){
00254
00255 for(i=id;i<N;i++){
00256 if(tab_node[i].parent)
00257 continue;
00258 cur_group[depth]=&tab_node[i];
00259
00260 list_all_possible_groups(tab,tab_node,i+1,arity,depth+1,cur_group,N,list);
00261 }
00262 }
00263 }
00264
00265
00266 void update_val(double **tab,tree_t *parent,int N){
00267 int i;
00268
00269 parent->val=eval_grouping(tab,parent->child,parent->arity,N);
00270
00271 for(i=0;i<parent->arity;i++){
00272
00273
00274
00275
00276
00277
00278
00279 }
00280
00281
00282
00283 }
00284
00285
00286 int independent_groups(group_list_t **selection,int d,group_list_t *elem,int arity){
00287 int i,j,k;
00288
00289 if(d==0)
00290 return 1;
00291
00292 for(i=0;i<arity;i++){
00293 for(j=0;j<d;j++){
00294 for(k=0;k<arity;k++){
00295 if(elem->tab[i]->id==selection[j]->tab[k]->id)
00296 return 0;
00297 }
00298 }
00299 }
00300
00301 return 1;
00302
00303
00304 }
00305
00306 void display_selection (group_list_t** selection,int M,int arity,double val){
00307 int i,j;
00308 for(i=0;i<M;i++){
00309 for(j=0;j<arity;j++)
00310 printf("%d ",selection[i]->tab[j]->id);
00311 printf("-- ");
00312 }
00313 printf(":%f\n",val);
00314
00315 }
00316
00317 void display_grouping (tree_t *father,int M,int arity,double val){
00318 int i,j;
00319 for(i=0;i<M;i++){
00320 for(j=0;j<arity;j++)
00321 printf("%d ",father[i].child[j]->id);
00322 printf("-- ");
00323 }
00324 printf(":%f\n",val);
00325
00326 }
00327
00328
00329 int recurs_select_independent_groups(group_list_t **tab,int i,int n,int arity,int d,int M,double val,double *best_val,group_list_t **selection,group_list_t **best_selection){
00330 group_list_t *elem;
00331
00332
00333
00334
00335 if(d==M){
00336
00337 if(val<*best_val){
00338 *best_val=val;
00339 for(i=0;i<M;i++)
00340 best_selection[i]=selection[i];
00341 return 1;
00342 }
00343 return 0;
00344 }
00345
00346 while(i<n){
00347 elem=tab[i];
00348 if(independent_groups(selection,d,elem,arity)){
00349
00350 selection[d]=elem;
00351 val+=elem->val;
00352 return recurs_select_independent_groups(tab,i+1,n,arity,d+1,M,val,best_val,selection,best_selection);
00353 }
00354 i++;
00355 }
00356 return 0;
00357 }
00358
00359
00360 int test_independent_groups(group_list_t **tab,int i,int n,int arity,int d,int M,double val,double *best_val,group_list_t **selection,group_list_t **best_selection){
00361 group_list_t *elem;
00362
00363 if(d==M){
00364
00365 return 1;
00366 }
00367
00368 while(i<n){
00369 elem=tab[i];
00370 if(independent_groups(selection,d,elem,arity)){
00371
00372 selection[d]=elem;
00373 val+=elem->val;
00374 return recurs_select_independent_groups(tab,i+1,n,arity,d+1,M,val,best_val,selection,best_selection);
00375 }
00376 i++;
00377 }
00378 return 0;
00379 }
00380
00381 void delete_group_list(group_list_t *list){
00382
00383 if(list){
00384 delete_group_list(list->next);
00385 free(list->tab);
00386 free(list);
00387 }
00388 }
00389
00390
00391 int group_list_id(const void* x1,const void* x2){
00392
00393 group_list_t *e1,*e2;
00394
00395 e1=*((group_list_t**)x1);
00396 e2=*((group_list_t**)x2);
00397
00398
00399 return e1->tab[0]->id<e2->tab[0]->id?-1:1;
00400 }
00401
00402 int group_list_asc(const void* x1,const void* x2){
00403
00404 group_list_t *e1,*e2;
00405
00406 e1=*((group_list_t**)x1);
00407 e2=*((group_list_t**)x2);
00408
00409
00410 return e1->val<e2->val?-1:1;
00411 }
00412
00413
00414 int group_list_dsc(const void* x1,const void* x2){
00415
00416 group_list_t *e1,*e2;
00417
00418 e1=*((group_list_t**)x1);
00419 e2=*((group_list_t**)x2);
00420
00421
00422 return e1->val>e2->val?-1:1;
00423 }
00424
00425
00426 int weighted_degree_asc(const void* x1,const void* x2){
00427
00428 group_list_t *e1,*e2;
00429
00430 e1=*((group_list_t**)x1);
00431 e2=*((group_list_t**)x2);
00432
00433
00434 return e1->wg>e2->wg?1:-1;
00435 }
00436
00437
00438 int weighted_degree_dsc(const void* x1,const void* x2){
00439
00440 group_list_t *e1,*e2;
00441
00442 e1=*((group_list_t**)x1);
00443 e2=*((group_list_t**)x2);
00444
00445
00446 return e1->wg>e2->wg?-1:1;
00447 }
00448
00449 int select_independent_groups(group_list_t **tab_group,int n,int arity,int M,double *best_val,group_list_t **best_selection,int bound,double max_duration){
00450 int i;
00451 group_list_t **selection;
00452 double val,duration;
00453 CLOCK_T time1,time0;
00454
00455
00456 selection=(group_list_t **)malloc(sizeof(group_list_t*)*M);
00457 CLOCK(time0);
00458 for(i=0;i<MIN(bound,n);i++){
00459 selection[0]=tab_group[i];
00460 val=tab_group[i]->val;
00461 recurs_select_independent_groups(tab_group,i+1,n,arity,1,M,val,best_val,selection,best_selection);
00462 if(i%5){
00463 CLOCK(time1);
00464 duration=CLOCK_DIFF(time1,time0);
00465 if(duration>max_duration){
00466 free(selection);
00467 return 1;
00468 }
00469 }
00470 }
00471
00472 free(selection);
00473
00474 #ifdef DEBUG
00475 display_selection(best_selection,M,arity,*best_val);
00476 #endif
00477 return 0;
00478 }
00479
00480 int select_independent_groups_by_largest_index(group_list_t **tab_group,int n,int arity,int M,double *best_val,group_list_t **best_selection,int bound,double max_duration){
00481 int i,nb_groups=0;
00482 group_list_t **selection;
00483 double val,duration;
00484 int dec;
00485 CLOCK_T time1,time0;
00486
00487 selection=(group_list_t **)malloc(sizeof(group_list_t*)*M);
00488 CLOCK(time0);
00489
00490 dec=MAX(n/10000,1);
00491 for(i=n-1;i>=0;i-=dec*dec){
00492 selection[0]=tab_group[i];
00493 val=tab_group[i]->val;
00494 nb_groups+=test_independent_groups(tab_group,i+1,n,arity,1,M,val,best_val,selection,best_selection);
00495
00496 if(nb_groups>=bound){
00497 free(selection);
00498 return 0;
00499 }
00500 if(i%5){
00501 CLOCK(time1);
00502 duration=CLOCK_DIFF(time1,time0);
00503 if(duration>max_duration){
00504 free(selection);
00505 return 1;
00506 }
00507 }
00508 }
00509
00510 free(selection);
00511 return 0;
00512 }
00513
00514 void list_to_tab(group_list_t *list,group_list_t **tab,int n){
00515 int i;
00516 for(i=0;i<n;i++){
00517 if(!list){
00518 fprintf(stderr,"Error not enough elements. Only %d on %d\n",i,n);
00519 exit(-1);
00520 }
00521 tab[n-i-1]=list;
00522 list=list->next;
00523 }
00524 if(list){
00525 fprintf(stderr,"Error too many elements\n");
00526 exit(-1);
00527 }
00528 }
00529
00530 void display_tab_group(group_list_t **tab, int n,int arity){
00531 int i,j;
00532 for(i=0;i<n;i++){
00533 for(j=0;j<arity;j++)
00534 printf("%d ",tab[i]->tab[j]->id);
00535 printf(": %.2f %.2f\n",tab[i]->val,tab[i]->wg);
00536 }
00537 }
00538
00539 int independent_tab(tree_t **tab1,tree_t **tab2,int n){
00540 int i,j;
00541 i=0;j=0;
00542 while((i<n)&&(j<n)){
00543 if(tab1[i]->id==tab2[j]->id)
00544 return 0;
00545 else if(tab1[i]->id>tab2[j]->id)
00546 j++;
00547 else
00548 i++;
00549 }
00550 return 1;
00551 }
00552
00553
00554
00555 void compute_weighted_degree(group_list_t **tab, int n,int arity){
00556 int i,j;
00557 for(i=0;i<n;i++)
00558 tab[i]->sum_neighbour=0;
00559 for(i=0;i<n;i++){
00560
00561 for(j=i+1;j<n;j++){
00562
00563 if(!independent_tab(tab[i]->tab,tab[j]->tab,arity)){
00564 tab[i]->sum_neighbour+=tab[j]->val;
00565 tab[j]->sum_neighbour+=tab[i]->val;
00566 }
00567 }
00568
00569 tab[i]->wg=tab[i]->sum_neighbour/tab[i]->val;
00570 if(tab[i]->sum_neighbour==0)
00571 tab[i]->wg=0;
00572
00573 }
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 void group(double **tab,tree_t *tab_node,tree_t *parent,int id,int arity, int n,double *best_val,tree_t **cur_group,int N){
00588 double val;
00589 int i;
00590
00591
00592
00593 if(n==arity){
00594
00595 val=eval_grouping(tab,cur_group,arity,N);
00596
00597 if(val<*best_val){
00598 *best_val=val;
00599 for(i=0;i<arity;i++){
00600 parent->child[i]=cur_group[i];
00601 }
00602 parent->arity=arity;
00603 }
00604 return;
00605 }
00606
00607
00608
00609
00610
00611 for(i=id+1;i<N;i++){
00612
00613 if(tab_node[i].parent)
00614 continue;
00615
00616 cur_group[n]=&tab_node[i];
00617
00618
00619 group(tab,tab_node,parent,i,arity,n+1,best_val,cur_group,N);
00620 }
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 void fast_group(double **tab,tree_t *tab_node,tree_t *parent,int id,int arity, int n,
00634 double *best_val,tree_t **cur_group,int N, int *nb_groups,int max_groups){
00635 double val;
00636 int i;
00637
00638
00639
00640
00641 if(n==arity){
00642 (*nb_groups)++;
00643
00644 val=eval_grouping(tab,cur_group,arity,N);
00645
00646 if(val<*best_val){
00647 *best_val=val;
00648 for(i=0;i<arity;i++){
00649 parent->child[i]=cur_group[i];
00650 }
00651 parent->arity=arity;
00652 }
00653 return;
00654 }
00655
00656
00657
00658
00659
00660 for(i=id+1;i<N;i++){
00661
00662 if(tab_node[i].parent)
00663 continue;
00664
00665 cur_group[n]=&tab_node[i];
00666
00667
00668
00669 fast_group(tab,tab_node,parent,i,arity,n+1,best_val,cur_group,N,nb_groups,max_groups);
00670 if(*nb_groups>max_groups)
00671 return;
00672 }
00673 }
00674
00675
00676
00677
00678 void fast_grouping(double **tab,tree_t *tab_node, tree_t *new_tab_node, int arity,int N, int M,long int k){
00679 tree_t **cur_group;
00680 int l,i;
00681 double best_val,val=0;
00682 int nb_groups;
00683
00684 cur_group=(tree_t**)malloc(sizeof(tree_t*)*arity);
00685 for(l=0;l<M;l++){
00686 best_val=DBL_MAX;
00687 nb_groups=0;
00688
00689
00690
00691 fast_group(tab,tab_node,&new_tab_node[l],-1,arity,0,&best_val,cur_group,N,&nb_groups,MAX(1,(int)(50-CmiLog2(k))-M/10));
00692 val+=best_val;
00693 for(i=0;i<new_tab_node[l].arity;i++){
00694 new_tab_node[l].child[i]->parent=&new_tab_node[l];
00695 }
00696 update_val(tab,&new_tab_node[l],N);
00697 }
00698
00699 free(cur_group);
00700
00701 printf("val=%f\n",val);
00702
00703
00704 #ifdef DEBUG
00705 display_grouping(new_tab_node,M,arity,val);
00706 #endif
00707 }
00708
00709
00710
00711
00712 int adjacency_asc(const void* x1,const void* x2){
00713
00714 adjacency_t *e1,*e2;
00715
00716 e1=((adjacency_t*)x1);
00717 e2=((adjacency_t*)x2);
00718
00719
00720 return e1->val<e2->val?-1:1;
00721 }
00722
00723
00724 int adjacency_dsc(const void* x1,const void* x2){
00725
00726 adjacency_t *e1,*e2;
00727
00728 e1=((adjacency_t*)x1);
00729 e2=((adjacency_t*)x2);
00730
00731
00732 return e1->val>e2->val?-1:1;
00733 }
00734 void super_fast_grouping(double **tab,tree_t *tab_node, tree_t *new_tab_node, int arity,int N, int M,int k){
00735 double val=0;
00736 adjacency_t *graph;
00737 int i,j,e,l,nb_groups;
00738 double duration;
00739
00740 assert(arity==2);
00741
00742 TIC;
00743 graph=(adjacency_t*)malloc(sizeof(adjacency_t)*((N*N-N)/2));
00744 e=0;
00745 for(i=0;i<N;i++){
00746 for(j=i+1;j<N;j++){
00747 graph[e].i=i;
00748 graph[e].j=j;
00749 graph[e].val=tab[i][j];
00750 e++;
00751 }
00752 }
00753 duration=TOC;
00754 printf("linearization=%fs\n",duration);
00755
00756
00757 assert(e==(N*N-N)/2);
00758 TIC;
00759 qsort(graph,e,sizeof(adjacency_t),adjacency_dsc);
00760 duration=TOC;
00761
00762 printf("sorting=%fs\n",duration);
00763
00764 TIC;
00765
00766 TIC;
00767 l=0;
00768 nb_groups=0;
00769 for(i=0;i<e&&l<M;i++){
00770 if(try_add_edge(tab,tab_node,&new_tab_node[l],arity,graph[i].i,graph[i].j,N,&nb_groups)){
00771 l++;
00772 }
00773 }
00774
00775 for(l=0;l<M;l++){
00776 update_val(tab,&new_tab_node[l],N);
00777 val+=new_tab_node[l].val;
00778 }
00779
00780 duration=TOC;
00781 printf("Grouping=%fs\n",duration);
00782
00783 printf("val=%f\n",val);
00784
00785 #ifdef DEBUG
00786 display_grouping(new_tab_node,M,arity,val);
00787 #endif
00788 }
00789
00790
00791
00792 double **build_cost_matrix(double **comm_matrix, double* obj_weight, double comm_speed, int N){
00793 double **res,avg;
00794 int i,j;
00795
00796 if(!obj_weight)
00797 return comm_matrix;
00798
00799 res=(double**)malloc(N*sizeof(double*));
00800 for(i=0;i<N;i++)
00801 res[i]=(double*)malloc(N*sizeof(double));
00802
00803 avg=0;
00804 for(i=0;i<N;i++)
00805 avg+=obj_weight[i];
00806 avg/=N;
00807
00808 printf("avg=%f\n",avg);
00809
00810 for(i=0;i<N;i++)
00811 for(j=0;j<N;j++)
00812 if(i==j)
00813 res[i][j]=0;
00814 else
00815 res[i][j]=1e-4*comm_matrix[i][j]/comm_speed-fabs(avg-(obj_weight[i]+obj_weight[j])/2);
00816
00817 return res;
00818
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831 void group_nodes(double **comm_matrix,tree_t *tab_node, tree_t *new_tab_node, int depth, int arity,int N, int M, double* obj_weigth, double comm_speed){
00832 tree_t **cur_group;
00833 int j,l,n;
00834 long int k;
00835 group_list_t list,**best_selection,**tab_group;
00836 double best_val,last_best;
00837 int timeout;
00838 double **tab;
00839 double duration;
00840
00841 TIC;
00842
00843
00844 tab=build_cost_matrix(comm_matrix,obj_weigth,comm_speed,N);
00845
00846
00847
00848 k=choose(N,arity);
00849 printf("Number of groups:%ld\n",k);
00850
00851 if(k>30000||depth>5){
00852 #ifdef DEBUG
00853 printf("Fast Grouping...\n");
00854 #endif
00855
00856 double duration;
00857
00858 TIC;
00859 if(arity<=2){
00860
00861 bucket_grouping(tab,tab_node,new_tab_node,arity,N,M,k);
00862 }else{
00863 fast_grouping(tab,tab_node,new_tab_node,arity,N,M,k);
00864 }
00865 duration=TOC;
00866
00867 printf("Fast grouping duration=%f\n",duration);
00868
00869
00870 }else{
00871 #ifdef DEBUG
00872 printf("Grouping nodes...\n");
00873 #endif
00874 list.next=NULL;
00875 list.val=0;
00876 cur_group=(tree_t**)malloc(sizeof(tree_t*)*arity);
00877 best_selection=(group_list_t **)malloc(sizeof(group_list_t*)*M);
00878
00879 list_all_possible_groups(tab,tab_node,0,arity,0,cur_group,N,&list);
00880 n=(int)list.val;
00881 assert(n==k);
00882 tab_group=(group_list_t**)malloc(sizeof(group_list_t)*n);
00883 list_to_tab(list.next,tab_group,n);
00884 #ifdef DEBUG
00885 printf("List to tab done\n");
00886 #endif
00887 best_val=DBL_MAX;
00888
00889
00890 timeout=select_independent_groups(tab_group,n,arity,M,&best_val,best_selection,1,0.1);
00891 #ifdef DEBUG
00892 if(timeout){
00893 printf("Packed mapping timeout!\n");
00894 }
00895 #endif
00896
00897 best_val/=1.001;
00898 #ifdef DEBUG
00899 printf("Packing computed\n");
00900 #endif
00901
00902 qsort(tab_group,n,sizeof(group_list_t*),group_list_asc);
00903 last_best=best_val;
00904 timeout=select_independent_groups(tab_group,n,arity,M,&best_val,best_selection,10,0.1);
00905 #ifdef DEBUG
00906 if(timeout){
00907 printf("Cost less first timeout!\n");
00908 }else if(last_best>best_val){
00909 printf("Cost less first Impoved solution\n");
00910 }
00911 printf("----\n");
00912 #endif
00913
00914 qsort(tab_group,n,sizeof(group_list_t*),group_list_dsc);
00915 last_best=best_val;
00916 timeout=select_independent_groups_by_largest_index(tab_group,n,arity,M,&best_val,best_selection,10,0.1);
00917 #ifdef DEBUG
00918 if(timeout){
00919 printf("Cost most last timeout!\n");
00920 }else if(last_best>best_val){
00921 printf("Cost most last impoved solution\n");
00922 }
00923 #endif
00924 if(n<10000){
00925
00926 #ifdef DEBUG
00927 printf("----WG----\n");
00928 #endif
00929 compute_weighted_degree(tab_group,n,arity);
00930 #ifdef DEBUG
00931 printf("Weigted degree computed\n");
00932 #endif
00933 qsort(tab_group,n,sizeof(group_list_t*),weighted_degree_dsc);
00934
00935 last_best=best_val;
00936 timeout=select_independent_groups(tab_group,n,arity,M,&best_val,best_selection,10,0.1);
00937 #ifdef DEBUG
00938 if(timeout){
00939 printf("WG timeout!\n");
00940 }else if(last_best>best_val){
00941 printf("WG impoved solution\n");
00942 }
00943 #endif
00944 }
00945
00946 qsort(best_selection,M,sizeof(group_list_t*),group_list_id);
00947
00948 for(l=0;l<M;l++){
00949 for(j=0;j<arity;j++){
00950 new_tab_node[l].child[j]=best_selection[l]->tab[j];
00951 new_tab_node[l].child[j]->parent=&new_tab_node[l];
00952 }
00953 new_tab_node[l].arity=arity;
00954
00955
00956 update_val(tab,&new_tab_node[l],N);
00957 }
00958
00959 delete_group_list((&list)->next);
00960 free(best_selection);
00961 free(tab_group);
00962 free(cur_group);
00963 }
00964
00965 if(tab!=comm_matrix)
00966 free_tab_double(tab,N);
00967
00968 duration=TOC;
00969 printf("Grouping done in %.4fs!\n",duration);
00970 }
00971
00972
00973
00974
00975
00976 void complete_com_mat(double ***tab,int N, int K){
00977 double **old_tab,**new_tab;
00978 int M,i,j;
00979
00980 old_tab=*tab;
00981
00982 M=N+K;
00983 new_tab=(double**)malloc(M*sizeof(double*));
00984 for(i=0;i<M;i++)
00985 new_tab[i]=(double*)malloc(M*sizeof(double));
00986
00987 *tab=new_tab;
00988 for(i=0;i<M;i++){
00989 for(j=0;j<M;j++){
00990 if((i<N)&&(j<N)){
00991 new_tab[i][j]=old_tab[i][j];
00992 }else{
00993 new_tab[i][j]=0;
00994 }
00995 }
00996 }
00997 }
00998
00999 void complete_obj_weight(double **tab,int N, int K){
01000 double *old_tab,*new_tab,avg;
01001 int M,i;
01002
01003 old_tab=*tab;
01004
01005 if(!old_tab)
01006 return;
01007
01008
01009 avg=0;
01010 for(i=0;i<N;i++)
01011 avg+=old_tab[i];
01012 avg/=N;
01013
01014
01015 M=N+K;
01016 new_tab=(double*)malloc(M*sizeof(double));
01017
01018 *tab=new_tab;
01019 for(i=0;i<M;i++){
01020 if(i<N){
01021 new_tab[i]=old_tab[i];
01022 }else{
01023 new_tab[i]=avg;
01024 }
01025 }
01026 }
01027
01028
01029
01030 void create_dumb_tree(tree_t *node,int depth,tm_topology_t *topology){
01031 tree_t **list_child;
01032 int arity,i;
01033
01034
01035 if(depth==topology->nb_levels-1){
01036 set_node(node,NULL,0,NULL,-1,0,NULL);
01037 return;
01038 }
01039
01040 arity=topology->arity[depth];
01041 assert(arity>0);
01042 list_child=(tree_t**)calloc(arity,sizeof(tree_t*));
01043 for(i=0;i<arity;i++){
01044 list_child[i]=(tree_t*)malloc(sizeof(tree_t));
01045 create_dumb_tree(list_child[i],depth+1,topology);
01046 list_child[i]->parent=node;
01047 list_child[i]->dumb=1;
01048 }
01049
01050 set_node(node,list_child,arity,NULL,-1,0,list_child[0]);
01051
01052 }
01053
01054 void complete_tab_node(tree_t **tab,int N, int K,int depth,tm_topology_t *topology){
01055 tree_t *old_tab,*new_tab;
01056 int M,i;
01057 if(K==0)
01058 return;
01059
01060 old_tab=*tab;
01061
01062
01063 M=N+K;
01064 new_tab=(tree_t*)malloc(M*sizeof(tree_t));
01065
01066 *tab=new_tab;
01067 for(i=0;i<M;i++){
01068 if((i<N)){
01069 clone_tree(&new_tab[i],&old_tab[i]);
01070 }else{
01071 create_dumb_tree(&new_tab[i],depth,topology);
01072 new_tab[i].id=i;
01073 }
01074 }
01075
01076
01077 free(old_tab);
01078 }
01079
01080
01081 void set_deb_tab_child(tree_t *tree, tree_t *child,int depth){
01082
01083 if(depth>0)
01084 set_deb_tab_child(tree->tab_child,child,depth-1);
01085 else
01086 tree->tab_child=child;
01087 }
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103 tree_t *build_level_topology(tree_t *tab_node,double **com_mat,int N,int arity,int depth,tm_topology_t *topology, double *obj_weight, double *comm_speed){
01104 int M;
01105 int K=0,i;
01106 tree_t *new_tab_node;
01107 double **new_com_mat;
01108 tree_t *res;
01109 int completed=0;
01110 double speed;
01111 double *new_obj_weight;
01112 if((depth==0)){
01113 if((N==1)&&(depth==0))
01114 return &tab_node[0];
01115 else{
01116 fprintf(stderr,"Error: matrix size: %d and depth:%d (should be 1 and -1 respectively)\n",N,depth);
01117 exit(-1);
01118 }
01119 }
01120
01121
01122
01123 if(N%arity!=0){
01124 K=arity*((N/arity)+1)-N;
01125
01126
01127
01128 complete_com_mat(&com_mat,N,K);
01129
01130 complete_obj_weight(&obj_weight,N,K);
01131
01132
01133 complete_tab_node(&tab_node,N,K,depth,topology);
01134 completed=1;
01135 N+=K;
01136 }
01137
01138
01139 M=N/arity;
01140 printf("Depth=%d\tnb_nodes=%d\tnb_groups=%d\tsize of groups(arity)=%d\n",depth,N,M,arity);
01141
01142
01143 new_tab_node=(tree_t*)malloc(sizeof(tree_t)*M);
01144
01145 for(i=0;i<M;i++){
01146 tree_t **list_child;
01147 list_child=(tree_t**)calloc(arity,sizeof(tree_t*));
01148 set_node(&new_tab_node[i],list_child,arity,NULL,i,0,tab_node);
01149 }
01150
01151
01152 if(comm_speed)
01153 speed=comm_speed[depth];
01154 else
01155 speed=-1;
01156 group_nodes(com_mat,tab_node,new_tab_node,depth,arity,N,M,obj_weight,speed);
01157
01158
01159 new_com_mat=aggregate_com_mat(new_tab_node,com_mat,M);
01160
01161 new_obj_weight=aggregate_obj_weight(new_tab_node,obj_weight,M);
01162
01163
01164 for(i=N-K;i<N;i++)
01165 tab_node[i].id=-1;
01166
01167
01168
01169
01170
01171
01172
01173 depth--;
01174 if(depth>0)
01175 arity = topology->arity[depth-1];
01176 else
01177 arity=1;
01178
01179 res = build_level_topology(new_tab_node,new_com_mat,M,arity,depth,topology,new_obj_weight,comm_speed);
01180
01181 set_deb_tab_child(res,tab_node,depth);
01182
01183
01184 if(completed){
01185 free_tab_double(com_mat,N);
01186 free(obj_weight);
01187 }
01188 free_tab_double(new_com_mat,M);
01189 free(new_obj_weight);
01190
01191 return res;
01192 }
01193
01194
01195
01196 double speed(int depth){
01197
01198
01199
01200
01201 double tab[5]={100000,10000,1000,500,10};
01202
01203 return 1.0/tab[depth];
01204
01205
01206
01207 }
01208
01209 tree_t * build_tree_from_topology(tm_topology_t *topology,double **tab,int N,double *obj_weight, double *comm_speed){
01210 int depth,i;
01211 tree_t *res,*tab_node;
01212
01213
01214 tab_node=(tree_t*)malloc(sizeof(tree_t)*N);
01215 for(i=0;i<N;i++)
01216 set_node(&tab_node[i],NULL,0,NULL,i,0,NULL);
01217
01218
01219 depth = topology->nb_levels -1;
01220 printf("nb_levels=%d\n",depth+1);
01221
01222 res = build_level_topology(tab_node,tab,N,topology->arity[depth-1],depth,topology, obj_weight, comm_speed);
01223 printf("Build tree done!\n");
01224 return res;
01225 }