00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __CKARRAY_H
00027 #define __CKARRAY_H
00028
00029 #include "cklocation.h"
00030 #include "ckmulticast.h"
00031 #include "ckmemcheckpoint.h"
00032 #include "ckarrayindex.h"
00033
00034
00035
00036
00037 extern void _registerCkArray(void);
00038 CpvExtern (int ,serializer);
00039
00040 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00041 #define _MLOG_BCAST_TREE_ 1
00042 #define _MLOG_BCAST_BFACTOR_ 8
00043 #endif
00044
00048 extern bool _isAnytimeMigration;
00049
00053 extern bool _isStaticInsertion;
00054
00059 extern bool _isNotifyChildInRed;
00060
00068
00070
00071 class CkVerboseListener : public CkArrayListener {
00072 public:
00073 CkVerboseListener(void);
00074 CkVerboseListener(CkMigrateMessage *m):CkArrayListener(m) {}
00075 PUPable_decl(CkVerboseListener);
00076
00077 virtual void ckRegister(CkArray *arrMgr,int dataOffset_);
00078 virtual void ckBeginInserting(void);
00079 virtual void ckEndInserting(void);
00080
00081 virtual void ckElementStamp(int *eltInfo);
00082 virtual void ckElementCreating(ArrayElement *elt);
00083 virtual bool ckElementCreated(ArrayElement *elt);
00084 virtual void ckElementDied(ArrayElement *elt);
00085
00086 virtual void ckElementLeaving(ArrayElement *elt);
00087 virtual bool ckElementArriving(ArrayElement *elt);
00088 };
00089
00094
00095
00096
00097 class ArrayBase { };
00098 class ArrayElement;
00099
00105 class CProxy_ArrayBase :public CProxy {
00106 private:
00107 CkArrayID _aid;
00108 public:
00109 CProxy_ArrayBase() {
00110 #if CMK_ERROR_CHECKING
00111 _aid.setZero();
00112 #endif
00113 }
00114 CProxy_ArrayBase(const CkArrayID &aid,CK_DELCTOR_PARAM)
00115 :CProxy(CK_DELCTOR_ARGS), _aid(aid) { }
00116 CProxy_ArrayBase(const CkArrayID &aid)
00117 :CProxy(), _aid(aid) { }
00118 CProxy_ArrayBase(const ArrayElement *e);
00119 CProxy_ArrayBase(const CProxy_ArrayBase &cs): CProxy(cs), _aid(cs.ckGetArrayID()) {}
00120
00121 bool operator==(const CProxy_ArrayBase& other) {
00122 return ckGetArrayID() == other.ckGetArrayID();
00123 }
00124
00125 #if CMK_ERROR_CHECKING
00126 inline void ckCheck(void) const{
00127 if (_aid.isZero())
00128 CkAbort("Error! This array proxy has not been initialized!");
00129 }
00130 #else
00131 inline void ckCheck(void) const {}
00132 #endif
00133
00134 static CkArrayID ckCreateEmptyArray(CkArrayOptions opts);
00135 static void ckCreateEmptyArrayAsync(CkCallback cb, CkArrayOptions opts);
00136 static CkArrayID ckCreateArray(CkArrayMessage *m,int ctor,const CkArrayOptions &opts);
00137
00138 void ckInsertIdx(CkArrayMessage *m,int ctor,int onPe,const CkArrayIndex &idx);
00139 void ckBroadcast(CkArrayMessage *m, int ep, int opts=0) const;
00140 CkArrayID ckGetArrayID(void) const { return _aid; }
00141 CkArray *ckLocalBranch(void) const { return _aid.ckLocalBranch(); }
00142 CkLocMgr *ckLocMgr(void) const;
00143 inline operator CkArrayID () const {return ckGetArrayID();}
00144 unsigned int numLocalElements() const { return ckLocMgr()->numLocalElements(); }
00145
00146 void doneInserting(void);
00147 void beginInserting(void);
00148
00149 CK_REDUCTION_CLIENT_DECL
00150
00151 void pup(PUP::er &p);
00152 };
00153 PUPmarshall(CProxy_ArrayBase)
00154
00155 class CProxyElement_ArrayBase:public CProxy_ArrayBase {
00156 private:
00157 CkArrayIndex _idx;
00158 public:
00159 CProxyElement_ArrayBase() { }
00160 CProxyElement_ArrayBase(const CkArrayID &aid,
00161 const CkArrayIndex &idx,CK_DELCTOR_PARAM)
00162 :CProxy_ArrayBase(aid,CK_DELCTOR_ARGS), _idx(idx) { }
00163 CProxyElement_ArrayBase(const CkArrayID &aid, const CkArrayIndex &idx)
00164 :CProxy_ArrayBase(aid), _idx(idx) { }
00165 CProxyElement_ArrayBase(const ArrayElement *e);
00166
00167 bool operator==(const CProxyElement_ArrayBase& other) {
00168 return ckGetArrayID() == other.ckGetArrayID() &&
00169 ckGetIndex() == other.ckGetIndex();
00170 }
00171
00172 void ckInsert(CkArrayMessage *m,int ctor,int onPe);
00173 void ckSend(CkArrayMessage *m, int ep, int opts = 0) const;
00174
00175 static void ckSendWrapper(CkArrayID _aid, CkArrayIndex _idx, void *m, int ep, int opts);
00176 void *ckSendSync(CkArrayMessage *m, int ep) const;
00177 const CkArrayIndex &ckGetIndex() const {return _idx;}
00178
00179 ArrayElement *ckLocal(void) const;
00180 void pup(PUP::er &p);
00181 };
00182 PUPmarshall(CProxyElement_ArrayBase)
00183
00184
00185 #define _AUTO_DELEGATE_MCASTMGR_ON_ 1
00186
00187 class CProxySection_ArrayBase:public CProxy_ArrayBase {
00188 private:
00189 std::vector<CkSectionID> _sid;
00190 public:
00191 CProxySection_ArrayBase() =default;
00192 CProxySection_ArrayBase(const CkArrayID &aid,
00193 const CkArrayIndex *elems, const int nElems, int factor=USE_DEFAULT_BRANCH_FACTOR);
00194 CProxySection_ArrayBase(const CkArrayID &aid,
00195 const std::vector<CkArrayIndex> &elems, int factor=USE_DEFAULT_BRANCH_FACTOR);
00196 CProxySection_ArrayBase(const CkArrayID &aid,
00197 const CkArrayIndex *elems, const int nElems, CK_DELCTOR_PARAM)
00198 :CProxy_ArrayBase(aid,CK_DELCTOR_ARGS) { _sid.emplace_back(aid, elems, nElems); }
00199 CProxySection_ArrayBase(const CkArrayID &aid,
00200 const std::vector<CkArrayIndex> &elems, CK_DELCTOR_PARAM)
00201 :CProxy_ArrayBase(aid,CK_DELCTOR_ARGS) { _sid.emplace_back(aid, elems); }
00202 CProxySection_ArrayBase(const CkSectionID &sid)
00203 :CProxy_ArrayBase(sid._cookie.get_aid()) { _sid.emplace_back(sid); }
00204 CProxySection_ArrayBase(const CkSectionID &sid, CK_DELCTOR_PARAM)
00205 :CProxy_ArrayBase(sid._cookie.get_aid(), CK_DELCTOR_ARGS) { _sid.emplace_back(sid); }
00206 CProxySection_ArrayBase(const CProxySection_ArrayBase &cs)
00207 :CProxy_ArrayBase(cs) {
00208 _sid.resize(cs._sid.size());
00209 for (size_t i=0; i<_sid.size(); ++i) {
00210 _sid[i] = cs._sid[i];
00211 }
00212 }
00213 CProxySection_ArrayBase(const CProxySection_ArrayBase &cs, CK_DELCTOR_PARAM)
00214 :CProxy_ArrayBase(cs.ckGetArrayID(),CK_DELCTOR_ARGS) {
00215 _sid.resize(cs._sid.size());
00216 for (size_t i=0; i<_sid.size(); ++i) {
00217 _sid[i] = cs._sid[i];
00218 }
00219 }
00220 CProxySection_ArrayBase(const int n, const CkArrayID *aid, CkArrayIndex const * const *elems, const int *nElems, int factor=USE_DEFAULT_BRANCH_FACTOR);
00221 CProxySection_ArrayBase(const std::vector<CkArrayID> &aid, const std::vector<std::vector<CkArrayIndex> > &elems, int factor=USE_DEFAULT_BRANCH_FACTOR);
00222 CProxySection_ArrayBase(const int n, const CkArrayID *aid, CkArrayIndex const * const *elems, const int *nElems,CK_DELCTOR_PARAM)
00223 :CProxy_ArrayBase(aid[0],CK_DELCTOR_ARGS) {
00224 _sid.resize(n);
00225 for (size_t i=0; i<_sid.size(); ++i) {
00226 _sid[i] = CkSectionID(aid[i], elems[i], nElems[i]);
00227 }
00228 }
00229 CProxySection_ArrayBase(const std::vector<CkArrayID> &aid, const std::vector<std::vector<CkArrayIndex> > &elems, CK_DELCTOR_PARAM)
00230 :CProxy_ArrayBase(aid[0],CK_DELCTOR_ARGS) {
00231 _sid.resize(aid.size());
00232 for (size_t i=0; i<_sid.size(); ++i) {
00233 _sid[i] = CkSectionID(aid[i], elems[i]);
00234 }
00235 }
00236
00237 ~CProxySection_ArrayBase() =default;
00238
00239 CProxySection_ArrayBase &operator=(const CProxySection_ArrayBase &cs) {
00240 CProxy_ArrayBase::operator=(cs);
00241 _sid.resize(cs._sid.size());
00242 for (size_t i=0; i<_sid.size(); ++i) {
00243 _sid[i] = cs._sid[i];
00244 }
00245 return *this;
00246 }
00247
00248 void ckAutoDelegate(int opts=1);
00249 using CProxy_ArrayBase::setReductionClient;
00250 void setReductionClient(CkCallback *cb);
00251 void resetSection();
00252
00253 void ckSectionDelegate(CkDelegateMgr *d, int opts=1) {
00254 ckDelegate(d);
00255 if(opts==1)
00256 d->initDelegateMgr(this);
00257 }
00258
00259 void ckSend(CkArrayMessage *m, int ep, int opts = 0) ;
00260
00261
00262 inline int ckGetNumSubSections() const { return _sid.size(); }
00263 inline CkSectionInfo &ckGetSectionInfo() {return _sid[0]._cookie;}
00264 inline CkSectionID *ckGetSectionIDs() {return _sid.data();}
00265 inline CkSectionID &ckGetSectionID() {return _sid[0];}
00266 inline CkSectionID &ckGetSectionID(int i) {return _sid[i];}
00267 inline CkArrayID ckGetArrayIDn(int i) const {return _sid[i]._cookie.get_aid();}
00268 inline CkArrayIndex *ckGetArrayElements() const {return const_cast<CkArrayIndex *>(_sid[0]._elems.data());}
00269 inline CkArrayIndex *ckGetArrayElements(int i) const {return const_cast<CkArrayIndex *>(_sid[i]._elems.data());}
00270 inline int ckGetNumElements() const { return _sid[0]._elems.size(); }
00271 inline int ckGetNumElements(int i) const { return _sid[i]._elems.size(); }
00272 inline int ckGetBfactor() const { return _sid[0].bfactor; }
00273 void pup(PUP::er &p);
00274 };
00275 PUPmarshall(CProxySection_ArrayBase)
00276
00277
00278 void CkSetMsgArrayIfNotThere(void *msg);
00279 void CkSendMsgArray(int entryIndex, void *msg, CkArrayID aID, const CkArrayIndex &idx, int opts=0);
00280 void CkSendMsgArrayInline(int entryIndex, void *msg, CkArrayID aID, const CkArrayIndex &idx, int opts=0);
00281 void CkBroadcastMsgArray(int entryIndex, void *msg, CkArrayID aID, int opts=0);
00282 void CkBroadcastMsgSection(int entryIndex, void *msg, CkSectionID sID, int opts= 0);
00283
00290 class ArrayElement : public CkMigratable
00291 {
00292 friend class CkArray;
00293
00294 friend class CkArrayListener;
00295 int numInitialElements;
00296 void initBasics(void);
00297 #ifdef _PIPELINED_ALLREDUCE_
00298 AllreduceMgr * allredMgr;
00299 #endif
00300 public:
00301 ArrayElement(void);
00302 ArrayElement(CkMigrateMessage *m);
00303 virtual ~ArrayElement();
00304
00306 void pup(PUP::er &p);
00307
00308
00310 virtual void ckAboutToMigrate(void);
00311 virtual void ckJustMigrated(void);
00312
00313 virtual void ckJustRestored(void);
00314
00315 virtual void ckDestroy(void);
00316 virtual char *ckDebugChareName(void);
00317 virtual int ckDebugChareID(char*, int);
00318
00320 inline void migrateMe(int toPe) {ckMigrate(toPe);}
00321
00322 #ifdef _PIPELINED_ALLREDUCE_
00323 void contribute2(CkArrayIndex myIndex, int dataSize,const void *data,CkReduction::reducerType type,
00324 const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00325 void contribute2(int dataSize,const void *data,CkReduction::reducerType type,
00326 CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00327 void contribute2(int dataSize,const void *data,CkReduction::reducerType type,
00328 const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00329 void contribute2(CkReductionMsg *msg);
00330 void contribute2(const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00331 void contribute2(CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00332 #else
00333 CK_REDUCTION_CONTRIBUTE_METHODS_DECL
00334 #endif
00335
00336 inline void defrag(CkReductionMsg* msg);
00337 inline const CkArrayID &ckGetArrayID(void) const {return thisArrayID;}
00338 inline ck::ObjID ckGetID(void) const { return ck::ObjID(thisArrayID, myRec->getID()); }
00339
00340 inline int ckGetArraySize(void) const { return numInitialElements; }
00341
00342 int getRedNo(void) const;
00343
00344 protected:
00345 CkArray *thisArray;
00346 CkArrayID thisArrayID;
00347
00348
00349 virtual void CkAbort(const char *str) const;
00350
00351 private:
00352
00353 int listenerData[CK_ARRAYLISTENER_MAXLEN];
00354
00355 #if CMK_MEM_CHECKPOINT
00356 friend class CkMemCheckPT;
00357 friend class CkLocMgr;
00358 protected:
00359 int budPEs[2];
00360 private:
00361 void init_checkpt();
00362 #endif
00363 public:
00364 void inmem_checkpoint(CkArrayCheckPTReqMessage *m);
00365 void recvBroadcast(CkMessage *);
00366
00367 #if CMK_GRID_QUEUE_AVAILABLE
00368 public:
00369 int grid_queue_interval;
00370 int grid_queue_threshold;
00371 int msg_count;
00372 int msg_count_grid;
00373 int border_flag;
00374 #endif
00375 };
00376 inline int *CkArrayListener::ckGetData(ArrayElement *el) const
00377 {return &el->listenerData[dataOffset];}
00378
00382 template <class T>
00383 class ArrayElementT : public ArrayElement
00384 {
00385 public:
00386 using array_index_t = T;
00387
00388 ArrayElementT(void): thisIndex(*(const T *)thisIndexMax.data()) {
00389 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00390 mlogData->objID.data.array.idx=thisIndexMax;
00391 #endif
00392 }
00393 #ifdef _PIPELINED_ALLREDUCE_
00394 void contribute(int dataSize,const void *data,CkReduction::reducerType type,
00395 CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1)
00396 {
00397 contribute2( dataSize,data, type, userFlag);
00398
00399 }
00400 void contribute(int dataSize,const void *data,CkReduction::reducerType type,
00401 const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1)
00402 {
00403 contribute2((CkArrayIndex)(thisIndex) ,dataSize, data, type, cb, userFlag);
00404 }
00405 void contribute(CkReductionMsg *msg)
00406 {
00407 contribute2(msg);
00408 }
00409 void contribute(const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1)
00410 {
00411 contribute2(cb ,userFlag);
00412 }
00413 void contribute(CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1)
00414 {
00415 contribute2(userFlag);
00416 }
00417 #endif
00418 ArrayElementT(CkMigrateMessage *msg)
00419 :ArrayElement(msg),
00420 thisIndex(*(const T *)thisIndexMax.data()) {}
00421
00422 const T thisIndex;
00423 };
00424
00425 typedef ArrayElementT<CkIndex1D> ArrayElement1D;
00426 typedef ArrayElementT<CkIndex2D> ArrayElement2D;
00427 typedef ArrayElementT<CkIndex3D> ArrayElement3D;
00428 typedef ArrayElementT<CkIndex4D> ArrayElement4D;
00429 typedef ArrayElementT<CkIndex5D> ArrayElement5D;
00430 typedef ArrayElementT<CkIndex6D> ArrayElement6D;
00431 typedef ArrayElementT<CkIndexMax> ArrayElementMax;
00432
00433 extern void (*ArrayMsgRecvExtCallback)(int, int, int *, int, int, char *, int);
00434 extern int (*ArrayElemLeaveExt)(int, int, int *, char**, int);
00435 extern void (*ArrayElemJoinExt)(int, int, int *, int, char*, int);
00436 extern void (*ArrayResumeFromSyncExtCallback)(int, int, int *);
00437
00438 class ArrayElemExt: public ArrayElement {
00439 private:
00440 int ctorEpIdx;
00441
00442 public:
00443 ArrayElemExt(void *impl_msg);
00444 ArrayElemExt(CkMigrateMessage *m) { delete m; }
00445
00446 static void __ArrayElemExt(void *impl_msg, void *impl_obj_void) {
00447 new (impl_obj_void) ArrayElemExt(impl_msg);
00448 }
00449
00450 static void __entryMethod(void *impl_msg, void *impl_obj_void) {
00451
00452 ArrayElemExt *e = static_cast<ArrayElemExt *>(impl_obj_void);
00453 CkMarshallMsg *impl_msg_typed = (CkMarshallMsg *)impl_msg;
00454 char *impl_buf = impl_msg_typed->msgBuf;
00455 PUP::fromMem implP(impl_buf);
00456 int msgSize; implP|msgSize;
00457 int ep; implP|ep;
00458 int dcopy_start; implP|dcopy_start;
00459 ArrayMsgRecvExtCallback(((CkGroupID)e->thisArrayID).idx,
00460 int(e->thisIndexMax.getDimension()),
00461 e->thisIndexMax.data(), ep, msgSize, impl_buf+(3*sizeof(int)),
00462 dcopy_start);
00463 }
00464
00465 static void __AtSyncEntryMethod(void *impl_msg, void *impl_obj_void) {
00466 ArrayElemExt *e = static_cast<ArrayElemExt *>(impl_obj_void);
00467
00468 e->AtSync();
00469 if (UsrToEnv(impl_msg)->isVarSysMsg() == 0) CkFreeSysMsg(impl_msg);
00470 }
00471
00472 static void __CkMigrateMessage(void *impl_msg, void *impl_obj_void) {
00473
00474 call_migration_constructor<ArrayElemExt> c = impl_obj_void;
00475 c((CkMigrateMessage*)impl_msg);
00476 }
00477
00478
00479
00480 void pup(PUP::er &p) {
00481
00482
00483
00484 ArrayElement::pup(p);
00485 int nDims = thisIndexMax.getDimension();
00486 int aid = ((CkGroupID)thisArrayID).idx;
00487 int data_size;
00488 if (!p.isUnpacking()) {
00489 char *msg;
00490 data_size = ArrayElemLeaveExt(aid, nDims, thisIndexMax.data(), &msg, p.isSizing());
00491 p | data_size;
00492 p | ctorEpIdx;
00493 p(msg, data_size);
00494 } else {
00495 p | data_size;
00496 p | ctorEpIdx;
00497 PUP::fromMem *p_mem = (PUP::fromMem *)&p;
00498 ArrayElemJoinExt(aid, nDims, thisIndexMax.data(), ctorEpIdx, p_mem->get_current_pointer(), data_size);
00499 p_mem->advance(data_size);
00500 }
00501 }
00502
00503 void ResumeFromSync() {
00504 if (!usesAtSync) {
00505
00506
00507
00508
00509
00510
00511 return;
00512 }
00513 ArrayResumeFromSyncExtCallback(((CkGroupID)thisArrayID).idx,
00514 int(thisIndexMax.getDimension()),
00515 thisIndexMax.data());
00516 }
00517 };
00518
00522
00527
00528 #include "CkArray.decl.h"
00529
00530 void CkSendAsyncCreateArray(int ctor, CkCallback cb, CkArrayOptions opts, void *ctorMsg);
00531
00532 class CkArrayCreatedMsg : public CMessage_CkArrayCreatedMsg {
00533 public:
00534 CkArrayID aid;
00535 CkArrayCreatedMsg(CkArrayID _aid) : aid(_aid) { }
00536 };
00537
00538 class CkArrayBroadcaster;
00539 class CkArrayReducer;
00540
00541 void _ckArrayInit(void);
00542
00543 class CkArray : public CkReductionMgr {
00544 friend class ArrayElement;
00545 friend class CProxy_ArrayBase;
00546 friend class CProxyElement_ArrayBase;
00547
00548 CkMagicNumber<ArrayElement> magic;
00549 CkLocMgr *locMgr;
00550 CkGroupID locMgrID;
00551 CkGroupID mCastMgrID;
00552 bool sectionAutoDelegate;
00553 CkCallback initCallback;
00554 CProxy_CkArray thisProxy;
00555
00556 std::unordered_map<CmiUInt8, unsigned int> localElems;
00557 std::vector<CkMigratable *> localElemVec;
00558 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00559 int *children;
00560 int numChildren;
00561 #endif
00562
00563 UShort recvBroadcastEpIdx;
00564 private:
00565 bool stableLocations;
00566
00567 public:
00568
00569 CkArray(CkArrayOptions &&c, CkMarshalledMessage &&initMsg);
00570 CkArray(CkMigrateMessage *m);
00571 ~CkArray();
00572 CkGroupID &getGroupID(void) {return thisgroup;}
00573 CkGroupID &getmCastMgr(void) {return mCastMgrID;}
00574 bool isSectionAutoDelegated(void) {return sectionAutoDelegate;}
00575
00576 UShort &getRecvBroadcastEpIdx(void) {return recvBroadcastEpIdx;}
00577
00578
00579 inline CkLocMgr *getLocMgr(void) {return locMgr;}
00580 inline const CkArrayIndex &getNumInitial(void) const {return numInitial;}
00581 inline int homePe(const CkArrayIndex &idx) const {return locMgr->homePe(idx);}
00582 inline int procNum(const CkArrayIndex &idx) const {return locMgr->procNum(idx);}
00583
00586 inline int lastKnown(const CkArrayIndex &idx) const
00587 {return locMgr->lastKnown(idx);}
00590 inline void deliver(CkMessage *m, const CkArrayIndex &idx, CkDeliver_t type,int opts=0)
00591 { locMgr->sendMsg((CkArrayMessage*)m, thisgroup, idx, type, opts); }
00592 inline int deliver(CkArrayMessage *m, CkDeliver_t type)
00593 { return locMgr->deliverMsg(m, thisgroup, m->array_element_id(), NULL, type); }
00595 inline ArrayElement *lookup(const CmiUInt8 id) { return (ArrayElement*) getEltFromArrMgr(id); }
00597 inline ArrayElement *lookup(const CkArrayIndex &idx) {
00598 CmiUInt8 id;
00599 if (locMgr->lookupID(idx,id)) {
00600 return (ArrayElement*) getEltFromArrMgr(id);
00601 } else {
00602 return NULL;
00603 }
00604 }
00605
00606 virtual CkMigratable* getEltFromArrMgr(const CmiUInt8 id) {
00607 const auto itr = localElems.find(id);
00608 return ( itr == localElems.end() ? NULL : localElemVec[itr->second] );
00609 }
00610 virtual void putEltInArrMgr(const CmiUInt8 id, CkMigratable* elt)
00611 {
00612 localElems[id] = localElemVec.size();
00613 localElemVec.push_back(elt);
00614 }
00615 virtual void eraseEltFromArrMgr(const CmiUInt8 id)
00616 {
00617 auto itr = localElems.find(id);
00618 if (itr != localElems.end()) {
00619 unsigned int offset = itr->second;
00620 localElems.erase(itr);
00621
00622
00623 if (offset != localElemVec.size() - 1) {
00624 CkMigratable *moved = localElemVec[localElemVec.size()-1];
00625 localElemVec[offset] = moved;
00626 localElems[moved->ckGetID()] = offset;
00627 }
00628
00629 localElemVec.pop_back();
00630 }
00631 }
00632
00633 void deleteElt(const CmiUInt8 id) {
00634 auto itr = localElems.find(id);
00635 if (itr != localElems.end()) {
00636 unsigned int offset = itr->second;
00637 localElems.erase(itr);
00638 delete localElemVec[offset];
00639
00640 if (offset != localElemVec.size() - 1) {
00641 CkMigratable *moved = localElemVec[localElemVec.size()-1];
00642 localElemVec[offset] = moved;
00643 localElems[moved->ckGetID()] = offset;
00644 }
00645
00646 localElemVec.pop_back();
00647 }
00648 }
00649
00650
00654 virtual CkMigratable *allocateMigrated(int elChareType, CkElementCreation_t type);
00655 void stampListenerData(CkMigratable *elt);
00656
00658 void prepareCtorMsg(CkMessage *m, int listenerData[CK_ARRAYLISTENER_MAXLEN]);
00659
00660 int findInitialHostPe(const CkArrayIndex &idx, int proposedPe);
00661
00663 virtual void insertInitial(const CkArrayIndex &idx,void *ctorMsg);
00664 virtual void doneInserting(void);
00665 virtual void beginInserting(void);
00666 void remoteDoneInserting(void);
00667 void remoteBeginInserting(void);
00668 void initDone(void);
00669
00671 bool insertElement(CkArrayMessage *, const CkArrayIndex &idx, int listenerData[CK_ARRAYLISTENER_MAXLEN]);
00672 void insertElement(CkMarshalledMessage &&, const CkArrayIndex &idx, int listenerData[CK_ARRAYLISTENER_MAXLEN]);
00673
00676 void demandCreateElement(const CkArrayIndex &idx, int ctor, CkDeliver_t type);
00677
00679 void sendBroadcast(CkMessage *msg);
00680 void recvBroadcast(CkMessage *msg);
00681 void sendExpeditedBroadcast(CkMessage *msg);
00682 void recvExpeditedBroadcast(CkMessage *msg) { recvBroadcast(msg); }
00683 void recvBroadcastViaTree(CkMessage *msg);
00684
00686 void ckDestroy();
00687
00688 void pup(PUP::er &p);
00689 void ckJustMigrated(void){ doneInserting(); }
00690
00691 virtual bool isArrMgr(void) {return true;}
00692
00693 private:
00694 CkArrayIndex numInitial;
00695 bool isInserting;
00696 int numPesInited;
00697
00699 ArrayElement *allocate(int elChareType, CkMessage *msg, bool fromMigration, int *listenerData);
00700
00701
00702 void springCleaning(void);
00703 static void staticSpringCleaning(void *forWhom,double curWallTime);
00704 void setupSpringCleaning();
00705 int springCleaningCcd;
00706
00707
00708 CkPupAblePtrVec<CkArrayListener> listeners;
00709 int listenerDataOffset;
00710 public:
00711 void addListener(CkArrayListener *l) {
00712 l->ckRegister(this,listenerDataOffset);
00713 listenerDataOffset+=l->ckGetLen();
00714 listeners.push_back(l);
00715 if (listenerDataOffset>CK_ARRAYLISTENER_MAXLEN)
00716 CkAbort("Too much array listener data!\n"
00717 "You'll have to either use fewer array listeners, or increase the compile-time\n"
00718 "constant CK_ARRAYLISTENER_MAXLEN!\n");
00719 }
00720 private:
00721
00722 CkArrayReducer *reducer;
00723 CkArrayBroadcaster *broadcaster;
00724 public:
00725 void flushStates();
00726 #if CMK_ONESIDED_IMPL
00727 void forwardZCMsgToOtherElems(envelope *env);
00728 #endif
00729
00730 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00731
00732 virtual int numberReductionMessages(){CkAssert(CkMyPe() == 0);return numInitial.data()[0];}
00733 void broadcastHomeElements(void *data,CkLocRec *rec,CkArrayIndex *index);
00734 static void staticBroadcastHomeElements(CkArray *arr,void *data,CkLocRec *rec,CkArrayIndex *index);
00735 #endif
00736
00737 static bool isIrreducible() { return true; }
00738 };
00739
00740
00741
00742 typedef CkArray CkArrMgr;
00743
00746 #endif