void initAll() { glClearColor(0.0,0.0,0.0,0.0); initTexture(); initStructs(); initObjects(); }
void TempAwareCommLB::work(LDStats* stats) { /** ========================== INITIALIZATION ============================= */ #ifdef TEMP_LDB ////////////////////////////////////////////////////// // initialize structures for TempLBs initStructs(stats); tempControl(); populateEffectiveFreq(stats->nprocs()); ////////////////////////////////////////////////////// CkPrintf(" ================== in TempAwareCommLB::work() ===========\n"); ProcArrayTemp *parr = new ProcArrayTemp(stats,procFreq,procFreqNew); // Processor Array parr->convertToInsts(stats); ObjGraphTemp *ogr = new ObjGraphTemp(stats,procFreq,procFreqNew); // Object Graph ogr->convertToInsts(stats); double avgload = parr->getAverageLoad(); // Average load of processors // Sets to false if it is overloaded, else to true vector<bool> proc_load_info(parr->procs.size(), false); // Create an array of vectors for each processor mapping to the objects in // that processor std::vector<int>* parr_objs = new std::vector<int>[parr->procs.size()]; upper_threshold_temp = avgload + (avgload * THRESHOLD); //lower_threshold = avgload - (avgload * THRESHOLD * THRESHOLD); lower_threshold_temp = avgload; int less_loaded_counter = 0; srand(time(NULL)); /** ============================= STRATEGY ================================ */ if (_lb_args.debug()>1) CkPrintf("[%d] In TempAwareCommLB strategy\n",CkMyPe()); CkPrintf("Average load %E\n", avgload); int vert, i, j; int curr_pe; // Iterate over all the chares and construct the peid, vector<chareid> array for(vert = 0; vert < ogr->vertices.size(); vert++) { curr_pe = ogr->vertices[vert].getCurrentPe(); parr_objs[curr_pe].push_back(vert); ogr->vertices[vert].setNewPe(curr_pe); } std::vector<int> parr_above_avg; std::vector<int> parr_below_avg; double pe_load; // Insert into parr_above_avg if the processor fits under the criteria of // overloaded processor. // Insert the processor id into parr_below_avg if the processor is underloaded for (vert = 0; vert < parr->procs.size(); vert++) { pe_load = parr->procs[vert].getTotalLoad(); if (pe_load > upper_threshold_temp) { // Pushing ProcInfo into this list parr_above_avg.push_back(vert); } else if (pe_load < lower_threshold_temp) { parr_below_avg.push_back(parr->procs[vert].getProcId()); proc_load_info[parr->procs[vert].getProcId()] = true; less_loaded_counter++; } } std::make_heap(parr_above_avg.begin(), parr_above_avg.end(), ProcLoadGreater(parr)); int random; int randomly_obj_id; bool obj_allocated; int num_tries; // Allow as many swaps as there are chares int total_swaps = ogr->vertices.size() * SWAP_MULTIPLIER; int possible_pe; double obj_load; // Keep on loadbalancing until the number of above avg processors is 0 while (parr_above_avg.size() != 0 && total_swaps > 0 && parr_below_avg.size() != 0) { // CkPrintf("Above avg : %d Below avg : %d Total swaps: %d\n", parr_above_avg.size(), // parr_below_avg.size(), total_swaps); obj_allocated = false; num_tries = 0; // Pop the heaviest processor int p_index = popFromProcHeap(parr_above_avg, parr); ProcInfo& p = parr->procs[p_index]; while (!obj_allocated && num_tries < parr_objs[p.getProcId()].size()) { // It might so happen that due to overhead load, it might not have any // more objects in its list if (parr_objs[p.getProcId()].size() == 0) { // CkPrintf("No obj left to be allocated\n"); obj_allocated = true; break; } int randd = rand(); random = randd % parr_objs[p.getProcId()].size(); randomly_obj_id = parr_objs[p.getProcId()][random]; //need to update the load below .. account for freqs obj_load = ogr->vertices[randomly_obj_id].getVertexLoad(); // CkPrintf("Heavy %d: Parr obj size : %d random : %d random obj id : %d\n", p_index, // parr_objs[p.getProcId()].size(), randd, randomly_obj_id); std::vector<int> possible_pes; getPossiblePes(possible_pes, randomly_obj_id, ogr, parr); for (i = 0; i < possible_pes.size(); i++) { // If the heaviest communicating processor is there in the list, then // assign it to that. possible_pe = possible_pes[i]; if ((parr->procs[possible_pe].getTotalLoad() + obj_load) < upper_threshold_temp) { // CkPrintf("** Transfered %d(Load %lf) from %d:%d(Load %lf) to %d:%d(Load %lf)\n", // randomly_obj_id, obj_load, CkNodeOf(p.getProcId()), p.getProcId(), p.getTotalLoad(), // CkNodeOf(possible_pe), possible_pe, // parr->procs[possible_pe].getTotalLoad()); handleTransfer(randomly_obj_id, p, possible_pe, parr_objs, ogr, parr); obj_allocated = true; total_swaps--; updateLoadInfo(p_index, possible_pe, upper_threshold_temp, lower_threshold_temp, parr_above_avg, parr_below_avg, proc_load_info, parr); break; } } // Since there is no processor in the least loaded list with which this // chare communicates, pick a random least loaded processor. if (!obj_allocated) { //CkPrintf(":( Could not transfer to the nearest communicating ones\n"); for (int x = 0; x < parr_below_avg.size(); x++) { int random_pe = parr_below_avg[x]; if ((parr->procs[random_pe].getTotalLoad() + obj_load) < upper_threshold_temp) { obj_allocated = true; total_swaps--; handleTransfer(randomly_obj_id, p, random_pe, parr_objs, ogr, parr); updateLoadInfo(p_index, random_pe, upper_threshold_temp, lower_threshold_temp, parr_above_avg, parr_below_avg, proc_load_info, parr); break; } num_tries++; } } } if (!obj_allocated) { //CkPrintf("!!!! Could not handle the heavy proc %d so giving up\n", p_index); // parr_above_avg.push_back(p_index); // std::push_heap(parr_above_avg.begin(), parr_above_avg.end(), // ProcLoadGreater(parr)); } } //CkPrintf("CommAwareRefine> After lb max load: %lf avg load: %lf\n", max_load, avg_load/parr->procs.size()); /** ============================== CLEANUP ================================ */ ogr->convertDecisions(stats); // Send decisions back to LDStats delete parr; delete ogr; delete[] parr_objs; #else CmiAbort("TempLBs are not supported without the TEMP_LDB flag\n"); #endif }