00001
00006
00007 #include "converse.h"
00008
00009
00010
00011
00012 #include "MetaBalancer.h"
00013 #include "topology.h"
00014
00015 #include "limits.h"
00016 #include <limits>
00017 #include <algorithm>
00018
00019 #define VEC_SIZE 50
00020 #define IMB_TOLERANCE 1.1
00021 #define OUTOFWAY_TOLERANCE 2
00022 #define UTILIZATION_THRESHOLD 0.7
00023 #define NEGLECT_IDLE 2 // Should never be == 1
00024 #define MIN_STATS 6
00025 #define STATS_COUNT 29 // The number of stats collected during reduction
00026
00027 #define MAXDOUBLE std::numeric_limits<double>::max()
00028
00029 #define DEBAD(x)
00030 #define DEBADDETAIL(x)
00031 #define EXTRA_FEATURE 0
00032
00033 using std::min;
00034 using std::max;
00035
00036 CkReductionMsg* lbDataCollection(int nMsg, CkReductionMsg** msgs) {
00037 double *lb_data;
00038 lb_data = (double*)msgs[0]->getData();
00039 for (int i = 1; i < nMsg; i++) {
00040 CkAssert(msgs[i]->getSize() == STATS_COUNT*sizeof(double));
00041 if (msgs[i]->getSize() != STATS_COUNT*sizeof(double)) {
00042 CkPrintf("Error!!! Reduction not correct. Msg size is %d\n",
00043 msgs[i]->getSize());
00044 CkAbort("Incorrect Reduction size in MetaBalancer\n");
00045 }
00046 double* m = (double *)msgs[i]->getData();
00047 lb_data[NUM_PROCS] += m[NUM_PROCS];
00048 lb_data[TOTAL_LOAD] += m[TOTAL_LOAD];
00049 lb_data[MAX_LOAD] = max(m[MAX_LOAD], lb_data[MAX_LOAD]);
00050 lb_data[MIN_LOAD] = min(m[MIN_LOAD], lb_data[MIN_LOAD]);
00051 lb_data[IDLE_TIME] += m[IDLE_TIME];
00052 lb_data[UTILIZATION] = min(m[UTILIZATION], lb_data[UTILIZATION]);
00053 lb_data[MAX_UTIL] = max(m[MAX_UTIL], lb_data[MAX_UTIL]);
00054 lb_data[TOTAL_LOAD_W_BG] += m[TOTAL_LOAD_W_BG];
00055 lb_data[MIN_BG] = min(m[MIN_BG], lb_data[MIN_BG]);
00056 lb_data[MAX_LOAD_W_BG] = max(m[MAX_LOAD_W_BG], lb_data[MAX_LOAD_W_BG]);
00057 lb_data[TOTAL_KBYTES] += m[TOTAL_KBYTES];
00058 lb_data[TOTAL_KMSGS] += m[TOTAL_KMSGS];
00059 lb_data[WITHIN_PE_KBYTES] += m[WITHIN_PE_KBYTES];
00060 lb_data[OUTSIDE_PE_KBYTES] += m[OUTSIDE_PE_KBYTES];
00061 lb_data[SUM_COMM_NEIGHBORS] += m[SUM_COMM_NEIGHBORS];
00062 lb_data[MAX_COMM_NEIGHBORS] = max(m[MAX_COMM_NEIGHBORS], lb_data[MAX_COMM_NEIGHBORS]);
00063 lb_data[SUM_OBJ_COUNT] += m[SUM_OBJ_COUNT];
00064 lb_data[MAX_OBJ_COUNT] = max(m[MAX_OBJ_COUNT], lb_data[MAX_OBJ_COUNT]);
00065 lb_data[MIN_OBJ_LOAD] = min(m[MIN_OBJ_LOAD], lb_data[MIN_OBJ_LOAD]);
00066 lb_data[SUM_OBJ_LOAD] += m[SUM_OBJ_LOAD];
00067 lb_data[MAX_OBJ_LOAD] = max(m[MAX_OBJ_LOAD], lb_data[MAX_OBJ_LOAD]);
00068 lb_data[SUM_HOPS] += m[SUM_HOPS];
00069 lb_data[SUM_HOP_KBYTES] += m[SUM_HOP_KBYTES];
00070 lb_data[MAX_ITER_TIME] = max(m[MAX_ITER_TIME], lb_data[MAX_ITER_TIME]);
00071 lb_data[LOAD_STDEV2] += m[LOAD_STDEV2];
00072 lb_data[LOAD_SKEWNESS] += m[LOAD_SKEWNESS];
00073 lb_data[LOAD_KURTOSIS] += m[LOAD_KURTOSIS];
00074 lb_data[TOTAL_OVERLOADED_PES] += m[TOTAL_OVERLOADED_PES];
00075
00076 if (m[ITER_NO] != lb_data[ITER_NO]) {
00077 CkPrintf("Error!!! Reduction is intermingled between iteration %lf \
00078 and %lf\n", lb_data[ITER_NO], m[ITER_NO]);
00079 CkAbort("Intermingling iterations in MetaBalancer\n");
00080 }
00081 }
00082 return CkReductionMsg::buildNew(msgs[0]->getSize(), NULL, msgs[0]->getReducer(), msgs[0]);
00083 }
00084
00085 CkReduction::reducerType lbDataCollectionType;
00086 void registerLBDataCollection(void) {
00087 lbDataCollectionType = CkReduction::addReducer(lbDataCollection, true, "lbDataCollection");
00088 }
00089
00090 CkGroupID _metalb;
00091 CkGroupID _metalbred;
00092
00093 CkpvDeclare(int, metalbInited);
00095 double _nobj_timer = 10.0;
00096
00097
00098 MetaLBInit::MetaLBInit(CkArgMsg *m) {
00099 #if CMK_LBDB_ON
00100 if (_lb_args.metaLbOn()) {
00101 _metalbred = CProxy_MetaBalancerRedn::ckNew();
00102 _metalb = CProxy_MetaBalancer::ckNew();
00103 }
00104 #endif
00105 delete m;
00106 }
00107
00108
00109 void _metabalancerInit() {
00110 _registerCommandLineOpt("+MetaLBNoObjTimer");
00111 CkpvInitialize(int, metalbInited);
00112 CkpvAccess(metalbInited) = 0;
00113 char **argv = CkGetArgv();
00114 CmiGetArgDoubleDesc(argv, "+MetaLBNoObjTimer", &_nobj_timer,
00115 "Time in seconds before triggering reduction for no objs");
00116 }
00117
00118 void MetaBalancer::initnodeFn() {
00119 }
00120
00121
00122 void MetaBalancer::init(void) {
00123 lbdatabase = (LBDatabase *)CkLocalBranch(_lbdb);
00124 CkpvAccess(metalbInited) = 1;
00125 total_load_vec.resize(VEC_SIZE, 0.0);
00126 total_count_vec.resize(VEC_SIZE, 0);
00127 max_load_vec.resize(VEC_SIZE, 0.0);
00128 min_load_vec.resize(VEC_SIZE, MAXDOUBLE);
00129 prev_idle = 0.0;
00130 prev_bytes = prev_msgs = 0;
00131 prev_outsidepemsgs = prev_outsidepebytes = 0;
00132 prev_hops = prev_hopbytes = 0;
00133 prev_avg_load = 0;
00134 alpha_beta_cost_to_load = 1.0;
00135 chare_pup_size = 0;
00136
00137 metaRdnGroup = (MetaBalancerRedn*)CkLocalBranch(_metalbred);
00138
00139 adaptive_lbdb.lb_iter_no = -1;
00140
00141
00142 adaptive_struct.tentative_period = INT_MAX;
00143 adaptive_struct.final_lb_period = INT_MAX;
00144 adaptive_struct.lb_calculated_period = INT_MAX;
00145 adaptive_struct.lb_iteration_no = -1;
00146 adaptive_struct.finished_iteration_no = -1;
00147 adaptive_struct.global_max_iter_no = 0;
00148 adaptive_struct.tentative_max_iter_no = -1;
00149 adaptive_struct.in_progress = false;
00150 adaptive_struct.lb_strategy_cost = 0.0;
00151 adaptive_struct.lb_migration_cost = 0.0;
00152 adaptive_struct.lb_msg_send_no = 0;
00153 adaptive_struct.lb_msg_recv_no = 0;
00154 adaptive_struct.total_syncs_called = 0;
00155 adaptive_struct.last_lb_type = -1;
00156
00157
00158
00159
00160
00161
00162
00163 lb_in_progress = false;
00164
00165 is_prev_lb_refine = -1;
00166 if (_lb_args.metaLbOn()) {
00167 periodicCall((void *) this);
00168 }
00169 if (_lb_args.metaLbModelDir() != NULL) {
00170 current_balancer = -1;
00171 if (CkMyPe() == 0) {
00172 srand(time(NULL));
00173 rFmodel = new ForestModel;
00174 rFmodel->readModel(_lb_args.metaLbModelDir());
00175 }
00176 }
00177 }
00178
00179 void MetaBalancer::pup(PUP::er& p) {
00180 if (p.isUnpacking()) {
00181 lbdatabase = (LBDatabase *)CkLocalBranch(_lbdb);
00182 metaRdnGroup = (MetaBalancerRedn*)CkLocalBranch(_metalbred);
00183 }
00184 p|prev_idle;
00185 p|alpha_beta_cost_to_load;
00186 p|is_prev_lb_refine;
00187 p|lb_in_progress;
00188 p|prev_bytes;
00189 p|prev_msgs;
00190 p|prev_outsidepemsgs;
00191 p|prev_outsidepebytes;
00192 p|prev_hops;
00193 p|prev_hopbytes;
00194 p|prev_avg_load;
00195 p|chare_pup_size;
00196 }
00197
00198
00199 void MetaBalancer::ResumeClients() {
00200
00201 adaptive_lbdb.history_data.clear();
00202
00203 adaptive_struct.tentative_period = INT_MAX;
00204 adaptive_struct.final_lb_period = INT_MAX;
00205 adaptive_struct.lb_calculated_period = INT_MAX;
00206 adaptive_struct.lb_iteration_no = -1;
00207 adaptive_struct.finished_iteration_no = -1;
00208 adaptive_struct.global_max_iter_no = 0;
00209 adaptive_struct.tentative_max_iter_no = -1;
00210 adaptive_struct.in_progress = false;
00211
00212
00213 adaptive_struct.lb_strategy_cost = 0.0;
00214 adaptive_struct.lb_migration_cost = 0.0;
00215 adaptive_struct.lb_msg_send_no = 0;
00216 adaptive_struct.lb_msg_recv_no = 0;
00217 adaptive_struct.total_syncs_called = 0;
00218
00219 prev_idle = 0.0;
00220 prev_bytes = prev_msgs = 0;
00221 prev_outsidepemsgs = prev_outsidepebytes = 0;
00222 prev_hops = prev_hopbytes = 0;
00223 if (lb_in_progress) {
00224 lbdb_no_obj_callback.clear();
00225 lb_in_progress = false;
00226 }
00227 HandleAdaptiveNoObj();
00228 }
00229
00230 int MetaBalancer::get_iteration() {
00231 return adaptive_struct.lb_iteration_no;
00232 }
00233
00234 int MetaBalancer::get_finished_iteration() {
00235 return adaptive_struct.finished_iteration_no;
00236 }
00237
00238 void MetaBalancer::AdjustCountForNewContributor(int it_n) {
00239 #if CMK_LBDB_ON
00240 int index;
00241
00242
00243
00244
00245
00246 for (int i = (get_finished_iteration()+1); i <= it_n; i++) {
00247 index = i % VEC_SIZE;
00248 total_count_vec[index]++;
00249 }
00250 #endif
00251 }
00252
00253 void MetaBalancer::AdjustCountForDeadContributor(int it_n) {
00254 #if CMK_LBDB_ON
00255 int index;
00256
00257
00258
00259 for (int i = (get_finished_iteration() + 1); i <= it_n; i++) {
00260 index = i % VEC_SIZE;
00261 total_count_vec[index]--;
00262 }
00263
00264
00265 for (int i = (it_n + 1); i <= adaptive_struct.lb_iteration_no; i++) {
00266 index = i % VEC_SIZE;
00267
00268
00269 if (total_count_vec[index] == (lbdatabase->getLBDB()->ObjDataCount() - 1)){
00270 ContributeStats(i);
00271 }
00272 }
00273 #endif
00274 }
00275
00276 void MetaBalancer::SetCharePupSize(size_t psize) {
00277
00278
00279 chare_pup_size = psize;
00280 }
00281
00282 bool MetaBalancer::AddLoad(int it_n, double load) {
00283 #if CMK_LBDB_ON
00284 int index = it_n % VEC_SIZE;
00285 total_count_vec[index]++;
00286 adaptive_struct.total_syncs_called++;
00287 DEBADDETAIL(("At PE %d Total contribution for iteration %d is %d \
00288 total objs %d\n", CkMyPe(), it_n, total_count_vec[index],
00289 lbdatabase->getLBDB()->ObjDataCount()));
00290
00291 if (it_n <= adaptive_struct.finished_iteration_no) {
00292 CkAbort("Error!! Received load for iteration that has contributed\n");
00293 }
00294 if (it_n > adaptive_struct.lb_iteration_no) {
00295 adaptive_struct.lb_iteration_no = it_n;
00296 }
00297 total_load_vec[index] += load;
00298 if (load > max_load_vec[index]) {
00299 max_load_vec[index] = load;
00300 }
00301 if (load < min_load_vec[index]) {
00302 min_load_vec[index] = load;
00303 }
00304 if (total_count_vec[index] > lbdatabase->getLBDB()->ObjDataCount()) {
00305 CkPrintf("iteration %d received %d contributions and expected %d\n", it_n,
00306 total_count_vec[index], lbdatabase->getLBDB()->ObjDataCount());
00307 CkAbort("Abort!!! Received more contribution");
00308 }
00309 if (total_count_vec[index] == lbdatabase->getLBDB()->ObjDataCount()){
00310 ContributeStats(it_n);
00311 }
00312 #endif
00313 return true;
00314 }
00315
00316 void MetaBalancer::ContributeStats(int it_n) {
00317 #if CMK_LBDB_ON
00318 int index = it_n % VEC_SIZE;
00319
00320 double idle_time, bg_walltime, cpu_bgtime;
00321 lbdatabase->IdleTime(&idle_time);
00322 lbdatabase->BackgroundLoad(&bg_walltime, &cpu_bgtime);
00323
00324 int bytes, msgs, outsidepemsgs, outsidepebytes, num_nghbors, hops, hopbytes;
00325 bytes = msgs = outsidepemsgs = outsidepebytes = num_nghbors = hops = hopbytes = 0;
00326 if(_lb_args.traceComm())
00327 lbdatabase->getLBDB()->GetCommInfo(bytes, msgs, outsidepemsgs,
00328 outsidepebytes, num_nghbors, hops, hopbytes);
00329
00330
00331 int sync_for_bg = adaptive_struct.total_syncs_called +
00332 lbdatabase->getLBDB()->ObjDataCount();
00333 bg_walltime = bg_walltime * lbdatabase->getLBDB()->ObjDataCount() / sync_for_bg;
00334
00335 if (it_n < NEGLECT_IDLE) {
00336 prev_idle = idle_time;
00337 }
00338 idle_time -= prev_idle;
00339
00340
00341
00342 int total_countable_syncs = adaptive_struct.total_syncs_called +
00343 (1 - NEGLECT_IDLE) * lbdatabase->getLBDB()->ObjDataCount();
00344 if (total_countable_syncs != 0) {
00345 idle_time = idle_time * lbdatabase->getLBDB()->ObjDataCount() / total_countable_syncs;
00346 }
00347
00348 double lb_data[STATS_COUNT];
00349 lb_data[0] = it_n;
00350 lb_data[NUM_PROCS] = 1;
00351 lb_data[TOTAL_LOAD] = total_load_vec[index];
00352 lb_data[MAX_LOAD] = total_load_vec[index];
00353 lb_data[MIN_LOAD] = total_load_vec[index];
00354
00355 if (total_load_vec[index] == 0.0) {
00356 lb_data[IDLE_TIME] = 0.0;
00357 lb_data[UTILIZATION] = 0.0;
00358 lb_data[MAX_UTIL] = 0.0;
00359 } else {
00360 lb_data[IDLE_TIME] = total_load_vec[index]/(idle_time + total_load_vec[index]);
00361 lb_data[UTILIZATION] = total_load_vec[index]/(idle_time + total_load_vec[index]);
00362 lb_data[MAX_UTIL] = total_load_vec[index]/(idle_time + total_load_vec[index]);
00363 }
00364 lb_data[TOTAL_LOAD_W_BG] = lb_data[TOTAL_LOAD] + bg_walltime;
00365 lb_data[MIN_BG] = lb_data[TOTAL_LOAD_W_BG];
00366 lb_data[MAX_LOAD_W_BG] = lb_data[TOTAL_LOAD_W_BG];
00367 lb_data[TOTAL_KBYTES] = ((double) bytes/1024.0);
00368 lb_data[TOTAL_KMSGS] = ((double) msgs/1024.0);
00369 lb_data[WITHIN_PE_KBYTES] = ((double) outsidepemsgs/1024.0);
00370 lb_data[OUTSIDE_PE_KBYTES] = ((double) outsidepebytes/1024.0);
00371 lb_data[SUM_COMM_NEIGHBORS] = num_nghbors;
00372 lb_data[MAX_COMM_NEIGHBORS] = 0;
00373 lb_data[SUM_OBJ_COUNT] = lbdatabase->getLBDB()->ObjDataCount();
00374 lb_data[MAX_OBJ_COUNT] = lb_data[SUM_OBJ_COUNT];
00375 lb_data[SUM_OBJ_LOAD] = total_load_vec[index];
00376 lb_data[MAX_OBJ_LOAD] = max_load_vec[index];
00377 lb_data[MIN_OBJ_LOAD] = min_load_vec[index];
00378 lb_data[LOAD_STDEV2] = (total_load_vec[index] - prev_avg_load)*
00379 (total_load_vec[index] - prev_avg_load);
00380 lb_data[LOAD_SKEWNESS] = (total_load_vec[index] - prev_avg_load)*
00381 (total_load_vec[index] - prev_avg_load) *
00382 (total_load_vec[index] - prev_avg_load);
00383 lb_data[LOAD_KURTOSIS] = lb_data[LOAD_STDEV2]*lb_data[LOAD_STDEV2];
00384 lb_data[TOTAL_OVERLOADED_PES] = (total_load_vec[index] > prev_avg_load) ? 1 : 0;
00385 lb_data[SUM_HOPS] = 0;
00386 lb_data[SUM_HOP_KBYTES] = 0;
00387 if (msgs > 0) {
00388 lb_data[SUM_HOPS] = (double) hops;
00389 lb_data[SUM_HOP_KBYTES] = ((double) hopbytes/1024.0);
00390 }
00391 lb_data[MAX_ITER_TIME] = total_load_vec[index] + idle_time;
00392
00393 total_load_vec[index] = 0.0;
00394 total_count_vec[index] = 0;
00395 max_load_vec[index] = 0.0;
00396 min_load_vec[index] = MAXDOUBLE;
00397
00398 adaptive_struct.finished_iteration_no = it_n;
00399
00400 DEBADDETAIL(("[%d] sends total load %lf idle time %lf utilization %lf at iter %d\n",
00401 CkMyPe(), total_load_vec[index], idle_time,
00402 lb_data[5], adaptive_struct.finished_iteration_no));
00403
00404 CkCallback cb(CkReductionTarget(MetaBalancer, ReceiveMinStats),
00405 thisProxy[0]);
00406 contribute(STATS_COUNT*sizeof(double), lb_data, lbDataCollectionType, cb);
00407
00408 #endif
00409 }
00410
00411 void MetaBalancer::ReceiveMinStats(double *load, int n) {
00412
00413 CmiAssert(n == STATS_COUNT);
00414 double pe_count = load[NUM_PROCS];
00415 double avg_load = load[TOTAL_LOAD]/load[NUM_PROCS];
00416 double max_load = load[MAX_LOAD];
00417 double min_load = load[MIN_LOAD];
00418 double avg_utilization = load[IDLE_TIME]/load[NUM_PROCS];
00419 double min_utilization = load[UTILIZATION];
00420 int iteration_n = (int) load[ITER_NO];
00421 double avg_load_bg = load[TOTAL_LOAD_W_BG]/load[NUM_PROCS];
00422 double min_load_bg = load[MIN_BG];
00423 double max_load_bg = load[MAX_LOAD_W_BG];
00424 int total_objs = (int) load[SUM_OBJ_COUNT];
00425 double total_Kbytes = load[TOTAL_KBYTES];
00426 double total_Kmsgs = load[TOTAL_KMSGS];
00427 double total_outsidepeKmsgs = load[WITHIN_PE_KBYTES];
00428 double total_outsidepeKbytes = load[OUTSIDE_PE_KBYTES];
00429 double avg_bg = avg_load_bg - avg_load;
00430 double avg_comm_neighbors = load[SUM_COMM_NEIGHBORS]/total_objs;
00431 double max_comm_neighbors = load[MAX_COMM_NEIGHBORS];
00432 double avg_obj_load = load[SUM_OBJ_LOAD]/total_objs;
00433 double min_obj_load = load[MIN_OBJ_LOAD];
00434 double max_obj_load = load[MAX_OBJ_LOAD];
00435 double avg_hops = load[SUM_HOPS]/(total_Kmsgs*1024.0);
00436 double avg_hop_Kbytes = load[SUM_HOP_KBYTES]/(total_Kmsgs*1024.0);
00437 double standard_dev = sqrt(load[LOAD_STDEV2]/load[NUM_PROCS]);
00438 double skewness = load[LOAD_SKEWNESS]/(load[NUM_PROCS] * standard_dev * standard_dev *
00439 standard_dev);
00440 double kurtosis = load[LOAD_KURTOSIS]/(load[NUM_PROCS] * standard_dev * standard_dev *
00441 standard_dev * standard_dev) - 3;
00442 int ovld_pes = (int) load[TOTAL_OVERLOADED_PES];
00443 double max_utilization = load[MAX_UTIL];
00444 double app_iteration_time = load[MAX_ITER_TIME];
00445
00446
00447 double pe_imbalance = max_load/avg_load;
00448 double pe_load_std_frac = standard_dev/avg_load;
00449 double pe_with_bg_imb = max_load_bg/avg_load_bg;
00450 double bg_load_frac = avg_bg/avg_load;
00451 double pe_gain = max_load - avg_load;
00452 double internal_bytes_frac = (total_Kbytes-total_outsidepeKbytes)/total_Kbytes;
00453 double comm_comp_ratio = (_lb_args.alpha()*total_Kmsgs+_lb_args.beta()*total_Kbytes)/(avg_load*pe_count);
00454
00455
00456 double max, avg, min;
00457 max = max_load_bg;
00458 avg = avg_load_bg;
00459 min = min_load_bg;
00460 thisProxy.PreviousAvgLoad(avg_load);
00461
00462 DEBAD(("** [%d] Iteration Avg load: %lf Max load: %lf Avg Util : %lf \
00463 Min Util : %lf for %lf procs\n",iteration_n, avg, max, avg_utilization,
00464 min_utilization, load[1]));
00465
00466 if(adaptive_lbdb.history_data.size() > 0){
00467 double mslope, aslope, mc, ac;
00468 double new_load_percent = max/avg;
00469 getLineEq(new_load_percent, aslope, ac, mslope, mc);
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 DEBAD(
00486 ("Features:%lf %lf %lf %lf %lf %lf %lf %lf \
00487 %lf %lf %lf %lf %lf %lf %lf %lf %lf \
00488 %lf %lf %lf %lf %lf %lf %lf %d %lf\n",
00489 pe_imbalance, pe_load_std_frac, pe_with_bg_imb, bg_load_frac, pe_gain,
00490 avg_utilization, min_utilization, max_utilization, avg_obj_load, min_obj_load,
00491 max_obj_load, total_objs / pe_count, pe_count, total_Kbytes, total_Kmsgs,
00492 total_outsidepeKbytes / total_Kbytes, total_outsidepeKmsgs / total_Kmsgs,
00493 internal_bytes_frac, avg_comm_neighbors, mslope, aslope, avg_hops,
00494 avg_hop_Kbytes, comm_comp_ratio, chare_pup_size, app_iteration_time));
00495
00496
00497 if (_lb_args.metaLbModelDir() != NULL) {
00498 std::vector<double> test_data{pe_imbalance,
00499 pe_load_std_frac,
00500 pe_with_bg_imb,
00501 0,
00502 bg_load_frac,
00503 pe_gain,
00504 avg_utilization,
00505 min_utilization,
00506 max_utilization,
00507 avg_obj_load,
00508 min_obj_load,
00509 max_obj_load,
00510 total_objs / pe_count,
00511 pe_count,
00512 total_Kbytes,
00513 total_Kmsgs,
00514 total_outsidepeKbytes / total_Kbytes,
00515 total_outsidepeKmsgs / total_Kmsgs,
00516 internal_bytes_frac,
00517 (total_Kbytes - total_outsidepeKbytes) / total_Kmsgs,
00518 avg_comm_neighbors,
00519 mslope,
00520 aslope,
00521 avg_hops,
00522 avg_hop_Kbytes,
00523 comm_comp_ratio};
00524
00525 int predicted_lb = rFmodel->forestTest(test_data, 1, 26);
00526 DEBAD(("***********Final classification = %d *****************\n", predicted_lb));
00527
00528
00529 thisProxy.MetaLBSetLBOnChares(current_balancer, predicted_lb - 1);
00530 current_balancer = predicted_lb - 1;
00531 }
00532 DEBAD(("mslope %lf aslope %lf\n", mslope, aslope));
00533
00534 pe_ld_skewness = skewness;
00535 pe_ld_kurtosis = kurtosis;
00536 total_ovld_pes = ovld_pes;
00537 }
00538
00539
00540 if (adaptive_struct.final_lb_period != iteration_n) {
00541 for (int i = 0; i < lbdb_no_obj_callback.size(); i++) {
00542 thisProxy[lbdb_no_obj_callback[i]].TriggerAdaptiveReduction();
00543 }
00544 }
00545
00546
00547 adaptive_lbdb.lb_iter_no = iteration_n;
00548 AdaptiveData data;
00549 data.iteration = adaptive_lbdb.lb_iter_no;
00550 data.max_load = max;
00551 data.avg_load = avg;
00552 data.min_utilization = min_utilization;
00553 data.avg_utilization = avg_utilization;
00554 adaptive_lbdb.history_data.push_back(data);
00555
00556 if (iteration_n == 1) {
00557 adaptive_struct.info_first_iter.max_avg_ratio = max/avg;
00558 }
00559
00560
00561 if (adaptive_struct.final_lb_period == iteration_n) {
00562 thisProxy.MetaLBCallLBOnChares();
00563 }
00564
00565
00566
00567
00568
00569 if (adaptive_struct.in_progress ||
00570 (adaptive_struct.final_lb_period == iteration_n)) {
00571 return;
00572 }
00573
00574
00575 if (data.avg_utilization >= 0.90) {
00576 return;
00577 }
00578
00579 double utilization_threshold = UTILIZATION_THRESHOLD;
00580
00581 #if EXTRA_FEATURE
00582 DEBAD(("alpha_beta_to_load %lf\n", alpha_beta_cost_to_load));
00583 if (alpha_beta_cost_to_load < 0.1) {
00584
00585
00586 DEBAD(("Changing the idle load tolerance coz this isn't \
00587 communication intensive benchmark\n"));
00588 utilization_threshold = 0.0;
00589 }
00590 #endif
00591
00592
00593
00594 int period;
00595
00596
00597 double ratio_at_t = 1.0;
00598 int tmp_lb_type;
00599 double tmp_max_avg_ratio, tmp_comm_ratio;
00600 GetPrevLBData(tmp_lb_type, tmp_max_avg_ratio, tmp_comm_ratio);
00601
00602 double tolerate_imb = IMB_TOLERANCE * tmp_max_avg_ratio;
00603
00604 if (generatePlan(period, ratio_at_t)) {
00605 DEBAD(("Generated period and calculated %d and period %d max iter %d\n",
00606 adaptive_struct.lb_calculated_period, period,
00607 adaptive_struct.tentative_max_iter_no));
00608
00609 if (ratio_at_t != 1.0) {
00610 DEBAD(("Changed tolerance to %lf after line eq whereas max/avg is %lf\n",
00611 ratio_at_t, max/avg));
00612
00613
00614 tolerate_imb = ratio_at_t * tmp_max_avg_ratio * OUTOFWAY_TOLERANCE;
00615 }
00616
00617 DEBAD(("Prev LB Data Type %d, max/avg %lf, local/remote %lf\n",
00618 tmp_lb_type, tmp_max_avg_ratio, tmp_comm_ratio));
00619
00620 #if EXTRA_FEATURE
00621 if ((avg_utilization < utilization_threshold || max/avg >= tolerate_imb) &&
00622 adaptive_lbdb.history_data.size() > MIN_STATS) {
00623 DEBAD(("Trigger soon even though we calculated lbperiod max/avg(%lf) and \
00624 utilization ratio (%lf)\n", max/avg, avg_utilization));
00625 TriggerSoon(iteration_n, max/avg, tolerate_imb);
00626 return;
00627 }
00628 #endif
00629
00630
00631
00632
00633 if (period > adaptive_struct.tentative_max_iter_no && period !=
00634 adaptive_struct.final_lb_period) {
00635 adaptive_struct.doCommStrategy = false;
00636 adaptive_struct.lb_calculated_period = period;
00637 adaptive_struct.in_progress = true;
00638 DEBAD(("Sticking to the calculated period %d\n",
00639 adaptive_struct.lb_calculated_period));
00640 thisProxy.LoadBalanceDecision(adaptive_struct.lb_msg_send_no++,
00641 adaptive_struct.lb_calculated_period);
00642 return;
00643 }
00644 return;
00645 }
00646
00647 DEBAD(("Prev LB Data Type %d, max/avg %lf, local/remote %lf\n", tmp_lb_type,
00648 tmp_max_avg_ratio, tmp_comm_ratio));
00649
00650 #if EXTRA_FEATURE
00651
00652
00653 if ((avg_utilization < utilization_threshold || max/avg >= tolerate_imb) &&
00654 adaptive_lbdb.history_data.size() > 4) {
00655 DEBAD(("Carry out load balancing step at iter max/avg(%lf) and utilization \
00656 ratio (%lf)\n", max/avg, avg_utilization));
00657 TriggerSoon(iteration_n, max/avg, tolerate_imb);
00658 return;
00659 }
00660 #endif
00661
00662 }
00663
00664 void MetaBalancer::TriggerSoon(int iteration_n, double imbalance_ratio,
00665 double tolerate_imb) {
00666
00667
00668
00669
00670 if ((iteration_n + 1 > adaptive_struct.tentative_max_iter_no) &&
00671 (iteration_n+1 < adaptive_struct.lb_calculated_period) &&
00672 (iteration_n + 1 != adaptive_struct.final_lb_period)) {
00673 if (imbalance_ratio < tolerate_imb) {
00674 adaptive_struct.doCommStrategy = true;
00675 DEBAD(("No load imbalance but idle time\n"));
00676 } else {
00677 adaptive_struct.doCommStrategy = false;
00678 DEBAD(("load imbalance \n"));
00679 }
00680 adaptive_struct.lb_calculated_period = iteration_n + 1;
00681 adaptive_struct.in_progress = true;
00682 DEBAD(("Informing everyone the lb period is %d\n",
00683 adaptive_struct.lb_calculated_period));
00684 thisProxy.LoadBalanceDecision(adaptive_struct.lb_msg_send_no++,
00685 adaptive_struct.lb_calculated_period);
00686 }
00687 }
00688
00689 bool MetaBalancer::generatePlan(int& period, double& ratio_at_t) {
00690 if (adaptive_lbdb.history_data.size() <= 4) {
00691 return false;
00692 }
00693
00694
00695
00696
00697 double max = 0.0;
00698 double avg = 0.0;
00699 AdaptiveData data;
00700 for (int i = 0; i < adaptive_lbdb.history_data.size(); i++) {
00701 data = adaptive_lbdb.history_data[i];
00702 max += data.max_load;
00703 avg += data.avg_load;
00704 DEBAD(("max (%d, %lf) avg (%d, %lf)\n", i, data.max_load, i, data.avg_load));
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714 int tmp_lb_type;
00715 double tmp_max_avg_ratio, tmp_comm_ratio;
00716 double tolerate_imb;
00717
00718 #if EXTRA_FEATURE
00719
00720 GetLBDataForLB(1, tmp_max_avg_ratio, tmp_comm_ratio);
00721 tolerate_imb = tmp_max_avg_ratio;
00722
00723
00724 if (tmp_max_avg_ratio <= 1.01) {
00725 if (max/avg < tolerate_imb) {
00726 DEBAD(("Resorting to imb = 1.0 coz max/avg (%lf) < imb(%lf)\n", max/avg,
00727 tolerate_imb));
00728 tolerate_imb = 1.0;
00729 }
00730 DEBAD(("Will generate plan for refine %lf imb and %lf overhead\n",
00731 tolerate_imb, 0.2));
00732 return getPeriodForStrategy(tolerate_imb, 0.2, period, ratio_at_t);
00733 }
00734
00735 GetLBDataForLB(0, tmp_max_avg_ratio, tmp_comm_ratio);
00736 #endif
00737
00738 GetPrevLBData(tmp_lb_type, tmp_max_avg_ratio, tmp_comm_ratio);
00739 tolerate_imb = tmp_max_avg_ratio;
00740
00741
00742
00743
00744 if (max/avg > tolerate_imb) {
00745 if (getPeriodForStrategy(tolerate_imb, 1, period, ratio_at_t)) {
00746 return true;
00747 }
00748 }
00749
00750 max = 0.0;
00751 avg = 0.0;
00752 for (int i = 0; i < adaptive_lbdb.history_data.size(); i++) {
00753 data = adaptive_lbdb.history_data[i];
00754 max += data.max_load;
00755 avg += data.avg_load*tolerate_imb;
00756 }
00757 max /= adaptive_lbdb.history_data.size();
00758 avg /= adaptive_lbdb.history_data.size();
00759 double cost = adaptive_struct.lb_strategy_cost + adaptive_struct.lb_migration_cost;
00760 period = (int) (cost/(max - avg));
00761 DEBAD(("Obtained period %d from constant prediction tolerated \
00762 imbalance(%f)\n", period, tolerate_imb));
00763 if (period < 0) {
00764 period = adaptive_struct.final_lb_period;
00765 DEBAD(("Obtained -ve period from constant prediction so changing to prev %d\n", period));
00766 }
00767 ratio_at_t = max / avg;
00768 return true;
00769 }
00770
00771 bool MetaBalancer::getPeriodForStrategy(double new_load_percent,
00772 double overhead_percent, int& period, double& ratio_at_t) {
00773 double mslope, aslope, mc, ac;
00774 getLineEq(new_load_percent, aslope, ac, mslope, mc);
00775 DEBAD(("new load percent %lf\n", new_load_percent));
00776 DEBAD(("\n max: %fx + %f; avg: %fx + %f\n", mslope, mc, aslope, ac));
00777 double a = (mslope - aslope)/2;
00778 double b = (mc - ac);
00779 double c = -(adaptive_struct.lb_strategy_cost +
00780 adaptive_struct.lb_migration_cost) * overhead_percent;
00781 DEBAD(("cost %f\n",
00782 (adaptive_struct.lb_strategy_cost+adaptive_struct.lb_migration_cost)));
00783 bool got_period = getPeriodForLinear(a, b, c, period);
00784 if (!got_period) {
00785 return false;
00786 }
00787
00788 if (mslope < 0) {
00789 if (period > (-mc/mslope)) {
00790 DEBAD(("Max < 0 Period set when max load is -ve\n"));
00791 return false;
00792 }
00793 }
00794
00795 if (aslope < 0) {
00796 if (period > (-ac/aslope)) {
00797 DEBAD(("Avg < 0 Period set when avg load is -ve\n"));
00798 return false;
00799 }
00800 }
00801
00802 int intersection_t = (int) ((mc-ac) / (aslope - mslope));
00803 if (intersection_t > 0 && period > intersection_t) {
00804 DEBAD(("Avg | Max Period set when curves intersect\n"));
00805 return false;
00806 }
00807 ratio_at_t = ((mslope*period + mc)/(aslope*period + ac));
00808 DEBAD(("Ratio at t (%lf*%d + %lf) / (%lf*%d+%lf) = %lf\n", mslope, period, mc, aslope, period, ac, ratio_at_t));
00809 return true;
00810 }
00811
00812 bool MetaBalancer::getPeriodForLinear(double a, double b, double c, int& period) {
00813 DEBAD(("Quadratic Equation %lf X^2 + %lf X + %lf\n", a, b, c));
00814 if (a == 0.0) {
00815 period = (int) (-c / b);
00816 if (period < 0) {
00817 DEBAD(("-ve period for -c/b (%d)\n", period));
00818 return false;
00819 }
00820 DEBAD(("Ideal period for linear load %d\n", period));
00821 return true;
00822 }
00823 int x;
00824 double t = (b * b) - (4*a*c);
00825 if (t < 0) {
00826 DEBAD(("(b * b) - (4*a*c) is -ve sqrt : %lf\n", sqrt(t)));
00827 return false;
00828 }
00829 t = (-b + sqrt(t)) / (2*a);
00830 x = (int) t;
00831 if (x < 0) {
00832 DEBAD(("Oops!!! x (%d) < 0\n", x));
00833 x = 0;
00834 return false;
00835 }
00836 period = x;
00837 DEBAD(("Ideal period for linear load %d\n", period));
00838 return true;
00839 }
00840
00841 bool MetaBalancer::getLineEq(double new_load_percent, double& aslope, double& ac, double& mslope, double& mc) {
00842 int total = adaptive_lbdb.history_data.size();
00843 int iterations = (int) (1 + adaptive_lbdb.history_data[total - 1].iteration -
00844 adaptive_lbdb.history_data[0].iteration);
00845 double a1 = 0;
00846 double m1 = 0;
00847 double a2 = 0;
00848 double m2 = 0;
00849 AdaptiveData data;
00850 int i = 0;
00851 for (i = 0; i < total/2; i++) {
00852 data = adaptive_lbdb.history_data[i];
00853 m1 += data.max_load;
00854 a1 += data.avg_load;
00855 DEBAD(("max (%d, %lf) avg (%d, %lf) adjusted_avg (%d, %lf)\n", i, data.max_load, i, data.avg_load, i, new_load_percent*data.avg_load));
00856 }
00857 m1 /= i;
00858 a1 = (a1 * new_load_percent) / i;
00859
00860 for (i = total/2; i < total; i++) {
00861 data = adaptive_lbdb.history_data[i];
00862 m2 += data.max_load;
00863 a2 += data.avg_load;
00864 DEBAD(("max (%d, %lf) avg (%d, %lf) adjusted_avg (%d, %lf)\n", i, data.max_load, i, data.avg_load, i, new_load_percent*data.avg_load));
00865 }
00866 m2 /= (i - total/2);
00867 a2 = (a2 * new_load_percent) / (i - total/2);
00868
00869 aslope = 2 * (a2 - a1) / iterations;
00870 mslope = 2 * (m2 - m1) / iterations;
00871 ac = adaptive_lbdb.history_data[0].avg_load * new_load_percent;
00872 mc = adaptive_lbdb.history_data[0].max_load;
00873
00874 ac = a1 - ((aslope * total)/4);
00875 mc = m1 - ((mslope * total)/4);
00876
00877
00878
00879
00880 return true;
00881 }
00882
00883 void MetaBalancer::LoadBalanceDecision(int req_no, int period) {
00884 if (req_no < adaptive_struct.lb_msg_recv_no) {
00885 DEBAD(("Error!!! Received a request which was already sent or old\n"));
00886 return;
00887 }
00888 DEBADDETAIL(("[%d] Load balance decision made cur iteration: %d period:%d\n",
00889 CkMyPe(), adaptive_struct.lb_iteration_no, period));
00890 adaptive_struct.tentative_period = period;
00891 adaptive_struct.lb_msg_recv_no = req_no;
00892 if (metaRdnGroup == NULL) {
00893 metaRdnGroup = (MetaBalancerRedn*)CkLocalBranch(_metalbred);
00894 }
00895 if (metaRdnGroup != NULL) {
00896 metaRdnGroup->getMaxIter(adaptive_struct.lb_iteration_no);
00897 }
00898 }
00899
00900 void MetaBalancer::LoadBalanceDecisionFinal(int req_no, int period) {
00901 if (req_no < adaptive_struct.lb_msg_recv_no) {
00902 return;
00903 }
00904 DEBADDETAIL(("[%d] Final Load balance decision made cur iteration: %d \
00905 period:%d \n",CkMyPe(), adaptive_struct.lb_iteration_no, period));
00906 adaptive_struct.tentative_period = period;
00907 adaptive_struct.final_lb_period = period;
00908 lbdatabase->MetaLBResumeWaitingChares(period);
00909 }
00910
00911 void MetaBalancer::MetaLBCallLBOnChares() {
00912 lbdatabase->MetaLBCallLBOnChares();
00913 }
00914
00915 void MetaBalancer::MetaLBSetLBOnChares(int switchFrom, int switchTo) {
00916 lbdatabase->switchLoadbalancer(switchFrom, switchTo);
00917 }
00918
00919 void MetaBalancer::ReceiveIterationNo(int local_iter_no) {
00920 CmiAssert(CkMyPe() == 0);
00921
00922 if (local_iter_no > adaptive_struct.global_max_iter_no) {
00923 adaptive_struct.global_max_iter_no = local_iter_no;
00924 }
00925
00926 int period;
00927
00928 if (adaptive_struct.global_max_iter_no > adaptive_struct.tentative_max_iter_no) {
00929 adaptive_struct.tentative_max_iter_no = adaptive_struct.global_max_iter_no;
00930 }
00931 period = (adaptive_struct.tentative_period > adaptive_struct.global_max_iter_no) ?
00932 adaptive_struct.tentative_period : adaptive_struct.global_max_iter_no + 1;
00933
00934
00935 if (adaptive_struct.global_max_iter_no < adaptive_struct.final_lb_period) {
00936 adaptive_struct.tentative_period = period;
00937 DEBAD(("Final lb_period CHANGED!%d\n", adaptive_struct.tentative_period));
00938 } else {
00939 adaptive_struct.tentative_period = adaptive_struct.final_lb_period;
00940 DEBAD(("Final lb_period NOT CHANGED!%d\n", adaptive_struct.tentative_period));
00941 }
00942 thisProxy.LoadBalanceDecisionFinal(adaptive_struct.lb_msg_recv_no, adaptive_struct.tentative_period);
00943 adaptive_struct.in_progress = false;
00944 }
00945
00946 int MetaBalancer::getPredictedLBPeriod(bool& is_tentative) {
00947
00948
00949
00950 if (adaptive_struct.tentative_period != adaptive_struct.final_lb_period) {
00951 is_tentative = true;
00952 } else {
00953 is_tentative = false;
00954 }
00955 if (adaptive_struct.tentative_period < adaptive_struct.final_lb_period) {
00956 return adaptive_struct.tentative_period;
00957 } else {
00958 return adaptive_struct.final_lb_period;
00959 }
00960 }
00961
00962
00963
00964 void MetaBalancer::ResetAdaptive() {
00965 adaptive_lbdb.lb_iter_no = -1;
00966 lb_in_progress = true;
00967 }
00968
00969
00970 void MetaBalancer::periodicCall(void *ad) {
00971 MetaBalancer *s = (MetaBalancer *)ad;
00972 CcdCallFnAfterOnPE((CcdVoidFn)checkForNoObj, (void *)s, _nobj_timer, CkMyPe());
00973 }
00974
00975 void MetaBalancer::checkForNoObj(void *ad) {
00976 MetaBalancer *s = (MetaBalancer *) ad;
00977 s->HandleAdaptiveNoObj();
00978 }
00979
00980
00981 void MetaBalancer::HandleAdaptiveNoObj() {
00982 #if CMK_LBDB_ON
00983 if (lbdatabase->getLBDB()->ObjDataCount() == 0) {
00984 adaptive_struct.finished_iteration_no++;
00985 adaptive_struct.lb_iteration_no++;
00986 DEBAD(("(%d) --HandleAdaptiveNoObj %d\n", CkMyPe(),
00987 adaptive_struct.finished_iteration_no));
00988 thisProxy[0].RegisterNoObjCallback(CkMyPe());
00989 TriggerAdaptiveReduction();
00990 }
00991 #endif
00992 }
00993
00994 void MetaBalancer::RegisterNoObjCallback(int index) {
00995
00996
00997
00998
00999 if (lb_in_progress) {
01000 lbdb_no_obj_callback.clear();
01001 lb_in_progress = false;
01002 }
01003 lbdb_no_obj_callback.push_back(index);
01004 DEBAD(("Registered %d to have no objs.\n", index));
01005
01006
01007
01008 if (adaptive_lbdb.lb_iter_no != -1) {
01009 DEBAD(("Collection already started now %d so kick in\n",
01010 adaptive_struct.finished_iteration_no));
01011
01012 }
01013 }
01014
01015 void MetaBalancer::TriggerAdaptiveReduction() {
01016 #if CMK_LBDB_ON
01017 if (lbdatabase->getLBDB()->ObjDataCount() == 0) {
01018 adaptive_struct.finished_iteration_no++;
01019 adaptive_struct.lb_iteration_no++;
01020 double lb_data[STATS_COUNT];
01021 lb_data[ITER_NO] = adaptive_struct.finished_iteration_no;
01022 lb_data[NUM_PROCS] = 1;
01023 lb_data[TOTAL_LOAD] = 0.0;
01024 lb_data[MAX_LOAD] = 0.0;
01025 lb_data[IDLE_TIME] = 0.0;
01026 lb_data[UTILIZATION] = 0.0;
01027 lb_data[TOTAL_LOAD_W_BG] = 0.0;
01028 lb_data[MAX_LOAD_W_BG] = 0.0;
01029
01030 DEBAD(("[%d] Triggered adaptive reduction for noobj %d\n", CkMyPe(),
01031 adaptive_struct.finished_iteration_no));
01032
01033 CkCallback cb(CkReductionTarget(MetaBalancer, ReceiveMinStats),
01034 thisProxy[0]);
01035 contribute(STATS_COUNT*sizeof(double), lb_data, lbDataCollectionType, cb);
01036 }
01037 #endif
01038 }
01039
01040
01041 bool MetaBalancer::isStrategyComm() {
01042 return adaptive_struct.doCommStrategy;
01043 }
01044
01045 void MetaBalancer::SetMigrationCost(double lb_migration_cost) {
01046 adaptive_struct.lb_migration_cost = lb_migration_cost;
01047 }
01048
01049 void MetaBalancer::SetStrategyCost(double lb_strategy_cost) {
01050 adaptive_struct.lb_strategy_cost = lb_strategy_cost;
01051 }
01052
01053 void MetaBalancer::UpdateAfterLBData(int lb, double lb_max, double lb_avg, double
01054 local_comm, double remote_comm) {
01055 adaptive_struct.last_lb_type = lb;
01056 if (lb == 0) {
01057 adaptive_struct.greedy_info.max_avg_ratio = lb_max/lb_avg;
01058 } else if (lb == 1) {
01059 adaptive_struct.refine_info.max_avg_ratio = lb_max/lb_avg;
01060 } else if (lb == 2) {
01061 adaptive_struct.comm_info.remote_local_ratio = remote_comm/local_comm;
01062 } else if (lb == 3) {
01063 adaptive_struct.comm_refine_info.remote_local_ratio =
01064 remote_comm/local_comm;
01065 }
01066 }
01067
01068 void MetaBalancer::UpdateAfterLBData(double max_load, double max_cpu,
01069 double avg_load) {
01070 if (adaptive_struct.last_lb_type == -1) {
01071 adaptive_struct.last_lb_type = 0;
01072 }
01073 int lb = adaptive_struct.last_lb_type;
01074 if (lb == 0) {
01075 adaptive_struct.greedy_info.max_avg_ratio = max_load/avg_load;
01076 } else if (lb == 1) {
01077 adaptive_struct.refine_info.max_avg_ratio = max_load/avg_load;
01078 } else if (lb == 2) {
01079 adaptive_struct.comm_info.max_avg_ratio = max_load/avg_load;
01080 } else if (lb == 3) {
01081 adaptive_struct.comm_refine_info.max_avg_ratio = max_load/avg_load;
01082 }
01083 }
01084
01085 void MetaBalancer::UpdateAfterLBComm(double alpha_beta_to_load) {
01086 DEBAD(("Setting alpha beta %lf\n", alpha_beta_to_load));
01087 alpha_beta_cost_to_load = alpha_beta_to_load;
01088 }
01089
01090
01091 void MetaBalancer::GetPrevLBData(int& lb_type, double& lb_max_avg_ratio,
01092 double& remote_local_comm_ratio) {
01093 lb_type = adaptive_struct.last_lb_type;
01094 lb_max_avg_ratio = 1;
01095 remote_local_comm_ratio = 1;
01096 GetLBDataForLB(lb_type, lb_max_avg_ratio, remote_local_comm_ratio);
01097
01098
01099 lb_max_avg_ratio = adaptive_struct.info_first_iter.max_avg_ratio;
01100 }
01101
01102 void MetaBalancer::GetLBDataForLB(int lb_type, double& lb_max_avg_ratio,
01103 double& remote_local_comm_ratio) {
01104 if (lb_type == 0) {
01105 lb_max_avg_ratio = adaptive_struct.greedy_info.max_avg_ratio;
01106 } else if (lb_type == 1) {
01107 lb_max_avg_ratio = adaptive_struct.refine_info.max_avg_ratio;
01108 } else if (lb_type == 2) {
01109 remote_local_comm_ratio = adaptive_struct.comm_info.remote_local_ratio;
01110 } else if (lb_type == 3) {
01111 remote_local_comm_ratio =
01112 adaptive_struct.comm_refine_info.remote_local_ratio;
01113 }
01114 }
01115
01116 void MetaBalancerRedn::init() {
01117
01118 metabalancer = NULL;
01119 }
01120
01121 void MetaBalancerRedn::pup(PUP::er& p) {
01122 }
01123
01124 void MetaBalancerRedn::ReceiveIterNo(int max_iter) {
01125 CkAssert(CkMyPe() == 0);
01126 if (metabalancer == NULL) {
01127 metabalancer = (MetaBalancer*)CkLocalBranch(_metalb);
01128 }
01129 if (metabalancer != NULL) {
01130 metabalancer->ReceiveIterationNo(max_iter);
01131 }
01132 }
01133
01134 void MetaBalancerRedn::getMaxIter(int max_iter) {
01135 CkCallback cb(CkReductionTarget(MetaBalancerRedn, ReceiveIterNo), thisProxy[0]);
01136 contribute(sizeof(int), &max_iter, CkReduction::max_int, cb);
01137 }
01138
01139 void MetaBalancer::PreviousAvgLoad(double avg) {
01140 prev_avg_load = avg;
01141 }
01142
01143 #include "MetaBalancer.def.h"
01144