00001
00011 #include "hilbert.h"
00012 #include "partitioning_strategies.h"
00013 #include "charm++.h"
00014 #include "register.h"
00015 #include "ck.h"
00016 #include "trace.h"
00017 #include "TopoManager.h"
00018 #include <vector>
00019 #include <algorithm>
00020 #include <sstream>
00021 #include <limits>
00022 #include "pup_stl.h"
00023
00024 #if CMK_LBDB_ON
00025 #include "LBDatabase.h"
00026 #include "MetaBalancer.h"
00027 #if CMK_GLOBAL_LOCATION_UPDATE
00028 #include "BaseLB.h"
00029 #include "init.h"
00030 #endif
00031 CkpvExtern(int, _lb_obj_index);
00032 #endif // CMK_LBDB_ON
00033
00034 #ifndef CMK_CHARE_USE_PTR
00035 CkpvExtern(int, currentChareIdx);
00036 #endif
00037
00038 #if CMK_GRID_QUEUE_AVAILABLE
00039 CpvExtern(void *, CkGridObject);
00040 #endif
00041
00042 #define ARRAY_DEBUG_OUTPUT 0
00043
00044 #if ARRAY_DEBUG_OUTPUT
00045 # define DEB(x) CkPrintf x //General debug messages
00046 # define DEBI(x) CkPrintf x //Index debug messages
00047 # define DEBC(x) CkPrintf x //Construction debug messages
00048 # define DEBS(x) CkPrintf x //Send/recv/broadcast debug messages
00049 # define DEBM(x) CkPrintf x //Migration debug messages
00050 # define DEBL(x) CkPrintf x //Load balancing debug messages
00051 # define DEBN(x) CkPrintf x //Location debug messages
00052 # define DEBB(x) CkPrintf x //Broadcast debug messages
00053 # define AA "LocMgr on %d: "
00054 # define AB ,CkMyPe()
00055 # define DEBUG(x) CkPrintf x
00056 # define DEBAD(x) CkPrintf x
00057 #else
00058 # define DEB(X)
00059 # define DEBI(X)
00060 # define DEBC(X)
00061 # define DEBS(x)
00062 # define DEBM(X)
00063 # define DEBL(X)
00064 # define DEBN(x)
00065 # define DEBB(x)
00066 # define str(x)
00067 # define DEBUG(x)
00068 # define DEBAD(x)
00069 #endif
00070
00071
00072 bool useNodeBlkMapping;
00073
00076 int _messageBufferingThreshold;
00077
00078 #if CMK_LBDB_ON
00079
00080 #if CMK_GLOBAL_LOCATION_UPDATE
00081 void UpdateLocation(MigrateInfo& migData) {
00082
00083 CkGroupID locMgrGid = ck::ObjID(migData.obj.id).getCollectionID();
00084 if (locMgrGid.idx == 0) {
00085 return;
00086 }
00087
00088 CkLocMgr *localLocMgr = (CkLocMgr *) CkLocalBranch(locMgrGid);
00089 localLocMgr->updateLocation(migData.obj.id, migData.to_pe);
00090 }
00091 #endif
00092
00093 #endif
00094
00095
00096 CmiUInt8 CkArrayMessage::array_element_id(void)
00097 {
00098 return ck::ObjID(UsrToEnv((void *)this)->getRecipientID()).getElementID();
00099 }
00100 unsigned short &CkArrayMessage::array_ep(void)
00101 {
00102 return UsrToEnv((void *)this)->getsetArrayEp();
00103 }
00104 unsigned short &CkArrayMessage::array_ep_bcast(void)
00105 {
00106 return UsrToEnv((void *)this)->getsetArrayBcastEp();
00107 }
00108 unsigned char &CkArrayMessage::array_hops(void)
00109 {
00110 return UsrToEnv((void *)this)->getsetArrayHops();
00111 }
00112 unsigned int CkArrayMessage::array_getSrcPe(void)
00113 {
00114 return UsrToEnv((void *)this)->getsetArraySrcPe();
00115 }
00116 unsigned int CkArrayMessage::array_ifNotThere(void)
00117 {
00118 return UsrToEnv((void *)this)->getArrayIfNotThere();
00119 }
00120 void CkArrayMessage::array_setIfNotThere(unsigned int i)
00121 {
00122 UsrToEnv((void *)this)->setArrayIfNotThere(i);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132 CkArrayMap::CkArrayMap(void) { }
00133 CkArrayMap::~CkArrayMap() { }
00134 int CkArrayMap::registerArray(const CkArrayIndex& numElements, CkArrayID aid)
00135 {return 0;}
00136 void CkArrayMap::unregisterArray(int idx)
00137 { }
00138
00139 #define CKARRAYMAP_POPULATE_INITIAL(POPULATE_CONDITION) \
00140 int i; \
00141 int index[6]; \
00142 int start_data[6], end_data[6], step_data[6]; \
00143 for (int d = 0; d < 6; d++) { \
00144 start_data[d] = 0; \
00145 end_data[d] = step_data[d] = 1; \
00146 if (end.dimension >= 4 && d < end.dimension) { \
00147 start_data[d] = ((short int*)start.data())[d]; \
00148 end_data[d] = ((short int*)end.data())[d]; \
00149 step_data[d] = ((short int*)step.data())[d]; \
00150 } else if (d < end.dimension) { \
00151 start_data[d] = start.data()[d]; \
00152 end_data[d] = end.data()[d]; \
00153 step_data[d] = step.data()[d]; \
00154 } \
00155 } \
00156 \
00157 for (index[0] = start_data[0]; index[0] < end_data[0]; index[0] += step_data[0]) { \
00158 for (index[1] = start_data[1]; index[1] < end_data[1]; index[1] += step_data[1]) { \
00159 for (index[2] = start_data[2]; index[2] < end_data[2]; index[2] += step_data[2]) { \
00160 for (index[3] = start_data[3]; index[3] < end_data[3]; index[3] += step_data[3]) { \
00161 for (index[4] = start_data[4]; index[4] < end_data[4]; index[4] += step_data[4]) { \
00162 for (index[5] = start_data[5]; index[5] < end_data[5]; index[5] += step_data[5]) { \
00163 if (end.dimension == 1) { \
00164 i = index[0]; \
00165 CkArrayIndex1D idx(index[0]); \
00166 if (POPULATE_CONDITION) { \
00167 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00168 } \
00169 } else if (end.dimension == 2) { \
00170 i = index[0] * end_data[1] + index[1]; \
00171 CkArrayIndex2D idx(index[0], index[1]); \
00172 if (POPULATE_CONDITION) { \
00173 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00174 } \
00175 } else if (end.dimension == 3) { \
00176 i = (index[0]*end_data[1] + index[1]) * end_data[2] + index[2]; \
00177 CkArrayIndex3D idx(index[0], index[1], index[2]); \
00178 if (POPULATE_CONDITION) { \
00179 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00180 } \
00181 } else if (end.dimension == 4) { \
00182 i = ((index[0]*end_data[1] + index[1]) * end_data[2] + index[2]) * end_data[3] + index[3]; \
00183 CkArrayIndex4D idx(index[0], index[1], index[2], index[3]); \
00184 if (POPULATE_CONDITION) { \
00185 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00186 } \
00187 } else if (end.dimension == 5) { \
00188 i = (((index[0]*end_data[1] + index[1]) * end_data[2] + index[2]) * end_data[3] + index[3]) * end_data[4] + index[4]; \
00189 CkArrayIndex5D idx(index[0], index[1], index[2], index[3], index[4]); \
00190 if (POPULATE_CONDITION) { \
00191 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00192 } \
00193 } else if (end.dimension == 6) { \
00194 i = ((((index[0]*end_data[1] + index[1]) * end_data[2] + index[2]) * end_data[3] + index[3]) * end_data[4] + index[4]) * end_data[5] + index[5]; \
00195 CkArrayIndex6D idx(index[0], index[1], index[2], index[3], index[4], index[5]); \
00196 if (POPULATE_CONDITION) { \
00197 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00198 } \
00199 } \
00200 } \
00201 } \
00202 } \
00203 } \
00204 } \
00205 }
00206
00207 void CkArrayMap::populateInitial(int arrayHdl,CkArrayOptions& options,void *ctorMsg,CkArray *mgr)
00208 {
00209 CkArrayIndex start = options.getStart();
00210 CkArrayIndex end = options.getEnd();
00211 CkArrayIndex step = options.getStep();
00212 if (end.nInts==0) {
00213 CkFreeMsg(ctorMsg);
00214 return;
00215 }
00216 int thisPe=CkMyPe();
00217
00218
00219
00220 CKARRAYMAP_POPULATE_INITIAL(CMK_RANK_0(procNum(arrayHdl,idx))==thisPe);
00221
00222 #if CMK_BIGSIM_CHARM
00223 BgEntrySplit("split-array-new-end");
00224 #endif
00225
00226 mgr->doneInserting();
00227 CkFreeMsg(ctorMsg);
00228 }
00229
00230 void CkArrayMap::storeCkArrayOpts(CkArrayOptions options) {
00231
00232 storeOpts = options;
00233 }
00234
00235 void CkArrayMap::pup(PUP::er &p) {
00236 p|storeOpts;
00237 p|dynamicIns;
00238 }
00239
00240 CkGroupID _defaultArrayMapID;
00241 CkGroupID _fastArrayMapID;
00242
00243 class RRMap : public CkArrayMap
00244 {
00245 private:
00246 CkArrayIndex maxIndex;
00247 uint64_t products[2*CK_ARRAYINDEX_MAXLEN];
00248 bool productsInit;
00249
00250 public:
00251 RRMap(void)
00252 {
00253 DEBC((AA "Creating RRMap\n" AB));
00254 productsInit = false;
00255 }
00256 RRMap(CkMigrateMessage *m):CkArrayMap(m){}
00257
00258 void indexInit() {
00259 productsInit = true;
00260 maxIndex = storeOpts.getEnd();
00261 products[maxIndex.dimension - 1] = 1;
00262 if(maxIndex.dimension <= CK_ARRAYINDEX_MAXLEN) {
00263 for(int dim = maxIndex.dimension - 2; dim >= 0; dim--) {
00264 products[dim] = products[dim + 1] * maxIndex.index[dim + 1];
00265 }
00266 } else {
00267 for(int dim = maxIndex.dimension - 2; dim >= 0; dim--) {
00268 products[dim] = products[dim + 1] * maxIndex.indexShorts[dim + 1];
00269 }
00270 }
00271 }
00272
00273 int procNum(int arrayHdl, const CkArrayIndex &i)
00274 {
00275 if (i.dimension == 1) {
00276
00277 int ans = (i.data()[0])%CkNumPes();
00278 #if CMK_FAULT_EVAC
00279 while(!CmiNodeAlive(ans) || (ans == CkMyPe() && CkpvAccess(startedEvac))){
00280 ans = (ans+1)%CkNumPes();
00281 }
00282 #endif
00283 return ans;
00284 }
00285 else {
00286 if(dynamicIns.find(arrayHdl) != dynamicIns.end()) {
00287
00288
00289 unsigned int hash=(i.hash()+739)%1280107;
00290 int ans = (hash % CkNumPes());
00291 #if CMK_FAULT_EVAC
00292 while(!CmiNodeAlive(ans)){
00293 ans = (ans+1)%CkNumPes();
00294 }
00295 #endif
00296 return ans;
00297 } else {
00298 if(!productsInit) { indexInit(); }
00299
00300 int indexOffset = 0;
00301 if(i.dimension <= CK_ARRAYINDEX_MAXLEN) {
00302 for(int dim = i.dimension - 1; dim >= 0; dim--) {
00303 indexOffset += (i.index[dim] * products[dim]);
00304 }
00305 } else {
00306 for(int dim = maxIndex.dimension - 1; dim >= 0; dim--) {
00307 indexOffset += (i.indexShorts[dim] * products[dim]);
00308 }
00309 }
00310 return indexOffset % CkNumPes();
00311 }
00312 }
00313 }
00314
00315 void pup(PUP::er& p) {
00316 CkArrayMap::pup(p);
00317 p|maxIndex;
00318 p|productsInit;
00319 PUParray(p, products, 2*CK_ARRAYINDEX_MAXLEN);
00320 }
00321 };
00322
00327 class arrayMapInfo {
00328 public:
00329 CkArrayIndex _nelems;
00330 int _binSizeFloor;
00331 int _binSizeCeil;
00332 int _numChares;
00333 int _remChares;
00334
00335 int _numFirstSet;
00336
00337
00338 int _nBinSizeFloor;
00339 int _nRemChares;
00340
00341 int _nNumFirstSet;
00342
00343
00347 arrayMapInfo(void) { }
00348
00349 arrayMapInfo(const CkArrayIndex& n) : _nelems(n), _numChares(0) {
00350 compute_binsize();
00351 }
00352
00353 ~arrayMapInfo() {}
00354
00355 void compute_binsize()
00356 {
00357 int numPes = CkNumPes();
00358
00359 int numNodes = CkNumNodes();
00360
00361 if (_nelems.dimension == 1) {
00362 _numChares = _nelems.data()[0];
00363 } else if (_nelems.dimension == 2) {
00364 _numChares = _nelems.data()[0] * _nelems.data()[1];
00365 } else if (_nelems.dimension == 3) {
00366 _numChares = _nelems.data()[0] * _nelems.data()[1] * _nelems.data()[2];
00367 } else if (_nelems.dimension == 4) {
00368 _numChares = (int)(((short int*)_nelems.data())[0] * ((short int*)_nelems.data())[1] * ((short int*)_nelems.data())[2] *
00369 ((short int*)_nelems.data())[3]);
00370 } else if (_nelems.dimension == 5) {
00371 _numChares = (int)(((short int*)_nelems.data())[0] * ((short int*)_nelems.data())[1] * ((short int*)_nelems.data())[2] *
00372 ((short int*)_nelems.data())[3] * ((short int*)_nelems.data())[4]);
00373 } else if (_nelems.dimension == 6) {
00374 _numChares = (int)(((short int*)_nelems.data())[0] * ((short int*)_nelems.data())[1] * ((short int*)_nelems.data())[2] *
00375 ((short int*)_nelems.data())[3] * ((short int*)_nelems.data())[4] * ((short int*)_nelems.data())[5]);
00376 }
00377
00378 _remChares = _numChares % numPes;
00379 _binSizeFloor = (int)floor((double)_numChares/(double)numPes);
00380 _binSizeCeil = (int)ceil((double)_numChares/(double)numPes);
00381 _numFirstSet = _remChares * (_binSizeFloor + 1);
00382
00383 _nRemChares = _numChares % numNodes;
00384 _nBinSizeFloor = _numChares/numNodes;
00385 _nNumFirstSet = _nRemChares * (_nBinSizeFloor +1);
00386 }
00387
00388 void pup(PUP::er& p){
00389 p|_nelems;
00390 p|_binSizeFloor;
00391 p|_binSizeCeil;
00392 p|_numChares;
00393 p|_remChares;
00394 p|_numFirstSet;
00395 p|_nBinSizeFloor;
00396 p|_nRemChares;
00397 p|_nNumFirstSet;
00398 }
00399 };
00400
00401
00406 class DefaultArrayMap : public RRMap
00407 {
00408 public:
00411 CkPupPtrVec<arrayMapInfo> amaps;
00412
00413 public:
00414 DefaultArrayMap(void) {
00415 DEBC((AA "Creating DefaultArrayMap\n" AB));
00416 }
00417
00418 DefaultArrayMap(CkMigrateMessage *m) : RRMap(m){}
00419
00420 int registerArray(const CkArrayIndex& numElements, CkArrayID aid)
00421 {
00422 int idx = amaps.size();
00423 amaps.resize(idx+1);
00424 amaps[idx] = new arrayMapInfo(numElements);
00425 return idx;
00426 }
00427
00428 void unregisterArray(int idx)
00429 {
00430 delete amaps[idx];
00431 amaps[idx] = NULL;
00432 }
00433
00434 int procNum(int arrayHdl, const CkArrayIndex &i) {
00435 int flati;
00436 if (amaps[arrayHdl]->_nelems.dimension == 0) {
00437 dynamicIns[arrayHdl] = true;
00438 return RRMap::procNum(arrayHdl, i);
00439 }
00440
00441 if (i.dimension == 1) {
00442 flati = i.data()[0];
00443 } else if (i.dimension == 2) {
00444 flati = i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1];
00445 } else if (i.dimension == 3) {
00446 flati = (i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1]) *
00447 amaps[arrayHdl]->_nelems.data()[2] + i.data()[2];
00448 } else if (i.dimension == 4) {
00449 flati = (int)(((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00450 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00451 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]);
00452 } else if (i.dimension == 5) {
00453 flati = (int)((((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00454 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00455 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]) *
00456 ((short int*)amaps[arrayHdl]->_nelems.data())[4] + ((short int*)i.data())[4]);
00457 } else if (i.dimension == 6) {
00458 flati = (int)(((((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00459 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00460 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]) *
00461 ((short int*)amaps[arrayHdl]->_nelems.data())[4] + ((short int*)i.data())[4]) *
00462 ((short int*)amaps[arrayHdl]->_nelems.data())[5] + ((short int*)i.data())[5]);
00463 }
00464 #if CMK_ERROR_CHECKING
00465 else {
00466 CkAbort("CkArrayIndex has more than 6 dimensions!");
00467 }
00468 #endif
00469
00470 if(useNodeBlkMapping){
00471 if(flati < amaps[arrayHdl]->_numChares){
00472 int numCharesOnNode = amaps[arrayHdl]->_nBinSizeFloor;
00473 int startNodeID, offsetInNode;
00474 if(flati < amaps[arrayHdl]->_nNumFirstSet){
00475 numCharesOnNode++;
00476 startNodeID = flati/numCharesOnNode;
00477 offsetInNode = flati%numCharesOnNode;
00478 }else{
00479 startNodeID = amaps[arrayHdl]->_nRemChares+(flati-amaps[arrayHdl]->_nNumFirstSet)/numCharesOnNode;
00480 offsetInNode = (flati-amaps[arrayHdl]->_nNumFirstSet)%numCharesOnNode;
00481 }
00482 int nodeSize = CkMyNodeSize();
00483 int elemsPerPE = numCharesOnNode/nodeSize;
00484 int remElems = numCharesOnNode%nodeSize;
00485 int firstSetPEs = remElems*(elemsPerPE+1);
00486 if(offsetInNode<firstSetPEs){
00487 return CkNodeFirst(startNodeID)+offsetInNode/(elemsPerPE+1);
00488 }else{
00489 return CkNodeFirst(startNodeID)+remElems+(offsetInNode-firstSetPEs)/elemsPerPE;
00490 }
00491 } else
00492 return (flati % CkNumPes());
00493 }
00494
00495 if(flati < amaps[arrayHdl]->_numFirstSet)
00496 return (flati / (amaps[arrayHdl]->_binSizeFloor + 1));
00497 else if (flati < amaps[arrayHdl]->_numChares)
00498 return (amaps[arrayHdl]->_remChares + (flati - amaps[arrayHdl]->_numFirstSet) / (amaps[arrayHdl]->_binSizeFloor));
00499 else
00500 return (flati % CkNumPes());
00501 }
00502
00503 void pup(PUP::er& p){
00504 RRMap::pup(p);
00505 int npes = CkNumPes();
00506 p|npes;
00507 p|amaps;
00508 if (p.isUnpacking() && npes != CkNumPes()) {
00509 for (int i=0; i<amaps.size(); i++)
00510 if (amaps[i])
00511 amaps[i]->compute_binsize();
00512 }
00513 }
00514 };
00515
00520 class FastArrayMap : public DefaultArrayMap
00521 {
00522 public:
00523 FastArrayMap(void) {
00524 DEBC((AA "Creating FastArrayMap\n" AB));
00525 }
00526
00527 FastArrayMap(CkMigrateMessage *m) : DefaultArrayMap(m){}
00528
00529 int registerArray(const CkArrayIndex& numElements, CkArrayID aid)
00530 {
00531 int idx;
00532 idx = DefaultArrayMap::registerArray(numElements, aid);
00533
00534 return idx;
00535 }
00536
00537 int procNum(int arrayHdl, const CkArrayIndex &i) {
00538 int flati = 0;
00539 if (amaps[arrayHdl]->_nelems.dimension == 0) {
00540 return RRMap::procNum(arrayHdl, i);
00541 }
00542
00543 if (i.dimension == 1) {
00544 flati = i.data()[0];
00545 } else if (i.dimension == 2) {
00546 flati = i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1];
00547 } else if (i.dimension == 3) {
00548 flati = (i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1]) *
00549 amaps[arrayHdl]->_nelems.data()[2] + i.data()[2];
00550 } else if (i.dimension == 4) {
00551 flati = (int)(((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00552 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00553 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]);
00554 } else if (i.dimension == 5) {
00555 flati = (int)((((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00556 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00557 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]) *
00558 ((short int*)amaps[arrayHdl]->_nelems.data())[4] + ((short int*)i.data())[4]);
00559 } else if (i.dimension == 6) {
00560 flati = (int)(((((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00561 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00562 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]) *
00563 ((short int*)amaps[arrayHdl]->_nelems.data())[4] + ((short int*)i.data())[4]) *
00564 ((short int*)amaps[arrayHdl]->_nelems.data())[5] + ((short int*)i.data())[5]);
00565 }
00566 #if CMK_ERROR_CHECKING
00567 else {
00568 CkAbort("CkArrayIndex has more than 6 dimensions!");
00569 }
00570 #endif
00571
00574 return (flati / amaps[arrayHdl]->_binSizeCeil);
00575 }
00576
00577 void pup(PUP::er& p){
00578 DefaultArrayMap::pup(p);
00579 }
00580 };
00581
00582
00583
00584
00585
00586
00587 typedef struct {
00588 int intIndex;
00589 std::vector<int> coords;
00590 }hilbert_pair;
00591
00592 bool operator== ( hilbert_pair p1, hilbert_pair p2)
00593 {
00594 return p1.intIndex == p2.intIndex;
00595 }
00596
00597 bool myCompare(hilbert_pair p1, hilbert_pair p2)
00598 {
00599 return p1.intIndex < p2.intIndex;
00600 }
00601
00602 class HilbertArrayMap: public DefaultArrayMap
00603 {
00604 std::vector<int> allpairs;
00605 std::vector<int> procList;
00606 public:
00607 HilbertArrayMap(void) {
00608 procList.resize(CkNumPes());
00609 getHilbertList(procList.data());
00610 DEBC((AA "Creating HilbertArrayMap\n" AB));
00611 }
00612
00613 HilbertArrayMap(CkMigrateMessage *m) : DefaultArrayMap(m){}
00614
00615 ~HilbertArrayMap() {}
00616
00617 int registerArray(const CkArrayIndex& i, CkArrayID aid)
00618 {
00619 int idx;
00620 idx = DefaultArrayMap::registerArray(i, aid);
00621
00622 if (i.dimension == 1) {
00623
00624 } else if (i.dimension == 2) {
00625
00626 const int dims = 2;
00627 int nDim0 = amaps[idx]->_nelems.data()[0];
00628 int nDim1 = amaps[idx]->_nelems.data()[1];
00629 int index;
00630 int counter = 0;
00631 std::vector<int> coords;
00632 allpairs.resize(nDim0*nDim1);
00633 coords.resize(dims);
00634 for(int i=0; i<nDim0; i++)
00635 for(int j=0; j<nDim1; j++)
00636 {
00637 coords[0] = i;
00638 coords[1] = j;
00639 index = Hilbert_to_int( coords, dims);
00640
00641 allpairs[counter] = index;
00642 counter++;
00643 }
00644 } else if (i.dimension == 3) {
00645
00646
00647 const int dims = 3;
00648 int nDim0 = amaps[idx]->_nelems.data()[0];
00649 int nDim1 = amaps[idx]->_nelems.data()[1];
00650 int nDim2 = amaps[idx]->_nelems.data()[2];
00651 int index;
00652 int counter = 0;
00653 std::vector<int> coords;
00654 allpairs.resize(nDim0*nDim1*nDim2);
00655 coords.resize(dims);
00656 for(int i=0; i<nDim0; i++)
00657 for(int j=0; j<nDim1; j++)
00658 for(int k=0; k<nDim2; k++)
00659 {
00660 coords[0] = i;
00661 coords[1] = j;
00662 coords[2] = k;
00663 index = Hilbert_to_int( coords, dims);
00664 allpairs[counter] = index;
00665 counter++;
00666 }
00667 } else if (i.dimension == 4) {
00668
00669
00670
00671 const int dims = 4;
00672 int nDim[dims];
00673 for(int k=0; k<dims; k++) {
00674 nDim[k] = (int)((short int*)amaps[idx]->_nelems.data())[k];
00675 }
00676 int index;
00677 int counter = 0;
00678 std::vector<int> coords;
00679 allpairs.resize(nDim[0]*nDim[1]*nDim[2]*nDim[3]);
00680 coords.resize(dims);
00681 for(int i=0; i<nDim[0]; i++)
00682 for(int j=0; j<nDim[1]; j++)
00683 for(int k=0; k<nDim[2]; k++)
00684 for(int x=0; x<nDim[3]; x++)
00685 {
00686 coords[0] = i;
00687 coords[1] = j;
00688 coords[2] = k;
00689 coords[3] = x;
00690 index = Hilbert_to_int(coords, dims);
00691 allpairs[counter] = index;
00692 counter++;
00693 }
00694 } else if (i.dimension == 5) {
00695
00696
00697
00698 const int dims = 5;
00699 int nDim[dims];
00700 for(int k=0; k<dims; k++) {
00701 nDim[k] = (int)((short int*)amaps[idx]->_nelems.data())[k];
00702 }
00703 int index;
00704 int counter = 0;
00705 std::vector<int> coords;
00706 allpairs.resize(nDim[0]*nDim[1]*nDim[2]*nDim[3]*nDim[4]);
00707 coords.resize(dims);
00708 for(int i=0; i<nDim[0]; i++)
00709 for(int j=0; j<nDim[1]; j++)
00710 for(int k=0; k<nDim[2]; k++)
00711 for(int x=0; x<nDim[3]; x++)
00712 for(int y=0; y<nDim[4]; y++)
00713 {
00714 coords[0] = i;
00715 coords[1] = j;
00716 coords[2] = k;
00717 coords[3] = x;
00718 coords[4] = y;
00719 index = Hilbert_to_int(coords, dims);
00720 allpairs[counter] = index;
00721 counter++;
00722 }
00723 } else if (i.dimension == 6) {
00724
00725
00726
00727
00728 const int dims = 6;
00729 int nDim[dims];
00730 for(int k=0; k<dims; k++) {
00731 nDim[k] = (int)((short int*)amaps[idx]->_nelems.data())[k];
00732 }
00733 int index;
00734 int counter = 0;
00735 std::vector<int> coords;
00736 allpairs.resize(nDim[0]*nDim[1]*nDim[2]*nDim[3]*nDim[4]*nDim[5]);
00737 coords.resize(dims);
00738 for(int i=0; i<nDim[0]; i++)
00739 for(int j=0; j<nDim[1]; j++)
00740 for(int k=0; k<nDim[2]; k++)
00741 for(int x=0; x<nDim[3]; x++)
00742 for(int y=0; y<nDim[4]; y++)
00743 for(int z=0; z<nDim[5]; z++)
00744 {
00745 coords[0] = i;
00746 coords[1] = j;
00747 coords[2] = k;
00748 coords[3] = x;
00749 coords[4] = y;
00750 coords[5] = y;
00751 index = Hilbert_to_int(coords, dims);
00752 allpairs[counter] = index;
00753 counter++;
00754 }
00755 }
00756 return idx;
00757 }
00758
00759 int procNum(int arrayHdl, const CkArrayIndex &i) {
00760 int flati = 0;
00761 int myInt;
00762 int dest;
00763 if (amaps[arrayHdl]->_nelems.dimension == 0) {
00764 return RRMap::procNum(arrayHdl, i);
00765 }
00766 if (i.dimension == 1) {
00767 flati = i.data()[0];
00768 } else if (i.dimension == 2) {
00769 int nDim1 = amaps[arrayHdl]->_nelems.data()[1];
00770 myInt = i.data()[0] * nDim1 + i.data()[1];
00771 flati = allpairs[myInt];
00772 } else if (i.dimension == 3) {
00773 hilbert_pair mypair;
00774 mypair.coords.resize(3);
00775 int nDim[2];
00776 for (int j = 0; j < 2; j++) {
00777 nDim[j] = amaps[arrayHdl]->_nelems.data()[j+1];
00778 }
00779 myInt = i.data()[0] * nDim[0] * nDim[1] + i.data()[1] * nDim[1] + i.data()[2];
00780 flati = allpairs[myInt];
00781 } else if (i.dimension == 4) {
00782 hilbert_pair mypair;
00783 mypair.coords.resize(4);
00784 short int nDim[3];
00785 for (int j = 0; j < 3; j++) {
00786 nDim[j] = ((short int*)amaps[arrayHdl]->_nelems.data())[j+1];
00787 }
00788 myInt = (int)(((short int*)i.data())[0] * nDim[0] * nDim[1] * nDim[2] +
00789 ((short int*)i.data())[1] * nDim[1] * nDim[2] +
00790 ((short int*)i.data())[2] * nDim[2] +
00791 ((short int*)i.data())[3]);
00792 flati = allpairs[myInt];
00793 } else if (i.dimension == 5) {
00794 hilbert_pair mypair;
00795 mypair.coords.resize(5);
00796 short int nDim[4];
00797 for (int j = 0; j < 4; j++) {
00798 nDim[j] = ((short int*)amaps[arrayHdl]->_nelems.data())[j+1];
00799 }
00800 myInt = (int)(((short int*)i.data())[0] * nDim[0] * nDim[1] * nDim[2] * nDim[3] +
00801 ((short int*)i.data())[1] * nDim[1] * nDim[2] * nDim[3] +
00802 ((short int*)i.data())[2] * nDim[2] * nDim[3] +
00803 ((short int*)i.data())[3] * nDim[3] +
00804 ((short int*)i.data())[4]);
00805 flati = allpairs[myInt];
00806 } else if (i.dimension == 6) {
00807 hilbert_pair mypair;
00808 mypair.coords.resize(6);
00809 short int nDim[5];
00810 for (int j = 0; j < 5; j++) {
00811 nDim[j] = ((short int*)amaps[arrayHdl]->_nelems.data())[j+1];
00812 }
00813 myInt = (int)(((short int*)i.data())[0] * nDim[0] * nDim[1] * nDim[2] * nDim[3] * nDim[4] +
00814 ((short int*)i.data())[1] * nDim[1] * nDim[2] * nDim[3] * nDim[4] +
00815 ((short int*)i.data())[2] * nDim[2] * nDim[3] * nDim[4] +
00816 ((short int*)i.data())[3] * nDim[3] * nDim[4] +
00817 ((short int*)i.data())[4] * nDim[4] +
00818 ((short int*)i.data())[5]);
00819 flati = allpairs[myInt];
00820 }
00821 #if CMK_ERROR_CHECKING
00822 else {
00823 CkAbort("CkArrayIndex has more than 6 dimensions!");
00824 }
00825 #endif
00826
00829 int block = flati / amaps[arrayHdl]->_binSizeCeil;
00830
00831
00832
00833
00834 return procList[block];
00835 }
00836
00837 void pup(PUP::er& p){
00838 DefaultArrayMap::pup(p);
00839 }
00840 };
00841
00842
00847 class ReadFileMap : public DefaultArrayMap
00848 {
00849 private:
00850 std::vector<int> mapping;
00851
00852 public:
00853 ReadFileMap(void) {
00854 DEBC((AA "Creating ReadFileMap\n" AB));
00855 }
00856
00857 ReadFileMap(CkMigrateMessage *m) : DefaultArrayMap(m){}
00858
00859 int registerArray(const CkArrayIndex& numElements, CkArrayID aid)
00860 {
00861 int idx;
00862 idx = DefaultArrayMap::registerArray(numElements, aid);
00863
00864 if(mapping.size() == 0) {
00865 int numChares;
00866
00867 if (amaps[idx]->_nelems.dimension == 1) {
00868 numChares = amaps[idx]->_nelems.data()[0];
00869 } else if (amaps[idx]->_nelems.dimension == 2) {
00870 numChares = amaps[idx]->_nelems.data()[0] * amaps[idx]->_nelems.data()[1];
00871 } else if (amaps[idx]->_nelems.dimension == 3) {
00872 numChares = amaps[idx]->_nelems.data()[0] * amaps[idx]->_nelems.data()[1] *
00873 amaps[idx]->_nelems.data()[2];
00874 } else if (amaps[idx]->_nelems.dimension == 4) {
00875 numChares = (int)(((short int*)amaps[idx]->_nelems.data())[0] * ((short int*)amaps[idx]->_nelems.data())[1] *
00876 ((short int*)amaps[idx]->_nelems.data())[2] * ((short int*)amaps[idx]->_nelems.data())[3]);
00877 } else if (amaps[idx]->_nelems.dimension == 5) {
00878 numChares = (int)(((short int*)amaps[idx]->_nelems.data())[0] * ((short int*)amaps[idx]->_nelems.data())[1] *
00879 ((short int*)amaps[idx]->_nelems.data())[2] * ((short int*)amaps[idx]->_nelems.data())[3] *
00880 ((short int*)amaps[idx]->_nelems.data())[4]);
00881 } else if (amaps[idx]->_nelems.dimension == 6) {
00882 numChares = (int)(((short int*)amaps[idx]->_nelems.data())[0] * ((short int*)amaps[idx]->_nelems.data())[1] *
00883 ((short int*)amaps[idx]->_nelems.data())[2] * ((short int*)amaps[idx]->_nelems.data())[3] *
00884 ((short int*)amaps[idx]->_nelems.data())[4] * ((short int*)amaps[idx]->_nelems.data())[5]);
00885 } else {
00886 CkAbort("CkArrayIndex has more than 6 dimension!");
00887 }
00888
00889 mapping.resize(numChares);
00890 FILE *mapf = fopen("mapfile", "r");
00891 TopoManager tmgr;
00892 int x, y, z, t;
00893
00894 for(int i=0; i<numChares; i++) {
00895 if (fscanf(mapf, "%d %d %d %d", &x, &y, &z, &t) != 4) {
00896 CkAbort("ReadFileMap> reading from mapfile failed!");
00897 }
00898 mapping[i] = tmgr.coordinatesToRank(x, y, z, t);
00899 }
00900 fclose(mapf);
00901 }
00902
00903 return idx;
00904 }
00905
00906 int procNum(int arrayHdl, const CkArrayIndex &i) {
00907 int flati;
00908
00909 if (i.dimension == 1) {
00910 flati = i.data()[0];
00911 } else if (i.dimension == 2) {
00912 flati = i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1];
00913 } else if (i.dimension == 3) {
00914 flati = (i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1]) *
00915 amaps[arrayHdl]->_nelems.data()[2] + i.data()[2];
00916 } else if (i.dimension == 4) {
00917 flati = (int)(((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00918 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00919 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]);
00920 } else if (i.dimension == 5) {
00921 flati = (int)((((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00922 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00923 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]) *
00924 ((short int*)amaps[arrayHdl]->_nelems.data())[4] + ((short int*)i.data())[4]);
00925 } else if (i.dimension == 6) {
00926 flati = (int)(((((((short int*)i.data())[0] * ((short int*)amaps[arrayHdl]->_nelems.data())[1] + ((short int*)i.data())[1]) *
00927 ((short int*)amaps[arrayHdl]->_nelems.data())[2] + ((short int*)i.data())[2]) *
00928 ((short int*)amaps[arrayHdl]->_nelems.data())[3] + ((short int*)i.data())[3]) *
00929 ((short int*)amaps[arrayHdl]->_nelems.data())[4] + ((short int*)i.data())[4]) *
00930 ((short int*)amaps[arrayHdl]->_nelems.data())[5] + ((short int*)i.data())[5]);
00931 } else {
00932 CkAbort("CkArrayIndex has more than 6 dimensions!");
00933 }
00934
00935 return mapping[flati];
00936 }
00937
00938 void pup(PUP::er& p){
00939 DefaultArrayMap::pup(p);
00940 p|mapping;
00941 }
00942 };
00943
00944 class BlockMap : public RRMap
00945 {
00946 public:
00947 BlockMap(void){
00948 DEBC((AA "Creating BlockMap\n" AB));
00949 }
00950 BlockMap(CkMigrateMessage *m):RRMap(m){ }
00951 void populateInitial(int arrayHdl,CkArrayOptions& options,void *ctorMsg,CkArray *mgr){
00952 CkArrayIndex start = options.getStart();
00953 CkArrayIndex end = options.getEnd();
00954 CkArrayIndex step = options.getStep();
00955 if (end.dimension == 0) {
00956 CkFreeMsg(ctorMsg);
00957 return;
00958 }
00959 int thisPe=CkMyPe();
00960 int numPes=CkNumPes();
00961 int binSize;
00962 if (end.dimension == 1) {
00963 binSize = (int)ceil((double)(end.data()[0]) / (double)numPes);
00964 } else if (end.dimension == 2) {
00965 binSize = (int)ceil((double)(end.data()[0] * end.data()[1]) / (double)numPes);
00966 } else if (end.dimension == 3) {
00967 binSize = (int)ceil((double)(end.data()[0] * end.data()[1] * end.data()[2])) / (double)numPes;
00968 } else if (end.dimension == 4) {
00969 binSize = (int)ceil((double)(((short int*)end.data())[0] * ((short int*)end.data())[1] *
00970 ((short int*)end.data())[2] * ((short int*)end.data())[3]) / (double)numPes);
00971 } else if (end.dimension == 5) {
00972 binSize = (int)ceil((double)(((short int*)end.data())[0] * ((short int*)end.data())[1] *
00973 ((short int*)end.data())[2] * ((short int*)end.data())[3] * ((short int*)end.data())[4]) /
00974 (double)numPes);
00975 } else if (end.dimension == 6) {
00976 binSize = (int)ceil((double)(((short int*)end.data())[0] * ((short int*)end.data())[1] *
00977 ((short int*)end.data())[2] * ((short int*)end.data())[3] * ((short int*)end.data())[4] *
00978 ((short int*)end.data())[5]) / (double)numPes);
00979 } else {
00980 CkAbort("CkArrayIndex has more than 6 dimensions!");
00981 }
00982 CKARRAYMAP_POPULATE_INITIAL(i/binSize==thisPe);
00983
00984
00985
00986
00987
00988
00989
00990 mgr->doneInserting();
00991 CkFreeMsg(ctorMsg);
00992 }
00993 };
00994
00998 class CldMap : public CkArrayMap
00999 {
01000 public:
01001 CldMap(void)
01002 {
01003 DEBC((AA "Creating CldMap\n" AB));
01004 }
01005 CldMap(CkMigrateMessage *m):CkArrayMap(m){}
01006 int homePe(int , const CkArrayIndex &i)
01007 {
01008 if (i.dimension == 1) {
01009
01010 return (i.data()[0])%CkNumPes();
01011 }
01012 else
01013 {
01014
01015 unsigned int hash=(i.hash()+739)%1280107;
01016 return (hash % CkNumPes());
01017 }
01018 }
01019 int procNum(int arrayHdl, const CkArrayIndex &i)
01020 {
01021 return CLD_ANYWHERE;
01022 }
01023 void populateInitial(int arrayHdl,CkArrayOptions& options,void *ctorMsg,CkArray *mgr) {
01024 CkArrayIndex start = options.getStart();
01025 CkArrayIndex end = options.getEnd();
01026 CkArrayIndex step = options.getStep();
01027 if (end.dimension == 0) {
01028 CkFreeMsg(ctorMsg);
01029 return;
01030 }
01031 int thisPe=CkMyPe();
01032 int numPes=CkNumPes();
01033
01034 CKARRAYMAP_POPULATE_INITIAL(i%numPes==thisPe);
01035 mgr->doneInserting();
01036 CkFreeMsg(ctorMsg);
01037 }
01038 };
01039
01040
01043 class ConfigurableRRMapLoader {
01044 public:
01045
01046 std::vector<int> locations;
01047 int objs_per_block;
01048 int PE_per_block;
01049
01051 enum ConfigurableRRMapLoadStatus : uint8_t {
01052 not_loaded,
01053 loaded_found,
01054 loaded_not_found
01055 };
01056
01057 enum ConfigurableRRMapLoadStatus state;
01058
01059 ConfigurableRRMapLoader(){
01060 state = not_loaded;
01061 objs_per_block = 0;
01062 PE_per_block = 0;
01063 }
01064
01066 bool haveConfiguration() {
01067 if(state == not_loaded) {
01068 DEBUG(("[%d] loading ConfigurableRRMap configuration\n", CkMyPe()));
01069 char **argv=CkGetArgv();
01070 char *configuration = NULL;
01071 bool found = CmiGetArgString(argv, "+ConfigurableRRMap", &configuration);
01072 if(!found){
01073 DEBUG(("Couldn't find +ConfigurableRRMap command line argument\n"));
01074 state = loaded_not_found;
01075 return false;
01076 } else {
01077
01078 DEBUG(("Found +ConfigurableRRMap command line argument in %p=\"%s\"\n", configuration, configuration));
01079
01080 std::istringstream instream(configuration);
01081 CkAssert(instream.good());
01082
01083
01084
01085
01086
01087
01088 instream >> objs_per_block >> PE_per_block;
01089 CkAssert(instream.good());
01090 CkAssert(objs_per_block > 0);
01091 CkAssert(PE_per_block > 0);
01092 locations.resize(objs_per_block);
01093 for(int i=0;i<objs_per_block;i++){
01094 locations[i] = 0;
01095 CkAssert(instream.good());
01096 instream >> locations[i];
01097 CkAssert(locations[i] < PE_per_block);
01098 }
01099 state = loaded_found;
01100 return true;
01101 }
01102
01103 } else {
01104 DEBUG(("[%d] ConfigurableRRMap has already been loaded\n", CkMyPe()));
01105 return state == loaded_found;
01106 }
01107
01108 }
01109
01110 };
01111
01112 CkpvDeclare(ConfigurableRRMapLoader, myConfigRRMapState);
01113
01114 void _initConfigurableRRMap(){
01115 CkpvInitialize(ConfigurableRRMapLoader, myConfigRRMapState);
01116 }
01117
01118
01120 bool haveConfigurableRRMap(){
01121 DEBUG(("haveConfigurableRRMap()\n"));
01122 ConfigurableRRMapLoader &loader = CkpvAccess(myConfigRRMapState);
01123 return loader.haveConfiguration();
01124 }
01125
01126 class ConfigurableRRMap : public RRMap
01127 {
01128 public:
01129 ConfigurableRRMap(void){
01130 DEBC((AA "Creating ConfigurableRRMap\n" AB));
01131 }
01132 ConfigurableRRMap(CkMigrateMessage *m):RRMap(m){ }
01133
01134
01135 void populateInitial(int arrayHdl,CkArrayOptions& options,void *ctorMsg,CkArray *mgr){
01136 CkArrayIndex start = options.getStart();
01137 CkArrayIndex end = options.getEnd();
01138 CkArrayIndex step = options.getStep();
01139
01140 CkAssert(haveConfigurableRRMap());
01141 ConfigurableRRMapLoader &loader = CkpvAccess(myConfigRRMapState);
01142 if (end.dimension == 0) {
01143 CkFreeMsg(ctorMsg);
01144 return;
01145 }
01146 int thisPe=CkMyPe();
01147 int maxIndex = end.data()[0];
01148 DEBUG(("[%d] ConfigurableRRMap: index=%d,%d,%d\n", CkMyPe(),(int)end.data()[0], (int)end.data()[1], (int)end.data()[2]));
01149
01150 if (end.dimension != 1) {
01151 CkAbort("ConfigurableRRMap only supports dimension 1!");
01152 }
01153
01154 for (int index=0; index<maxIndex; index++) {
01155 CkArrayIndex1D idx(index);
01156
01157 int cyclic_block = index / loader.objs_per_block;
01158 int cyclic_local = index % loader.objs_per_block;
01159 int l = loader.locations[ cyclic_local ];
01160 int PE = (cyclic_block*loader.PE_per_block + l) % CkNumPes();
01161
01162 DEBUG(("[%d] ConfigurableRRMap: index=%d is located on PE %d l=%d\n", CkMyPe(), (int)index, (int)PE, l));
01163
01164 if(PE == thisPe)
01165 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg));
01166
01167 }
01168
01169
01170 mgr->doneInserting();
01171 CkFreeMsg(ctorMsg);
01172 }
01173 };
01174
01175
01176 CkpvStaticDeclare(double*, rem);
01177
01178 class arrInfo {
01179 private:
01180 CkArrayIndex _nelems;
01181 std::vector<int> _map;
01182 public:
01183 arrInfo() {}
01184 arrInfo(const CkArrayIndex& n, int *speeds) : _nelems(n), _map(_nelems.getCombinedCount())
01185 {
01186 distrib(speeds);
01187 }
01188 ~arrInfo() {}
01189 int getMap(const CkArrayIndex &i);
01190 void distrib(int *speeds);
01191 void pup(PUP::er& p){
01192 p|_nelems;
01193 p|_map;
01194 }
01195 };
01196
01197 static int cmp(const void *first, const void *second)
01198 {
01199 int fi = *((const int *)first);
01200 int si = *((const int *)second);
01201 return ((CkpvAccess(rem)[fi]==CkpvAccess(rem)[si]) ?
01202 0 :
01203 ((CkpvAccess(rem)[fi]<CkpvAccess(rem)[si]) ?
01204 1 : (-1)));
01205 }
01206
01207 void
01208 arrInfo::distrib(int *speeds)
01209 {
01210 int _nelemsCount = _nelems.getCombinedCount();
01211 double total = 0.0;
01212 int npes = CkNumPes();
01213 int i,j,k;
01214 for(i=0;i<npes;i++)
01215 total += (double) speeds[i];
01216 std::vector<double> nspeeds(npes);
01217 for(i=0;i<npes;i++)
01218 nspeeds[i] = (double) speeds[i] / total;
01219 std::vector<int> cp(npes);
01220 for(i=0;i<npes;i++)
01221 cp[i] = (int) (nspeeds[i]*_nelemsCount);
01222 int nr = 0;
01223 for(i=0;i<npes;i++)
01224 nr += cp[i];
01225 nr = _nelemsCount - nr;
01226 if(nr != 0)
01227 {
01228 CkpvAccess(rem) = new double[npes];
01229 for(i=0;i<npes;i++)
01230 CkpvAccess(rem)[i] = (double)_nelemsCount*nspeeds[i] - cp[i];
01231 std::vector<int> pes(npes);
01232 for(i=0;i<npes;i++)
01233 pes[i] = i;
01234 qsort(pes.data(), npes, sizeof(int), cmp);
01235 for(i=0;i<nr;i++)
01236 cp[pes[i]]++;
01237 delete[] CkpvAccess(rem);
01238 }
01239 k = 0;
01240 for(i=0;i<npes;i++)
01241 {
01242 for(j=0;j<cp[i];j++)
01243 _map[k++] = i;
01244 }
01245 }
01246
01247 int
01248 arrInfo::getMap(const CkArrayIndex &i)
01249 {
01250 if(i.dimension == 1)
01251 return _map[i.data()[0]];
01252 else
01253 return _map[((i.hash()+739)%1280107)%_nelems.getCombinedCount()];
01254 }
01255
01256
01257
01258 static int* speeds;
01259
01260 #if CMK_USE_PROP_MAP
01261 typedef struct _speedmsg
01262 {
01263 char hdr[CmiMsgHeaderSizeBytes];
01264 int node;
01265 int speed;
01266 } speedMsg;
01267
01268 static void _speedHdlr(void *m)
01269 {
01270 speedMsg *msg=(speedMsg *)m;
01271 if (CmiMyRank()==0)
01272 for (int pe=0;pe<CmiNodeSize(msg->node);pe++)
01273 speeds[CmiNodeFirst(msg->node)+pe] = msg->speed;
01274 CmiFree(m);
01275 }
01276
01277
01278 void _propMapInit(void)
01279 {
01280 speeds = new int[CkNumPes()];
01281 int hdlr = CkRegisterHandler(_speedHdlr);
01282 CmiPrintf("[%d]Measuring processor speed for prop. mapping...\n", CkMyPe());
01283 int s = LDProcessorSpeed();
01284 speedMsg msg;
01285 CmiSetHandler(&msg, hdlr);
01286 msg.node = CkMyNode();
01287 msg.speed = s;
01288 CmiSyncBroadcastAllAndFree(sizeof(msg), &msg);
01289 for(int i=0;i<CkNumNodes();i++)
01290 CmiDeliverSpecificMsg(hdlr);
01291 }
01292 #else
01293 void _propMapInit(void)
01294 {
01295 speeds = new int[CkNumPes()];
01296 int i;
01297 for(i=0;i<CkNumPes();i++)
01298 speeds[i] = 1;
01299 }
01300 #endif
01301
01307 class PropMap : public CkArrayMap
01308 {
01309 private:
01310 CkPupPtrVec<arrInfo> arrs;
01311 public:
01312 PropMap(void)
01313 {
01314 CkpvInitialize(double*, rem);
01315 DEBC((AA "Creating PropMap\n" AB));
01316 }
01317 PropMap(CkMigrateMessage *m) {}
01318 int registerArray(const CkArrayIndex& numElements, CkArrayID aid)
01319 {
01320 int idx = arrs.size();
01321 arrs.resize(idx+1);
01322 arrs[idx] = new arrInfo(numElements, speeds);
01323 return idx;
01324 }
01325 void unregisterArray(int idx)
01326 {
01327 arrs[idx].destroy();
01328 }
01329 int procNum(int arrayHdl, const CkArrayIndex &i)
01330 {
01331 return arrs[arrayHdl]->getMap(i);
01332 }
01333 void pup(PUP::er& p){
01334 int oldNumPes = -1;
01335 if(p.isPacking()){
01336 oldNumPes = CkNumPes();
01337 }
01338 p|oldNumPes;
01339 p|arrs;
01340 if(p.isUnpacking() && oldNumPes != CkNumPes()){
01341 for(int idx = 0; idx < arrs.length(); ++idx){
01342 arrs[idx]->distrib(speeds);
01343 }
01344 }
01345 }
01346 };
01347
01348 class CkMapsInit : public Chare
01349 {
01350 public:
01351 CkMapsInit(CkArgMsg *msg) {
01352
01353 _defaultArrayMapID = CProxy_DefaultArrayMap::ckNew();
01354 _fastArrayMapID = CProxy_FastArrayMap::ckNew();
01355 delete msg;
01356 }
01357
01358 CkMapsInit(CkMigrateMessage *m) {}
01359 };
01360
01361
01362 CkMigratable * CkArrayMessageObjectPtr(envelope *env) {
01363 if (env->getMsgtype() != ForArrayEltMsg)
01364 return NULL;
01365
01367 CkArray *mgr = CProxy_CkArray(env->getArrayMgr()).ckLocalBranch();
01368 return mgr ? mgr->lookup(ck::ObjID(env->getRecipientID()).getElementID()) : NULL;
01369 }
01370
01371
01372
01373 #if CMK_OUT_OF_CORE
01374 CooPrefetchManager CkArrayElementPrefetcher;
01375 CkpvDeclare(int,CkSaveRestorePrefetch);
01376
01382 int CkArrayPrefetch_msg2ObjId(void *msg) {
01383 envelope *env=(envelope *)msg;
01384 CkMigratable *elt = CkArrayMessageObjectPtr(env);
01385 return elt?elt->prefetchObjID:-1;
01386 }
01387
01392 void CkArrayPrefetch_writeToSwap(FILE *swapfile,void *objptr) {
01393 CkMigratable *elt=(CkMigratable *)objptr;
01394
01395
01396 PUP::toDisk p(swapfile);
01397 elt->virtual_pup(p);
01398
01399
01400 CkpvAccess(CkSaveRestorePrefetch)=1;
01401 elt->~CkMigratable();
01402 CkpvAccess(CkSaveRestorePrefetch)=0;
01403 }
01404
01409 void CkArrayPrefetch_readFromSwap(FILE *swapfile,void *objptr) {
01410 CkMigratable *elt=(CkMigratable *)objptr;
01411
01412 CkpvAccess(CkSaveRestorePrefetch)=1;
01413 int ctorIdx=_chareTable[elt->thisChareType]->migCtor;
01414 elt->myRec->invokeEntry(elt,(CkMigrateMessage *)0,ctorIdx,true);
01415 CkpvAccess(CkSaveRestorePrefetch)=0;
01416
01417
01418 PUP::fromDisk p(swapfile);
01419 elt->virtual_pup(p);
01420 }
01421
01422 static void _CkMigratable_prefetchInit(void)
01423 {
01424 CkpvExtern(int,CkSaveRestorePrefetch);
01425 CkpvAccess(CkSaveRestorePrefetch)=0;
01426 CkArrayElementPrefetcher.msg2ObjId=CkArrayPrefetch_msg2ObjId;
01427 CkArrayElementPrefetcher.writeToSwap=CkArrayPrefetch_writeToSwap;
01428 CkArrayElementPrefetcher.readFromSwap=CkArrayPrefetch_readFromSwap;
01429 CooRegisterManager(&CkArrayElementPrefetcher, _charmHandlerIdx);
01430 }
01431 #endif
01432
01433
01438 class CkMigratable_initInfo {
01439 public:
01440 CkLocRec *locRec;
01441 int chareType;
01442 bool forPrefetch;
01443 };
01444
01445 CkpvStaticDeclare(CkMigratable_initInfo,mig_initInfo);
01446
01447
01448 void _CkMigratable_initInfoInit(void) {
01449 CkpvInitialize(CkMigratable_initInfo,mig_initInfo);
01450 #if CMK_OUT_OF_CORE
01451 _CkMigratable_prefetchInit();
01452 #endif
01453 }
01454
01455 void CkMigratable::commonInit(void) {
01456 CkMigratable_initInfo &i=CkpvAccess(mig_initInfo);
01457 #if CMK_OUT_OF_CORE
01458 isInCore=true;
01459 if (CkpvAccess(CkSaveRestorePrefetch))
01460 return;
01461 prefetchObjID=-1;
01462 #endif
01463 myRec=i.locRec;
01464 thisIndexMax=myRec->getIndex();
01465 thisChareType=i.chareType;
01466 usesAtSync=false;
01467 usesAutoMeasure=true;
01468 barrierRegistered=false;
01469
01470 local_state = OFF;
01471 prev_load = 0.0;
01472 can_reset = false;
01473
01474 #if CMK_LBDB_ON
01475 if (_lb_args.metaLbOn()) {
01476 atsync_iteration = myRec->getMetaBalancer()->get_iteration();
01477 myRec->getMetaBalancer()->AdjustCountForNewContributor(atsync_iteration);
01478 }
01479 #endif
01480
01481 #if CMK_FAULT_EVAC
01482 AsyncEvacuate(true);
01483 #endif
01484 }
01485
01486 CkMigratable::CkMigratable(void) {
01487 DEBC((AA "In CkMigratable constructor\n" AB));
01488 commonInit();
01489 }
01490 CkMigratable::CkMigratable(CkMigrateMessage *m): Chare(m) {
01491 commonInit();
01492 }
01493
01494 int CkMigratable::ckGetChareType(void) const {return thisChareType;}
01495
01496 void CkMigratable::pup(PUP::er &p) {
01497 DEBM((AA "In CkMigratable::pup %s\n" AB,idx2str(thisIndexMax)));
01498 Chare::pup(p);
01499 p|thisIndexMax;
01500 p(usesAtSync);
01501 p(can_reset);
01502 p(usesAutoMeasure);
01503 #if CMK_LBDB_ON
01504 int readyMigrate = 0;
01505 if (p.isPacking()) readyMigrate = myRec->isReadyMigrate();
01506 p|readyMigrate;
01507 if (p.isUnpacking()) myRec->ReadyMigrate(readyMigrate);
01508 #endif
01509 if(p.isUnpacking()) barrierRegistered=false;
01510
01511 #if CMK_FAULT_EVAC
01512 p | asyncEvacuate;
01513 if(p.isUnpacking()){myRec->AsyncEvacuate(asyncEvacuate);}
01514 #endif
01515
01516 ckFinishConstruction();
01517 }
01518
01519 void CkMigratable::ckDestroy(void) {}
01520 void CkMigratable::ckAboutToMigrate(void) { }
01521 void CkMigratable::ckJustMigrated(void) { }
01522 void CkMigratable::ckJustRestored(void) { }
01523
01524 CkMigratable::~CkMigratable() {
01525 DEBC((AA "In CkMigratable::~CkMigratable %s\n" AB,idx2str(thisIndexMax)));
01526 #if CMK_OUT_OF_CORE
01527 isInCore=false;
01528 if (CkpvAccess(CkSaveRestorePrefetch))
01529 return;
01530
01531 if (prefetchObjID!=-1) {
01532 CooDeregisterObject(prefetchObjID);
01533 prefetchObjID=-1;
01534 }
01535 #endif
01536 #if CMK_LBDB_ON
01537 if (barrierRegistered) {
01538 DEBL((AA "Removing barrier for element %s\n" AB,idx2str(thisIndexMax)));
01539 if (usesAtSync)
01540 myRec->getLBDB()->RemoveLocalBarrierClient(ldBarrierHandle);
01541 else
01542 myRec->getLBDB()->RemoveLocalBarrierReceiver(ldBarrierRecvHandle);
01543 }
01544
01545 if (_lb_args.metaLbOn()) {
01546 myRec->getMetaBalancer()->AdjustCountForDeadContributor(atsync_iteration);
01547 }
01548 #endif
01549 myRec->destroy();
01550
01551 thisIndexMax.nInts=0;
01552 thisIndexMax.dimension=0;
01553 }
01554
01555 void CkMigratable::CkAbort(const char *why) const {
01556 CkError("CkMigratable '%s' aborting:\n",_chareTable[thisChareType]->name);
01557 ::CkAbort(why);
01558 }
01559
01560 void CkMigratable::ResumeFromSync(void)
01561 {
01562
01563 }
01564
01565 void CkMigratable::UserSetLBLoad() {
01566 CkAbort("::UserSetLBLoad() not defined for this array element!\n");
01567 }
01568
01569 #if CMK_LBDB_ON //For load balancing:
01570
01571 void CkMigratable::setObjTime(double cputime) {
01572 myRec->setObjTime(cputime);
01573 }
01574 double CkMigratable::getObjTime() {
01575 return myRec->getObjTime();
01576 }
01577
01578 #if CMK_LB_USER_DATA
01579
01595 void *CkMigratable::getObjUserData(int idx) {
01596 return myRec->getObjUserData(idx);
01597 }
01598 #endif
01599
01600 void CkMigratable::clearMetaLBData() {
01601
01602 local_state = OFF;
01603 atsync_iteration = -1;
01604 prev_load = 0.0;
01605 can_reset = false;
01606
01607 }
01608
01609 void CkMigratable::recvLBPeriod(void *data) {
01610 if (atsync_iteration < 0) {
01611 return;
01612 }
01613 int lb_period = *((int *) data);
01614 DEBAD(("\t[obj %s] Received the LB Period %d current iter %d state %d on PE %d\n",
01615 idx2str(thisIndexMax), lb_period, atsync_iteration, local_state, CkMyPe()));
01616
01617 bool is_tentative;
01618 if (local_state == LOAD_BALANCE) {
01619 CkAssert(lb_period == myRec->getMetaBalancer()->getPredictedLBPeriod(is_tentative));
01620 return;
01621 }
01622
01623 if (local_state == PAUSE) {
01624 if (atsync_iteration < lb_period) {
01625 local_state = DECIDED;
01626 ResumeFromSync();
01627 return;
01628 }
01629 local_state = LOAD_BALANCE;
01630
01631 can_reset = true;
01632
01633 return;
01634 }
01635 local_state = DECIDED;
01636 }
01637
01638 void CkMigratable::metaLBCallLB() {
01639 if(usesAtSync)
01640 myRec->getLBDB()->AtLocalBarrier(ldBarrierHandle);
01641 }
01642
01643 void CkMigratable::ckFinishConstruction(void)
01644 {
01645
01646 myRec->setMeasure(usesAutoMeasure);
01647 if (barrierRegistered) return;
01648 DEBL((AA "Registering barrier client for %s\n" AB,idx2str(thisIndexMax)));
01649 if (usesAtSync)
01650 ldBarrierHandle = myRec->getLBDB()->AddLocalBarrierClient(
01651 (LDBarrierFn)staticResumeFromSync,(void*)(this));
01652 else
01653 ldBarrierRecvHandle = myRec->getLBDB()->AddLocalBarrierReceiver(
01654 (LDBarrierFn)staticResumeFromSync,(void*)(this));
01655 barrierRegistered=true;
01656 }
01657
01658 void CkMigratable::AtSync(int waitForMigration)
01659 {
01660 if (!usesAtSync)
01661 CkAbort("You must set usesAtSync=true in your array element constructor to use AtSync!\n");
01662 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01663 mlogData->toResumeOrNot=1;
01664 #endif
01665 if(CkpvAccess(hasNullLB)) {
01666 ResumeFromSync();
01667 return;
01668 }
01669 myRec->AsyncMigrate(!waitForMigration);
01670 if (waitForMigration) ReadyMigrate(true);
01671 ckFinishConstruction();
01672 DEBL((AA "Element %s going to sync\n" AB,idx2str(thisIndexMax)));
01673
01674 if (usesAutoMeasure == false) UserSetLBLoad();
01675
01676 if(_lb_psizer_on || _lb_args.metaLbOn()){
01677 PUP::sizer ps;
01678 this->virtual_pup(ps);
01679 if(_lb_psizer_on)
01680 setPupSize(ps.size());
01681 if(_lb_args.metaLbOn())
01682 myRec->getMetaBalancer()->SetCharePupSize(ps.size());
01683 }
01684
01685 if (!_lb_args.metaLbOn()) {
01686 myRec->getLBDB()->AtLocalBarrier(ldBarrierHandle);
01687 return;
01688 }
01689
01690
01691
01692 if (atsync_iteration == -1) {
01693 can_reset = false;
01694 local_state = OFF;
01695 prev_load = 0.0;
01696 }
01697
01698 atsync_iteration++;
01699
01700
01701
01702 double tmp = prev_load;
01703 prev_load = myRec->getObjTime();
01704 double current_load = prev_load - tmp;
01705
01706
01707
01708 if (!usesAutoMeasure) {
01709 current_load = myRec->getObjTime();
01710 }
01711
01712 if (atsync_iteration <= myRec->getMetaBalancer()->get_finished_iteration()) {
01713 CkPrintf("[%d:%s] Error!! Contributing to iter %d < current iter %d\n",
01714 CkMyPe(), idx2str(thisIndexMax), atsync_iteration,
01715 myRec->getMetaBalancer()->get_finished_iteration());
01716 CkAbort("Not contributing to the right iteration\n");
01717 }
01718
01719 if (atsync_iteration != 0) {
01720 myRec->getMetaBalancer()->AddLoad(atsync_iteration, current_load);
01721 }
01722
01723 bool is_tentative;
01724 if (atsync_iteration < myRec->getMetaBalancer()->getPredictedLBPeriod(is_tentative)) {
01725 ResumeFromSync();
01726 } else if (is_tentative) {
01727 local_state = PAUSE;
01728 } else if (local_state == DECIDED) {
01729 DEBAD(("[%d:%s] Went to load balance iter %d\n", CkMyPe(), idx2str(thisIndexMax), atsync_iteration));
01730 local_state = LOAD_BALANCE;
01731 can_reset = true;
01732
01733 } else {
01734 DEBAD(("[%d:%s] Went to pause state iter %d\n", CkMyPe(), idx2str(thisIndexMax), atsync_iteration));
01735 local_state = PAUSE;
01736 }
01737 }
01738
01739 void CkMigratable::ReadyMigrate(bool ready)
01740 {
01741 myRec->ReadyMigrate(ready);
01742 }
01743
01744 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01745 extern int globalResumeCount;
01746 #endif
01747
01748 void CkMigratable::staticResumeFromSync(void* data)
01749 {
01750 CkMigratable *el=(CkMigratable *)data;
01751 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01752 if(el->mlogData->toResumeOrNot ==0 || el->mlogData->resumeCount >= globalResumeCount){
01753 return;
01754 }
01755 #endif
01756 DEBL((AA "Element %s resuming from sync\n" AB,idx2str(el->thisIndexMax)));
01757 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01758 CpvAccess(_currentObj) = el;
01759 #endif
01760
01761 if (_lb_args.metaLbOn()) {
01762 el->clearMetaLBData();
01763 }
01764 el->ResumeFromSync();
01765 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01766 el->mlogData->resumeCount++;
01767 #endif
01768 }
01769
01770 void CkMigratable::setMigratable(int migratable)
01771 {
01772 myRec->setMigratable(migratable);
01773 }
01774
01775 void CkMigratable::setPupSize(size_t obj_pup_size)
01776 {
01777 myRec->setPupSize(obj_pup_size);
01778 }
01779
01780 struct CkArrayThreadListener {
01781 struct CthThreadListener base;
01782 CkMigratable *mig;
01783 };
01784
01785 static void CkArrayThreadListener_suspend(struct CthThreadListener *l)
01786 {
01787 CkArrayThreadListener *a=(CkArrayThreadListener *)l;
01788 a->mig->ckStopTiming();
01789 }
01790
01791 static void CkArrayThreadListener_resume(struct CthThreadListener *l)
01792 {
01793 CkArrayThreadListener *a=(CkArrayThreadListener *)l;
01794 a->mig->ckStartTiming();
01795 }
01796
01797 static void CkArrayThreadListener_free(struct CthThreadListener *l)
01798 {
01799 CkArrayThreadListener *a=(CkArrayThreadListener *)l;
01800 delete a;
01801 }
01802
01803 void CkMigratable::CkAddThreadListeners(CthThread tid, void *msg)
01804 {
01805 Chare::CkAddThreadListeners(tid, msg);
01806 CthSetThreadID(tid, thisIndexMax.data()[0], thisIndexMax.data()[1],
01807 thisIndexMax.data()[2]);
01808 CkArrayThreadListener *a=new CkArrayThreadListener;
01809 a->base.suspend=CkArrayThreadListener_suspend;
01810 a->base.resume=CkArrayThreadListener_resume;
01811 a->base.free=CkArrayThreadListener_free;
01812 a->mig=this;
01813 CthAddListener(tid,(struct CthThreadListener *)a);
01814 }
01815 #else
01816 void CkMigratable::setObjTime(double cputime) {}
01817 double CkMigratable::getObjTime() {return 0.0;}
01818
01819 #if CMK_LB_USER_DATA
01820 void *CkMigratable::getObjUserData(int idx) { return NULL; }
01821 #endif
01822
01823
01824 void CkMigratable::CkAddThreadListeners(CthThread tid, void *msg)
01825 {
01826 }
01827 #endif
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838 CkLocRec::CkLocRec(CkLocMgr *mgr,bool fromMigration,
01839 bool ignoreArrival, const CkArrayIndex &idx_, CmiUInt8 id_)
01840 :myLocMgr(mgr),idx(idx_), id(id_),
01841 deletedMarker(NULL),running(false)
01842 {
01843 #if CMK_LBDB_ON
01844 DEBL((AA "Registering element %s with load balancer\n" AB,idx2str(idx)));
01845
01846
01847 nextPe = -1;
01848 asyncMigrate = false;
01849 readyMigrate = true;
01850 enable_measure = true;
01851 #if CMK_FAULT_EVAC
01852 bounced = false;
01853 #endif
01854 the_lbdb=mgr->getLBDB();
01855 if(_lb_args.metaLbOn())
01856 the_metalb=mgr->getMetaBalancer();
01857 #if CMK_GLOBAL_LOCATION_UPDATE
01858 CmiUInt8 locMgrGid = mgr->getGroupID().idx;
01859 id_ = ck::ObjID(id_).getElementID();
01860 id_ |= locMgrGid << ck::ObjID().ELEMENT_BITS;
01861 #endif
01862 ldHandle=the_lbdb->RegisterObj(mgr->getOMHandle(),
01863 id_, (void *)this,1);
01864 if (fromMigration) {
01865 DEBL((AA "Element %s migrated in\n" AB,idx2str(idx)));
01866 if (!ignoreArrival) {
01867 the_lbdb->Migrated(ldHandle, true);
01868
01869
01870 }
01871 }
01872 #endif
01873
01874 #if CMK_FAULT_EVAC
01875 asyncEvacuate = true;
01876 #endif
01877 }
01878 CkLocRec::~CkLocRec()
01879 {
01880 if (deletedMarker!=NULL) *deletedMarker=true;
01881 #if CMK_LBDB_ON
01882 stopTiming();
01883 DEBL((AA "Unregistering element %s from load balancer\n" AB,idx2str(idx)));
01884 the_lbdb->UnregisterObj(ldHandle);
01885 #endif
01886 }
01887 void CkLocRec::migrateMe(int toPe)
01888 {
01889
01890
01891 myLocMgr->emigrate(this,toPe);
01892 }
01893
01894 #if CMK_LBDB_ON
01895 void CkLocRec::startTiming(int ignore_running) {
01896 if (!ignore_running) running=true;
01897 DEBL((AA "Start timing for %s at %.3fs {\n" AB,idx2str(idx),CkWallTimer()));
01898 if (enable_measure) the_lbdb->ObjectStart(ldHandle);
01899 }
01900 void CkLocRec::stopTiming(int ignore_running) {
01901 DEBL((AA "} Stop timing for %s at %.3fs\n" AB,idx2str(idx),CkWallTimer()));
01902 if ((ignore_running || running) && enable_measure) the_lbdb->ObjectStop(ldHandle);
01903 if (!ignore_running) running=false;
01904 }
01905 void CkLocRec::setObjTime(double cputime) {
01906 the_lbdb->EstObjLoad(ldHandle, cputime);
01907 }
01908 double CkLocRec::getObjTime() {
01909 LBRealType walltime, cputime;
01910 the_lbdb->GetObjLoad(ldHandle, walltime, cputime);
01911 return walltime;
01912 }
01913 #if CMK_LB_USER_DATA
01914 void* CkLocRec::getObjUserData(int idx) {
01915 return the_lbdb->GetDBObjUserData(ldHandle, idx);
01916 }
01917 #endif
01918 #endif
01919
01920
01921
01922 void CkLocRec::destroy(void) {
01923 myLocMgr->reclaim(this);
01924 }
01925
01926
01927
01928 LDObjHandle CkMigratable::timingBeforeCall(int* objstopped){
01929 LDObjHandle objHandle;
01930 #if CMK_LBDB_ON
01931 if (getLBDB()->RunningObject(&objHandle)) {
01932 *objstopped = 1;
01933 getLBDB()->ObjectStop(objHandle);
01934 }
01935 myRec->startTiming(1);
01936 #endif
01937
01938 return objHandle;
01939 }
01940
01941 void CkMigratable::timingAfterCall(LDObjHandle objHandle,int *objstopped){
01942 myRec->stopTiming(1);
01943 #if CMK_LBDB_ON
01944 if (*objstopped) {
01945 getLBDB()->ObjectStart(objHandle);
01946 }
01947 #endif
01948
01949 return;
01950 }
01951
01952
01953
01954 bool CkLocRec::invokeEntry(CkMigratable *obj,void *msg,
01955 int epIdx,bool doFree)
01956 {
01957
01958 DEBS((AA " Invoking entry %d on element %s\n" AB,epIdx,idx2str(idx)));
01959 bool isDeleted=false;
01960 deletedMarker=&isDeleted;
01961 startTiming();
01962
01963
01964 #if CMK_TRACE_ENABLED
01965 if (msg) {
01966 envelope *env=UsrToEnv(msg);
01967
01968 if (_entryTable[epIdx]->traceEnabled)
01969 {
01970 _TRACE_BEGIN_EXECUTE_DETAILED(env->getEvent(), ForChareMsg,epIdx,env->getSrcPe(), env->getTotalsize(), idx.getProjectionID(), obj);
01971 if(_entryTable[epIdx]->appWork)
01972 _TRACE_BEGIN_APPWORK();
01973 }
01974 }
01975 #endif
01976
01977 if (doFree)
01978 CkDeliverMessageFree(epIdx,msg,obj);
01979 else
01980 CkDeliverMessageReadonly(epIdx,msg,obj);
01981
01982
01983 #if CMK_TRACE_ENABLED
01984 if (msg) {
01985 if (_entryTable[epIdx]->traceEnabled)
01986 {
01987 if(_entryTable[epIdx]->appWork)
01988 _TRACE_END_APPWORK();
01989 _TRACE_END_EXECUTE();
01990 }
01991 }
01992 #endif
01993 #if CMK_LBDB_ON
01994 if (!isDeleted) checkBufferedMigration();
01995 #endif
01996 if (isDeleted) return false;
01997 deletedMarker=NULL;
01998 stopTiming();
01999 return true;
02000 }
02001
02002 #if CMK_LBDB_ON
02003
02004 void CkLocRec::staticMetaLBResumeWaitingChares(LDObjHandle h, int lb_ideal_period) {
02005 CkLocRec *el=(CkLocRec *)LDObjUserData(h);
02006 DEBL((AA "MetaBalancer wants to resume waiting chare %s\n" AB,idx2str(el->idx)));
02007 el->myLocMgr->informLBPeriod(el, lb_ideal_period);
02008 }
02009
02010 void CkLocRec::staticMetaLBCallLBOnChares(LDObjHandle h) {
02011 CkLocRec *el=(CkLocRec *)LDObjUserData(h);
02012 DEBL((AA "MetaBalancer wants to call LoadBalance on chare %s\n" AB,idx2str(el->idx)));
02013 el->myLocMgr->metaLBCallLB(el);
02014 }
02015
02016 void CkLocRec::staticMigrate(LDObjHandle h, int dest)
02017 {
02018 CkLocRec *el=(CkLocRec *)LDObjUserData(h);
02019 DEBL((AA "Load balancer wants to migrate %s to %d\n" AB,idx2str(el->idx),dest));
02020 el->recvMigrate(dest);
02021 }
02022
02023 void CkLocRec::recvMigrate(int toPe)
02024 {
02025
02026
02027 if (readyMigrate) { migrateMe(toPe); }
02028 else nextPe = toPe;
02029 }
02030
02031 void CkLocRec::AsyncMigrate(bool use)
02032 {
02033 asyncMigrate = use;
02034 the_lbdb->UseAsyncMigrate(ldHandle, use);
02035 }
02036
02037 bool CkLocRec::checkBufferedMigration()
02038 {
02039
02040
02041 if (readyMigrate && nextPe != -1) {
02042 int toPe = nextPe;
02043 nextPe = -1;
02044
02045 migrateMe(toPe);
02046
02047 return true;
02048 }
02049 return false;
02050 }
02051
02052 int CkLocRec::MigrateToPe()
02053 {
02054 int pe = nextPe;
02055 nextPe = -1;
02056 return pe;
02057 }
02058
02059 void CkLocRec::setMigratable(int migratable)
02060 {
02061 if (migratable)
02062 the_lbdb->Migratable(ldHandle);
02063 else
02064 the_lbdb->NonMigratable(ldHandle);
02065 }
02066
02067 void CkLocRec::setPupSize(size_t obj_pup_size) {
02068 the_lbdb->setPupSize(ldHandle, obj_pup_size);
02069 }
02070
02071 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02072 void CkLocRec::Migrated(){
02073 the_lbdb->Migrated(ldHandle, true);
02074 }
02075 #endif
02076 #endif
02077
02078
02079
02080
02081 void CkLocMgr::flushLocalRecs(void)
02082 {
02083 CmiImmediateLock(hashImmLock);
02084 while (hash.size()) {
02085 CkLocRec* rec = hash.begin()->second;
02086 callMethod(rec, &CkMigratable::ckDestroy);
02087 }
02088 CmiImmediateUnlock(hashImmLock);
02089 }
02090
02091
02092 void CkLocMgr::flushAllRecs(void)
02093 {
02094 flushLocalRecs();
02095 }
02096
02097
02098 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02099 void CkLocMgr::callForAllRecords(CkLocFn fnPointer,CkArray *arr,void *data){
02100 CmiImmediateLock(hashImmLock);
02101 for (LocRecHash::iterator it = hash.begin(); it != hash.end(); it++) {
02102 fnPointer(arr,data,it->second,it->second->idx);
02103 }
02104 CmiImmediateUnlock(hashImmLock);
02105 }
02106 #endif
02107
02108
02109 CkLocMgr::CkLocMgr(CkArrayOptions opts)
02110 :idCounter(1), thisProxy(thisgroup),
02111 thislocalproxy(thisgroup,CkMyPe())
02112 , bounds(opts.getBounds())
02113 {
02114 DEBC((AA "Creating new location manager %d\n" AB,thisgroup));
02115
02116
02117
02118 duringMigration = false;
02119
02120
02121 mapID = opts.getMap();
02122 map=(CkArrayMap *)CkLocalBranch(mapID);
02123 if (map==NULL) CkAbort("ERROR! Local branch of array map is NULL!");
02124 mapHandle=map->registerArray(opts.getEnd(), thisgroup);
02125
02126
02127 compressor = ck::FixedArrayIndexCompressor::make(bounds);
02128
02129
02130 #if CMK_LBDB_ON
02131 lbdbID = _lbdb;
02132 metalbID = _metalb;
02133 #endif
02134 initLB(lbdbID, metalbID);
02135 hashImmLock = CmiCreateImmediateLock();
02136 }
02137
02138 CkLocMgr::CkLocMgr(CkMigrateMessage* m)
02139 :IrrGroup(m),thisProxy(thisgroup),thislocalproxy(thisgroup,CkMyPe())
02140 {
02141 duringMigration = false;
02142 hashImmLock = CmiCreateImmediateLock();
02143 }
02144
02145 CkLocMgr::~CkLocMgr() {
02146 #if CMK_LBDB_ON
02147 the_lbdb->RemoveLocalBarrierClient(dummyBarrierHandle);
02148 the_lbdb->DecreaseLocalBarrier(dummyBarrierHandle, 1);
02149 the_lbdb->RemoveLocalBarrierReceiver(lbBarrierReceiver);
02150 the_lbdb->UnregisterOM(myLBHandle);
02151 #endif
02152 map->unregisterArray(mapHandle);
02153 CmiDestroyLock(hashImmLock);
02154 }
02155
02156 void CkLocMgr::pup(PUP::er &p){
02157 IrrGroup::pup(p);
02158 p|mapID;
02159 p|mapHandle;
02160 p|lbdbID;
02161 p|metalbID;
02162 p|bounds;
02163 if(p.isUnpacking()) {
02164 thisProxy=thisgroup;
02165 CProxyElement_CkLocMgr newlocalproxy(thisgroup,CkMyPe());
02166 thislocalproxy=newlocalproxy;
02167
02168 map=(CkArrayMap *)CkLocalBranch(mapID);
02169 if (map==NULL) CkAbort("ERROR! Local branch of array map is NULL!");
02170 CkArrayIndex emptyIndex;
02171
02172 initLB(lbdbID, metalbID);
02173 compressor = ck::FixedArrayIndexCompressor::make(bounds);
02174 #if __FAULT__
02175 int count = 0;
02176 p | count;
02177 DEBUG(CmiPrintf("[%d] Unpacking Locmgr %d has %d home elements\n",CmiMyPe(),thisgroup.idx,count));
02178 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02179 homeElementCount = count;
02180 #endif
02181 for(int i=0;i<count;i++){
02182 CkArrayIndex idx;
02183 int pe = 0;
02184 p | idx;
02185 p | pe;
02186
02187 inform(idx, lookupID(idx), pe);
02188 CmiUInt8 id = lookupID(idx);
02189 CkLocRec *rec = elementNrec(id);
02190 CmiAssert(rec!=NULL);
02191 CmiAssert(lastKnown(idx) == pe);
02192 }
02193 #endif
02194
02195
02196 if (!CkInRestarting())
02197 doneInserting();
02198 }else{
02205 #if __FAULT__
02206 int count=0;
02207 std::vector<int> pe_list;
02208 std::vector<CmiUInt8> idx_list;
02209 for (auto itr = id2pe.begin(); itr != id2pe.end(); ++itr)
02210 if (homePe(itr->first) == CmiMyPe() && itr->second != CmiMyPe())
02211 {
02212 idx_list.push_back(itr->first);
02213 pe_list.push_back(itr->second);
02214 count++;
02215 }
02216
02217 p | count;
02218
02219 for (int i=0; i<count; i++)
02220 {
02221 p | idx_list[i];
02222 p | pe_list[i];
02223 }
02224 #endif
02225
02226 }
02227 }
02228
02230 void CkLocMgr::addManager(CkArrayID id,CkArray *mgr)
02231 {
02232 CK_MAGICNUMBER_CHECK
02233 DEBC((AA "Adding new array manager\n" AB));
02234 managers[id] = mgr;
02235 }
02236
02237 void CkLocMgr::deleteManager(CkArrayID id, CkArray *mgr) {
02238 CkAssert(managers[id] == mgr);
02239 managers.erase(id);
02240
02241 if (managers.size() == 0)
02242 delete this;
02243 }
02244
02245
02246 void CkLocMgr::informHome(const CkArrayIndex &idx,int nowOnPe)
02247 {
02248 int home=homePe(idx);
02249 if (home!=CkMyPe() && home!=nowOnPe) {
02250
02251 DEBC((AA " Telling %s's home %d that it lives on %d.\n" AB,idx2str(idx),home,nowOnPe));
02252
02253
02254
02255
02256 thisProxy[home].updateLocation(idx, lookupID(idx), nowOnPe);
02257
02258 }
02259 }
02260
02261 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02262 CkLocRec *CkLocMgr::createLocal(const CkArrayIndex &idx,
02263 bool forMigration, bool ignoreArrival,
02264 bool notifyHome,int dummy)
02265 {
02266 DEBC((AA "Adding new record for element %s\n" AB,idx2str(idx)));
02267 CkLocRec *rec=new CkLocRec(this,forMigration,ignoreArrival,idx);
02268 if(!dummy){
02269 insertRec(rec,idx);
02270 id2pe[idx] = CkMyPe();
02271 deliverAnyBufferedMsgs(idx, bufferedMsgs);
02272 }
02273 if (notifyHome) informHome(idx,CkMyPe());
02274 return rec;
02275 }
02276 #else
02277 CkLocRec *CkLocMgr::createLocal(const CkArrayIndex &idx,
02278 bool forMigration, bool ignoreArrival,
02279 bool notifyHome)
02280 {
02281 DEBC((AA "Adding new record for element %s\n" AB,idx2str(idx)));
02282 CmiUInt8 id = lookupID(idx);
02283
02284 CkLocRec *rec=new CkLocRec(this, forMigration, ignoreArrival, idx, id);
02285 insertRec(rec, id);
02286 inform(idx, id, CkMyPe());
02287
02288 if (notifyHome) { informHome(idx,CkMyPe()); }
02289 return rec;
02290 }
02291 #endif
02292
02293
02294 void CkLocMgr::deliverAnyBufferedMsgs(CmiUInt8 id, MsgBuffer &buffer)
02295 {
02296 auto itr = buffer.find(id);
02297
02298 if (itr == buffer.end()) return;
02299
02300 std::vector<CkArrayMessage*> messagesToFlush;
02301 messagesToFlush.swap(itr->second);
02302
02303
02304 for (int i = 0; i < messagesToFlush.size(); ++i)
02305 {
02306 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02307 envelope *env = UsrToEnv(messagesToFlush[i]);
02308 Chare *oldObj = CpvAccess(_currentObj);
02309 CpvAccess(_currentObj) =(Chare *) env->sender.getObject();
02310 env->sender.type = TypeInvalid;
02311 #endif
02312 CkArrayMessage *m = messagesToFlush[i];
02313 deliverMsg(m, UsrToEnv(m)->getArrayMgr(), id, NULL, CkDeliver_queue);
02314 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02315 CpvAccess(_currentObj) = oldObj;
02316 #endif
02317 }
02318
02319 CkAssert(itr->second.empty());
02320
02321
02322
02323 buffer.erase(itr);
02324 }
02325
02326 CmiUInt8 CkLocMgr::getNewObjectID(const CkArrayIndex &idx)
02327 {
02328 CmiUInt8 id;
02329 if (!lookupID(idx, id)) {
02330 id = idCounter++ + ((CmiUInt8)CkMyPe() << 24);
02331 insertID(idx,id);
02332 }
02333 return id;
02334 }
02335
02336
02337 bool CkLocMgr::addElement(CkArrayID mgr,const CkArrayIndex &idx,
02338 CkMigratable *elt,int ctorIdx,void *ctorMsg)
02339 {
02340 CK_MAGICNUMBER_CHECK
02341
02342 CmiUInt8 id = getNewObjectID(idx);
02343
02344 CkLocRec *rec = elementNrec(id);
02345 if (rec == NULL)
02346 {
02347 rec=createLocal(idx,false,false,true);
02348 #if CMK_GLOBAL_LOCATION_UPDATE
02349 if (homePe(idx) != CkMyPe()) {
02350 DEBC((AA "Global location broadcast for new element idx %s "
02351 "assigned to %d \n" AB, idx2str(idx), CkMyPe()));
02352 thisProxy.updateLocation(id, CkMyPe());
02353 }
02354 #endif
02355
02356 }
02357
02358 else
02359 deliverAnyBufferedMsgs(id, bufferedShadowElemMsgs);
02360 if (!addElementToRec(rec, managers[mgr], elt, ctorIdx, ctorMsg)) return false;
02361 elt->ckFinishConstruction();
02362 return true;
02363 }
02364
02365
02366 bool CkLocMgr::addElementToRec(CkLocRec *rec,CkArray *mgr,
02367 CkMigratable *elt,int ctorIdx,void *ctorMsg)
02368 {
02369 CmiUInt8 id = lookupID(rec->getIndex());
02370 if (mgr->getEltFromArrMgr(id))
02371 CkAbort("Cannot insert array element twice!");
02372 mgr->putEltInArrMgr(id, elt);
02373
02374
02375 DEBC((AA "Constructing element %s of array\n" AB,idx2str(rec->getIndex())));
02376 CkMigratable_initInfo &i=CkpvAccess(mig_initInfo);
02377 i.locRec=rec;
02378 i.chareType=_entryTable[ctorIdx]->chareIdx;
02379
02380 #ifndef CMK_CHARE_USE_PTR
02381 int callingChareIdx = CkpvAccess(currentChareIdx);
02382 CkpvAccess(currentChareIdx) = -1;
02383 #endif
02384
02385 if (!rec->invokeEntry(elt,ctorMsg,ctorIdx,true)) return false;
02386
02387 #ifndef CMK_CHARE_USE_PTR
02388 CkpvAccess(currentChareIdx) = callingChareIdx;
02389 #endif
02390
02391 #if CMK_OUT_OF_CORE
02392
02393 PUP::sizer p_getSize;
02394 elt->virtual_pup(p_getSize);
02395 elt->prefetchObjID=CooRegisterObject(&CkArrayElementPrefetcher,p_getSize.size(),elt);
02396 #endif
02397
02398 return true;
02399 }
02400
02401
02402
02403 void CkLocMgr::requestLocation(const CkArrayIndex &idx, const int peToTell,
02404 bool suppressIfHere, int ifNonExistent, int chareType, CkArrayID mgr) {
02405 int onPe = -1;
02406 DEBN(("%d requestLocation for %s peToTell %d\n", CkMyPe(), idx2str(idx), peToTell));
02407
02408 if (peToTell == CkMyPe())
02409 return;
02410
02411 CmiUInt8 id;
02412 if (lookupID(idx,id)) {
02413
02414 onPe = lastKnown(idx);
02415 thisProxy[peToTell].updateLocation(idx, id, onPe);
02416 } else {
02417
02418 DEBN(("%d Buffering ID/location req for %s\n", CkMyPe(), idx2str(idx)));
02419 bufferedLocationRequests[idx].emplace_back(peToTell, suppressIfHere);
02420
02421 switch (ifNonExistent) {
02422 case CkArray_IfNotThere_createhome:
02423 demandCreateElement(idx, chareType, CkMyPe(), mgr);
02424 break;
02425 case CkArray_IfNotThere_createhere:
02426 demandCreateElement(idx, chareType, peToTell, mgr);
02427 break;
02428 default:
02429 break;
02430 }
02431 }
02432 }
02433
02434 void CkLocMgr::requestLocation(CmiUInt8 id, const int peToTell,
02435 bool suppressIfHere) {
02436 int onPe = -1;
02437 DEBN(("%d requestLocation for %u peToTell %d\n", CkMyPe(), id, peToTell));
02438
02439 if (peToTell == CkMyPe())
02440 return;
02441
02442 onPe = lastKnown(id);
02443
02444 if (suppressIfHere && peToTell == CkMyPe())
02445 return;
02446
02447 thisProxy[peToTell].updateLocation(id, onPe);
02448 }
02449
02450 void CkLocMgr::updateLocation(const CkArrayIndex &idx, CmiUInt8 id, int nowOnPe) {
02451 DEBN(("%d updateLocation for %s on %d\n", CkMyPe(), idx2str(idx), nowOnPe));
02452 inform(idx, id, nowOnPe);
02453 deliverAnyBufferedMsgs(id, bufferedRemoteMsgs);
02454 }
02455
02456 void CkLocMgr::updateLocation(CmiUInt8 id, int nowOnPe) {
02457 DEBN(("%d updateLocation for %s on %d\n", CkMyPe(), idx2str(idx), nowOnPe));
02458 inform(id, nowOnPe);
02459 deliverAnyBufferedMsgs(id, bufferedRemoteMsgs);
02460 }
02461
02462 void CkLocMgr::inform(const CkArrayIndex &idx, CmiUInt8 id, int nowOnPe) {
02463
02464
02465
02466 if (CkInRestarting()) {
02467 CmiUInt8 maskedID = id & ((1u << 24) - 1);
02468 CmiUInt8 origPe = id >> 24;
02469 if (origPe == CkMyPe()) {
02470 if (maskedID >= idCounter)
02471 idCounter = maskedID + 1;
02472 } else {
02473 if (origPe < CkNumPes())
02474 thisProxy[origPe].updateLocation(idx, id, nowOnPe);
02475 }
02476 }
02477
02478 insertID(idx,id);
02479 id2pe[id] = nowOnPe;
02480
02481 auto itr = bufferedLocationRequests.find(idx);
02482 if (itr != bufferedLocationRequests.end()) {
02483 for (std::vector<std::pair<int, bool> >::iterator i = itr->second.begin();
02484 i != itr->second.end(); ++i) {
02485 int peToTell = i->first;
02486 DEBN(("%d Replying to buffered ID/location req to pe %d\n", CkMyPe(), peToTell));
02487 if (peToTell != CkMyPe())
02488 thisProxy[peToTell].updateLocation(idx, id, nowOnPe);
02489 }
02490 bufferedLocationRequests.erase(itr);
02491 }
02492
02493 deliverAnyBufferedMsgs(id, bufferedMsgs);
02494
02495 auto idx_itr = bufferedIndexMsgs.find(idx);
02496 if (idx_itr != bufferedIndexMsgs.end()) {
02497 vector<CkArrayMessage*> &msgs = idx_itr->second;
02498 for (int i = 0; i < msgs.size(); ++i) {
02499 envelope *env = UsrToEnv(msgs[i]);
02500 CkGroupID mgr = ck::ObjID(env->getRecipientID()).getCollectionID();
02501 env->setRecipientID(ck::ObjID(mgr, id));
02502 deliverMsg(msgs[i], mgr, id, &idx, CkDeliver_queue);
02503 }
02504 bufferedIndexMsgs.erase(idx_itr);
02505 }
02506 }
02507
02508 void CkLocMgr::inform(CmiUInt8 id, int nowOnPe) {
02509 id2pe[id] = nowOnPe;
02510 deliverAnyBufferedMsgs(id, bufferedMsgs);
02511 }
02512
02513
02514
02515
02516
02517
02518 void CkLocMgr::reclaim(CkLocRec* rec) {
02519 CK_MAGICNUMBER_CHECK
02520
02521 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
02522 if (itr->second->lookup(rec->getID())) return;
02523 }
02524 removeFromTable(rec->getID());
02525
02526 DEBC((AA "Destroying record for element %s\n" AB,idx2str(rec->getIndex())));
02527 if (!duringMigration)
02528 {
02529 #if CMK_BIGSIM_CHARM
02530
02531
02532
02533
02534
02535
02536
02537 if(_BgOutOfCoreFlag==1) return;
02538 #endif
02539 int home=homePe(rec->getIndex());
02540 if (home!=CkMyPe())
02541 #if CMK_MEM_CHECKPOINT
02542 if (!CkInRestarting())
02543 #endif
02544 if (!duringDestruction)
02545 thisProxy[home].reclaimRemote(rec->getIndex(),CkMyPe());
02546 }
02547 delete rec;
02548 }
02549
02550
02551
02552 void CkLocMgr::reclaimRemote(const CkArrayIndex &idx,int deletedOnPe) {
02553 DEBC((AA "Our element %s died on PE %d\n" AB,idx2str(idx),deletedOnPe));
02554
02555 CmiUInt8 id;
02556 if (!lookupID(idx, id)) CkAbort("Cannot find ID for the given index\n");
02557
02558
02559 id2pe.erase(id);
02560 idx2id.erase(idx);
02561
02562
02563 CkAssert(bufferedMsgs.count(id) == 0);
02564 CkAssert(bufferedRemoteMsgs.count(id) == 0);
02565 CkAssert(bufferedShadowElemMsgs.count(id) == 0);
02566 CkAssert(bufferedLocationRequests.count(idx) == 0);
02567 CkAssert(bufferedIndexMsgs.count(idx) == 0);
02568 }
02569
02570 void CkLocMgr::removeFromTable(const CmiUInt8 id) {
02571 #if CMK_ERROR_CHECKING
02572
02573 if (NULL==elementNrec(id))
02574 CkAbort("CkLocMgr::removeFromTable called on invalid index!");
02575 #endif
02576 CmiImmediateLock(hashImmLock);
02577 hash.erase(id);
02578 CmiImmediateUnlock(hashImmLock);
02579 #if CMK_ERROR_CHECKING
02580
02581 if (NULL!=elementNrec(id))
02582 CkAbort("CkLocMgr::removeFromTable called, but element still there!");
02583 #endif
02584 }
02585
02586
02589 int CkLocMgr::deliverMsg(CkArrayMessage *msg, CkArrayID mgr, CmiUInt8 id, const CkArrayIndex* idx, CkDeliver_t type, int opts) {
02590 CkLocRec *rec = elementNrec(id);
02591
02592 #if CMK_LBDB_ON
02593 if ((idx || compressor) && type==CkDeliver_queue && !(opts & CK_MSG_LB_NOTRACE) && the_lbdb->CollectingCommStats())
02594 {
02595 #if CMK_GLOBAL_LOCATION_UPDATE
02596 CmiUInt8 locMgrGid = thisgroup.idx;
02597 id = ck::ObjID(id).getElementID();
02598 id |= locMgrGid << ck::ObjID().ELEMENT_BITS;
02599 #endif
02600 the_lbdb->Send(myLBHandle
02601 , id
02602 , UsrToEnv(msg)->getTotalsize()
02603 , lastKnown(id)
02604 , 1);
02605 }
02606 #endif
02607
02608
02609 if (rec == NULL)
02610 {
02611 if (opts & CK_MSG_KEEP)
02612 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
02613
02614 int destPE = whichPE(id);
02615 if (destPE != -1)
02616 {
02617 #if CMK_FAULT_EVAC
02618 if((!CmiNodeAlive(destPE) && destPE != allowMessagesOnly)){
02619 CkAbort("Cannot send to a chare on a dead node");
02620 }
02621 #endif
02622 msg->array_hops()++;
02623 CkArrayManagerDeliver(destPE,msg,opts);
02624 return true;
02625 }
02626
02627 deliverUnknown(msg,idx,type,opts);
02628 return true;
02629 }
02630
02631
02632 if (type==CkDeliver_queue)
02633 {
02634 if (opts & CK_MSG_KEEP)
02635 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
02636 CkArrayManagerDeliver(CkMyPe(),msg,opts);
02637 return true;
02638 }
02639
02640 CkAssert(mgr == UsrToEnv(msg)->getArrayMgr());
02641 CkArray *arr = managers[mgr];
02642 if (!arr) {
02643 bufferedShadowElemMsgs[id].push_back(msg);
02644 return true;
02645 }
02646 CkMigratable *obj = arr->lookup(id);
02647 if (obj==NULL) {
02648 if (opts & CK_MSG_KEEP)
02649 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
02650 if (msg->array_ifNotThere()!=CkArray_IfNotThere_buffer)
02651 return demandCreateElement(msg, rec->getIndex(), CkMyPe(),type);
02652 else {
02653 bufferedShadowElemMsgs[id].push_back(msg);
02654 return true;
02655 }
02656 }
02657
02658 if (msg->array_hops()>1)
02659 multiHop(msg);
02660 #if CMK_LBDB_ON
02661
02662 LDObjHandle objHandle;
02663 bool wasAnObjRunning = false;
02664 if ((wasAnObjRunning = the_lbdb->RunningObject(&objHandle)))
02665 the_lbdb->ObjectStop(objHandle);
02666 #endif
02667
02668 bool result = ((CkLocRec*)rec)->invokeEntry(obj,(void *)msg,msg->array_ep(),!(opts & CK_MSG_KEEP));
02669 #if CMK_LBDB_ON
02670 if (wasAnObjRunning) the_lbdb->ObjectStart(objHandle);
02671 #endif
02672 return result;
02673 }
02674
02675 void CkLocMgr::sendMsg(CkArrayMessage *msg, CkArrayID mgr, const CkArrayIndex &idx, CkDeliver_t type, int opts) {
02676 CK_MAGICNUMBER_CHECK
02677 DEBS((AA "send %s\n" AB,idx2str(idx)));
02678 envelope *env = UsrToEnv(msg);
02679 env->setMsgtype(ForArrayEltMsg);
02680
02681 checkInBounds(idx);
02682
02683 if (type==CkDeliver_queue)
02684 _TRACE_CREATION_DETAILED(env, msg->array_ep());
02685
02686 CmiUInt8 id;
02687 if (lookupID(idx, id)) {
02688 env->setRecipientID(ck::ObjID(mgr, id));
02689 deliverMsg(msg, mgr, id, &idx, type, opts);
02690 return;
02691 }
02692
02693 env->setRecipientID(ck::ObjID(mgr, 0));
02694
02695 int home = homePe(idx);
02696 if (home != CkMyPe()) {
02697 if (bufferedIndexMsgs.find(idx) == bufferedIndexMsgs.end())
02698 thisProxy[home].requestLocation(idx, CkMyPe(), false, msg->array_ifNotThere(), _entryTable[env->getEpIdx()]->chareIdx, mgr);
02699 bufferedIndexMsgs[idx].push_back(msg);
02700
02701 return;
02702 }
02703
02704
02705
02706 if (managers.find(mgr) == managers.end()) {
02707
02708 if (CkInRestarting()) {
02709
02710 delete msg;
02711 } else {
02712
02713
02714
02715
02716 bufferedIndexMsgs[idx].push_back(msg);
02717 }
02718 return;
02719 }
02720
02721
02722 if (opts & CK_MSG_KEEP)
02723 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
02724
02725
02726 bufferedIndexMsgs[idx].push_back(msg);
02727
02728 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02729 envelope *env = UsrToEnv(msg);
02730 env->sender = CpvAccess(_currentObj)->mlogData->objID;
02731 #endif
02732
02733
02734 if (msg->array_ifNotThere()!=CkArray_IfNotThere_buffer) {
02735 demandCreateElement(msg, idx, -1, type);
02736 }
02737 }
02738
02740 void CkLocMgr::deliverUnknown(CkArrayMessage *msg, const CkArrayIndex* idx, CkDeliver_t type, int opts)
02741 {
02742 CK_MAGICNUMBER_CHECK
02743 CmiUInt8 id = msg->array_element_id();
02744 int home;
02745 if (idx) home = homePe(*idx);
02746 else home = homePe(id);
02747
02748 if (home != CkMyPe()) {
02749 id2pe[id] = home;
02750 if (UsrToEnv(msg)->getTotalsize() < _messageBufferingThreshold) {
02751 DEBM((AA "Forwarding message for unknown %u to home %d \n" AB, id, home));
02752 msg->array_hops()++;
02753 CkArrayManagerDeliver(home, msg, opts);
02754 } else {
02755 DEBM((AA "Buffering message for unknown %u, home %d \n" AB, id, home));
02756 if (bufferedRemoteMsgs.find(id) == bufferedRemoteMsgs.end())
02757 thisProxy[home].requestLocation(id, CkMyPe(), false);
02758 bufferedRemoteMsgs[id].push_back(msg);
02759 }
02760 } else {
02761
02762
02763 if (managers.find(UsrToEnv((void*)msg)->getArrayMgr()) == managers.end()) {
02764 if (CkInRestarting()) {
02765
02766 delete msg;
02767 } else {
02768 CkArrayManagerDeliver(CkMyPe(),msg);
02769 }
02770 } else {
02771
02772 if (opts & CK_MSG_KEEP)
02773 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
02774
02775 bufferedMsgs[id].push_back(msg);
02776 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02777 envelope *env = UsrToEnv(msg);
02778 env->sender = CpvAccess(_currentObj)->mlogData->objID;
02779 #endif
02780
02781 if (msg->array_ifNotThere()!=CkArray_IfNotThere_buffer) {
02782 CkAbort("Demand creation of elements is currently unimplemented");
02783 }
02784 }
02785 }
02786 }
02787
02788 void CkLocMgr::demandCreateElement(const CkArrayIndex &idx, int chareType, int onPe, CkArrayID mgr)
02789 {
02790 int ctor=_chareTable[chareType]->getDefaultCtor();
02791 if (ctor==-1) CkAbort("Can't create array element to handle message--\n"
02792 "The element has no default constructor in the .ci file!\n");
02793
02794
02795 DEBC((AA "Demand-creating element %s on pe %d\n" AB,idx2str(idx),onPe));
02796 inform(idx, getNewObjectID(idx), onPe);
02797 CProxy_CkArray(mgr)[onPe].demandCreateElement(idx, ctor, CkDeliver_inline);
02798 }
02799
02800 bool CkLocMgr::demandCreateElement(CkArrayMessage *msg, const CkArrayIndex &idx, int onPe,CkDeliver_t type)
02801 {
02802 CK_MAGICNUMBER_CHECK
02803 int chareType=_entryTable[msg->array_ep()]->chareIdx;
02804 int ctor=_chareTable[chareType]->getDefaultCtor();
02805 if (ctor==-1) CkAbort("Can't create array element to handle message--\n"
02806 "The element has no default constructor in the .ci file!\n");
02807 if (onPe==-1)
02808 {
02809 if (msg->array_ifNotThere()==CkArray_IfNotThere_createhere)
02810 onPe=UsrToEnv(msg)->getsetArraySrcPe();
02811 else
02812 onPe=homePe(idx);
02813 }
02814
02815
02816 DEBC((AA "Demand-creating element %s on pe %d\n" AB,idx2str(idx),onPe));
02817 CProxy_CkArray(UsrToEnv((void *)msg)->getArrayMgr())[onPe].demandCreateElement(idx, ctor, type);
02818 return onPe == CkMyPe();
02819 }
02820
02821
02822 void CkLocMgr::multiHop(CkArrayMessage *msg)
02823 {
02824 CK_MAGICNUMBER_CHECK
02825 int srcPe=msg->array_getSrcPe();
02826 if (srcPe==CkMyPe())
02827 DEB((AA "Odd routing: local element %u is %d hops away!\n" AB, msg->array_element_id(),msg->array_hops()));
02828 else
02829 {
02830 DEBS((AA "Sending update back to %d for element %u\n" AB, srcPe, msg->array_element_id()));
02831 thisProxy[srcPe].updateLocation(msg->array_element_id(), CkMyPe());
02832 }
02833 }
02834
02835 void CkLocMgr::checkInBounds(const CkArrayIndex &idx)
02836 {
02837 #if CMK_ERROR_CHECKING
02838 if (bounds.nInts > 0) {
02839 CkAssert(idx.dimension == bounds.dimension);
02840 bool shorts = idx.dimension > 3;
02841
02842 for (int i = 0; i < idx.dimension; ++i) {
02843 unsigned int thisDim = shorts ? idx.indexShorts[i] : idx.index[i];
02844 unsigned int thatDim = shorts ? bounds.indexShorts[i] : bounds.index[i];
02845 CkAssert(thisDim < thatDim);
02846 }
02847 }
02848 #endif
02849 }
02850
02851
02852 CkLocation::CkLocation(CkLocMgr *mgr_, CkLocRec *rec_)
02853 :mgr(mgr_), rec(rec_) {}
02854
02855 const CkArrayIndex &CkLocation::getIndex(void) const {
02856 return rec->getIndex();
02857 }
02858
02859 CmiUInt8 CkLocation::getID() const {
02860 return rec->getID();
02861 }
02862
02863 void CkLocation::destroyAll() {
02864 mgr->callMethod(rec, &CkMigratable::ckDestroy);
02865 }
02866
02867 void CkLocation::pup(PUP::er &p) {
02868 mgr->pupElementsFor(p,rec,CkElementCreation_migrate);
02869 }
02870
02871 CkLocIterator::~CkLocIterator() {}
02872
02874 void CkLocMgr::iterate(CkLocIterator &dest) {
02875
02876 CmiImmediateLock(hashImmLock);
02877 for (LocRecHash::iterator it = hash.begin(); it != hash.end(); it++) {
02878 CkLocation loc(this,it->second);
02879 dest.addLocation(loc);
02880 }
02881 CmiImmediateUnlock(hashImmLock);
02882 }
02883
02884
02885
02886
02887
02888 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02889 void CkLocMgr::pupElementsFor(PUP::er &p,CkLocRec *rec,
02890 CkElementCreation_t type, bool create, int dummy)
02891 {
02892 p.comment("-------- Array Location --------");
02893 std::vector<CkMigratable *> dummyElts;
02894
02895 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
02896 int elCType;
02897 if (!p.isUnpacking())
02898 {
02899 CkMigratable *elt = itr->second->getEltFromArrMgr(rec->getIndex());
02900 if (elt) elCType=elt->ckGetChareType();
02901 else elCType=-1;
02902 }
02903 p(elCType);
02904 if (p.isUnpacking() && elCType!=-1) {
02905 CkMigratable *elt = itr->second->allocateMigrated(elCType,rec->getIndex(),type);
02906 int migCtorIdx=_chareTable[elCType]->getMigCtor();
02907 if(!dummy){
02908 if(create)
02909 if (!addElementToRec(rec, itr->second, elt, migCtorIdx, NULL)) return;
02910 }else{
02911 CkMigratable_initInfo &i=CkpvAccess(mig_initInfo);
02912 i.locRec=rec;
02913 i.chareType=_entryTable[migCtorIdx]->chareIdx;
02914 dummyElts.push_back(elt);
02915 if (!rec->invokeEntry(elt,NULL,migCtorIdx,true)) return ;
02916 }
02917 }
02918 }
02919 if(!dummy){
02920 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
02921 CkMigratable *elt = itr->second->getEltFromArrMgr(rec->getIndex());
02922 if (elt!=NULL)
02923 {
02924 elt->virtual_pup(p);
02925 }
02926 }
02927 }else{
02928 for(int i=0;i<dummyElts.size();i++){
02929 CkMigratable *elt = dummyElts[i];
02930 if (elt!=NULL){
02931 elt->virtual_pup(p);
02932 }
02933 delete elt;
02934 }
02935 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
02936 itr->second->eraseEltFromArrMgr(rec->getIndex());
02937 }
02938 }
02939 }
02940 #else
02941 void CkLocMgr::pupElementsFor(PUP::er &p,CkLocRec *rec,
02942 CkElementCreation_t type,bool rebuild)
02943 {
02944 p.comment("-------- Array Location --------");
02945
02946
02947
02948 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
02949 int elCType;
02950 CkArray *arr = itr->second;
02951 if (!p.isUnpacking())
02952 {
02953 CkMigratable *elt = arr->getEltFromArrMgr(rec->getID());
02954 if (elt) elCType=elt->ckGetChareType();
02955 else elCType=-1;
02956 }
02957 p(elCType);
02958 if (p.isUnpacking() && elCType!=-1) {
02959
02960 CkMigratable *elt = arr->allocateMigrated(elCType, type);
02961 int migCtorIdx=_chareTable[elCType]->getMigCtor();
02962
02963 if (!addElementToRec(rec,arr,elt,migCtorIdx,NULL)) return;
02964 if (type==CkElementCreation_resume)
02965 {
02966
02967 arr->stampListenerData(elt);
02968 }
02969 }
02970 }
02971
02972 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
02973 CkMigratable *elt = itr->second->getEltFromArrMgr(rec->getID());
02974 if (elt!=NULL)
02975 {
02976 elt->virtual_pup(p);
02977 #if CMK_ERROR_CHECKING
02978 if (p.isUnpacking()) elt->sanitycheck();
02979 #endif
02980 }
02981 }
02982 #if CMK_MEM_CHECKPOINT
02983 if(rebuild){
02984 ArrayElement *elt;
02985 std::vector<CkMigratable *> list;
02986 migratableList(rec, list);
02987 CmiAssert(!list.empty());
02988 for (int l=0; l<list.size(); l++) {
02989
02990
02991 for (int i=0; i<CK_ARRAYLISTENER_MAXLEN; i++) {
02992 ArrayElement * elt = (ArrayElement *)list[l];
02993 contributorInfo *c=(contributorInfo *)&elt->listenerData[i];
02994 if (c) c->redNo = 0;
02995 }
02996 }
02997
02998 }
02999 #endif
03000 }
03001 #endif
03002
03004 void CkLocMgr::callMethod(CkLocRec *rec,CkMigratable_voidfn_t fn)
03005 {
03006 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
03007 CkMigratable *el = itr->second->getEltFromArrMgr(rec->getID());
03008 if (el) (el->* fn)();
03009 }
03010 }
03011
03013 void CkLocMgr::callMethod(CkLocRec *rec,CkMigratable_voidfn_arg_t fn, void * data)
03014 {
03015 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
03016 CkMigratable *el = itr->second->getEltFromArrMgr(rec->getID());
03017 if (el) (el->* fn)(data);
03018 }
03019 }
03020
03022 void CkLocMgr::migratableList(CkLocRec *rec, std::vector<CkMigratable *> &list)
03023 {
03024 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
03025 CkMigratable *elt = itr->second->getEltFromArrMgr(rec->getID());
03026 if (elt) list.push_back(elt);
03027 }
03028 }
03029
03031 void CkLocMgr::emigrate(CkLocRec *rec,int toPe)
03032 {
03033 CK_MAGICNUMBER_CHECK
03034 if (toPe==CkMyPe()) return;
03035
03036 #if CMK_FAULT_EVAC
03037
03038
03039
03040
03041 if(!CmiNodeAlive(toPe)){
03042 return;
03043 }
03044 #endif
03045
03046 CkArrayIndex idx=rec->getIndex();
03047 CmiUInt8 id = rec->getID();
03048
03049 #if CMK_OUT_OF_CORE
03050
03051 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
03052 CkMigratable *el = itr->second->getEltFromArrMgr(rec->getIndex());
03053 if (el) if (!el->isInCore) CooBringIn(el->prefetchObjID);
03054 }
03055 #endif
03056
03057
03058 callMethod(rec,&CkMigratable::ckAboutToMigrate);
03059
03060
03061
03062 size_t bufSize;
03063 {
03064 PUP::sizer p;
03065 pupElementsFor(p,rec,CkElementCreation_migrate);
03066 bufSize=p.size();
03067 }
03068 #if CMK_ERROR_CHECKING
03069 if (bufSize > std::numeric_limits<int>::max()) {
03070 CmiPrintf("Cannot migrate an object with size greater than %zu bytes!\n", std::numeric_limits<int>::max());
03071 CmiAbort("");
03072 }
03073 #endif
03074
03075
03076 CkArrayElementMigrateMessage *msg = new (bufSize, 0) CkArrayElementMigrateMessage(idx, id,
03077 #if CMK_LBDB_ON
03078 rec->isAsyncMigrate(),
03079 #else
03080 false,
03081 #endif
03082 bufSize, managers.size(),
03083 #if CMK_FAULT_EVAC
03084 rec->isBounced()
03085 #else
03086 false
03087 #endif
03088 );
03089
03090 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
03091 msg->gid = ckGetGroupID();
03092 #endif
03093 {
03094 PUP::toMem p(msg->packData);
03095 p.becomeDeleting();
03096 pupElementsFor(p,rec,CkElementCreation_migrate);
03097 if (p.size()!=bufSize) {
03098 CkError("ERROR! Array element claimed it was %d bytes to a "
03099 "sizing PUP::er, but copied %d bytes into the packing PUP::er!\n",
03100 bufSize,p.size());
03101 CkAbort("Array element's pup routine has a direction mismatch.\n");
03102 }
03103 }
03104
03105 DEBM((AA "Migrated index size %s to %d \n" AB,idx2str(idx),toPe));
03106
03107
03108
03109
03110
03111
03112 thisProxy[toPe].immigrate(msg);
03113
03114
03115 duringMigration=true;
03116 for (auto itr = managers.begin(); itr != managers.end(); ++itr) {
03117 itr->second->deleteElt(id);
03118 }
03119 duringMigration=false;
03120
03121
03122 inform(idx, id, toPe);
03123
03124
03125 informHome(idx,toPe);
03126
03127
03128 #if !CMK_LBDB_ON && CMK_GLOBAL_LOCATION_UPDATE
03129 DEBM((AA "Global location update. idx %s "
03130 "assigned to %d \n" AB,idx2str(idx),toPe));
03131 thisProxy.updateLocation(id, toPe);
03132 #endif
03133
03134 CK_MAGICNUMBER_CHECK
03135 }
03136
03137 #if CMK_LBDB_ON
03138 void CkLocMgr::informLBPeriod(CkLocRec *rec, int lb_ideal_period) {
03139 callMethod(rec,&CkMigratable::recvLBPeriod, (void *)&lb_ideal_period);
03140 }
03141
03142 void CkLocMgr::metaLBCallLB(CkLocRec *rec) {
03143 callMethod(rec, &CkMigratable::metaLBCallLB);
03144 }
03145 #endif
03146
03150 void CkLocMgr::immigrate(CkArrayElementMigrateMessage *msg)
03151 {
03152 const CkArrayIndex &idx=msg->idx;
03153
03154 PUP::fromMem p(msg->packData);
03155
03156 if (msg->nManagers < managers.size())
03157 CkAbort("Array element arrived from location with fewer managers!\n");
03158 if (msg->nManagers > managers.size()) {
03159
03160 DEBM((AA "Busy-waiting for array registration on migrating %s\n" AB,idx2str(idx)));
03161 thisProxy[CkMyPe()].immigrate(msg);
03162 return;
03163 }
03164
03165 insertID(idx,msg->id);
03166
03167
03168
03169
03170 CkLocRec *rec=createLocal(idx,true,msg->ignoreArrival,false );
03171
03172
03173
03174
03175
03176 pupElementsFor(p,rec,CkElementCreation_migrate);
03177 if (p.size()!=msg->length) {
03178 CkError("ERROR! Array element claimed it was %d bytes to a"
03179 "packing PUP::er, but %d bytes in the unpacking PUP::er!\n",
03180 msg->length,p.size());
03181 CkError("(I have %d managers; he claims %d managers)\n",
03182 managers.size(), msg->nManagers);
03183
03184 CkAbort("Array element's pup routine has a direction mismatch.\n");
03185 }
03186
03187 #if CMK_FAULT_EVAC
03188
03189
03190
03191
03192
03193 if(msg->bounced){
03194 callMethod(rec,&CkMigratable::ResumeFromSync);
03195 }
03196 #endif
03197
03198
03199 callMethod(rec,&CkMigratable::ckJustMigrated);
03200
03201 #if CMK_FAULT_EVAC
03202
03203
03204
03205
03206
03207
03208 if(CkpvAccess(startedEvac)){
03209 int newhomePE = getNextPE(idx);
03210 DEBM((AA "Migrated into failed processor index size %s resent to %d \n" AB,idx2str(idx),newhomePE));
03211 int targetPE=getNextPE(idx);
03212
03213
03214 rec->AsyncMigrate(true);
03215 rec->Bounced(true);
03216 emigrate(rec,targetPE);
03217 }
03218 #endif
03219
03220 delete msg;
03221 }
03222
03223 void CkLocMgr::restore(const CkArrayIndex &idx, CmiUInt8 id, PUP::er &p)
03224 {
03225 insertID(idx,id);
03226
03227
03228
03229
03230 #if CMK_ERROR_CHECKING
03231 if(_BgOutOfCoreFlag!=2)
03232 CmiAbort("CkLocMgr::restore should only be used in out-of-core emulation for BigSim and be called when object is brought into memory!\n");
03233 #endif
03234 CkLocRec *rec=createLocal(idx,false,false,false);
03235
03236
03237
03238
03239
03240 pupElementsFor(p,rec,CkElementCreation_restore);
03241
03242 callMethod(rec,&CkMigratable::ckJustRestored);
03243 }
03244
03245
03247 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
03248 void CkLocMgr::resume(const CkArrayIndex &idx, CmiUInt8 id, PUP::er &p, bool create, int dummy)
03249 {
03250 insertID(idx,id);
03251
03252 CkLocRec *rec;
03253
03254 if(create){
03255 rec = createLocal(idx,false,false,true && !dummy ,dummy );
03256 }else{
03257 rec = elementNrec(idx);
03258 if(rec == NULL)
03259 CmiAbort("Local object not found");
03260 }
03261
03262 pupElementsFor(p,rec,CkElementCreation_resume,create,dummy);
03263
03264 if(!dummy){
03265 callMethod(rec,&CkMigratable::ckJustMigrated);
03266 }
03267 }
03268 #else
03269 void CkLocMgr::resume(const CkArrayIndex &idx, CmiUInt8 id, PUP::er &p, bool notify,bool rebuild)
03270 {
03271 insertID(idx,id);
03272
03273 CkLocRec *rec=createLocal(idx,false,false,notify );
03274
03275
03276 pupElementsFor(p,rec,CkElementCreation_resume,rebuild);
03277
03278 callMethod(rec,&CkMigratable::ckJustMigrated);
03279 }
03280 #endif
03281
03282
03283 void CkMagicNumber_impl::badMagicNumber(
03284 int expected,const char *file,int line,void *obj) const
03285 {
03286 CkError("FAILURE on pe %d, %s:%d> Expected %p's magic number "
03287 "to be 0x%08x; but found 0x%08x!\n", CkMyPe(),file,line,obj,
03288 expected, magic);
03289 CkAbort("Bad magic number detected! This implies either\n"
03290 "the heap or a message was corrupted!\n");
03291 }
03292 CkMagicNumber_impl::CkMagicNumber_impl(int m) :magic(m) { }
03293
03294 int CkLocMgr::whichPE(const CkArrayIndex &idx) const
03295 {
03296 CmiUInt8 id;
03297 if (!lookupID(idx, id))
03298 return -1;
03299
03300 IdPeMap::const_iterator itr = id2pe.find(id);
03301 return (itr != id2pe.end() ? itr->second : -1);
03302 }
03303
03304 int CkLocMgr::whichPE(const CmiUInt8 id) const
03305 {
03306 IdPeMap::const_iterator itr = id2pe.find(id);
03307 return (itr != id2pe.end() ? itr->second : -1);
03308 }
03309
03310
03311 int CkLocMgr::lastKnown(const CkArrayIndex &idx) {
03312 CkLocMgr *vthis=(CkLocMgr *)this;
03313 int pe = whichPE(idx);
03314 if (pe==-1) return homePe(idx);
03315 else{
03316 #if CMK_FAULT_EVAC
03317 if(!CmiNodeAlive(pe)){
03318 CkAbort("Last known PE is no longer alive");
03319 }
03320 #endif
03321 return pe;
03322 }
03323 }
03324
03325
03326 int CkLocMgr::lastKnown(CmiUInt8 id) {
03327 int pe = whichPE(id);
03328 if (pe==-1) return homePe(id);
03329 else{
03330 #if CMK_FAULT_EVAC
03331 if(!CmiNodeAlive(pe)){
03332 CkAbort("Last known PE is no longer alive");
03333 }
03334 #endif
03335 return pe;
03336 }
03337 }
03338
03340 bool CkLocMgr::isRemote(const CkArrayIndex &idx,int *onPe) const
03341 {
03342 int pe = whichPE(idx);
03343
03344 if (pe == -1 || pe == CkMyPe())
03345 return false;
03346
03347 *onPe = pe;
03348 return true;
03349 }
03350
03351 static const char *rec2str[]={
03352 "base (INVALID)",
03353 "local",
03354 };
03355
03356 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
03357 void CkLocMgr::setDuringMigration(bool _duringMigration){
03358 duringMigration = _duringMigration;
03359 }
03360 #endif
03361
03362
03363
03364 void CkLocMgr::setDuringDestruction(bool _duringDestruction) {
03365 duringDestruction = (_duringDestruction && managers.size() == 1);
03366 }
03367
03368
03369 void CkLocMgr::insertRec(CkLocRec *rec, const CmiUInt8 &id) {
03370 CkLocRec *old_rec = elementNrec(id);
03371 CmiImmediateLock(hashImmLock);
03372 hash[id] = rec;
03373 CmiImmediateUnlock(hashImmLock);
03374 delete old_rec;
03375 }
03376
03377
03378 static void abort_out_of_bounds(const CkArrayIndex &idx)
03379 {
03380 CkPrintf("ERROR! Unknown array index: %s\n",idx2str(idx));
03381 CkAbort("Array index out of bounds\n");
03382 }
03383
03384
03385
03386 CkLocRec *CkLocMgr::elementRec(const CkArrayIndex &idx) {
03387 #if ! CMK_ERROR_CHECKING
03388
03389 return hash[lookupID(idx)];
03390 #else
03391
03392 CmiUInt8 id;
03393 CkLocRec *rec = NULL;
03394 if (lookupID(idx, id) && (rec = elementNrec(id))) {
03395 return rec;
03396 } else {
03397 if (rec==NULL) abort_out_of_bounds(idx);
03398 return NULL;
03399 }
03400 #endif
03401 }
03402
03403
03404 CkLocRec *CkLocMgr::elementNrec(const CmiUInt8 id) {
03405 LocRecHash::iterator it = hash.find(id);
03406 return it == hash.end() ? NULL : it->second;
03407 }
03408
03409 struct LocalElementCounter : public CkLocIterator
03410 {
03411 unsigned int count;
03412 LocalElementCounter() : count(0) {}
03413 void addLocation(CkLocation &loc)
03414 { ++count; }
03415 };
03416
03417 unsigned int CkLocMgr::numLocalElements()
03418 {
03419 LocalElementCounter c;
03420 iterate(c);
03421 return c.count;
03422 }
03423
03424
03425
03426
03427 #if !CMK_LBDB_ON
03428
03429 void CkLocMgr::initLB(CkGroupID lbdbID_, CkGroupID metalbID_) {}
03430 void CkLocMgr::startInserting(void) {}
03431 void CkLocMgr::doneInserting(void) {}
03432 void CkLocMgr::dummyAtSync(void) {}
03433 #endif
03434
03435
03436 #if CMK_LBDB_ON
03437 void CkLocMgr::initLB(CkGroupID lbdbID_, CkGroupID metalbID_)
03438 {
03439 the_lbdb = (LBDatabase *)CkLocalBranch(lbdbID_);
03440 if (the_lbdb == 0)
03441 CkAbort("LBDatabase not yet created?\n");
03442 DEBL((AA "Connected to load balancer %p\n" AB,the_lbdb));
03443 if(_lb_args.metaLbOn()){
03444 the_metalb = (MetaBalancer *)CkLocalBranch(metalbID_);
03445 if (the_metalb == 0)
03446 CkAbort("MetaBalancer not yet created?\n");
03447 }
03448
03449 LDOMid myId;
03450 myId.id = thisgroup;
03451 LDCallbacks myCallbacks;
03452 myCallbacks.migrate = (LDMigrateFn)CkLocRec::staticMigrate;
03453 myCallbacks.setStats = NULL;
03454 myCallbacks.queryEstLoad = NULL;
03455 myCallbacks.metaLBResumeWaitingChares =
03456 (LDMetaLBResumeWaitingCharesFn)CkLocRec::staticMetaLBResumeWaitingChares;
03457 myCallbacks.metaLBCallLBOnChares =
03458 (LDMetaLBCallLBOnCharesFn)CkLocRec::staticMetaLBCallLBOnChares;
03459 myLBHandle = the_lbdb->RegisterOM(myId,this,myCallbacks);
03460
03461
03462 the_lbdb->RegisteringObjects(myLBHandle);
03463
03464
03465
03466
03467
03468 lbBarrierReceiver = the_lbdb->AddLocalBarrierReceiver(
03469 (LDBarrierFn)staticRecvAtSync,(void*)(this));
03470 dummyBarrierHandle = the_lbdb->AddLocalBarrierClient(
03471 (LDResumeFn)staticDummyResumeFromSync,(void*)(this));
03472 dummyAtSync();
03473 }
03474 void CkLocMgr::dummyAtSync(void)
03475 {
03476 DEBL((AA "dummyAtSync called\n" AB));
03477 the_lbdb->AtLocalBarrier(dummyBarrierHandle);
03478 }
03479
03480 void CkLocMgr::staticDummyResumeFromSync(void* data)
03481 { ((CkLocMgr*)data)->dummyResumeFromSync(); }
03482 void CkLocMgr::dummyResumeFromSync()
03483 {
03484 DEBL((AA "DummyResumeFromSync called\n" AB));
03485 the_lbdb->DoneRegisteringObjects(myLBHandle);
03486 dummyAtSync();
03487 }
03488 void CkLocMgr::staticRecvAtSync(void* data)
03489 { ((CkLocMgr*)data)->recvAtSync(); }
03490 void CkLocMgr::recvAtSync()
03491 {
03492 DEBL((AA "recvAtSync called\n" AB));
03493 the_lbdb->RegisteringObjects(myLBHandle);
03494 }
03495
03496 void CkLocMgr::startInserting(void)
03497 {
03498 the_lbdb->RegisteringObjects(myLBHandle);
03499 }
03500 void CkLocMgr::doneInserting(void)
03501 {
03502 the_lbdb->DoneRegisteringObjects(myLBHandle);
03503 }
03504 #endif
03505
03506 #include "CkLocation.def.h"
03507
03508