00001 00005 00006 #include "PhasebyArrayLB.h" 00007 00008 extern LBAllocFn getLBAllocFn(const char *lbname); 00009 00010 extern int quietModeRequested; 00011 00012 CreateLBFunc_Def(PhasebyArrayLB, "Load balancer which balances many arrays together, specifically for CPAIMD") 00013 00014 #include "PhasebyArrayLB.def.h" 00015 00016 PhasebyArrayLB::PhasebyArrayLB(const CkLBOptions &opt): CBase_PhasebyArrayLB(opt) 00017 { 00018 lbname = (char*)"PhasebyArrayLB"; 00019 if (CkMyPe() == 0 && !quietModeRequested) 00020 CkPrintf("CharmLB> PhasebyArrayLB created.\n"); 00021 00022 const char *lbs = theLbdb->loadbalancer(opt.getSeqNo()); 00023 00024 char *lbcopy = strdup(lbs); 00025 char *p = strchr(lbcopy, ':'); 00026 if (p==NULL) return; 00027 p++; 00028 LBAllocFn fn = getLBAllocFn(p); 00029 if (fn == NULL) { 00030 CkPrintf("LB> Invalid load balancer: %s.\n", p); 00031 CmiAbort(""); 00032 } 00033 lb = (CentralLB *)fn(); 00034 } 00035 00036 bool PhasebyArrayLB::QueryBalanceNow(int _step) 00037 { 00038 return true; 00039 } 00040 00041 void PhasebyArrayLB::copyStats(BaseLB::LDStats *stats,BaseLB::LDStats *tempStats){ 00042 int i; 00043 tempStats->nprocs() = stats->nprocs(); 00044 tempStats->n_objs = stats->n_objs; 00045 tempStats->n_comm = stats->n_comm; 00046 tempStats->n_migrateobjs = stats->n_migrateobjs; 00047 tempStats->hashSize = stats->hashSize; 00048 if(tempStats->hashSize && stats->objHash!=NULL){ 00049 tempStats->objHash = new int[tempStats->hashSize]; 00050 for(int i=0;i<tempStats->hashSize;i++) 00051 tempStats->objHash[i]=stats->objHash[i]; 00052 } 00053 else 00054 tempStats->objHash=NULL; 00055 tempStats->objData.resize(tempStats->n_objs); 00056 tempStats->from_proc.resize(tempStats->n_objs); 00057 tempStats->to_proc.resize(tempStats->n_objs); 00058 tempStats->commData.resize(tempStats->n_comm); 00059 for(i=0;i<tempStats->n_objs;i++){ 00060 tempStats->objData[i]=stats->objData[i]; 00061 tempStats->from_proc[i]=stats->from_proc[i]; 00062 tempStats->to_proc[i]=stats->to_proc[i]; 00063 } 00064 for(i=0;i<tempStats->n_comm;i++) 00065 tempStats->commData[i]=stats->commData[i]; 00066 00067 tempStats->procs = new BaseLB::ProcStats[tempStats->nprocs()]; 00068 for(i=0; i<tempStats->nprocs(); i++) 00069 tempStats->procs[i]=stats->procs[i]; 00070 } 00071 00072 void PhasebyArrayLB::updateStats(BaseLB::LDStats *stats,BaseLB::LDStats *tempStats){ 00073 tempStats->hashSize = stats->hashSize; 00074 if(tempStats->hashSize && stats->objHash!=NULL){ 00075 tempStats->objHash = new int[tempStats->hashSize]; 00076 for(int i=0;i<tempStats->hashSize;i++) 00077 tempStats->objHash[i]=stats->objHash[i]; 00078 } 00079 else 00080 tempStats->objHash=NULL; 00081 00082 for(int i=0;i<tempStats->n_objs;i++) 00083 tempStats->objData[i]=stats->objData[i]; 00084 00085 } 00086 00087 void PhasebyArrayLB::work(LDStats *stats){ 00088 //It is assumed that statically placed arrays are set non-migratable in the application 00089 tempStats = new BaseLB::LDStats; 00090 00091 copyStats(stats,tempStats); 00092 int obj, i; 00093 int flag=0; 00094 LDObjData *odata; 00095 00096 00097 odata = &(tempStats->objData[0]); 00098 omids.push_back(odata->omID()); 00099 if(odata->migratable) 00100 migratableOMs.push_back(true); 00101 else 00102 migratableOMs.push_back(false); 00103 00104 for(i=0;i<tempStats->n_objs; i++){ 00105 odata = &(tempStats->objData[i]); 00106 for(int j=0;j<omids.size();j++) 00107 if(odata->omID()==omids[j]){ 00108 flag=1; 00109 break; 00110 } 00111 00112 if(flag==1){ 00113 flag=0; 00114 } 00115 else{ 00116 omids.push_back(odata->omID()); 00117 if(odata->migratable) 00118 migratableOMs.push_back(true); 00119 else 00120 migratableOMs.push_back(false); 00121 } 00122 } 00123 00124 for(i=0;i<omids.size();i++){ 00125 //copy to_proc from previous iteration to from_proc for this iteration 00126 LDOMid omid = omids[i]; 00127 //Set other objects as background load 00128 if(migratableOMs[i]){ 00129 for (obj = 0; obj < tempStats->n_objs; obj++) { 00130 odata = &(tempStats->objData[obj]); 00131 if (odata->omID() != omid) 00132 odata->migratable=false; 00133 } 00134 //Call a strategy here 00135 lb->work(tempStats); 00136 if(i!=omids.size()-1){ 00137 for(obj = 0; obj < tempStats->n_objs; obj++) 00138 tempStats->from_proc[obj]=tempStats->to_proc[obj]; 00139 updateStats(stats,tempStats); 00140 } 00141 } 00142 } 00143 //Copy to stats array 00144 for(obj = 0; obj < tempStats->n_objs; obj++) 00145 stats->to_proc[obj]=tempStats->to_proc[obj]; 00146 tempStats->clear(); 00147 omids.free(); 00148 migratableOMs.free(); 00149 } 00150