00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __CKLOCATION_H
00010 #define __CKLOCATION_H
00011
00012 #include <unordered_map>
00013 struct IndexHasher {
00014 public:
00015 size_t operator()(const CkArrayIndex& idx) const {
00016 return std::hash<unsigned int>()(idx.hash());
00017 }
00018 };
00019
00020 struct ArrayIDHasher {
00021 public:
00022 size_t operator()(const CkArrayID& aid) const {
00023 return std::hash<int>()(((CkGroupID)aid).idx);
00024 }
00025 };
00026
00027
00028 class CkArrayMessage : public CkMessage {
00029 public:
00030
00031 CmiUInt8 array_element_id(void);
00032 unsigned short &array_ep(void);
00033 unsigned short &array_ep_bcast(void);
00034 unsigned char &array_hops(void);
00035 unsigned int array_getSrcPe(void);
00036 unsigned int array_ifNotThere(void);
00037 void array_setIfNotThere(unsigned int);
00038
00039
00040 void operator delete(void *p){CkFreeMsg(p);}
00041 };
00042
00043
00044
00045 #include "LBDatabase.h"
00046 #include "MetaBalancer.h"
00047 class LBDatabase;
00048
00049
00050
00051 class CkArray;
00052 class ArrayElement;
00053
00054
00055 typedef enum : uint8_t {
00056 CkArray_IfNotThere_buffer=0,
00057 CkArray_IfNotThere_createhere=1,
00058 CkArray_IfNotThere_createhome=2
00059 } CkArray_IfNotThere;
00060
00062 typedef enum : uint8_t {
00063 CkDeliver_queue=0,
00064 CkDeliver_inline=1
00065 } CkDeliver_t;
00066 PUPbytes(CkDeliver_t)
00067
00068 class CkArrayOptions;
00069 #include "CkLocation.decl.h"
00070
00071
00076 class CkArrayElementMigrateMessage : public CMessage_CkArrayElementMigrateMessage {
00077 public:
00078 CkArrayElementMigrateMessage(CkArrayIndex idx_, CmiUInt8 id_, bool ignoreArrival_, int length_,
00079 int nManagers_, bool bounced_)
00080 : idx(idx_), id(id_), ignoreArrival(ignoreArrival_), length(length_), nManagers(nManagers_), bounced(bounced_)
00081 { }
00082
00083 CkArrayIndex idx;
00084 CmiUInt8 id;
00085 bool ignoreArrival;
00086 int length;
00087 int nManagers;
00088 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00089 CkGroupID gid;
00090 #endif
00091 bool bounced;
00092 char* packData;
00093 };
00094
00095
00096
00097 extern CkGroupID _defaultArrayMapID;
00098 extern CkGroupID _fastArrayMapID;
00099 class CkLocMgr;
00100 class CkArray;
00101
00106
00107 #include "ckarrayoptions.h"
00108
00112 class CkArrayMap : public IrrGroup
00113 {
00114 public:
00115 CkArrayMap(void);
00116 CkArrayMap(CkMigrateMessage *m): IrrGroup(m) {}
00117 virtual ~CkArrayMap();
00118 virtual int registerArray(const CkArrayIndex& numElements, CkArrayID aid);
00119 virtual void unregisterArray(int idx);
00120 virtual void storeCkArrayOpts(CkArrayOptions options);
00121 virtual void populateInitial(int arrayHdl,CkArrayOptions& options,void *ctorMsg,CkArray *mgr);
00122 virtual int procNum(int arrayHdl,const CkArrayIndex &element) =0;
00123 virtual int homePe(int arrayHdl,const CkArrayIndex &element)
00124 { return procNum(arrayHdl, element); }
00125
00126 virtual void pup(PUP::er &p);
00127
00128 CkArrayOptions storeOpts;
00129 std::unordered_map<int, bool> dynamicIns;
00130 };
00131
00132 extern int (*ArrayMapProcNumExtCallback)(int, int, const int *);
00133
00134 class ArrayMapExt: public CkArrayMap {
00135 public:
00136 ArrayMapExt(void *impl_msg);
00137
00138 static void __ArrayMapExt(void *impl_msg, void *impl_obj_void) {
00139 new (impl_obj_void) ArrayMapExt(impl_msg);
00140 }
00141
00142 static void __entryMethod(void *impl_msg, void *impl_obj_void) {
00143
00144 ArrayMapExt *obj = static_cast<ArrayMapExt *>(impl_obj_void);
00145 CkMarshallMsg *impl_msg_typed = (CkMarshallMsg *)impl_msg;
00146 char *impl_buf = impl_msg_typed->msgBuf;
00147 PUP::fromMem implP(impl_buf);
00148 int msgSize; implP|msgSize;
00149 int ep; implP|ep;
00150 int dcopy_start; implP|dcopy_start;
00151 GroupMsgRecvExtCallback(obj->thisgroup.idx, ep, msgSize, impl_buf+(3*sizeof(int)),
00152 dcopy_start);
00153 }
00154
00155 int procNum(int arrayHdl, const CkArrayIndex &element) {
00156 return ArrayMapProcNumExtCallback(thisgroup.idx, element.getDimension(), element.data());
00157
00158 }
00159 };
00160
00168 static inline CkGroupID CkCreatePropMap(void)
00169 {
00170 return CProxy_PropMap::ckNew();
00171 }
00172
00173 extern void _propMapInit(void);
00174 extern void _CkMigratable_initInfoInit(void);
00175
00176 #include "cklocrec.h"
00177
00178
00182 #if CMK_OUT_OF_CORE
00183 # include "conv-ooc.h"
00184 extern CooPrefetchManager CkArrayElementPrefetcher;
00185
00186
00187 CkpvExtern(int,CkSaveRestorePrefetch);
00188 #endif
00189
00190 #include "ckmigratable.h"
00191
00192
00193
00194
00196 class CkMagicNumber_impl {
00197 protected:
00198 int magic;
00199 void badMagicNumber(int expected,const char *file,int line,void *obj) const;
00200 CkMagicNumber_impl(int m);
00201 };
00202 template<class T>
00203 class CkMagicNumber : public CkMagicNumber_impl {
00204 enum {good=sizeof(T)^0x7EDC0000};
00205 public:
00206 CkMagicNumber(void) :CkMagicNumber_impl(good) {}
00207 inline void check(const char *file,int line,void *obj) const {
00208 if (magic!=good) badMagicNumber(good,file,line,obj);
00209 }
00210 #if CMK_ERROR_CHECKING
00211 # define CK_MAGICNUMBER_CHECK magic.check(__FILE__,__LINE__,this);
00212 #else
00213 # define CK_MAGICNUMBER_CHECK
00214 #endif
00215 };
00216
00225 class CkLocation {
00226 CkLocMgr *mgr;
00227 CkLocRec *rec;
00228 public:
00229 CkLocation(CkLocMgr *mgr_, CkLocRec *rec_);
00230
00232 inline CkLocMgr *getManager(void) const {return mgr;}
00233
00235 inline CkLocRec *getLocalRecord(void) const {return rec;}
00236
00238 const CkArrayIndex &getIndex(void) const;
00239 CmiUInt8 getID() const;
00240
00241 void destroyAll();
00242
00244 void pup(PUP::er &p);
00245 };
00246
00251 class CkLocIterator {
00252 public:
00253 virtual ~CkLocIterator();
00254
00256 virtual void addLocation(CkLocation &loc) =0;
00257 };
00258
00259 enum CkElementCreation_t : uint8_t {
00260 CkElementCreation_migrate=2,
00261 CkElementCreation_resume=3,
00262 CkElementCreation_restore=4
00263 };
00264
00265
00266 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00267 typedef void (*CkLocFn)(CkArray *,void *,CkLocRec *,CkArrayIndex *);
00268 #endif
00269
00270
00271 #if CMK_DRONE_MODE
00272 #define CMK_RANK_0(pe) (CkNodeOf(pe)*CkNodeSize(0))
00273 #else
00274 #define CMK_RANK_0(pe) pe
00275 #endif
00276
00282 class CkLocMgr : public IrrGroup {
00283 CkMagicNumber<CkMigratable> magic;
00284
00285 public:
00286
00287 typedef std::unordered_map<CkArrayID, CkArray*, ArrayIDHasher> ArrayIdMap;
00288 typedef std::unordered_map<CmiUInt8, int> IdPeMap;
00289 typedef std::unordered_map<CmiUInt8, std::vector<CkArrayMessage*> > MsgBuffer;
00290 typedef std::unordered_map<CkArrayIndex, std::vector<CkArrayMessage *>, IndexHasher> IndexMsgBuffer;
00291 typedef std::unordered_map<CkArrayIndex, std::vector<std::pair<int, bool> >, IndexHasher > LocationRequestBuffer;
00292 typedef std::unordered_map<CkArrayIndex, CmiUInt8, IndexHasher> IdxIdMap;
00293 typedef std::unordered_map<CmiUInt8, CkLocRec*> LocRecHash;
00294
00295 CkLocMgr(CkArrayOptions opts);
00296 CkLocMgr(CkMigrateMessage *m);
00297 ~CkLocMgr();
00298
00299 inline bool isLocMgr(void) { return true; }
00300 CkGroupID &getGroupID(void) {return thisgroup;}
00301 inline CProxy_CkLocMgr &getProxy(void) {return thisProxy;}
00302 inline CProxyElement_CkLocMgr &getLocalProxy(void) {return thislocalproxy;}
00303
00304
00306 inline int homePe(const CkArrayIndex &idx) const {return CMK_RANK_0(map->homePe(mapHandle,idx));}
00307 inline int homePe(const CmiUInt8 id) const {
00308 if (compressor)
00309 return CMK_RANK_0(homePe(compressor->decompress(id)));
00310
00311 return CMK_RANK_0(id >> 24);
00312 }
00313 inline int procNum(const CkArrayIndex &idx) const {return CMK_RANK_0(map->procNum(mapHandle,idx));}
00314 inline bool isHome (const CkArrayIndex &idx) const {return (bool)(homePe(idx)==CkMyPe());}
00315 int whichPE(const CkArrayIndex &idx) const;
00316 int whichPE(const CmiUInt8 id) const;
00318 int lastKnown(const CkArrayIndex &idx);
00319 int lastKnown(CmiUInt8 id);
00320
00321 inline void insertID(const CkArrayIndex& idx, const CmiUInt8 id) {
00322 if (compressor) return;
00323 idx2id[idx] = id;
00324 }
00325
00326 inline CmiUInt8 lookupID(const CkArrayIndex &idx) const {
00327 if (compressor) {
00328 return compressor->compress(idx);
00329 } else {
00330 CkLocMgr::IdxIdMap::const_iterator itr = idx2id.find(idx);
00331 CkAssert(itr != idx2id.end());
00332 return itr->second;
00333 }
00334 }
00335
00336 inline bool lookupID(const CkArrayIndex &idx, CmiUInt8& id) const {
00337 if (compressor) {
00338 id = compressor->compress(idx);
00339 return true;
00340 } else {
00341 CkLocMgr::IdxIdMap::const_iterator itr = idx2id.find(idx);
00342 if (itr == idx2id.end()) {
00343 return false;
00344 } else {
00345 id = itr->second;
00346 return true;
00347 }
00348 }
00349 }
00350
00351
00352 inline CkArrayIndex lookupIdx(const CmiUInt8 &id) const {
00353 if (compressor) {
00354 return compressor->decompress(id);
00355 } else {
00356 CkLocMgr::IdxIdMap::const_iterator itr;
00357 for ( itr = idx2id.begin(); itr != idx2id.end(); itr++ ) {
00358 if(itr->second == id)
00359 break;
00360 }
00361 CkAssert(itr != idx2id.end());
00362 return itr->first;
00363 }
00364 }
00365
00366
00367 CkLocRec *elementRec(const CkArrayIndex &idx);
00368
00369 CkLocRec *elementNrec(const CmiUInt8 id);
00370
00372 bool isRemote(const CkArrayIndex &idx,int *onPe) const;
00373
00374 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00375
00376 void setDuringMigration(bool _duringMigration);
00377 #endif
00378
00379 void setDuringDestruction(bool _duringDestruction);
00380
00382 void iterate(CkLocIterator &dest);
00383
00385 void restore(const CkArrayIndex &idx, CmiUInt8 id, PUP::er &p);
00387 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00388 void resume(const CkArrayIndex &idx, CmiUInt8 id, PUP::er &p, bool create, int dummy=0);
00389 #else
00390 void resume(const CkArrayIndex &idx, CmiUInt8 id, PUP::er &p, bool notify=true,bool=false);
00391 #endif
00392
00393
00395 void addManager(CkArrayID aid,CkArray *mgr);
00396 void deleteManager(CkArrayID aid, CkArray *mgr);
00397
00399 void populateInitial(CkArrayOptions& options,void *initMsg,CkArray *mgr)
00400 {
00401 map->storeCkArrayOpts(options);
00402 map->populateInitial(mapHandle,options,initMsg,mgr);
00403 }
00404
00407 bool addElement(CkArrayID aid,const CkArrayIndex &idx, CkMigratable *elt,int ctorIdx,void *ctorMsg);
00408
00410 void doneInserting(void);
00411 void startInserting(void);
00412
00413
00414
00415
00416 unsigned int numLocalElements();
00417
00419
00420 int deliverMsg(CkArrayMessage *m, CkArrayID mgr, CmiUInt8 id, const CkArrayIndex* idx, CkDeliver_t type, int opts = 0);
00421
00422 void sendMsg(CkArrayMessage *msg, CkArrayID mgr, const CkArrayIndex &idx, CkDeliver_t type, int opts);
00423
00424
00426 void inform(const CkArrayIndex &idx, CmiUInt8 id, int nowOnPe);
00427 void inform(CmiUInt8 id, int nowOnPe);
00428
00430 void informHome(const CkArrayIndex &idx,int nowOnPe);
00431
00433 void multiHop(CkArrayMessage *m);
00434
00435
00436
00437
00438 void emigrate(CkLocRec *rec,int toPe);
00439 void informLBPeriod(CkLocRec *rec, int lb_ideal_period);
00440 void metaLBCallLB(CkLocRec *rec);
00441
00442 #if CMK_LBDB_ON
00443 LBDatabase *getLBDB(void) const { return the_lbdb; }
00444 MetaBalancer *getMetaBalancer(void) const { return the_metalb;}
00445 const LDOMHandle &getOMHandle(void) const { return myLBHandle; }
00446 #endif
00447
00448
00449 void reclaim(CkLocRec* rec);
00450
00451 bool demandCreateElement(CkArrayMessage *msg, const CkArrayIndex &idx, int onPe, CkDeliver_t type);
00452 void demandCreateElement(const CkArrayIndex &idx, int chareType, int onPe, CkArrayID mgr);
00453
00454
00455 void immigrate(CkArrayElementMigrateMessage *msg);
00456 void requestLocation(const CkArrayIndex &idx, int peToTell, bool suppressIfHere, int ifNonExistent, int chareType, CkArrayID mgr);
00457 void requestLocation(CmiUInt8 id, int peToTell, bool suppressIfHere);
00458 void updateLocation(const CkArrayIndex &idx, CmiUInt8 id, int nowOnPe);
00459 void updateLocation(CmiUInt8 id, int nowOnPe);
00460 void reclaimRemote(const CkArrayIndex &idx,int deletedOnPe);
00461 void dummyAtSync(void);
00462
00464 void migratableList(CkLocRec *rec, std::vector<CkMigratable *> &list);
00465
00466 void flushAllRecs(void);
00467 void flushLocalRecs(void);
00468 void pup(PUP::er &p);
00469
00470
00471 private:
00472
00473
00474 void insertRec(CkLocRec *rec,const CmiUInt8 &id);
00475
00476
00477 void removeFromTable(const CmiUInt8 id);
00478
00479 friend class CkLocation;
00480 friend class ArrayElement;
00481 friend class MemElementPacker;
00482 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00483 void pupElementsFor(PUP::er &p,CkLocRec *rec,
00484 CkElementCreation_t type, bool create=true, int dummy=0);
00485 #else
00486 void pupElementsFor(PUP::er &p,CkLocRec *rec,
00487 CkElementCreation_t type,bool rebuild = false);
00488 #endif
00489
00491 typedef void (CkMigratable::* CkMigratable_voidfn_t)(void);
00492
00493 typedef void (CkMigratable::* CkMigratable_voidfn_arg_t)(void*);
00494 void callMethod(CkLocRec *rec,CkMigratable_voidfn_arg_t fn, void*);
00495
00496 void deliverUnknown(CkArrayMessage *msg, const CkArrayIndex* idx, CkDeliver_t type, int opts);
00498 void deliverAnyBufferedMsgs(CmiUInt8, MsgBuffer &buffer);
00499
00501 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00502 CkLocRec *createLocal(const CkArrayIndex &idx,
00503 bool forMigration, bool ignoreArrival,
00504 bool notifyHome,int dummy=0);
00505 #else
00506 CkLocRec *createLocal(const CkArrayIndex &idx,
00507 bool forMigration, bool ignoreArrival,
00508 bool notifyHome);
00509 #endif
00510
00511 LocationRequestBuffer bufferedLocationRequests;
00512
00513 public:
00514 void callMethod(CkLocRec *rec,CkMigratable_voidfn_t fn);
00515
00516
00517
00518 ArrayIdMap managers;
00519
00520 IdPeMap id2pe;
00521
00522
00523 IdxIdMap idx2id;
00524
00525 CmiUInt8 idCounter;
00526 CmiUInt8 getNewObjectID(const CkArrayIndex &idx);
00527
00532 MsgBuffer bufferedMsgs;
00533 MsgBuffer bufferedRemoteMsgs;
00534 MsgBuffer bufferedShadowElemMsgs;
00535
00536 IndexMsgBuffer bufferedIndexMsgs;
00537
00538 bool addElementToRec(CkLocRec *rec,CkArray *m,
00539 CkMigratable *elt,int ctorIdx,void *ctorMsg);
00540
00541 CProxy_CkLocMgr thisProxy;
00542 CProxyElement_CkLocMgr thislocalproxy;
00543
00545 bool duringMigration;
00547 bool duringDestruction;
00548
00549 private:
00551 LocRecHash hash;
00552 CmiImmediateLockType hashImmLock;
00553
00554
00555 CkGroupID mapID;
00556 int mapHandle;
00557 CkArrayMap *map;
00558
00559 CkGroupID lbdbID;
00560 CkGroupID metalbID;
00561
00562 ck::ArrayIndexCompressor *compressor;
00563 CkArrayIndex bounds;
00564 void checkInBounds(const CkArrayIndex &idx);
00565
00566 #if CMK_LBDB_ON
00567 LBDatabase *the_lbdb;
00568 MetaBalancer *the_metalb;
00569 LDBarrierClient dummyBarrierHandle;
00570 static void staticDummyResumeFromSync(void* data);
00571 void dummyResumeFromSync(void);
00572 static void staticRecvAtSync(void* data);
00573 void recvAtSync(void);
00574 LDOMHandle myLBHandle;
00575 LDBarrierReceiver lbBarrierReceiver;
00576 #endif
00577 private:
00578 void initLB(CkGroupID lbdbID, CkGroupID metalbID);
00579
00580 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00581 public:
00582 void callForAllRecords(CkLocFn,CkArray *,void *);
00583 int homeElementCount;
00584 #endif
00585
00586 };
00587
00588
00589
00590
00591
00593 bool haveConfigurableRRMap();
00594
00595
00596
00597
00600 #endif