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