00001
00002
00003
00004
00005
00006
00007
00008 #include <math.h>
00009 #include <stdlib.h>
00010 #include "RefineTopoLB.decl.h"
00011
00012 #include "RefineTopoLB.h"
00013
00014 #define alpha PER_MESSAGE_SEND_OVERHEAD_DEFAULT
00015 #define beta PER_BYTE_SEND_OVERHEAD_DEFAULT
00016 #define DEG_THRES 0.50
00017 #define EPSILON -0.001
00018
00019 #define _lb_debug_on 0
00020 #define _lb_debug2_on 0
00021 #define _make_new_grouping_ 0
00022 #define _USE_MAX_HOPBYTES_ 1
00023
00024 CreateLBFunc_Def(RefineTopoLB,"TopoLB: Balance objects based on the network topology")
00025
00026
00027 RefineTopoLB::RefineTopoLB(const CkLBOptions &opt) : TopoLB (opt)
00028 {
00029 lbname = "RefineTopoLB";
00030 if (CkMyPe () == 0) {
00031 CkPrintf ("[%d] RefineTopoLB created\n",CkMyPe());
00032 }
00033 }
00034
00035 CmiBool RefineTopoLB::QueryBalanceNow (int _step)
00036 {
00037 return CmiTrue;
00038 }
00039
00040 void RefineTopoLB :: work(LDStats *stats)
00041 {
00042 int i, j;
00043 int n_pes = stats->nprocs();
00044
00045 if (_lb_args.debug() >= 2) {
00046 CkPrintf("In TopoLB Strategy...\n");
00047 }
00048
00049
00050 int proc;
00051 for (proc = 0; proc < n_pes; proc++) {
00052 if (stats->procs[proc].available)
00053 break;
00054 }
00055
00056 if (proc == n_pes) {
00057 CmiAbort ("TopoLB: no available processors!");
00058 }
00059
00060 removeNonMigratable(stats, n_pes);
00061
00062 if(_lb_debug_on) {
00063 CkPrintf("Num of procs: %d\n", n_pes);
00064 CkPrintf("Num of objs: %d\n", stats->n_objs);
00065 }
00066
00067
00068 LBtopoFn topofn;
00069 topofn = LBTopoLookup(_lbtopo);
00070 if (topofn == NULL)
00071 {
00072 char str[1024];
00073 CmiPrintf("TopoLB> Fatal error: Unknown topology: %s. Choose from:\n", _lbtopo);
00074 printoutTopo();
00075 sprintf(str, "TopoLB> Fatal error: Unknown topology: %s", _lbtopo);
00076 CmiAbort(str);
00077 }
00078 topo = topofn(n_pes);
00079
00080 if(_lb_debug_on)
00081 CkPrintf("before computing partitions...\n");
00082
00083 int *newmap = new int[stats->n_objs];
00084 if(_make_new_grouping_)
00085 computePartitions(stats, n_pes, newmap);
00086 else
00087 {
00088 for(int i=0;i<stats->n_objs;i++)
00089 {
00090 newmap[i]=stats->from_proc[i];
00091 }
00092 }
00093
00094 if(_lb_debug_on)
00095 CkPrintf("before allocating dataStructures...\n");
00096 allocateDataStructures(n_pes);
00097 if(_lb_debug_on)
00098 CkPrintf("before initizlizing dataStructures...\n");
00099 initDataStructures(stats, n_pes, newmap);
00100 if(_lb_debug_on)
00101 CkPrintf("After initizlizing dataStructures...\n");
00102
00103 for(i = 0; i < n_pes; i++)
00104 assign[i]=i;
00105
00106
00107
00108 if(_lb_debug_on)
00109 printDataStructures(n_pes, stats->n_objs,newmap);
00110
00111 bool *swapdone=new bool[n_pes];
00112 for(i = 0; i < n_pes; i++)
00113 swapdone[i]=false;
00114
00115
00116
00117
00118
00119
00120 double totalGain=0;
00121 for(i = 0; i < n_pes; i++)
00122 {
00123
00124 if(_USE_MAX_HOPBYTES_)
00125 {
00126 updateCommUA(n_pes);
00127 }
00128 int cpart=-1;
00129 double maxComm=-1;
00130 for(j = 0; j < n_pes; j++)
00131 {
00132 if(swapdone[j]) continue;
00133 if(commUA[j]>maxComm)
00134 {
00135 maxComm=commUA[j];
00136 cpart=j;
00137 }
00138 }
00139 CmiAssert(cpart!=-1);
00140
00141
00142 int swapcpart=-1;
00143 double gainMax=-1;
00144 double gain=-1;;
00145
00146 for(j = 0; j < n_pes; j++)
00147 {
00148 if(j==cpart)
00149 continue;
00150
00151 gain=findSwapGain(j, cpart, n_pes);
00152
00153
00154 if(gain>gainMax && gain>0)
00155 {
00156 gainMax=gain;
00157 swapcpart=j;
00158 }
00159 }
00160 if(swapcpart==-1)
00161 {
00162 swapdone[cpart]=true;
00163 continue;
00164 }
00165 totalGain+=gainMax;
00166 CmiAssert(swapcpart!=-1);
00167
00168
00169 int temp=assign[cpart];
00170 assign[cpart]=assign[swapcpart];
00171 assign[swapcpart]=temp;
00172 swapdone[cpart]=true;
00173
00174
00175
00176
00177 }
00178
00179 for(i=0;i<stats->n_objs;i++)
00180 {
00181 stats->to_proc[i]= assign[newmap[i]];
00182 }
00183 if(_lb_debug2_on)
00184 {
00185
00186 double hbval1=getHopBytesNew(NULL, n_pes);
00187 CkPrintf(" Original hopBytes : %lf Avg comm hops: %lf\n", hbval1,hbval1/total_comm);
00188 double hbval2=getHopBytesNew(assign, n_pes);
00189 CkPrintf(" Resulting hopBytes : %lf Avg comm hops: %lf\n", hbval2,hbval2/total_comm);
00190 CkPrintf(" Percentage gain %.2lf\n",(hbval1-hbval2)*100/hbval1);
00191 CkPrintf("\n");
00192 }
00193 freeDataStructures(n_pes);
00194 delete[] newmap;
00195 delete[] swapdone;
00196 }
00197
00198 double RefineTopoLB::findSwapGain(int cpart1, int cpart2, int n_pes)
00199 {
00200 double oldvalue=0;
00201 int proc1=assign[cpart1];
00202 int proc2=assign[cpart2];
00203 int proci=-1;
00204
00205 for(int i = 0; i < n_pes; i++)
00206 {
00207 proci=assign[i];
00208 if(i!=cpart1 && i!=cpart2)
00209 {
00210
00211
00212 oldvalue+=(comm[cpart1][i]-comm[cpart2][i])*(dist[proc1][proci]-dist[proc2][proci]);
00213
00214 }
00215 }
00216 return oldvalue;
00217 }
00218
00219 double RefineTopoLB::getCpartHopBytes(int cpart, int proc, int count)
00220 {
00221 double totalHB=0;
00222 for(int i=0;i<count;i++)
00223 {
00224 if(assign[i]==proc)
00225 {
00226 totalHB+=comm[cpart][i]*dist[proc][assign[cpart]];
00227 }
00228 else
00229 {
00230 totalHB+=comm[cpart][i]*dist[proc][assign[i]];
00231 }
00232 }
00233 return totalHB;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 void RefineTopoLB::updateCommUA(int count)
00259 {
00260 int i,j;
00261 for(i=0;i<count;i++)
00262 {
00263 commUA[i]=0;
00264 for(j=0;j<count;j++)
00265 commUA[i]+=comm[i][j]*dist[assign[i]][assign[j]];
00266 }
00267 }
00268
00269 #include "RefineTopoLB.def.h"