00001
00011 #include "charm++.h"
00012 #include "register.h"
00013 #include "ck.h"
00014 #include "trace.h"
00015 #include "TopoManager.h"
00016
00017 #include<sstream>
00018
00019 #if CMK_LBDB_ON
00020 #include "LBDatabase.h"
00021 #endif // CMK_LBDB_ON
00022
00023 #if CMK_GRID_QUEUE_AVAILABLE
00024 CpvExtern(void *, CkGridObject);
00025 #endif
00026
00027 static const char *idx2str(const CkArrayMessage *m) {
00028 return idx2str(((CkArrayMessage *)m)->array_index());
00029 }
00030
00031 #define ARRAY_DEBUG_OUTPUT 0
00032
00033 #if ARRAY_DEBUG_OUTPUT
00034 # define DEB(x) CkPrintf x //General debug messages
00035 # define DEBI(x) CkPrintf x //Index debug messages
00036 # define DEBC(x) CkPrintf x //Construction debug messages
00037 # define DEBS(x) CkPrintf x //Send/recv/broadcast debug messages
00038 # define DEBM(x) CkPrintf x //Migration debug messages
00039 # define DEBL(x) CkPrintf x //Load balancing debug messages
00040 # define DEBK(x) //CkPrintf x //Spring Cleaning debug messages
00041 # define DEBB(x) CkPrintf x //Broadcast debug messages
00042 # define AA "LocMgr on %d: "
00043 # define AB ,CkMyPe()
00044 # define DEBUG(x) CkPrintf x
00045 #else
00046 # define DEB(X)
00047 # define DEBI(X)
00048 # define DEBC(X)
00049 # define DEBS(x)
00050 # define DEBM(X)
00051 # define DEBL(X)
00052 # define DEBK(x)
00053 # define DEBB(x)
00054 # define str(x)
00055 # define DEBUG(x)
00056 #endif
00057
00058
00059 bool useNodeBlkMapping;
00060
00061 #if CMK_LBDB_ON
00062
00063
00064
00065 LDObjid idx2LDObjid(const CkArrayIndex &idx)
00066 {
00067 LDObjid r;
00068 int i;
00069 const int *data=idx.data();
00070 if (OBJ_ID_SZ>=idx.nInts) {
00071 for (i=0;i<idx.nInts;i++)
00072 r.id[i]=data[i];
00073 for (i=idx.nInts;i<OBJ_ID_SZ;i++)
00074 r.id[i]=0;
00075 } else {
00076
00077 int j;
00078 for (j=0;j<OBJ_ID_SZ;j++)
00079 r.id[j]=data[j];
00080 for (i=0;i<idx.nInts;i++)
00081 for (j=0;j<OBJ_ID_SZ;j++)
00082 r.id[j]+=circleShift(data[i],22+11*i*(j+1))+
00083 circleShift(data[i],21-9*i*(j+1));
00084 }
00085 return r;
00086 }
00087 #endif
00088
00089
00090 CkArrayIndex &CkArrayMessage::array_index(void)
00091 {
00092 return UsrToEnv((void *)this)->getsetArrayIndex();
00093 }
00094 unsigned short &CkArrayMessage::array_ep(void)
00095 {
00096 return UsrToEnv((void *)this)->getsetArrayEp();
00097 }
00098 unsigned short &CkArrayMessage::array_ep_bcast(void)
00099 {
00100 return UsrToEnv((void *)this)->getsetArrayBcastEp();
00101 }
00102 unsigned char &CkArrayMessage::array_hops(void)
00103 {
00104 return UsrToEnv((void *)this)->getsetArrayHops();
00105 }
00106 unsigned int CkArrayMessage::array_getSrcPe(void)
00107 {
00108 return UsrToEnv((void *)this)->getsetArraySrcPe();
00109 }
00110 unsigned int CkArrayMessage::array_ifNotThere(void)
00111 {
00112 return UsrToEnv((void *)this)->getArrayIfNotThere();
00113 }
00114 void CkArrayMessage::array_setIfNotThere(unsigned int i)
00115 {
00116 UsrToEnv((void *)this)->setArrayIfNotThere(i);
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126 CkArrayMap::CkArrayMap(void) { }
00127 CkArrayMap::~CkArrayMap() { }
00128 int CkArrayMap::registerArray(CkArrayIndex& numElements,CkArrayID aid)
00129 {return 0;}
00130
00131 #define CKARRAYMAP_POPULATE_INITIAL(POPULATE_CONDITION) \
00132 int i; \
00133 for (int i1=0; i1<numElements.data()[0]; i1++) { \
00134 if (numElements.dimension == 1) { \
00135 \
00136 i = i1; \
00137 CkArrayIndex1D idx(i1); \
00138 if (POPULATE_CONDITION) \
00139 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00140 } else { \
00141 \
00142 for (int i2=0; i2<numElements.data()[1]; i2++) { \
00143 if (numElements.dimension == 2) { \
00144 \
00145 i = i1 * numElements.data()[1] + i2; \
00146 CkArrayIndex2D idx(i1, i2); \
00147 if (POPULATE_CONDITION) \
00148 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00149 } else { \
00150 \
00151 CkAssert(numElements.dimension == 3); \
00152 for (int i3=0; i3<numElements.data()[2]; i3++) { \
00153 \
00154 i = (i1 * numElements.data()[1] + i2) * numElements.data()[2] + i3; \
00155 CkArrayIndex3D idx(i1, i2, i3 ); \
00156 if (POPULATE_CONDITION) \
00157 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg)); \
00158 } \
00159 } \
00160 } \
00161 } \
00162 }
00163
00164 void CkArrayMap::populateInitial(int arrayHdl,CkArrayIndex& numElements,void *ctorMsg,CkArrMgr *mgr)
00165 {
00166 if (numElements.nInts==0) {
00167 CkFreeMsg(ctorMsg);
00168 return;
00169 }
00170 int thisPe=CkMyPe();
00171
00172
00173
00174 CKARRAYMAP_POPULATE_INITIAL(procNum(arrayHdl,idx)==thisPe);
00175
00176 #if CMK_BIGSIM_CHARM
00177 BgEntrySplit("split-array-new-end");
00178 #endif
00179
00180 mgr->doneInserting();
00181 CkFreeMsg(ctorMsg);
00182 }
00183
00184 CkGroupID _defaultArrayMapID;
00185 CkGroupID _fastArrayMapID;
00186
00187 class RRMap : public CkArrayMap
00188 {
00189 public:
00190 RRMap(void)
00191 {
00192 DEBC((AA"Creating RRMap\n"AB));
00193 }
00194 RRMap(CkMigrateMessage *m):CkArrayMap(m){}
00195 int procNum(int , const CkArrayIndex &i)
00196 {
00197 #if 1
00198 if (i.nInts==1) {
00199
00200 int ans= (i.data()[0])%CkNumPes();
00201 while(!CmiNodeAlive(ans) || (ans == CkMyPe() && CkpvAccess(startedEvac))){
00202 ans = (ans +1 )%CkNumPes();
00203 }
00204 return ans;
00205 }
00206 else
00207 #endif
00208 {
00209
00210 unsigned int hash=(i.hash()+739)%1280107;
00211 int ans = (hash % CkNumPes());
00212 while(!CmiNodeAlive(ans)){
00213 ans = (ans +1 )%CkNumPes();
00214 }
00215 return ans;
00216
00217 }
00218 }
00219 };
00220
00225 class arrayMapInfo {
00226 public:
00227 CkArrayIndex _nelems;
00228 int _binSizeFloor;
00229 int _binSizeCeil;
00230 int _numChares;
00231 int _remChares;
00232
00233 int _numFirstSet;
00234
00235
00236 int _nBinSizeFloor;
00237 int _nRemChares;
00238
00239 int _nNumFirstSet;
00240
00241
00245 arrayMapInfo(void) { }
00246
00247 arrayMapInfo(CkArrayIndex& n) : _nelems(n), _numChares(0) {
00248 compute_binsize();
00249 }
00250
00251 ~arrayMapInfo() {}
00252
00253 void compute_binsize()
00254 {
00255 int numPes = CkNumPes();
00256
00257 int numNodes = CkNumNodes();
00258
00259 if (_nelems.nInts == 1) {
00260 _numChares = _nelems.data()[0];
00261 } else if (_nelems.nInts == 2) {
00262 _numChares = _nelems.data()[0] * _nelems.data()[1];
00263 } else if (_nelems.nInts == 3) {
00264 _numChares = _nelems.data()[0] * _nelems.data()[1] * _nelems.data()[2];
00265 }
00266
00267 _remChares = _numChares % numPes;
00268 _binSizeFloor = (int)floor((double)_numChares/(double)numPes);
00269 _binSizeCeil = (int)ceil((double)_numChares/(double)numPes);
00270 _numFirstSet = _remChares * (_binSizeFloor + 1);
00271
00272 _nRemChares = _numChares % numNodes;
00273 _nBinSizeFloor = _numChares/numNodes;
00274 _nNumFirstSet = _nRemChares * (_nBinSizeFloor +1);
00275 }
00276
00277 void pup(PUP::er& p){
00278 p|_nelems;
00279 p|_binSizeFloor;
00280 p|_binSizeCeil;
00281 p|_numChares;
00282 p|_remChares;
00283 p|_numFirstSet;
00284 p|_nRemChares;
00285 p|_nBinSizeFloor;
00286 p|_nNumFirstSet;
00287 }
00288 }c;
00289
00290
00295 class DefaultArrayMap : public RRMap
00296 {
00297 public:
00300 CkPupPtrVec<arrayMapInfo> amaps;
00301
00302 public:
00303 DefaultArrayMap(void) {
00304 DEBC((AA"Creating DefaultArrayMap\n"AB));
00305 }
00306
00307 DefaultArrayMap(CkMigrateMessage *m) : RRMap(m){}
00308
00309 int registerArray(CkArrayIndex& numElements, CkArrayID aid)
00310 {
00311 int idx = amaps.size();
00312 amaps.resize(idx+1);
00313 amaps[idx] = new arrayMapInfo(numElements);
00314 return idx;
00315 }
00316
00317 int procNum(int arrayHdl, const CkArrayIndex &i) {
00318 int flati;
00319 if (amaps[arrayHdl]->_nelems.nInts == 0) {
00320 return RRMap::procNum(arrayHdl, i);
00321 }
00322
00323 if (i.nInts == 1) {
00324 flati = i.data()[0];
00325 } else if (i.nInts == 2) {
00326 flati = i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1];
00327 } else if (i.nInts == 3) {
00328 flati = (i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1]) * amaps[arrayHdl]->_nelems.data()[2] + i.data()[2];
00329 }
00330 #if CMK_ERROR_CHECKING
00331 else {
00332 CkAbort("CkArrayIndex has more than 3 integers!");
00333 }
00334 #endif
00335
00336 if(useNodeBlkMapping){
00337 if(flati < amaps[arrayHdl]->_numChares){
00338 int numCharesOnNode = amaps[arrayHdl]->_nBinSizeFloor;
00339 int startNodeID, offsetInNode;
00340 if(flati < amaps[arrayHdl]->_nNumFirstSet){
00341 numCharesOnNode++;
00342 startNodeID = flati/numCharesOnNode;
00343 offsetInNode = flati%numCharesOnNode;
00344 }else{
00345 startNodeID = amaps[arrayHdl]->_nRemChares+(flati-amaps[arrayHdl]->_nNumFirstSet)/numCharesOnNode;
00346 offsetInNode = (flati-amaps[arrayHdl]->_nNumFirstSet)%numCharesOnNode;
00347 }
00348 int nodeSize = CkMyNodeSize();
00349 int elemsPerPE = numCharesOnNode/nodeSize;
00350 int remElems = numCharesOnNode%nodeSize;
00351 int firstSetPEs = remElems*(elemsPerPE+1);
00352 if(offsetInNode<firstSetPEs){
00353 return CkNodeFirst(startNodeID)+offsetInNode/(elemsPerPE+1);
00354 }else{
00355 return CkNodeFirst(startNodeID)+remElems+(offsetInNode-firstSetPEs)/elemsPerPE;
00356 }
00357 } else
00358 return (flati % CkNumPes());
00359 }
00360
00361 if(flati < amaps[arrayHdl]->_numFirstSet)
00362 return (flati / (amaps[arrayHdl]->_binSizeFloor + 1));
00363 else if (flati < amaps[arrayHdl]->_numChares)
00364 return (amaps[arrayHdl]->_remChares + (flati - amaps[arrayHdl]->_numFirstSet) / (amaps[arrayHdl]->_binSizeFloor));
00365 else
00366 return (flati % CkNumPes());
00367 }
00368
00369 void pup(PUP::er& p){
00370 RRMap::pup(p);
00371 int npes = CkNumPes();
00372 p|npes;
00373 p|amaps;
00374 if (p.isUnpacking() && npes != CkNumPes()) {
00375 for (int i=0; i<amaps.size(); i++)
00376 amaps[i]->compute_binsize();
00377 }
00378 }
00379 };
00380
00385 class FastArrayMap : public DefaultArrayMap
00386 {
00387 public:
00388 FastArrayMap(void) {
00389 DEBC((AA"Creating FastArrayMap\n"AB));
00390 }
00391
00392 FastArrayMap(CkMigrateMessage *m) : DefaultArrayMap(m){}
00393
00394 int registerArray(CkArrayIndex& numElements, CkArrayID aid)
00395 {
00396 int idx;
00397 idx = DefaultArrayMap::registerArray(numElements, aid);
00398
00399 return idx;
00400 }
00401
00402 int procNum(int arrayHdl, const CkArrayIndex &i) {
00403 int flati;
00404 if (amaps[arrayHdl]->_nelems.nInts == 0) {
00405 return RRMap::procNum(arrayHdl, i);
00406 }
00407
00408 if (i.nInts == 1) {
00409 flati = i.data()[0];
00410 } else if (i.nInts == 2) {
00411 flati = i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1];
00412 } else if (i.nInts == 3) {
00413 flati = (i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1]) * amaps[arrayHdl]->_nelems.data()[2] + i.data()[2];
00414 }
00415 #if CMK_ERROR_CHECKING
00416 else {
00417 CkAbort("CkArrayIndex has more than 3 integers!");
00418 }
00419 #endif
00420
00423 return (flati / amaps[arrayHdl]->_binSizeCeil);
00424 }
00425
00426 void pup(PUP::er& p){
00427 DefaultArrayMap::pup(p);
00428 }
00429 };
00430
00431
00436 class ReadFileMap : public DefaultArrayMap
00437 {
00438 private:
00439 CkVec<int> mapping;
00440
00441 public:
00442 ReadFileMap(void) {
00443 DEBC((AA"Creating ReadFileMap\n"AB));
00444 }
00445
00446 ReadFileMap(CkMigrateMessage *m) : DefaultArrayMap(m){}
00447
00448 int registerArray(CkArrayIndex& numElements, CkArrayID aid)
00449 {
00450 int idx;
00451 idx = DefaultArrayMap::registerArray(numElements, aid);
00452
00453 if(mapping.size() == 0) {
00454 int numChares;
00455
00456 if (amaps[idx]->_nelems.nInts == 1) {
00457 numChares = amaps[idx]->_nelems.data()[0];
00458 } else if (amaps[idx]->_nelems.nInts == 2) {
00459 numChares = amaps[idx]->_nelems.data()[0] * amaps[idx]->_nelems.data()[1];
00460 } else if (amaps[idx]->_nelems.nInts == 3) {
00461 numChares = amaps[idx]->_nelems.data()[0] * amaps[idx]->_nelems.data()[1] * amaps[idx]->_nelems.data()[2];
00462 } else {
00463 CkAbort("CkArrayIndex has more than 3 integers!");
00464 }
00465
00466 mapping.resize(numChares);
00467 FILE *mapf = fopen("mapfile", "r");
00468 TopoManager tmgr;
00469 int x, y, z, t;
00470
00471 for(int i=0; i<numChares; i++) {
00472 (void) fscanf(mapf, "%d %d %d %d", &x, &y, &z, &t);
00473 mapping[i] = tmgr.coordinatesToRank(x, y, z, t);
00474 }
00475 fclose(mapf);
00476 }
00477
00478 return idx;
00479 }
00480
00481 int procNum(int arrayHdl, const CkArrayIndex &i) {
00482 int flati;
00483
00484 if (i.nInts == 1) {
00485 flati = i.data()[0];
00486 } else if (i.nInts == 2) {
00487 flati = i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1];
00488 } else if (i.nInts == 3) {
00489 flati = (i.data()[0] * amaps[arrayHdl]->_nelems.data()[1] + i.data()[1]) * amaps[arrayHdl]->_nelems.data()[2] + i.data()[2];
00490 } else {
00491 CkAbort("CkArrayIndex has more than 3 integers!");
00492 }
00493
00494 return mapping[flati];
00495 }
00496
00497 void pup(PUP::er& p){
00498 DefaultArrayMap::pup(p);
00499 p|mapping;
00500 }
00501 };
00502
00503 class BlockMap : public RRMap
00504 {
00505 public:
00506 BlockMap(void){
00507 DEBC((AA"Creating BlockMap\n"AB));
00508 }
00509 BlockMap(CkMigrateMessage *m):RRMap(m){ }
00510 void populateInitial(int arrayHdl,CkArrayIndex& numElements,void *ctorMsg,CkArrMgr *mgr){
00511 if (numElements.nInts==0) {
00512 CkFreeMsg(ctorMsg);
00513 return;
00514 }
00515 int thisPe=CkMyPe();
00516 int numPes=CkNumPes();
00517 int binSize;
00518 if (numElements.nInts == 1) {
00519 binSize = (int)ceil((double)numElements.data()[0]/(double)numPes);
00520 } else if (numElements.nInts == 2) {
00521 binSize = (int)ceil((double)(numElements.data()[0]*numElements.data()[1])/(double)numPes);
00522 } else if (numElements.nInts == 3) {
00523 binSize = (int)ceil((double)(numElements.data()[0]*numElements.data()[1]*numElements.data()[2])/(double)numPes);
00524 } else {
00525 CkAbort("CkArrayIndex has more than 3 integers!");
00526 }
00527 CKARRAYMAP_POPULATE_INITIAL(i/binSize==thisPe);
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 mgr->doneInserting();
00538 CkFreeMsg(ctorMsg);
00539 }
00540 };
00541
00545 class CldMap : public CkArrayMap
00546 {
00547 public:
00548 CldMap(void)
00549 {
00550 DEBC((AA"Creating CldMap\n"AB));
00551 }
00552 CldMap(CkMigrateMessage *m):CkArrayMap(m){}
00553 int homePe(int , const CkArrayIndex &i)
00554 {
00555 if (i.nInts==1) {
00556
00557 return (i.data()[0])%CkNumPes();
00558 }
00559 else
00560 {
00561
00562 unsigned int hash=(i.hash()+739)%1280107;
00563 return (hash % CkNumPes());
00564 }
00565 }
00566 int procNum(int arrayHdl, const CkArrayIndex &i)
00567 {
00568 return CLD_ANYWHERE;
00569 }
00570 void populateInitial(int arrayHdl,CkArrayIndex& numElements,void *ctorMsg,CkArrMgr *mgr) {
00571 if (numElements.nInts==0) {
00572 CkFreeMsg(ctorMsg);
00573 return;
00574 }
00575 int thisPe=CkMyPe();
00576 int numPes=CkNumPes();
00577
00578
00579 CKARRAYMAP_POPULATE_INITIAL(i%numPes==thisPe);
00580
00581
00582
00583
00584
00585 mgr->doneInserting();
00586 CkFreeMsg(ctorMsg);
00587 }
00588
00589 };
00590
00591
00594 class ConfigurableRRMapLoader {
00595 public:
00596
00597 int *locations;
00598 int objs_per_block;
00599 int PE_per_block;
00600
00602 enum ConfigurableRRMapLoadStatus{
00603 not_loaded,
00604 loaded_found,
00605 loaded_not_found
00606 };
00607
00608 enum ConfigurableRRMapLoadStatus state;
00609
00610 ConfigurableRRMapLoader(){
00611 state = not_loaded;
00612 locations = NULL;
00613 objs_per_block = 0;
00614 PE_per_block = 0;
00615 }
00616
00618 bool haveConfiguration() {
00619 if(state == not_loaded) {
00620 DEBUG(("[%d] loading ConfigurableRRMap configuration\n", CkMyPe()));
00621 char **argv=CkGetArgv();
00622 char *configuration = NULL;
00623 bool found = CmiGetArgString(argv, "+ConfigurableRRMap", &configuration);
00624 if(!found){
00625 DEBUG(("Couldn't find +ConfigurableRRMap command line argument\n"));
00626 state = loaded_not_found;
00627 return false;
00628 } else {
00629
00630 DEBUG(("Found +ConfigurableRRMap command line argument in %p=\"%s\"\n", configuration, configuration));
00631
00632 std::istringstream instream(configuration);
00633 CkAssert(instream.good());
00634
00635
00636
00637
00638
00639
00640 instream >> objs_per_block >> PE_per_block;
00641 CkAssert(instream.good());
00642 CkAssert(objs_per_block > 0);
00643 CkAssert(PE_per_block > 0);
00644 locations = new int[objs_per_block];
00645 for(int i=0;i<objs_per_block;i++){
00646 locations[i] = 0;
00647 CkAssert(instream.good());
00648 instream >> locations[i];
00649 CkAssert(locations[i] < PE_per_block);
00650 }
00651 state = loaded_found;
00652 return true;
00653 }
00654
00655 } else {
00656 DEBUG(("[%d] ConfigurableRRMap has already been loaded\n", CkMyPe()));
00657 return state == loaded_found;
00658 }
00659
00660 }
00661
00662 };
00663
00664 CkpvDeclare(ConfigurableRRMapLoader, myConfigRRMapState);
00665
00666 void _initConfigurableRRMap(){
00667 CkpvInitialize(ConfigurableRRMapLoader, myConfigRRMapState);
00668 }
00669
00670
00672 bool haveConfigurableRRMap(){
00673 DEBUG(("haveConfigurableRRMap()\n"));
00674 ConfigurableRRMapLoader &loader = CkpvAccess(myConfigRRMapState);
00675 return loader.haveConfiguration();
00676 }
00677
00678 class ConfigurableRRMap : public RRMap
00679 {
00680 public:
00681 ConfigurableRRMap(void){
00682 DEBC((AA"Creating ConfigurableRRMap\n"AB));
00683 }
00684 ConfigurableRRMap(CkMigrateMessage *m):RRMap(m){ }
00685
00686
00687 void populateInitial(int arrayHdl,CkArrayIndex& numElements,void *ctorMsg,CkArrMgr *mgr){
00688
00689 CkAssert(haveConfigurableRRMap());
00690 ConfigurableRRMapLoader &loader = CkpvAccess(myConfigRRMapState);
00691 if (numElements.nInts==0) {
00692 CkFreeMsg(ctorMsg);
00693 return;
00694 }
00695 int thisPe=CkMyPe();
00696 int maxIndex = numElements.data()[0];
00697 DEBUG(("[%d] ConfigurableRRMap: index=%d,%d,%d\n", CkMyPe(),(int)numElements.data()[0], (int)numElements.data()[1], (int)numElements.data()[2]));
00698
00699 if (numElements.nInts != 1) {
00700 CkAbort("ConfigurableRRMap only supports dimension 1!");
00701 }
00702
00703 for (int index=0; index<maxIndex; index++) {
00704 CkArrayIndex1D idx(index);
00705
00706 int cyclic_block = index / loader.objs_per_block;
00707 int cyclic_local = index % loader.objs_per_block;
00708 int l = loader.locations[ cyclic_local ];
00709 int PE = (cyclic_block*loader.PE_per_block + l) % CkNumPes();
00710
00711 DEBUG(("[%d] ConfigurableRRMap: index=%d is located on PE %d l=%d\n", CkMyPe(), (int)index, (int)PE, l));
00712
00713 if(PE == thisPe)
00714 mgr->insertInitial(idx,CkCopyMsg(&ctorMsg));
00715
00716 }
00717
00718
00719 mgr->doneInserting();
00720 CkFreeMsg(ctorMsg);
00721 }
00722 };
00723
00724
00725 CkpvStaticDeclare(double*, rem);
00726
00727 class arrInfo {
00728 private:
00729 CkArrayIndex _nelems;
00730 int *_map;
00731 void distrib(int *speeds);
00732 public:
00733 arrInfo(void):_map(NULL){}
00734 arrInfo(CkArrayIndex& n, int *speeds)
00735 {
00736 _nelems = n;
00737 _map = new int[_nelems.getCombinedCount()];
00738 distrib(speeds);
00739 }
00740 ~arrInfo() { delete[] _map; }
00741 int getMap(const CkArrayIndex &i);
00742 void pup(PUP::er& p){
00743 p|_nelems;
00744 int totalElements = _nelems.getCombinedCount();
00745 if(p.isUnpacking()){
00746 _map = new int[totalElements];
00747 }
00748 p(_map,totalElements);
00749 }
00750 };
00751
00752 static int cmp(const void *first, const void *second)
00753 {
00754 int fi = *((const int *)first);
00755 int si = *((const int *)second);
00756 return ((CkpvAccess(rem)[fi]==CkpvAccess(rem)[si]) ?
00757 0 :
00758 ((CkpvAccess(rem)[fi]<CkpvAccess(rem)[si]) ?
00759 1 : (-1)));
00760 }
00761
00762 void
00763 arrInfo::distrib(int *speeds)
00764 {
00765 int _nelemsCount = _nelems.getCombinedCount();
00766 double total = 0.0;
00767 int npes = CkNumPes();
00768 int i,j,k;
00769 for(i=0;i<npes;i++)
00770 total += (double) speeds[i];
00771 double *nspeeds = new double[npes];
00772 for(i=0;i<npes;i++)
00773 nspeeds[i] = (double) speeds[i] / total;
00774 int *cp = new int[npes];
00775 for(i=0;i<npes;i++)
00776 cp[i] = (int) (nspeeds[i]*_nelemsCount);
00777 int nr = 0;
00778 for(i=0;i<npes;i++)
00779 nr += cp[i];
00780 nr = _nelemsCount - nr;
00781 if(nr != 0)
00782 {
00783 CkpvAccess(rem) = new double[npes];
00784 for(i=0;i<npes;i++)
00785 CkpvAccess(rem)[i] = (double)_nelemsCount*nspeeds[i] - cp[i];
00786 int *pes = new int[npes];
00787 for(i=0;i<npes;i++)
00788 pes[i] = i;
00789 qsort(pes, npes, sizeof(int), cmp);
00790 for(i=0;i<nr;i++)
00791 cp[pes[i]]++;
00792 delete[] pes;
00793 delete[] CkpvAccess(rem);
00794 }
00795 k = 0;
00796 for(i=0;i<npes;i++)
00797 {
00798 for(j=0;j<cp[i];j++)
00799 _map[k++] = i;
00800 }
00801 delete[] cp;
00802 delete[] nspeeds;
00803 }
00804
00805 int
00806 arrInfo::getMap(const CkArrayIndex &i)
00807 {
00808 if(i.nInts==1)
00809 return _map[i.data()[0]];
00810 else
00811 return _map[((i.hash()+739)%1280107)%_nelems.getCombinedCount()];
00812 }
00813
00814
00815
00816 static int* speeds;
00817
00818 #if CMK_USE_PROP_MAP
00819 typedef struct _speedmsg
00820 {
00821 char hdr[CmiMsgHeaderSizeBytes];
00822 int node;
00823 int speed;
00824 } speedMsg;
00825
00826 static void _speedHdlr(void *m)
00827 {
00828 speedMsg *msg=(speedMsg *)m;
00829 if (CmiMyRank()==0)
00830 for (int pe=0;pe<CmiNodeSize(msg->node);pe++)
00831 speeds[CmiNodeFirst(msg->node)+pe] = msg->speed;
00832 CmiFree(m);
00833 }
00834
00835
00836 void _propMapInit(void)
00837 {
00838 speeds = new int[CkNumPes()];
00839 int hdlr = CkRegisterHandler((CmiHandler)_speedHdlr);
00840 CmiPrintf("[%d]Measuring processor speed for prop. mapping...\n", CkMyPe());
00841 int s = LDProcessorSpeed();
00842 speedMsg msg;
00843 CmiSetHandler(&msg, hdlr);
00844 msg.node = CkMyNode();
00845 msg.speed = s;
00846 CmiSyncBroadcastAllAndFree(sizeof(msg), &msg);
00847 for(int i=0;i<CkNumNodes();i++)
00848 CmiDeliverSpecificMsg(hdlr);
00849 }
00850 #else
00851 void _propMapInit(void)
00852 {
00853 speeds = new int[CkNumPes()];
00854 int i;
00855 for(i=0;i<CkNumPes();i++)
00856 speeds[i] = 1;
00857 }
00858 #endif
00859
00865 class PropMap : public CkArrayMap
00866 {
00867 private:
00868 CkPupPtrVec<arrInfo> arrs;
00869 public:
00870 PropMap(void)
00871 {
00872 CkpvInitialize(double*, rem);
00873 DEBC((AA"Creating PropMap\n"AB));
00874 }
00875 PropMap(CkMigrateMessage *m) {}
00876 int registerArray(CkArrayIndex& numElements,CkArrayID aid)
00877 {
00878 int idx = arrs.size();
00879 arrs.resize(idx+1);
00880 arrs[idx] = new arrInfo(numElements, speeds);
00881 return idx;
00882 }
00883 int procNum(int arrayHdl, const CkArrayIndex &i)
00884 {
00885 return arrs[arrayHdl]->getMap(i);
00886 }
00887 void pup(PUP::er& p){
00888 p|arrs;
00889 }
00890 };
00891
00892 class CkMapsInit : public Chare
00893 {
00894 public:
00895 CkMapsInit(CkArgMsg *msg) {
00896 _defaultArrayMapID = CProxy_DefaultArrayMap::ckNew();
00897 _fastArrayMapID = CProxy_FastArrayMap::ckNew();
00898 delete msg;
00899 }
00900
00901 CkMapsInit(CkMigrateMessage *m) {}
00902 };
00903
00904
00905 CkMigratable * CkArrayMessageObjectPtr(envelope *env) {
00906 if (env->getMsgtype()!=ForArrayEltMsg) return NULL;
00907
00908 CkArrayID aid = env->getsetArrayMgr();
00909 CkArray *mgr=(CkArray *)_localBranch(aid);
00910 if (mgr) {
00911 CkLocMgr *locMgr = mgr->getLocMgr();
00912 if (locMgr) {
00913 return locMgr->lookup(env->getsetArrayIndex(),aid);
00914 }
00915 }
00916 return NULL;
00917 }
00918
00919
00920
00921 #if CMK_OUT_OF_CORE
00922 CooPrefetchManager CkArrayElementPrefetcher;
00923 CkpvDeclare(int,CkSaveRestorePrefetch);
00924
00930 int CkArrayPrefetch_msg2ObjId(void *msg) {
00931 envelope *env=(envelope *)msg;
00932 CkMigratable *elt = CkArrayMessageObjectPtr(env);
00933 return elt?elt->prefetchObjID:-1;
00934 }
00935
00940 void CkArrayPrefetch_writeToSwap(FILE *swapfile,void *objptr) {
00941 CkMigratable *elt=(CkMigratable *)objptr;
00942
00943
00944 PUP::toDisk p(swapfile);
00945 elt->pup(p);
00946
00947
00948 CkpvAccess(CkSaveRestorePrefetch)=1;
00949 elt->~CkMigratable();
00950 CkpvAccess(CkSaveRestorePrefetch)=0;
00951 }
00952
00957 void CkArrayPrefetch_readFromSwap(FILE *swapfile,void *objptr) {
00958 CkMigratable *elt=(CkMigratable *)objptr;
00959
00960 CkpvAccess(CkSaveRestorePrefetch)=1;
00961 int ctorIdx=_chareTable[elt->thisChareType]->migCtor;
00962 elt->myRec->invokeEntry(elt,(CkMigrateMessage *)0,ctorIdx,CmiTrue);
00963 CkpvAccess(CkSaveRestorePrefetch)=0;
00964
00965
00966 PUP::fromDisk p(swapfile);
00967 elt->pup(p);
00968 }
00969
00970 static void _CkMigratable_prefetchInit(void)
00971 {
00972 CkpvExtern(int,CkSaveRestorePrefetch);
00973 CkpvAccess(CkSaveRestorePrefetch)=0;
00974 CkArrayElementPrefetcher.msg2ObjId=CkArrayPrefetch_msg2ObjId;
00975 CkArrayElementPrefetcher.writeToSwap=CkArrayPrefetch_writeToSwap;
00976 CkArrayElementPrefetcher.readFromSwap=CkArrayPrefetch_readFromSwap;
00977 CooRegisterManager(&CkArrayElementPrefetcher, _charmHandlerIdx);
00978 }
00979 #endif
00980
00981
00986 class CkMigratable_initInfo {
00987 public:
00988 CkLocRec_local *locRec;
00989 int chareType;
00990 CmiBool forPrefetch;
00991 };
00992
00993 CkpvStaticDeclare(CkMigratable_initInfo,mig_initInfo);
00994
00995
00996 void _CkMigratable_initInfoInit(void) {
00997 CkpvInitialize(CkMigratable_initInfo,mig_initInfo);
00998 #if CMK_OUT_OF_CORE
00999 _CkMigratable_prefetchInit();
01000 #endif
01001 }
01002
01003 void CkMigratable::commonInit(void) {
01004 CkMigratable_initInfo &i=CkpvAccess(mig_initInfo);
01005 #if CMK_OUT_OF_CORE
01006 isInCore=CmiTrue;
01007 if (CkpvAccess(CkSaveRestorePrefetch))
01008 return;
01009 prefetchObjID=-1;
01010 #endif
01011 myRec=i.locRec;
01012 thisIndexMax=myRec->getIndex();
01013 thisChareType=i.chareType;
01014 usesAtSync=CmiFalse;
01015 usesAutoMeasure=CmiTrue;
01016 barrierRegistered=CmiFalse;
01017
01018
01019
01020 AsyncEvacuate(CmiTrue);
01021 }
01022
01023 CkMigratable::CkMigratable(void) {
01024 DEBC((AA"In CkMigratable constructor\n"AB));
01025 commonInit();
01026 }
01027 CkMigratable::CkMigratable(CkMigrateMessage *m): Chare(m) {
01028 commonInit();
01029 }
01030
01031 int CkMigratable::ckGetChareType(void) const {return thisChareType;}
01032
01033 void CkMigratable::pup(PUP::er &p) {
01034 DEBM((AA"In CkMigratable::pup %s\n"AB,idx2str(thisIndexMax)));
01035 Chare::pup(p);
01036 p|thisIndexMax;
01037 p(usesAtSync);
01038 p(usesAutoMeasure);
01039 #if CMK_LBDB_ON
01040 int readyMigrate;
01041 if (p.isPacking()) readyMigrate = myRec->isReadyMigrate();
01042 p|readyMigrate;
01043 if (p.isUnpacking()) myRec->ReadyMigrate(readyMigrate);
01044 #endif
01045 if(p.isUnpacking()) barrierRegistered=CmiFalse;
01046
01047
01048
01049 p | asyncEvacuate;
01050 if(p.isUnpacking()){myRec->AsyncEvacuate(asyncEvacuate);}
01051
01052 ckFinishConstruction();
01053 }
01054
01055 void CkMigratable::ckDestroy(void) {
01056 DEBC((AA"In CkMigratable::ckDestroy %s\n"AB,idx2str(thisIndexMax)));
01057 myRec->destroy();
01058 }
01059
01060 void CkMigratable::ckAboutToMigrate(void) { }
01061 void CkMigratable::ckJustMigrated(void) { }
01062 void CkMigratable::ckJustRestored(void) { }
01063
01064 CkMigratable::~CkMigratable() {
01065 DEBC((AA"In CkMigratable::~CkMigratable %s\n"AB,idx2str(thisIndexMax)));
01066 #if CMK_OUT_OF_CORE
01067 isInCore=CmiFalse;
01068 if (CkpvAccess(CkSaveRestorePrefetch))
01069 return;
01070
01071 if (prefetchObjID!=-1) {
01072 CooDeregisterObject(prefetchObjID);
01073 prefetchObjID=-1;
01074 }
01075 #endif
01076
01077
01078
01079 #if CMK_LBDB_ON
01080 if (barrierRegistered) {
01081 DEBL((AA"Removing barrier for element %s\n"AB,idx2str(thisIndexMax)));
01082 if (usesAtSync)
01083 myRec->getLBDB()->RemoveLocalBarrierClient(ldBarrierHandle);
01084 else
01085 myRec->getLBDB()->RemoveLocalBarrierReceiver(ldBarrierRecvHandle);
01086 }
01087 #endif
01088
01089 thisIndexMax.nInts=-12345;
01090 thisIndexMax.dimension=-12345;
01091 }
01092
01093 void CkMigratable::CkAbort(const char *why) const {
01094 CkError("CkMigratable '%s' aborting:\n",_chareTable[thisChareType]->name);
01095 ::CkAbort(why);
01096 }
01097
01098 void CkMigratable::ResumeFromSync(void)
01099 {
01100
01101 }
01102
01103 void CkMigratable::UserSetLBLoad() {
01104 CkAbort("::UserSetLBLoad() not defined for this array element!\n");
01105 }
01106
01107 #if CMK_LBDB_ON //For load balancing:
01108
01109 void CkMigratable::setObjTime(double cputime) {
01110 myRec->setObjTime(cputime);
01111 }
01112 double CkMigratable::getObjTime() {
01113 return myRec->getObjTime();
01114 }
01115
01116 void CkMigratable::ckFinishConstruction(void)
01117 {
01118
01119 myRec->setMeasure(usesAutoMeasure);
01120 if (barrierRegistered) return;
01121 DEBL((AA"Registering barrier client for %s\n"AB,idx2str(thisIndexMax)));
01122 if (usesAtSync)
01123 ldBarrierHandle = myRec->getLBDB()->AddLocalBarrierClient(
01124 (LDBarrierFn)staticResumeFromSync,(void*)(this));
01125 else
01126 ldBarrierRecvHandle = myRec->getLBDB()->AddLocalBarrierReceiver(
01127 (LDBarrierFn)staticResumeFromSync,(void*)(this));
01128 barrierRegistered=CmiTrue;
01129 }
01130 void CkMigratable::AtSync(int waitForMigration)
01131 {
01132 if (!usesAtSync)
01133 CkAbort("You must set usesAtSync=CmiTrue in your array element constructor to use AtSync!\n");
01134 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01135 mlogData->toResumeOrNot=1;
01136 #endif
01137 myRec->AsyncMigrate(!waitForMigration);
01138 if (waitForMigration) ReadyMigrate(CmiTrue);
01139 ckFinishConstruction();
01140 DEBL((AA"Element %s going to sync\n"AB,idx2str(thisIndexMax)));
01141
01142 if (usesAutoMeasure == CmiFalse) UserSetLBLoad();
01143 myRec->getLBDB()->AtLocalBarrier(ldBarrierHandle);
01144 }
01145 void CkMigratable::ReadyMigrate(CmiBool ready)
01146 {
01147 myRec->ReadyMigrate(ready);
01148 }
01149
01150 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01151 extern int globalResumeCount;
01152 #endif
01153
01154 void CkMigratable::staticResumeFromSync(void* data)
01155 {
01156 CkMigratable *el=(CkMigratable *)data;
01157 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01158 if(el->mlogData->toResumeOrNot ==0 || el->mlogData->resumeCount >= globalResumeCount){
01159 return;
01160 }
01161 #endif
01162 DEBL((AA"Element %s resuming from sync\n"AB,idx2str(el->thisIndexMax)));
01163 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01164 CpvAccess(_currentObj) = el;
01165 #endif
01166 el->ResumeFromSync();
01167 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01168 el->mlogData->resumeCount++;
01169 #endif
01170 }
01171 void CkMigratable::setMigratable(int migratable)
01172 {
01173 myRec->setMigratable(migratable);
01174 }
01175
01176 struct CkArrayThreadListener {
01177 struct CthThreadListener base;
01178 CkMigratable *mig;
01179 };
01180
01181 extern "C"
01182 void CkArrayThreadListener_suspend(struct CthThreadListener *l)
01183 {
01184 CkArrayThreadListener *a=(CkArrayThreadListener *)l;
01185 a->mig->ckStopTiming();
01186 }
01187
01188 extern "C"
01189 void CkArrayThreadListener_resume(struct CthThreadListener *l)
01190 {
01191 CkArrayThreadListener *a=(CkArrayThreadListener *)l;
01192 a->mig->ckStartTiming();
01193 }
01194
01195 extern "C"
01196 void CkArrayThreadListener_free(struct CthThreadListener *l)
01197 {
01198 CkArrayThreadListener *a=(CkArrayThreadListener *)l;
01199 delete a;
01200 }
01201
01202 void CkMigratable::CkAddThreadListeners(CthThread tid, void *msg)
01203 {
01204 Chare::CkAddThreadListeners(tid, msg);
01205 CthSetThreadID(tid, thisIndexMax.data()[0], thisIndexMax.data()[1],
01206 thisIndexMax.data()[2]);
01207 CkArrayThreadListener *a=new CkArrayThreadListener;
01208 a->base.suspend=CkArrayThreadListener_suspend;
01209 a->base.resume=CkArrayThreadListener_resume;
01210 a->base.free=CkArrayThreadListener_free;
01211 a->mig=this;
01212 CthAddListener(tid,(struct CthThreadListener *)a);
01213 }
01214 #else
01215 void CkMigratable::setObjTime(double cputime) {}
01216 double CkMigratable::getObjTime() {return 0.0;}
01217
01218
01219 void CkMigratable::CkAddThreadListeners(CthThread tid, void *msg)
01220 {
01221 }
01222 #endif
01223
01224
01225
01226 CkMigratableList::CkMigratableList() {}
01227 CkMigratableList::~CkMigratableList() {}
01228
01229 void CkMigratableList::setSize(int s) {
01230 el.resize(s);
01231 }
01232
01233 void CkMigratableList::put(CkMigratable *v,int atIdx) {
01234 #if CMK_ERROR_CHECKING
01235 if (atIdx>=length())
01236 CkAbort("Internal array manager error (CkMigrableList::put index out of bounds)");
01237 #endif
01238 el[atIdx]=v;
01239 }
01240
01241
01242
01243
01244
01245 void CkLocRec::weAreObsolete(const CkArrayIndex &idx) {}
01246 CkLocRec::~CkLocRec() { }
01247 void CkLocRec::beenReplaced(void)
01248 {}
01249
01250
01251 CkMigratable *CkLocRec::lookupElement(CkArrayID aid) {return NULL;}
01252
01253
01254 int CkLocRec::lookupProcessor(void) {return -1;}
01255
01256
01257
01258
01259
01260
01261
01262 CkLocRec_local::CkLocRec_local(CkLocMgr *mgr,CmiBool fromMigration,
01263 CmiBool ignoreArrival, const CkArrayIndex &idx_,int localIdx_)
01264 :CkLocRec(mgr),idx(idx_),localIdx(localIdx_),
01265 running(CmiFalse),deletedMarker(NULL)
01266 {
01267 #if CMK_LBDB_ON
01268 DEBL((AA"Registering element %s with load balancer\n"AB,idx2str(idx)));
01269
01270
01271 nextPe = -1;
01272 asyncMigrate = CmiFalse;
01273 readyMigrate = CmiTrue;
01274 enable_measure = CmiTrue;
01275 bounced = CmiFalse;
01276 the_lbdb=mgr->getLBDB();
01277 ldHandle=the_lbdb->RegisterObj(mgr->getOMHandle(),
01278 idx2LDObjid(idx),(void *)this,1);
01279 if (fromMigration) {
01280 DEBL((AA"Element %s migrated in\n"AB,idx2str(idx)));
01281 if (!ignoreArrival) {
01282 the_lbdb->Migrated(ldHandle, CmiTrue);
01283
01284
01285 }
01286 }
01287 #endif
01288
01289
01290
01291 asyncEvacuate = CmiTrue;
01292 }
01293 CkLocRec_local::~CkLocRec_local()
01294 {
01295 if (deletedMarker!=NULL) *deletedMarker=CmiTrue;
01296 myLocMgr->reclaim(idx,localIdx);
01297 #if CMK_LBDB_ON
01298 stopTiming();
01299 DEBL((AA"Unregistering element %s from load balancer\n"AB,idx2str(idx)));
01300 the_lbdb->UnregisterObj(ldHandle);
01301 #endif
01302 }
01303 void CkLocRec_local::migrateMe(int toPe)
01304 {
01305
01306
01307 myLocMgr->emigrate(this,toPe);
01308 }
01309
01310 #if CMK_LBDB_ON
01311 void CkLocRec_local::startTiming(int ignore_running) {
01312 if (!ignore_running) running=CmiTrue;
01313 DEBL((AA"Start timing for %s at %.3fs {\n"AB,idx2str(idx),CkWallTimer()));
01314 if (enable_measure) the_lbdb->ObjectStart(ldHandle);
01315 }
01316 void CkLocRec_local::stopTiming(int ignore_running) {
01317 DEBL((AA"} Stop timing for %s at %.3fs\n"AB,idx2str(idx),CkWallTimer()));
01318 if ((ignore_running || running) && enable_measure) the_lbdb->ObjectStop(ldHandle);
01319 if (!ignore_running) running=CmiFalse;
01320 }
01321 void CkLocRec_local::setObjTime(double cputime) {
01322 the_lbdb->EstObjLoad(ldHandle, cputime);
01323 }
01324 double CkLocRec_local::getObjTime() {
01325 LBRealType walltime, cputime;
01326 the_lbdb->GetObjLoad(ldHandle, walltime, cputime);
01327 return walltime;
01328 }
01329 #endif
01330
01331 void CkLocRec_local::destroy(void)
01332 {
01333
01334 delete this;
01335 }
01336
01337 CkMigratable *CkLocRec_local::lookupElement(CkArrayID aid) {
01338 return myLocMgr->lookupLocal(localIdx,aid);
01339 }
01340
01341
01342 int CkLocRec_local::lookupProcessor(void) {
01343 return CkMyPe();
01344 }
01345
01346 CkLocRec::RecType CkLocRec_local::type(void)
01347 {
01348 return local;
01349 }
01350
01351 void CkLocRec_local::addedElement(void)
01352 {
01353
01354
01355 while (!halfCreated.isEmpty())
01356 CkArrayManagerDeliver(CkMyPe(),halfCreated.deq());
01357 }
01358
01359 CmiBool CkLocRec_local::isObsolete(int nSprings,const CkArrayIndex &idx_)
01360 {
01361 int len=halfCreated.length();
01362 if (len!=0) {
01363
01364
01365
01366
01367 CkPrintf("CkLoc WARNING> %d messages still around for uncreated element %s!\n",
01368 len,idx2str(idx));
01369 }
01370
01371 return CmiFalse;
01372 }
01373
01374
01375
01376 LDObjHandle CkMigratable::timingBeforeCall(int* objstopped){
01377
01378 LDObjHandle objHandle;
01379 #if CMK_LBDB_ON
01380 if (getLBDB()->RunningObject(&objHandle)) {
01381 *objstopped = 1;
01382 getLBDB()->ObjectStop(objHandle);
01383 }
01384 myRec->startTiming(1);
01385 #endif
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400 return objHandle;
01401 }
01402
01403 void CkMigratable::timingAfterCall(LDObjHandle objHandle,int *objstopped){
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 myRec->stopTiming(1);
01418 #if CMK_LBDB_ON
01419 if (*objstopped) {
01420 getLBDB()->ObjectStart(objHandle);
01421 }
01422 #endif
01423
01424 return;
01425 }
01426
01427
01428
01429 CmiBool CkLocRec_local::invokeEntry(CkMigratable *obj,void *msg,
01430 int epIdx,CmiBool doFree)
01431 {
01432
01433 DEBS((AA" Invoking entry %d on element %s\n"AB,epIdx,idx2str(idx)));
01434 CmiBool isDeleted=CmiFalse;
01435 deletedMarker=&isDeleted;
01436 startTiming();
01437
01438
01439 #if CMK_TRACE_ENABLED
01440 if (msg) {
01441 envelope *env=UsrToEnv(msg);
01442
01443 if (_entryTable[epIdx]->traceEnabled)
01444 _TRACE_BEGIN_EXECUTE_DETAILED(env->getEvent(),
01445 ForChareMsg,epIdx,env->getsetArraySrcPe(), env->getTotalsize(), idx.getProjectionID((((CkGroupID)env->getsetArrayMgr())).idx));
01446 }
01447 #endif
01448
01449 if (doFree)
01450 CkDeliverMessageFree(epIdx,msg,obj);
01451 else
01452 CkDeliverMessageReadonly(epIdx,msg,obj);
01453
01454
01455 #if CMK_TRACE_ENABLED
01456 if (msg) {
01457 if (_entryTable[epIdx]->traceEnabled)
01458 _TRACE_END_EXECUTE();
01459 }
01460 #endif
01461 #if CMK_LBDB_ON
01462 if (!isDeleted) checkBufferedMigration();
01463 #endif
01464 if (isDeleted) return CmiFalse;
01465 deletedMarker=NULL;
01466 stopTiming();
01467 return CmiTrue;
01468 }
01469
01470 CmiBool CkLocRec_local::deliver(CkArrayMessage *msg,CkDeliver_t type,int opts)
01471 {
01472
01473 if (type==CkDeliver_queue) {
01474 if (opts & CK_MSG_KEEP)
01475 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
01476 CkArrayManagerDeliver(CkMyPe(),msg,opts);
01477 return CmiTrue;
01478 }
01479 else
01480 {
01481 CkMigratable *obj=myLocMgr->lookupLocal(localIdx,
01482 UsrToEnv(msg)->getsetArrayMgr());
01483 if (obj==NULL) {
01484 if (opts & CK_MSG_KEEP)
01485 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
01486 if (msg->array_ifNotThere()!=CkArray_IfNotThere_buffer) {
01487 return myLocMgr->demandCreateElement(msg,CkMyPe(),type);
01488 }
01489 else {
01490 DEBS((AA" BUFFERING message for nonexistent element %s!\n"AB,idx2str(this->idx)));
01491 halfCreated.enq(msg);
01492 return CmiTrue;
01493 }
01494 }
01495
01496 if (msg->array_hops()>1)
01497 myLocMgr->multiHop(msg);
01498 CmiBool doFree = (CmiBool)!(opts & CK_MSG_KEEP);
01499 #if CMK_LBDB_ON
01500
01501 LDObjHandle objHandle;
01502 int objstopped = 0;
01503 if (the_lbdb->RunningObject(&objHandle)) {
01504 objstopped = 1;
01505 the_lbdb->ObjectStop(objHandle);
01506 }
01507 #endif
01508 #if CMK_GRID_QUEUE_AVAILABLE
01509
01510 CpvAccess(CkGridObject) = obj;
01511 #endif
01512
01513 CmiBool status = invokeEntry(obj,(void *)msg,msg->array_ep(),doFree);
01514
01515 #if CMK_GRID_QUEUE_AVAILABLE
01516 CpvAccess(CkGridObject) = NULL;
01517 #endif
01518 #if CMK_LBDB_ON
01519 if (objstopped) the_lbdb->ObjectStart(objHandle);
01520 #endif
01521 return status;
01522 }
01523
01524
01525 }
01526
01527 #if CMK_LBDB_ON
01528 void CkLocRec_local::staticMigrate(LDObjHandle h, int dest)
01529 {
01530 CkLocRec_local *el=(CkLocRec_local *)LDObjUserData(h);
01531 DEBL((AA"Load balancer wants to migrate %s to %d\n"AB,idx2str(el->idx),dest));
01532 el->recvMigrate(dest);
01533 }
01534
01535 void CkLocRec_local::recvMigrate(int toPe)
01536 {
01537
01538
01539 if (readyMigrate) { migrateMe(toPe); }
01540 else nextPe = toPe;
01541 }
01542
01543 void CkLocRec_local::AsyncMigrate(CmiBool use)
01544 {
01545 asyncMigrate = use;
01546 the_lbdb->UseAsyncMigrate(ldHandle, use);
01547 }
01548
01549 CmiBool CkLocRec_local::checkBufferedMigration()
01550 {
01551
01552
01553 if (readyMigrate && nextPe != -1) {
01554 int toPe = nextPe;
01555 nextPe = -1;
01556
01557 migrateMe(toPe);
01558
01559 return CmiTrue;
01560 }
01561 return CmiFalse;
01562 }
01563
01564 int CkLocRec_local::MigrateToPe()
01565 {
01566 int pe = nextPe;
01567 nextPe = -1;
01568 return pe;
01569 }
01570
01571 void CkLocRec_local::setMigratable(int migratable)
01572 {
01573 if (migratable)
01574 the_lbdb->Migratable(ldHandle);
01575 else
01576 the_lbdb->NonMigratable(ldHandle);
01577 }
01578 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01579 void CkLocRec_local::Migrated(){
01580 the_lbdb->Migrated(ldHandle, CmiTrue);
01581 }
01582 #endif
01583 #endif
01584
01590 class CkLocRec_dead:public CkLocRec {
01591 public:
01592 CkLocRec_dead(CkLocMgr *Narr):CkLocRec(Narr) {}
01593
01594 virtual RecType type(void) {return dead;}
01595
01596 virtual CmiBool deliver(CkArrayMessage *msg,CkDeliver_t type,int opts=0) {
01597 CkPrintf("Dead array element is %s.\n",idx2str(msg->array_index()));
01598 CkAbort("Send to dead array element!\n");
01599 return CmiFalse;
01600 }
01601 virtual void beenReplaced(void)
01602 {CkAbort("Can't re-use dead array element!\n");}
01603
01604
01605 virtual CmiBool isObsolete(int nSprings,const CkArrayIndex &idx) {return CmiFalse;}
01606 };
01607
01612 class CkLocRec_aging:public CkLocRec {
01613 private:
01614 int lastAccess;
01615 protected:
01616
01617 inline void access(void) {
01618 lastAccess=myLocMgr->getSpringCount();
01619 }
01620
01621 CmiBool isStale(void) {
01622 if (myLocMgr->getSpringCount()-lastAccess>3) return CmiTrue;
01623 else return CmiFalse;
01624 }
01625 public:
01626 CkLocRec_aging(CkLocMgr *Narr):CkLocRec(Narr) {
01627 lastAccess=myLocMgr->getSpringCount();
01628 }
01629
01630 virtual CmiBool isObsolete(int nSprings,const CkArrayIndex &idx)=0;
01631
01632 };
01633
01634
01638 class CkLocRec_remote:public CkLocRec_aging {
01639 private:
01640 int onPe;
01641 public:
01642 CkLocRec_remote(CkLocMgr *Narr,int NonPe)
01643 :CkLocRec_aging(Narr)
01644 {
01645 onPe=NonPe;
01646 #if CMK_ERROR_CHECKING
01647 if (onPe==CkMyPe())
01648 CkAbort("ERROR! 'remote' array element on this Pe!\n");
01649 #endif
01650 }
01651
01652 int lookupProcessor(void) {
01653 return onPe;
01654 }
01655 virtual RecType type(void) {return remote;}
01656
01657
01658 virtual CmiBool deliver(CkArrayMessage *msg,CkDeliver_t type,int opts=0) {
01659
01660 int destPE = onPe;
01661 if((!CmiNodeAlive(onPe) && onPe != allowMessagesOnly)){
01662
01663
01664
01665
01666 const CkArrayIndex &idx=msg->array_index();
01667 destPE = getNextPE(idx);
01668 }
01669 access();
01670 msg->array_hops()++;
01671 DEBS((AA" Forwarding message for element %s to %d (REMOTE)\n"AB,
01672 idx2str(msg->array_index()),destPE));
01673 if (opts & CK_MSG_KEEP)
01674 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
01675 CkArrayManagerDeliver(destPE,msg,opts);
01676 return CmiTrue;
01677 }
01678
01679 virtual CmiBool isObsolete(int nSprings,const CkArrayIndex &idx) {
01680 if (myLocMgr->isHome(idx))
01681
01682
01683 return CmiFalse;
01684 else if (isStale())
01685 return CmiTrue;
01686 else
01687 return CmiFalse;
01688 }
01689
01690 };
01691
01692
01704 class CkLocRec_buffering:public CkLocRec_aging {
01705 private:
01706 CkQ<CkArrayMessage *> buffer;
01707 public:
01708 CkLocRec_buffering(CkLocMgr *Narr):CkLocRec_aging(Narr) {}
01709 virtual ~CkLocRec_buffering() {
01710 if (0!=buffer.length()) {
01711 CkPrintf("[%d] Warning: Messages abandoned in array manager buffer!\n", CkMyPe());
01712 CkArrayMessage *m;
01713 while (NULL!=(m=buffer.deq())) {
01714 delete m;
01715 }
01716 }
01717 }
01718
01719 virtual RecType type(void) {return buffering;}
01720
01721
01722 virtual CmiBool deliver(CkArrayMessage *msg,CkDeliver_t type,int opts=0) {
01723 DEBS((AA" Queued message for %s\n"AB,idx2str(msg->array_index())));
01724 if (opts & CK_MSG_KEEP)
01725 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
01726 buffer.enq(msg);
01727 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01728 envelope *env = UsrToEnv(msg);
01729 env->sender = CpvAccess(_currentObj)->mlogData->objID;
01730 #endif
01731 return CmiTrue;
01732 }
01733
01734
01735
01736
01737 virtual void beenReplaced(void) {
01738 DEBS((AA" Delivering queued messages:\n"AB));
01739 CkArrayMessage *m;
01740 while (NULL!=(m=buffer.deq())) {
01741 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01742 DEBUG(CmiPrintf("[%d] buffered message being sent\n",CmiMyPe()));
01743 envelope *env = UsrToEnv(m);
01744 Chare *oldObj = CpvAccess(_currentObj);
01745 CpvAccess(_currentObj) =(Chare *) env->sender.getObject();
01746 env->sender.type = TypeInvalid;
01747 #endif
01748 DEBS((AA"Sending buffered message to %s\n"AB,idx2str(m->array_index())));
01749 myLocMgr->deliverViaQueue(m);
01750 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01751 CpvAccess(_currentObj) = oldObj;
01752 #endif
01753 }
01754 }
01755
01756
01757 virtual CmiBool isObsolete(int nSprings,const CkArrayIndex &idx) {
01758 if (isStale() && buffer.length()>0) {
01759
01760
01761 CkPrintf("[%d] WARNING: %d stale array message(s) found!\n",CkMyPe(),buffer.length());
01762 CkArrayMessage *msg=buffer[0];
01763 CkPrintf("Addressed to: ");
01764 CkPrintEntryMethod(msg->array_ep());
01765 CkPrintf(" index %s\n",idx2str(idx));
01766 if (myLocMgr->isHome(idx))
01767 CkPrintf("is this an out-of-bounds array index, or was it never created?\n");
01768 else
01769 CkPrintf("why weren't they forwarded?\n");
01770
01771
01772 }
01773 return CmiFalse;
01774 }
01775
01776
01777
01778
01779
01780 };
01781
01782
01793 inline void CkLocMgr::springCleaning(void)
01794 {
01795 nSprings++;
01796
01797
01798 void *objp;
01799 void *keyp;
01800
01801 CkHashtableIterator *it=hash.iterator();
01802 CmiImmediateLock(hashImmLock);
01803 while (NULL!=(objp=it->next(&keyp))) {
01804 CkLocRec *rec=*(CkLocRec **)objp;
01805 CkArrayIndex &idx=*(CkArrayIndex *)keyp;
01806 if (rec->isObsolete(nSprings,idx)) {
01807
01808 DEBK((AA"Cleaning out old record %s\n"AB,idx2str(idx)));
01809 hash.remove(*(CkArrayIndex *)&idx);
01810 delete rec;
01811 it->seek(-1);
01812 }
01813 }
01814 CmiImmediateUnlock(hashImmLock);
01815 delete it;
01816 }
01817 void CkLocMgr::staticSpringCleaning(void *forWhom,double curWallTime) {
01818 DEBK((AA"Starting spring cleaning at %.2f\n"AB,CkWallTimer()));
01819 ((CkLocMgr *)forWhom)->springCleaning();
01820 }
01821
01822
01823 void CkLocMgr::flushAllRecs(void)
01824 {
01825 void *objp;
01826 void *keyp;
01827
01828 CkHashtableIterator *it=hash.iterator();
01829 CmiImmediateLock(hashImmLock);
01830 while (NULL!=(objp=it->next(&keyp))) {
01831 CkLocRec *rec=*(CkLocRec **)objp;
01832 CkArrayIndex &idx=*(CkArrayIndex *)keyp;
01833 if (rec->type() != CkLocRec::local) {
01834
01835
01836
01837 if(_BgOutOfCoreFlag!=1){
01838 hash.remove(*(CkArrayIndex *)&idx);
01839 delete rec;
01840 it->seek(-1);
01841 }
01842 }
01843 else {
01844 callMethod((CkLocRec_local*)rec, &CkMigratable::ckDestroy);
01845 it->seek(-1);
01846 }
01847 }
01848 delete it;
01849 CmiImmediateUnlock(hashImmLock);
01850 }
01851
01852 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01853 void CkLocMgr::callForAllRecords(CkLocFn fnPointer,CkArray *arr,void *data){
01854 void *objp;
01855 void *keyp;
01856
01857 CkHashtableIterator *it = hash.iterator();
01858 while (NULL!=(objp=it->next(&keyp))) {
01859 CkLocRec *rec=*(CkLocRec **)objp;
01860 CkArrayIndex &idx=*(CkArrayIndex *)keyp;
01861 fnPointer(arr,data,rec,&idx);
01862 }
01863 }
01864 #endif
01865
01866
01867 CkLocMgr::CkLocMgr(CkGroupID mapID_,CkGroupID lbdbID_,CkArrayIndex& numInitial)
01868 :thisProxy(thisgroup),thislocalproxy(thisgroup,CkMyPe()),
01869 hash(17,0.3)
01870 {
01871 DEBC((AA"Creating new location manager %d\n"AB,thisgroup));
01872
01873
01874
01875 managers.init();
01876 nManagers=0;
01877 firstManager=NULL;
01878 firstFree=localLen=0;
01879 duringMigration=CmiFalse;
01880 nSprings=0;
01881 CcdCallOnConditionKeepOnPE(CcdPERIODIC_1minute,staticSpringCleaning,(void *)this, CkMyPe());
01882
01883
01884 mapID=mapID_;
01885 map=(CkArrayMap *)CkLocalBranch(mapID);
01886 if (map==NULL) CkAbort("ERROR! Local branch of array map is NULL!");
01887 mapHandle=map->registerArray(numInitial,thisgroup);
01888
01889
01890 lbdbID = lbdbID_;
01891 initLB(lbdbID_);
01892 hashImmLock = CmiCreateImmediateLock();
01893 }
01894
01895 CkLocMgr::CkLocMgr(CkMigrateMessage* m)
01896 :IrrGroup(m),thisProxy(thisgroup),thislocalproxy(thisgroup,CkMyPe()),hash(17,0.3)
01897 {
01898 managers.init();
01899 nManagers=0;
01900 firstManager=NULL;
01901 firstFree=localLen=0;
01902 duringMigration=CmiFalse;
01903 nSprings=0;
01904 CcdCallOnConditionKeepOnPE(CcdPERIODIC_1minute,staticSpringCleaning,(void *)this, CkMyPe());
01905 hashImmLock = CmiCreateImmediateLock();
01906 }
01907
01908 void CkLocMgr::pup(PUP::er &p){
01909 IrrGroup::pup(p);
01910 p|mapID;
01911 p|mapHandle;
01912 p|lbdbID;
01913 mapID = _defaultArrayMapID;
01914 if(p.isUnpacking()){
01915 thisProxy=thisgroup;
01916 CProxyElement_CkLocMgr newlocalproxy(thisgroup,CkMyPe());
01917 thislocalproxy=newlocalproxy;
01918
01919 map=(CkArrayMap *)CkLocalBranch(mapID);
01920 if (map==NULL) CkAbort("ERROR! Local branch of array map is NULL!");
01921 CkArrayIndex emptyIndex;
01922 map->registerArray(emptyIndex,thisgroup);
01923
01924 initLB(lbdbID);
01925
01926 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01927 int count;
01928 p | count;
01929 DEBUG(CmiPrintf("[%d] Unpacking Locmgr %d has %d home elements\n",CmiMyPe(),thisgroup.idx,count));
01930 homeElementCount = count;
01931
01932 for(int i=0;i<count;i++){
01933 CkArrayIndex idx;
01934 int pe;
01935 idx.pup(p);
01936 p | pe;
01937 DEBUG(CmiPrintf("[%d] idx %s is a home element exisiting on pe %d\n",CmiMyPe(),idx2str(idx),pe));
01938 inform(idx,pe);
01939 CkLocRec *rec = elementNrec(idx);
01940 CmiAssert(rec!=NULL);
01941 CmiAssert(lastKnown(idx) == pe);
01942 }
01943 #endif
01944
01945
01946 if (!CkInRestarting())
01947 doneInserting();
01948 }else{
01955 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
01956 int count=0,count1=0;
01957 void *objp;
01958 void *keyp;
01959 CkHashtableIterator *it = hash.iterator();
01960 while (NULL!=(objp=it->next(&keyp))) {
01961 CkLocRec *rec=*(CkLocRec **)objp;
01962 CkArrayIndex &idx=*(CkArrayIndex *)keyp;
01963 if(rec->type() != CkLocRec::local){
01964 if(homePe(idx) == CmiMyPe()){
01965 count++;
01966 }
01967 }
01968 }
01969 p | count;
01970 DEBUG(CmiPrintf("[%d] Packing Locmgr %d has %d home elements\n",CmiMyPe(),thisgroup.idx,count));
01971
01972 it = hash.iterator();
01973 while (NULL!=(objp=it->next(&keyp))) {
01974 CkLocRec *rec=*(CkLocRec **)objp;
01975 CkArrayIndex &idx=*(CkArrayIndex *)keyp;
01976 CkArrayIndex max = idx;
01977 if(rec->type() != CkLocRec::local){
01978 if(homePe(idx) == CmiMyPe()){
01979 int pe;
01980 max.pup(p);
01981 pe = rec->lookupProcessor();
01982 p | pe;
01983 count1++;
01984 }
01985 }
01986 }
01987 CmiAssert(count == count1);
01988
01989 #endif
01990
01991 }
01992 }
01993
01994 void _CkLocMgrInit(void) {
01995
01996 CkDisableTracing(CkIndex_CkLocMgr::deliverInline(0));
01997 }
01998
02002 CkMigratableList *CkLocMgr::addManager(CkArrayID id,CkArrMgr *mgr)
02003 {
02004 CK_MAGICNUMBER_CHECK
02005 DEBC((AA"Adding new array manager\n"AB));
02006
02007 ManagerRec *n=new ManagerRec;
02008 managers.find(id)=n;
02009 n->next=firstManager;
02010 n->mgr=mgr;
02011 n->elts.setSize(localLen);
02012 nManagers++;
02013 firstManager=n;
02014 return &n->elts;
02015 }
02016
02018 int CkLocMgr::nextFree(void) {
02019 if (firstFree>=localLen)
02020 {
02021 int oldLen=localLen;
02022 localLen=localLen*2+8;
02023 DEBC((AA"Growing the local list from %d to %d...\n"AB,oldLen,localLen));
02024 for (ManagerRec *m=firstManager;m!=NULL;m=m->next)
02025 m->elts.setSize(localLen);
02026
02027 freeList.resize(localLen);
02028 for (int i=oldLen;i<localLen;i++)
02029 freeList[i]=i+1;
02030 }
02031 int localIdx=firstFree;
02032 if (localIdx==-1) CkAbort("CkLocMgr free list corrupted!");
02033 firstFree=freeList[localIdx];
02034 freeList[localIdx]=-1;
02035 return localIdx;
02036 }
02037
02038 CkLocRec_remote *CkLocMgr::insertRemote(const CkArrayIndex &idx,int nowOnPe)
02039 {
02040 DEBS((AA"Remote element %s lives on %d\n"AB,idx2str(idx),nowOnPe));
02041 CkLocRec_remote *rem=new CkLocRec_remote(this,nowOnPe);
02042 insertRec(rem,idx);
02043 return rem;
02044 }
02045
02046
02047 void CkLocMgr::inform(const CkArrayIndex &idx,int nowOnPe)
02048 {
02049 if (nowOnPe==CkMyPe())
02050 return;
02051 CkLocRec *rec=elementNrec(idx);
02052 if (rec!=NULL && rec->type()==CkLocRec::local){
02053 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02054 CmiPrintf("[%d]WARNING!!! Element %d:%s is local but is being told it exists on %d\n",CkMyPe(),idx.dimension,idx2str(idx), nowOnPe);
02055 #endif
02056 return;
02057 }
02058 insertRemote(idx,nowOnPe);
02059 }
02060
02061
02062 void CkLocMgr::informHome(const CkArrayIndex &idx,int nowOnPe)
02063 {
02064 int home=homePe(idx);
02065 if (home!=CkMyPe() && home!=nowOnPe) {
02066
02067 DEBC((AA" Telling %s's home %d that it lives on %d.\n"AB,idx2str(idx),home,nowOnPe));
02068
02069 #if defined(_FAULT_MLOG_)
02070 informLocationHome(thisgroup,idx,home,CkMyPe());
02071 #else
02072 thisProxy[home].updateLocation(idx,nowOnPe);
02073 #endif
02074 }
02075 }
02076
02077 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02078 CkLocRec_local *CkLocMgr::createLocal(const CkArrayIndex &idx,
02079 CmiBool forMigration, CmiBool ignoreArrival,
02080 CmiBool notifyHome,int dummy)
02081 {
02082 int localIdx=nextFree();
02083 DEBC((AA"Adding new record for element %s at local index %d\n"AB,idx2str(idx),localIdx));
02084 CkLocRec_local *rec=new CkLocRec_local(this,forMigration,ignoreArrival,idx,localIdx);
02085 if(!dummy){
02086 insertRec(rec,idx);
02087 }
02088 if (notifyHome) informHome(idx,CkMyPe());
02089 return rec;
02090 }
02091 #else
02092 CkLocRec_local *CkLocMgr::createLocal(const CkArrayIndex &idx,
02093 CmiBool forMigration, CmiBool ignoreArrival,
02094 CmiBool notifyHome)
02095 {
02096 int localIdx=nextFree();
02097 DEBC((AA"Adding new record for element %s at local index %d\n"AB,idx2str(idx),localIdx));
02098 CkLocRec_local *rec=new CkLocRec_local(this,forMigration,ignoreArrival,idx,localIdx);
02099 insertRec(rec,idx);
02100
02101
02102 if (notifyHome) informHome(idx,CkMyPe());
02103 return rec;
02104 }
02105 #endif
02106
02107
02108 CmiBool CkLocMgr::addElement(CkArrayID id,const CkArrayIndex &idx,
02109 CkMigratable *elt,int ctorIdx,void *ctorMsg)
02110 {
02111 CK_MAGICNUMBER_CHECK
02112 CkLocRec *oldRec=elementNrec(idx);
02113 CkLocRec_local *rec;
02114 if (oldRec==NULL||oldRec->type()!=CkLocRec::local)
02115 {
02116 rec=createLocal(idx,CmiFalse,CmiFalse,CmiTrue);
02117 } else
02118 {
02119 rec=((CkLocRec_local *)oldRec);
02120 rec->addedElement();
02121 }
02122 if (!addElementToRec(rec,managers.find(id),elt,ctorIdx,ctorMsg)) return CmiFalse;
02123 elt->ckFinishConstruction();
02124 return CmiTrue;
02125 }
02126
02127
02128 CmiBool CkLocMgr::addElementToRec(CkLocRec_local *rec,ManagerRec *m,
02129 CkMigratable *elt,int ctorIdx,void *ctorMsg)
02130 {
02131 int localIdx=rec->getLocalIndex();
02132 if (m->elts.get(localIdx)!=NULL) CkAbort("Cannot insert array element twice!");
02133 m->elts.put(elt,localIdx);
02134
02135
02136 DEBC((AA"Constructing element %s of array\n"AB,idx2str(rec->getIndex())));
02137 CkMigratable_initInfo &i=CkpvAccess(mig_initInfo);
02138 i.locRec=rec;
02139 i.chareType=_entryTable[ctorIdx]->chareIdx;
02140 if (!rec->invokeEntry(elt,ctorMsg,ctorIdx,CmiTrue)) return CmiFalse;
02141
02142 #if CMK_OUT_OF_CORE
02143
02144 PUP::sizer p_getSize; elt->pup(p_getSize);
02145 elt->prefetchObjID=CooRegisterObject(&CkArrayElementPrefetcher,p_getSize.size(),elt);
02146 #endif
02147
02148 return CmiTrue;
02149 }
02150 void CkLocMgr::updateLocation(const CkArrayIndex &idx,int nowOnPe) {
02151 inform(idx,nowOnPe);
02152 }
02153
02154
02156 void CkLocMgr::reclaim(const CkArrayIndex &idx,int localIdx) {
02157 CK_MAGICNUMBER_CHECK
02158 DEBC((AA"Destroying element %s (local %d)\n"AB,idx2str(idx),localIdx));
02159
02160 for (ManagerRec *m=firstManager;m!=NULL;m=m->next) {
02161 delete m->elts.get(localIdx);
02162 m->elts.empty(localIdx);
02163 }
02164
02165 removeFromTable(idx);
02166
02167
02168 freeList[localIdx]=firstFree;
02169 firstFree=localIdx;
02170
02171
02172 if (!duringMigration)
02173 {
02174 #if CMK_BIGSIM_CHARM
02175
02176
02177
02178
02179
02180
02181
02182 if(_BgOutOfCoreFlag==1) return;
02183 #endif
02184 int home=homePe(idx);
02185 if (home!=CkMyPe())
02186 #if CMK_MEM_CHECKPOINT
02187 if (!CkInRestarting())
02188 #endif
02189 thisProxy[home].reclaimRemote(idx,CkMyPe());
02190
02191
02192 }
02193 }
02194
02195 void CkLocMgr::reclaimRemote(const CkArrayIndex &idx,int deletedOnPe) {
02196 DEBC((AA"Our element %s died on PE %d\n"AB,idx2str(idx),deletedOnPe));
02197 CkLocRec *rec=elementNrec(idx);
02198 if (rec==NULL) return;
02199 if (rec->type()==CkLocRec::local) return;
02200 removeFromTable(idx);
02201 delete rec;
02202 }
02203 void CkLocMgr::removeFromTable(const CkArrayIndex &idx) {
02204 #if CMK_ERROR_CHECKING
02205
02206 if (NULL==elementNrec(idx))
02207 CkAbort("CkLocMgr::removeFromTable called on invalid index!");
02208 #endif
02209 CmiImmediateLock(hashImmLock);
02210 hash.remove(*(CkArrayIndex *)&idx);
02211 CmiImmediateUnlock(hashImmLock);
02212 #if CMK_ERROR_CHECKING
02213
02214 if (NULL!=elementNrec(idx))
02215 CkAbort("CkLocMgr::removeFromTable called, but element still there!");
02216 #endif
02217 }
02218
02219
02222 int CkLocMgr::deliver(CkMessage *m,CkDeliver_t type,int opts) {
02223 DEBS((AA"deliver \n"AB));
02224 CK_MAGICNUMBER_CHECK
02225 CkArrayMessage *msg=(CkArrayMessage *)m;
02226
02227
02228 const CkArrayIndex &idx=msg->array_index();
02229 DEBS((AA"deliver %s\n"AB,idx2str(idx)));
02230 if (type==CkDeliver_queue)
02231 _TRACE_CREATION_DETAILED(UsrToEnv(m),msg->array_ep());
02232 CkLocRec *rec=elementNrec(idx);
02233 if(rec != NULL){
02234 DEBS((AA"deliver %s of type %d \n"AB,idx2str(idx),rec->type()));
02235 }else{
02236 DEBS((AA"deliver %s rec is null\n"AB,idx2str(idx)));
02237 }
02238
02239 #if !defined(_FAULT_MLOG_)
02240 #if CMK_LBDB_ON
02241 if (type==CkDeliver_queue) {
02242 if (!(opts & CK_MSG_LB_NOTRACE) && the_lbdb->CollectingCommStats()) {
02243 if(rec!=NULL) the_lbdb->Send(myLBHandle,idx2LDObjid(idx),UsrToEnv(msg)->getTotalsize(), rec->lookupProcessor(), 1);
02244 else the_lbdb->Send(myLBHandle,idx2LDObjid(idx),UsrToEnv(msg)->getTotalsize(),homePe(msg->array_index()), 1);
02245 }
02246 }
02247 #endif
02248 #endif
02249 #if CMK_GRID_QUEUE_AVAILABLE
02250 int gridSrcPE;
02251 int gridSrcCluster;
02252 int gridDestPE;
02253 int gridDestCluster;
02254 CkMigratable *obj;
02255 ArrayElement *obj2;
02256 CkGroupID gid;
02257 int *data;
02258
02259 obj = (CkMigratable *) CpvAccess(CkGridObject);
02260 if (obj != NULL) {
02261 obj2 = dynamic_cast<ArrayElement *> (obj);
02262 if (obj2 > 0) {
02263
02264
02265 gid = obj2->ckGetArrayID ();
02266 data = obj2->thisIndexMax.data ();
02267
02268
02269 gridSrcPE = CkMyPe ();
02270 if (rec != NULL) {
02271 gridDestPE = rec->lookupProcessor ();
02272 } else {
02273 gridDestPE = homePe (msg->array_index ());
02274 }
02275
02276
02277 gridSrcCluster = CmiGetCluster (gridSrcPE);
02278 gridDestCluster = CmiGetCluster (gridDestPE);
02279
02280
02281
02282
02283
02284
02285
02286 if (obj2->grid_queue_interval > 0) {
02287
02288 obj2->msg_count += 1;
02289
02290
02291
02292 if (gridSrcCluster != gridDestCluster) {
02293 obj2->msg_count_grid += 1;
02294 }
02295
02296
02297
02298 if (obj2->msg_count >= obj2->grid_queue_interval) {
02299 if (obj2->msg_count_grid >= obj2->grid_queue_threshold) {
02300
02301 if (!obj2->border_flag) {
02302 CmiGridQueueRegister (gid.idx, obj2->thisIndexMax.nInts, data[0], data[1], data[2]);
02303 }
02304 obj2->border_flag = 1;
02305 } else {
02306
02307 if (obj2->border_flag) {
02308 CmiGridQueueDeregister (gid.idx, obj2->thisIndexMax.nInts, data[0], data[1], data[2]);
02309 }
02310 obj2->border_flag = 0;
02311 }
02312
02313 obj2->msg_count = 0;
02314 obj2->msg_count_grid = 0;
02315 }
02316 } else {
02317 if (gridSrcCluster != gridDestCluster) {
02318 CmiGridQueueRegister (gid.idx, obj2->thisIndexMax.nInts, data[0], data[1], data[2]);
02319 }
02320 }
02321 }
02322
02323
02324 CpvAccess(CkGridObject) = NULL;
02325 }
02326 #endif
02327
02328 if (rec!=NULL){
02329 CmiBool result = rec->deliver(msg,type,opts);
02330
02331
02332
02333 if (result==CmiTrue && rec->type()==CkLocRec::local) return 0;
02334 else return 1;
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344 }else {
02345 if (opts & CK_MSG_KEEP)
02346 msg = (CkArrayMessage *)CkCopyMsg((void **)&msg);
02347 deliverUnknown(msg,type,opts);
02348 return 1;
02349 }
02350
02351 }
02352
02354 CmiBool CkLocMgr::deliverUnknown(CkArrayMessage *msg,CkDeliver_t type,int opts)
02355 {
02356 CK_MAGICNUMBER_CHECK
02357 const CkArrayIndex &idx=msg->array_index();
02358 int onPe=homePe(idx);
02359 if (onPe!=CkMyPe())
02360 {
02361 DEBM((AA"Forwarding message for unknown %s to home %d \n"AB,idx2str(idx),onPe));
02362 msg->array_hops()++;
02363 CkArrayManagerDeliver(onPe,msg,opts);
02364 return CmiTrue;
02365 }
02366 else
02367 {
02368
02369 CkArrMgr *mgr=managers.find(UsrToEnv((void *)msg)->getsetArrayMgr())->mgr;
02370 if (!mgr) {
02371 if (CkInRestarting()) {
02372
02373 delete msg;
02374 }
02375 else {
02376 CkArrayManagerDeliver(CkMyPe(),msg);
02377 }
02378 }
02379 else {
02380 DEBC((AA"Adding buffer for unknown element %s\n"AB,idx2str(idx)));
02381 CkLocRec *rec=new CkLocRec_buffering(this);
02382 insertRecN(rec,idx);
02383 rec->deliver(msg,type);
02384
02385 if (msg->array_ifNotThere()!=CkArray_IfNotThere_buffer)
02386 {
02387 return demandCreateElement(msg,-1,type);
02388 }
02389 }
02390 return CmiTrue;
02391 }
02392 }
02393
02394 CmiBool CkLocMgr::demandCreateElement(CkArrayMessage *msg,int onPe,CkDeliver_t type)
02395 {
02396 CK_MAGICNUMBER_CHECK
02397 const CkArrayIndex &idx=msg->array_index();
02398 int chareType=_entryTable[msg->array_ep()]->chareIdx;
02399 int ctor=_chareTable[chareType]->getDefaultCtor();
02400 if (ctor==-1) CkAbort("Can't create array element to handle message--\n"
02401 "The element has no default constructor in the .ci file!\n");
02402 if (onPe==-1)
02403 {
02404 if (msg->array_ifNotThere()==CkArray_IfNotThere_createhere)
02405 onPe=UsrToEnv(msg)->getsetArraySrcPe();
02406 else
02407 onPe=homePe(idx);
02408 }
02409
02410
02411 DEBC((AA"Demand-creating element %s on pe %d\n"AB,idx2str(idx),onPe));
02412 CkArrMgr *mgr=managers.find(UsrToEnv((void *)msg)->getsetArrayMgr())->mgr;
02413 if (!mgr) CkAbort("Tried to demand-create for nonexistent arrMgr");
02414 return mgr->demandCreateElement(idx,onPe,ctor,type);
02415 }
02416
02417
02418 void CkLocMgr::multiHop(CkArrayMessage *msg)
02419 {
02420 CK_MAGICNUMBER_CHECK
02421 int srcPe=msg->array_getSrcPe();
02422 if (srcPe==CkMyPe())
02423 DEB((AA"Odd routing: local element %s is %d hops away!\n"AB,idx2str(msg),msg->array_hops()));
02424 else
02425 {
02426 DEBS((AA"Sending update back to %d for element\n"AB,srcPe,idx2str(msg)));
02427 thisProxy[srcPe].updateLocation(msg->array_index(),CkMyPe());
02428 }
02429 }
02430
02431
02432 CkLocation::CkLocation(CkLocMgr *mgr_, CkLocRec_local *rec_)
02433 :mgr(mgr_), rec(rec_) {}
02434
02435 const CkArrayIndex &CkLocation::getIndex(void) const {
02436 return rec->getIndex();
02437 }
02438
02439 void CkLocation::destroyAll() {
02440 mgr->callMethod(rec, &CkMigratable::ckDestroy);
02441 }
02442
02443 void CkLocation::pup(PUP::er &p) {
02444 mgr->pupElementsFor(p,rec,CkElementCreation_migrate);
02445 }
02446
02447 CkLocIterator::~CkLocIterator() {}
02448
02450 void CkLocMgr::iterate(CkLocIterator &dest) {
02451
02452 void *objp;
02453 CkHashtableIterator *it=hash.iterator();
02454 CmiImmediateLock(hashImmLock);
02455
02456 while (NULL!=(objp=it->next())) {
02457 CkLocRec *rec=*(CkLocRec **)objp;
02458 if (rec->type()==CkLocRec::local) {
02459 CkLocation loc(this,(CkLocRec_local *)rec);
02460 dest.addLocation(loc);
02461 }
02462 }
02463 CmiImmediateUnlock(hashImmLock);
02464 delete it;
02465 }
02466
02467
02468
02469
02470
02471 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02472 void CkLocMgr::pupElementsFor(PUP::er &p,CkLocRec_local *rec,
02473 CkElementCreation_t type, CmiBool create, int dummy)
02474 {
02475 p.comment("-------- Array Location --------");
02476 register ManagerRec *m;
02477 int localIdx=rec->getLocalIndex();
02478 CkVec<CkMigratable *> dummyElts;
02479
02480 for (m=firstManager;m!=NULL;m=m->next) {
02481 int elCType;
02482 if (!p.isUnpacking())
02483 {
02484 CkMigratable *elt=m->element(localIdx);
02485 if (elt) elCType=elt->ckGetChareType();
02486 else elCType=-1;
02487 }
02488 p(elCType);
02489 if (p.isUnpacking() && elCType!=-1) {
02490 CkMigratable *elt=m->mgr->allocateMigrated(elCType,rec->getIndex(),type);
02491 int migCtorIdx=_chareTable[elCType]->getMigCtor();
02492 if(!dummy){
02493 if(create)
02494 if (!addElementToRec(rec,m,elt,migCtorIdx,NULL)) return;
02495 }else{
02496 CkMigratable_initInfo &i=CkpvAccess(mig_initInfo);
02497 i.locRec=rec;
02498 i.chareType=_entryTable[migCtorIdx]->chareIdx;
02499 dummyElts.push_back(elt);
02500 if (!rec->invokeEntry(elt,NULL,migCtorIdx,CmiTrue)) return ;
02501 }
02502 }
02503 }
02504 if(!dummy){
02505 for (m=firstManager;m!=NULL;m=m->next) {
02506 CkMigratable *elt=m->element(localIdx);
02507 if (elt!=NULL)
02508 {
02509 elt->pup(p);
02510 }
02511 }
02512 }else{
02513 for(int i=0;i<dummyElts.size();i++){
02514 CkMigratable *elt = dummyElts[i];
02515 if (elt!=NULL){
02516 elt->pup(p);
02517 }
02518 delete elt;
02519 }
02520 for (ManagerRec *m=firstManager;m!=NULL;m=m->next) {
02521 m->elts.empty(localIdx);
02522 }
02523 freeList[localIdx]=firstFree;
02524 firstFree=localIdx;
02525 }
02526 }
02527 #else
02528 void CkLocMgr::pupElementsFor(PUP::er &p,CkLocRec_local *rec,
02529 CkElementCreation_t type)
02530 {
02531 p.comment("-------- Array Location --------");
02532 register ManagerRec *m;
02533 int localIdx=rec->getLocalIndex();
02534
02535
02536
02537 for (m=firstManager;m!=NULL;m=m->next) {
02538 int elCType;
02539 if (!p.isUnpacking())
02540 {
02541 CkMigratable *elt=m->element(localIdx);
02542 if (elt) elCType=elt->ckGetChareType();
02543 else elCType=-1;
02544 }
02545 p(elCType);
02546 if (p.isUnpacking() && elCType!=-1) {
02547
02548 CkMigratable *elt=m->mgr->allocateMigrated(elCType,rec->getIndex(),type);
02549 int migCtorIdx=_chareTable[elCType]->getMigCtor();
02550
02551 if (!addElementToRec(rec,m,elt,migCtorIdx,NULL)) return;
02552 }
02553 }
02554
02555 for (m=firstManager;m!=NULL;m=m->next) {
02556 CkMigratable *elt=m->element(localIdx);
02557 if (elt!=NULL)
02558 {
02559 elt->pup(p);
02560 #if CMK_ERROR_CHECKING
02561 if (p.isUnpacking()) elt->sanitycheck();
02562 #endif
02563 }
02564 }
02565 }
02566 #endif
02567
02569 void CkLocMgr::callMethod(CkLocRec_local *rec,CkMigratable_voidfn_t fn)
02570 {
02571 int localIdx=rec->getLocalIndex();
02572 for (ManagerRec *m=firstManager;m!=NULL;m=m->next) {
02573 CkMigratable *el=m->element(localIdx);
02574 if (el) (el->* fn)();
02575 }
02576 }
02577
02579 void CkLocMgr::migratableList(CkLocRec_local *rec, CkVec<CkMigratable *> &list)
02580 {
02581 register ManagerRec *m;
02582 int localIdx=rec->getLocalIndex();
02583
02584 for (m=firstManager;m!=NULL;m=m->next) {
02585 CkMigratable *elt=m->element(localIdx);
02586 if (elt) list.push_back(elt);
02587 }
02588 }
02589
02591 void CkLocMgr::emigrate(CkLocRec_local *rec,int toPe)
02592 {
02593 CK_MAGICNUMBER_CHECK
02594 if (toPe==CkMyPe()) return;
02595
02596
02597
02598
02599
02600 if(!CmiNodeAlive(toPe)){
02601 return;
02602 }
02603 CkArrayIndex idx=rec->getIndex();
02604
02605 #if CMK_OUT_OF_CORE
02606 int localIdx=rec->getLocalIndex();
02607
02608 for (ManagerRec *m=firstManager;m!=NULL;m=m->next) {
02609 CkMigratable *el=m->element(localIdx);
02610 if (el) if (!el->isInCore) CooBringIn(el->prefetchObjID);
02611 }
02612 #endif
02613
02614
02615 callMethod(rec,&CkMigratable::ckAboutToMigrate);
02616
02617
02618
02619 int bufSize;
02620 {
02621 PUP::sizer p;
02622 p(nManagers);
02623 pupElementsFor(p,rec,CkElementCreation_migrate);
02624 bufSize=p.size();
02625 }
02626
02627
02628 int doubleSize=bufSize/sizeof(double)+1;
02629 CkArrayElementMigrateMessage *msg =
02630 new (doubleSize, 0) CkArrayElementMigrateMessage;
02631 msg->idx=idx;
02632 msg->length=bufSize;
02633 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02634 msg->gid = ckGetGroupID();
02635 #endif
02636 #if CMK_LBDB_ON
02637 msg->ignoreArrival = rec->isAsyncMigrate()?1:0;
02638 #endif
02639
02640
02641
02642 msg->bounced = rec->isBounced();
02643 {
02644 PUP::toMem p(msg->packData);
02645 p.becomeDeleting();
02646 p(nManagers);
02647 pupElementsFor(p,rec,CkElementCreation_migrate);
02648 if (p.size()!=bufSize) {
02649 CkError("ERROR! Array element claimed it was %d bytes to a "
02650 "sizing PUP::er, but copied %d bytes into the packing PUP::er!\n",
02651 bufSize,p.size());
02652 CkAbort("Array element's pup routine has a direction mismatch.\n");
02653 }
02654 }
02655
02656 DEBM((AA"Migrated index size %s to %d \n"AB,idx2str(idx),toPe));
02657
02658
02659 #if defined(_FAULT_MLOG_)
02660 sendMlogLocation(toPe,UsrToEnv(msg));
02661 #else
02662
02663 thisProxy[toPe].immigrate(msg);
02664 #endif
02665
02666 duringMigration=CmiTrue;
02667 delete rec;
02668
02669
02670 duringMigration=CmiFalse;
02671
02672 inform(idx,toPe);
02673
02674 #if !defined(_FAULT_MLOG_)
02675 informHome(idx,toPe);
02676 #endif
02677
02678 #if CMK_GLOBAL_LOCATION_UPDATE
02679 DEBM((AA"Global location update! idx %s to %d \n"AB,idx2str(idx),toPe));
02680 thisProxy.updateLocation(idx, toPe);
02681 #endif
02682
02683 CK_MAGICNUMBER_CHECK
02684 }
02685
02689 void CkLocMgr::immigrate(CkArrayElementMigrateMessage *msg)
02690 {
02691 const CkArrayIndex &idx=msg->idx;
02692
02693 PUP::fromMem p(msg->packData);
02694
02695 int nMsgMan;
02696 p(nMsgMan);
02697 if (nMsgMan<nManagers)
02698 CkAbort("Array element arrived from location with fewer managers!\n");
02699 if (nMsgMan>nManagers) {
02700
02701 DEBM((AA"Busy-waiting for array registration on migrating %s\n"AB,idx2str(idx)));
02702 thisProxy[CkMyPe()].immigrate(msg);
02703 return;
02704 }
02705
02706
02707
02708 #if !defined(_FAULT_MLOG_)
02709 CkLocRec_local *rec=createLocal(idx,CmiTrue,msg->ignoreArrival,CmiFalse );
02710 #else
02711 CkLocRec_local *rec=createLocal(idx,CmiTrue,CmiTrue,CmiFalse );
02712 #endif
02713
02714
02715 pupElementsFor(p,rec,CkElementCreation_migrate);
02716 if (p.size()!=msg->length) {
02717 CkError("ERROR! Array element claimed it was %d bytes to a"
02718 "packing PUP::er, but %d bytes in the unpacking PUP::er!\n",
02719 msg->length,p.size());
02720 CkError("(I have %d managers; he claims %d managers)\n",
02721 nManagers,nMsgMan);
02722
02723 CkAbort("Array element's pup routine has a direction mismatch.\n");
02724 }
02725
02726
02727
02728
02729
02730
02731 if(msg->bounced){
02732 callMethod(rec,&CkMigratable::ResumeFromSync);
02733 }
02734
02735
02736 callMethod(rec,&CkMigratable::ckJustMigrated);
02737
02738
02739
02740
02741
02742
02743
02744 if(CkpvAccess(startedEvac)){
02745 int newhomePE = getNextPE(idx);
02746 DEBM((AA"Migrated into failed processor index size %s resent to %d \n"AB,idx2str(idx),newhomePE));
02747 CkLocMgr *mgr = rec->getLocMgr();
02748 int targetPE=getNextPE(idx);
02749
02750
02751 rec->AsyncMigrate(CmiTrue);
02752 rec->Bounced(CmiTrue);
02753 mgr->emigrate(rec,targetPE);
02754
02755 }
02756
02757 delete msg;
02758 }
02759
02760 void CkLocMgr::restore(const CkArrayIndex &idx, PUP::er &p)
02761 {
02762
02763
02764
02765 #if CMK_ERROR_CHECKING
02766 if(_BgOutOfCoreFlag!=2)
02767 CmiAbort("CkLocMgr::restore should only be used in out-of-core emulation for BigSim and be called when object is brought into memory!\n");
02768 #endif
02769 CkLocRec_local *rec=createLocal(idx,CmiFalse,CmiFalse,CmiFalse);
02770
02771
02772
02773
02774
02775 pupElementsFor(p,rec,CkElementCreation_restore);
02776
02777 callMethod(rec,&CkMigratable::ckJustRestored);
02778 }
02779
02780
02782 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02783 void CkLocMgr::resume(const CkArrayIndex &idx, PUP::er &p, CmiBool create, int dummy)
02784 {
02785 CkLocRec_local *rec;
02786 CkLocRec *recGlobal;
02787
02788 if(create){
02789 rec = createLocal(idx,CmiFalse,CmiFalse,CmiTrue && !dummy ,dummy );
02790 }else{
02791 recGlobal = elementNrec(idx);
02792 if(recGlobal == NULL)
02793 CmiAbort("Local object not found");
02794 if(recGlobal->type() != CkLocRec::local)
02795 CmiAbort("Local object not local, :P");
02796 rec = (CkLocRec_local *)recGlobal;
02797 }
02798
02799 pupElementsFor(p,rec,CkElementCreation_resume,create,dummy);
02800
02801 if(!dummy){
02802 callMethod(rec,&CkMigratable::ckJustMigrated);
02803 }
02804 }
02805 #else
02806 void CkLocMgr::resume(const CkArrayIndex &idx, PUP::er &p, CmiBool notify)
02807 {
02808 CkLocRec_local *rec=createLocal(idx,CmiFalse,CmiFalse,notify );
02809
02810
02811 pupElementsFor(p,rec,CkElementCreation_resume);
02812
02813 callMethod(rec,&CkMigratable::ckJustMigrated);
02814 }
02815 #endif
02816
02817
02818 void CkMagicNumber_impl::badMagicNumber(
02819 int expected,const char *file,int line,void *obj) const
02820 {
02821 CkError("FAILURE on pe %d, %s:%d> Expected %p's magic number "
02822 "to be 0x%08x; but found 0x%08x!\n", CkMyPe(),file,line,obj,
02823 expected, magic);
02824 CkAbort("Bad magic number detected! This implies either\n"
02825 "the heap or a message was corrupted!\n");
02826 }
02827 CkMagicNumber_impl::CkMagicNumber_impl(int m) :magic(m) { }
02828
02829
02830 CkMigratable *CkLocMgr::lookup(const CkArrayIndex &idx,CkArrayID aid) {
02831 CkLocRec *rec=elementNrec(idx);
02832 if (rec==NULL) return NULL;
02833 else return rec->lookupElement(aid);
02834 }
02835
02836 int CkLocMgr::lastKnown(const CkArrayIndex &idx) {
02837 CkLocMgr *vthis=(CkLocMgr *)this;
02838 CkLocRec *rec=vthis->elementNrec(idx);
02839 int pe=-1;
02840 if (rec!=NULL) pe=rec->lookupProcessor();
02841 if (pe==-1) return homePe(idx);
02842 else{
02843
02844
02845
02846
02847 if(!CmiNodeAlive(pe)){
02848 removeFromTable(idx);
02849 return homePe(idx);
02850 }
02851 return pe;
02852 }
02853 }
02855 bool CkLocMgr::isRemote(const CkArrayIndex &idx,int *onPe) const
02856 {
02857 CkLocMgr *vthis=(CkLocMgr *)this;
02858 CkLocRec *rec=vthis->elementNrec(idx);
02859 if (rec==NULL || rec->type()!=CkLocRec::remote)
02860 return false;
02861 else
02862 {
02863 *onPe=rec->lookupProcessor();
02864 return true;
02865 }
02866 }
02867
02868 static const char *rec2str[]={
02869 "base (INVALID)",
02870 "local",
02871 "remote",
02872 "buffering",
02873 "dead"
02874 };
02875
02876 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
02877 void CkLocMgr::setDuringMigration(CmiBool _duringMigration){
02878 duringMigration = _duringMigration;
02879 }
02880 #endif
02881
02882
02883
02884 void CkLocMgr::insertRec(CkLocRec *rec,const CkArrayIndex &idx) {
02885 CkLocRec *old=elementNrec(idx);
02886 insertRecN(rec,idx);
02887 if (old!=NULL) {
02888 DEBC((AA" replaces old rec(%s) for %s\n"AB,rec2str[old->type()],idx2str(idx)));
02889
02890 if (old->type()==CkLocRec::local && rec->type()==CkLocRec::local) {
02891 if (!CkInRestarting()) {
02892 CkPrintf("ERROR! Duplicate array index: %s\n",idx2str(idx));
02893 CkAbort("Duplicate array index used");
02894 }
02895 }
02896 old->beenReplaced();
02897 delete old;
02898 }
02899 }
02900
02901
02902 void CkLocMgr::insertRecN(CkLocRec *rec,const CkArrayIndex &idx) {
02903 DEBC((AA" adding new rec(%s) for %s\n"AB,rec2str[rec->type()],idx2str(idx)));
02904 CmiImmediateLock(hashImmLock);
02905 hash.put(*(CkArrayIndex *)&idx)=rec;
02906 CmiImmediateUnlock(hashImmLock);
02907 }
02908
02909
02910 static void abort_out_of_bounds(const CkArrayIndex &idx)
02911 {
02912 CkPrintf("ERROR! Unknown array index: %s\n",idx2str(idx));
02913 CkAbort("Array index out of bounds\n");
02914 }
02915
02916
02917 CkLocRec *CkLocMgr::elementRec(const CkArrayIndex &idx) {
02918 #if ! CMK_ERROR_CHECKING
02919
02920 return hash.getRef(*(CkArrayIndex *)&idx);
02921 #else
02922
02923 CkLocRec *rec=elementNrec(idx);
02924 if (rec==NULL) abort_out_of_bounds(idx);
02925 return rec;
02926 #endif
02927 }
02928
02929
02930 CkLocRec *CkLocMgr::elementNrec(const CkArrayIndex &idx) {
02931 return hash.get(*(CkArrayIndex *)&idx);
02932 }
02933
02934 struct LocalElementCounter : public CkLocIterator
02935 {
02936 unsigned int count;
02937 LocalElementCounter() : count(0) {}
02938 void addLocation(CkLocation &loc)
02939 { ++count; }
02940 };
02941
02942 unsigned int CkLocMgr::numLocalElements()
02943 {
02944 LocalElementCounter c;
02945 iterate(c);
02946 return c.count;
02947 }
02948
02949
02950
02951
02952 #if !CMK_LBDB_ON
02953
02954 void CkLocMgr::initLB(CkGroupID lbdbID_) {}
02955 void CkLocMgr::startInserting(void) {}
02956 void CkLocMgr::doneInserting(void) {}
02957 void CkLocMgr::dummyAtSync(void) {}
02958 #endif
02959
02960
02961 #if CMK_LBDB_ON
02962 void CkLocMgr::initLB(CkGroupID lbdbID_)
02963 {
02964 the_lbdb = (LBDatabase *)CkLocalBranch(lbdbID_);
02965 if (the_lbdb == 0)
02966 CkAbort("LBDatabase not yet created?\n");
02967 DEBL((AA"Connected to load balancer %p\n"AB,the_lbdb));
02968
02969
02970 LDOMid myId;
02971 myId.id = thisgroup;
02972 LDCallbacks myCallbacks;
02973 myCallbacks.migrate = (LDMigrateFn)CkLocRec_local::staticMigrate;
02974 myCallbacks.setStats = NULL;
02975 myCallbacks.queryEstLoad = NULL;
02976 myLBHandle = the_lbdb->RegisterOM(myId,this,myCallbacks);
02977
02978
02979 the_lbdb->RegisteringObjects(myLBHandle);
02980
02981
02982
02983
02984
02985 the_lbdb->AddLocalBarrierReceiver(
02986 (LDBarrierFn)staticRecvAtSync,(void*)(this));
02987 dummyBarrierHandle = the_lbdb->AddLocalBarrierClient(
02988 (LDResumeFn)staticDummyResumeFromSync,(void*)(this));
02989 dummyAtSync();
02990 }
02991 void CkLocMgr::dummyAtSync(void)
02992 {
02993 DEBL((AA"dummyAtSync called\n"AB));
02994 the_lbdb->AtLocalBarrier(dummyBarrierHandle);
02995 }
02996
02997 void CkLocMgr::staticDummyResumeFromSync(void* data)
02998 { ((CkLocMgr*)data)->dummyResumeFromSync(); }
02999 void CkLocMgr::dummyResumeFromSync()
03000 {
03001 DEBL((AA"DummyResumeFromSync called\n"AB));
03002 the_lbdb->DoneRegisteringObjects(myLBHandle);
03003 dummyAtSync();
03004 }
03005 void CkLocMgr::staticRecvAtSync(void* data)
03006 { ((CkLocMgr*)data)->recvAtSync(); }
03007 void CkLocMgr::recvAtSync()
03008 {
03009 DEBL((AA"recvAtSync called\n"AB));
03010 the_lbdb->RegisteringObjects(myLBHandle);
03011 }
03012
03013 void CkLocMgr::startInserting(void)
03014 {
03015 the_lbdb->RegisteringObjects(myLBHandle);
03016 }
03017 void CkLocMgr::doneInserting(void)
03018 {
03019 the_lbdb->DoneRegisteringObjects(myLBHandle);
03020 }
03021 #endif
03022
03023 #include "CkLocation.def.h"
03024
03025