00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __CKLOCATION_H
00010 #define __CKLOCATION_H
00011
00012
00013 class CkArrayMessage : public CkMessage {
00014 public:
00015
00016 CkArrayIndex &array_index(void);
00017 unsigned short &array_ep(void);
00018 unsigned short &array_ep_bcast(void);
00019 unsigned char &array_hops(void);
00020 unsigned int array_getSrcPe(void);
00021 unsigned int array_ifNotThere(void);
00022 void array_setIfNotThere(unsigned int);
00023
00024
00025 void operator delete(void *p){CkFreeMsg(p);}
00026 };
00027
00028
00029
00030 #include "LBDatabase.h"
00031 class LBDatabase;
00032
00033
00034
00035 class CkArray;
00036 class ArrayElement;
00037
00038
00039 typedef enum {
00040 CkArray_IfNotThere_buffer=0,
00041 CkArray_IfNotThere_createhere=1,
00042 CkArray_IfNotThere_createhome=2
00043 } CkArray_IfNotThere;
00044
00046 typedef enum {
00047 CkDeliver_queue=0,
00048 CkDeliver_inline=1
00049 } CkDeliver_t;
00050
00051 #include "CkLocation.decl.h"
00052
00053
00058 class CkArrayElementMigrateMessage : public CMessage_CkArrayElementMigrateMessage {
00059 public:
00060 CkArrayIndex idx;
00061 int ignoreArrival;
00062 int length;
00063 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00064 CkGroupID gid;
00065 #endif
00066 CmiBool bounced;
00067 double* packData;
00068 };
00069
00070
00071
00072 extern CkGroupID _defaultArrayMapID;
00073 extern CkGroupID _fastArrayMapID;
00074 class CkLocMgr;
00075 class CkArrMgr;
00076
00081
00085 class CkArrayMap : public IrrGroup
00086 {
00087 public:
00088 CkArrayMap(void);
00089 CkArrayMap(CkMigrateMessage *m): IrrGroup(m) {}
00090 virtual ~CkArrayMap();
00091 virtual int registerArray(CkArrayIndex& numElements,CkArrayID aid);
00092 virtual void populateInitial(int arrayHdl,CkArrayIndex& numElements,void *ctorMsg,CkArrMgr *mgr);
00093 virtual int procNum(int arrayHdl,const CkArrayIndex &element) =0;
00094 virtual int homePe(int arrayHdl,const CkArrayIndex &element)
00095 { return procNum(arrayHdl, element); }
00096
00097 };
00105 static inline CkGroupID CkCreatePropMap(void)
00106 {
00107 return CProxy_PropMap::ckNew();
00108 }
00109
00110 extern void _propMapInit(void);
00111 extern void _CkMigratable_initInfoInit(void);
00112
00113
00114
00115 class CkArray;
00116 class CkLocMgr;
00117 class CkMigratable;
00118
00124 class CkLocRec {
00125 protected:
00126 CkLocMgr *myLocMgr;
00127
00128
00129 virtual void weAreObsolete(const CkArrayIndex &idx);
00130 public:
00131 CkLocRec(CkLocMgr *mgr) :myLocMgr(mgr) { }
00132 virtual ~CkLocRec();
00133 inline CkLocMgr *getLocMgr(void) const {return myLocMgr;}
00134
00136 typedef enum {
00137 base=0,
00138 local,
00139 remote,
00140 buffering,
00141 dead
00142 } RecType;
00143 virtual RecType type(void)=0;
00144
00146 virtual CmiBool deliver(CkArrayMessage *m,CkDeliver_t type,int opts=0)=0;
00147
00150 virtual void beenReplaced(void);
00151
00153 virtual CmiBool isObsolete(int nSprings,const CkArrayIndex &idx)=0;
00154
00156 virtual CkMigratable *lookupElement(CkArrayID aid);
00157
00159 virtual int lookupProcessor(void);
00160 };
00161
00165 class CkLocRec_local : public CkLocRec {
00166 CkArrayIndex idx;
00167 int localIdx;
00168 CmiBool running;
00169 CmiBool *deletedMarker;
00170 CkQ<CkArrayMessage *> halfCreated;
00171 public:
00172
00173 CkLocRec_local(CkLocMgr *mgr,CmiBool fromMigration,CmiBool ignoreArrival,
00174 const CkArrayIndex &idx_,int localIdx_);
00175 void migrateMe(int toPe);
00176 void destroy(void);
00177 virtual ~CkLocRec_local();
00178
00180 void addedElement(void);
00181
00186 virtual CmiBool deliver(CkArrayMessage *m,CkDeliver_t type,int opts=0);
00187
00193 CmiBool invokeEntry(CkMigratable *obj,void *msg,int idx,CmiBool doFree);
00194
00195 virtual RecType type(void);
00196 virtual CmiBool isObsolete(int nSprings,const CkArrayIndex &idx);
00197
00198 #if CMK_LBDB_ON //For load balancing:
00200 void startTiming(int ignore_running=0);
00201 void stopTiming(int ignore_running=0);
00202 void setObjTime(double cputime);
00203 double getObjTime();
00204 #else
00205 inline void startTiming(int ignore_running=0) { }
00206 inline void stopTiming(int ignore_running=0) { }
00207 #endif
00208 inline int getLocalIndex(void) const {return localIdx;}
00209 inline const CkArrayIndex &getIndex(void) const {return idx;}
00210 virtual CkMigratable *lookupElement(CkArrayID aid);
00211 virtual int lookupProcessor(void);
00212
00213 #if CMK_LBDB_ON
00214 public:
00215 inline LBDatabase *getLBDB(void) const {return the_lbdb;}
00216 inline LDObjHandle getLdHandle() const{return ldHandle;}
00217 static void staticMigrate(LDObjHandle h, int dest);
00218 void recvMigrate(int dest);
00219 void setMigratable(int migratable);
00220 void AsyncMigrate(CmiBool use);
00221 CmiBool isAsyncMigrate() { return asyncMigrate; }
00222 void ReadyMigrate(CmiBool ready) { readyMigrate = ready; }
00223 int isReadyMigrate() { return readyMigrate; }
00224 CmiBool checkBufferedMigration();
00225 int MigrateToPe();
00226 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00227 void Migrated();
00228 #endif
00229 inline void setMeasure(CmiBool status) { enable_measure = status; }
00230 private:
00231 LBDatabase *the_lbdb;
00232 LDObjHandle ldHandle;
00233 CmiBool asyncMigrate;
00234 CmiBool readyMigrate;
00235 CmiBool enable_measure;
00236 int nextPe;
00237 #else
00238 void AsyncMigrate(CmiBool use){};
00239 #endif
00240
00241 private:
00242 CmiBool asyncEvacuate;
00243 CmiBool bounced;
00244
00245
00246
00247 public:
00248 CmiBool isAsyncEvacuate(){return asyncEvacuate;}
00249 void AsyncEvacuate(CmiBool set){asyncEvacuate = set;}
00250 CmiBool isBounced(){return bounced;}
00251 void Bounced(CmiBool set){bounced = set;}
00252 };
00253 class CkLocRec_remote;
00254
00255
00259 #if CMK_OUT_OF_CORE
00260 # include "conv-ooc.h"
00261 extern CooPrefetchManager CkArrayElementPrefetcher;
00262
00263
00264 CkpvExtern(int,CkSaveRestorePrefetch);
00265 #endif
00266
00267 class CkMigratable : public Chare {
00268 protected:
00269 CkLocRec_local *myRec;
00270 private:
00271 int thisChareType;
00272 void commonInit(void);
00273 CmiBool asyncEvacuate;
00274 public:
00275 CkArrayIndex thisIndexMax;
00276
00277 CkMigratable(void);
00278 CkMigratable(CkMigrateMessage *m);
00279 virtual ~CkMigratable();
00280 virtual void pup(PUP::er &p);
00281 virtual void CkAddThreadListeners(CthThread tid, void *msg);
00282
00283 virtual int ckGetChareType(void) const;
00284 const CkArrayIndex &ckGetArrayIndex(void) const {return myRec->getIndex();}
00285
00286 #if CMK_LBDB_ON //For load balancing:
00287
00288 inline void ckStopTiming(void) {myRec->stopTiming();}
00289
00290 inline void ckStartTiming(void) {myRec->startTiming();}
00291 inline LBDatabase *getLBDB(void) const {return myRec->getLBDB();}
00292 #else
00293 inline void ckStopTiming(void) { }
00294 inline void ckStartTiming(void) { }
00295 #endif
00296
00298 LDObjHandle timingBeforeCall(int *objstopped);
00299 void timingAfterCall(LDObjHandle objHandle,int *objstopped);
00300
00301
00302 inline void ckMigrate(int toPe) {myRec->migrateMe(toPe);}
00303
00305 virtual void ckAboutToMigrate(void);
00306 virtual void ckJustMigrated(void);
00307
00308
00309 virtual void ckJustRestored(void);
00310
00312 virtual void ckDestroy(void);
00313
00316 inline CmiBool ckInvokeEntry(int epIdx,void *msg,CmiBool doFree)
00317 {return myRec->invokeEntry(this,msg,epIdx,doFree);}
00318
00319 protected:
00321 virtual void CkAbort(const char *str) const;
00322
00323 CmiBool usesAtSync;
00324 CmiBool usesAutoMeasure;
00325 CmiBool barrierRegistered;
00326
00327 public:
00328 virtual void ResumeFromSync(void);
00329 virtual void UserSetLBLoad(void);
00330 void setObjTime(double cputime);
00331 double getObjTime();
00332
00333 #if CMK_LBDB_ON //For load balancing:
00334 void AtSync(int waitForMigration=1);
00335 int MigrateToPe() { return myRec->MigrateToPe(); }
00336
00337 private:
00338 LDBarrierClient ldBarrierHandle;
00339 LDBarrierReceiver ldBarrierRecvHandle;
00340 static void staticResumeFromSync(void* data);
00341 public:
00342 void ReadyMigrate(CmiBool ready);
00343 void ckFinishConstruction(void);
00344 void setMigratable(int migratable);
00345 #else
00346 void AtSync(int waitForMigration=1) { ResumeFromSync();}
00347 void setMigratable(int migratable) { }
00348 public:
00349 void ckFinishConstruction(void) { }
00350 #endif
00351
00352 #if CMK_OUT_OF_CORE
00353 private:
00354 friend class CkLocMgr;
00355 friend int CkArrayPrefetch_msg2ObjId(void *msg);
00356 friend void CkArrayPrefetch_writeToSwap(FILE *swapfile,void *objptr);
00357 friend void CkArrayPrefetch_readFromSwap(FILE *swapfile,void *objptr);
00358 int prefetchObjID;
00359 CmiBool isInCore;
00360 #endif
00361
00362
00363 void AsyncEvacuate(CmiBool set){myRec->AsyncEvacuate(set);asyncEvacuate = set;};
00364 public:
00365 CmiBool isAsyncEvacuate(){return asyncEvacuate;};
00366 };
00367
00372 class CkMigratableList {
00373 CkVec< CkZeroPtr<CkMigratable> > el;
00374 public:
00375 CkMigratableList();
00376 ~CkMigratableList();
00377
00378 void setSize(int s);
00379 inline int length(void) const {return el.length();}
00380
00382 void put(CkMigratable *v,int atIdx);
00383
00385 inline CkMigratable *get(int localIdx) {return el[localIdx];}
00386
00391 CkMigratable *next(int &from) {
00392 while (from<length()) {
00393 CkMigratable *ret=el[from];
00394 from++;
00395 if (ret!=NULL) return ret;
00396 }
00397 return NULL;
00398 }
00399
00401 inline void empty(int localIdx) {el[localIdx]=NULL;}
00402 };
00403
00407 template <class T>
00408 class CkMigratableListT : public CkMigratableList {
00409 typedef CkMigratableList super;
00410 public:
00411 inline void put(T *v,int atIdx) {super::put((CkMigratable *)v,atIdx);}
00412 inline T *get(int localIdx) {return (T *)super::get(localIdx);}
00413 inline T *next(int &from) {return (T *)super::next(from);}
00414 };
00415
00416
00417
00419 class CkMagicNumber_impl {
00420 protected:
00421 int magic;
00422 void badMagicNumber(int expected,const char *file,int line,void *obj) const;
00423 CkMagicNumber_impl(int m);
00424 };
00425 template<class T>
00426 class CkMagicNumber : public CkMagicNumber_impl {
00427 enum {good=sizeof(T)^0x7EDC0000};
00428 public:
00429 CkMagicNumber(void) :CkMagicNumber_impl(good) {}
00430 inline void check(const char *file,int line,void *obj) const {
00431 if (magic!=good) badMagicNumber(good,file,line,obj);
00432 }
00433 #if CMK_ERROR_CHECKING
00434 # define CK_MAGICNUMBER_CHECK magic.check(__FILE__,__LINE__,this);
00435 #else
00436 # define CK_MAGICNUMBER_CHECK
00437 #endif
00438 };
00439
00448 class CkLocation {
00449 CkLocMgr *mgr;
00450 CkLocRec_local *rec;
00451 public:
00452 CkLocation(CkLocMgr *mgr_, CkLocRec_local *rec_);
00453
00455 inline CkLocMgr *getManager(void) const {return mgr;}
00456
00458 inline CkLocRec_local *getLocalRecord(void) const {return rec;}
00459
00461 const CkArrayIndex &getIndex(void) const;
00462
00463 void destroyAll();
00464
00466 void pup(PUP::er &p);
00467 };
00468
00473 class CkLocIterator {
00474 public:
00475 virtual ~CkLocIterator();
00476
00478 virtual void addLocation(CkLocation &loc) =0;
00479 };
00480
00481 enum CkElementCreation_t {
00482 CkElementCreation_migrate=2,
00483 CkElementCreation_resume=3,
00484 CkElementCreation_restore=4
00485 };
00487 class CkArrMgr {
00488 public:
00489 virtual ~CkArrMgr() {}
00491 virtual void insertInitial(const CkArrayIndex &idx,void *ctorMsg, int local=1)=0;
00492
00494 virtual void doneInserting(void)=0;
00495
00498 virtual CkMigratable *allocateMigrated(int elChareType,
00499 const CkArrayIndex &idx,CkElementCreation_t type) =0;
00500
00504 virtual CmiBool demandCreateElement(const CkArrayIndex &idx,
00505 int onPe,int ctor,CkDeliver_t type) =0;
00506 };
00507
00508
00509 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00510 typedef void (*CkLocFn)(CkArray *,void *,CkLocRec *,CkArrayIndex *);
00511 #endif
00512
00513
00519 class CkLocMgr : public IrrGroup {
00520 CkMagicNumber<CkMigratable> magic;
00521 public:
00522 CkLocMgr(CkGroupID map,CkGroupID _lbdb,CkArrayIndex& numInitial);
00523 CkLocMgr(CkMigrateMessage *m);
00524 inline CmiBool isLocMgr(void) { return CmiTrue; }
00525 CkGroupID &getGroupID(void) {return thisgroup;}
00526 inline CProxy_CkLocMgr &getProxy(void)
00527 {return thisProxy;}
00528 inline CProxyElement_CkLocMgr &getLocalProxy(void)
00529 {return thislocalproxy;}
00530
00531
00535 CkMigratableList *addManager(CkArrayID aid,CkArrMgr *mgr);
00536
00538 void populateInitial(CkArrayIndex& numElements,void *initMsg,CkArrMgr *mgr)
00539 {map->populateInitial(mapHandle,numElements,initMsg,mgr);}
00540
00544 CmiBool addElement(CkArrayID aid,const CkArrayIndex &idx,
00545 CkMigratable *elt,int ctorIdx,void *ctorMsg);
00546
00548 inline void deliverViaQueue(CkMessage *m) {deliver(m,CkDeliver_queue);}
00549 inline void deliverInline(CkMessage *m) {deliver(m,CkDeliver_inline);}
00550 int deliver(CkMessage *m, CkDeliver_t type, int opts=0);
00551
00553 void doneInserting(void);
00554 void startInserting(void);
00555
00556
00557
00558
00559 unsigned int numLocalElements();
00560
00561
00563 void inform(const CkArrayIndex &idx,int nowOnPe);
00564
00566 void informHome(const CkArrayIndex &idx,int nowOnPe);
00567
00569 void multiHop(CkArrayMessage *m);
00570
00571
00572
00573 inline CkMigratable *lookupLocal(int localIdx,CkArrayID arrayID) {
00574 #if CMK_ERROR_CHECKING
00575 if (managers.find(arrayID)->mgr==NULL)
00576 CkAbort("CkLocMgr::lookupLocal called for unknown array!\n");
00577 #endif
00578 return managers.find(arrayID)->elts.get(localIdx);
00579 }
00580
00581
00582 void emigrate(CkLocRec_local *rec,int toPe);
00583
00584 #if CMK_LBDB_ON
00585 LBDatabase *getLBDB(void) const { return the_lbdb; }
00586 const LDOMHandle &getOMHandle(void) const { return myLBHandle; }
00587 #endif
00588
00589
00590 void reclaim(const CkArrayIndex &idx,int localIdx);
00591
00592 int getSpringCount(void) const { return nSprings; }
00593
00594 CmiBool demandCreateElement(CkArrayMessage *msg,int onPe,CkDeliver_t type);
00595
00596
00598 inline int homePe(const CkArrayIndex &idx) const
00599 {return map->homePe(mapHandle,idx);}
00600 inline int procNum(const CkArrayIndex &idx) const
00601 {return map->procNum(mapHandle,idx);}
00602 inline CmiBool isHome(const CkArrayIndex &idx) const
00603 {return (CmiBool)(homePe(idx)==CkMyPe());}
00604
00606 CkMigratable *lookup(const CkArrayIndex &idx,CkArrayID aid);
00607
00609 int lastKnown(const CkArrayIndex &idx);
00610
00612 bool isRemote(const CkArrayIndex &idx,int *onPe) const;
00613
00614 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00615
00616 void setDuringMigration(CmiBool _duringMigration);
00617 #endif
00618
00620 void iterate(CkLocIterator &dest);
00621
00623 void restore(const CkArrayIndex &idx, PUP::er &p);
00625 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00626 void resume(const CkArrayIndex &idx, PUP::er &p, CmiBool create, int dummy=0);
00627 #else
00628 void resume(const CkArrayIndex &idx, PUP::er &p, CmiBool notify=CmiTrue);
00629 #endif
00630
00631
00632 void immigrate(CkArrayElementMigrateMessage *msg);
00633 void updateLocation(const CkArrayIndex &idx,int nowOnPe);
00634 void reclaimRemote(const CkArrayIndex &idx,int deletedOnPe);
00635 void dummyAtSync(void);
00636
00638 void migratableList(CkLocRec_local *rec, CkVec<CkMigratable *> &list);
00639
00640 void flushAllRecs(void);
00641 void pup(PUP::er &p);
00642
00643
00644 CkLocRec *elementRec(const CkArrayIndex &idx);
00645
00646 CkLocRec *elementNrec(const CkArrayIndex &idx);
00647
00648 private:
00649
00650
00651 void insertRec(CkLocRec *rec,const CkArrayIndex &idx);
00652
00653 void insertRecN(CkLocRec *rec,const CkArrayIndex &idx);
00654
00655 CkLocRec_remote *insertRemote(const CkArrayIndex &idx,int nowOnPe);
00656
00657
00658 void removeFromTable(const CkArrayIndex &idx);
00659
00660 friend class CkLocation;
00661 friend class ArrayElement;
00662 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00663 void pupElementsFor(PUP::er &p,CkLocRec_local *rec,
00664 CkElementCreation_t type, CmiBool create=CmiTrue, int dummy=0);
00665 #else
00666 void pupElementsFor(PUP::er &p,CkLocRec_local *rec,
00667 CkElementCreation_t type);
00668 #endif
00669
00671 typedef void (CkMigratable::* CkMigratable_voidfn_t)(void);
00672 void callMethod(CkLocRec_local *rec,CkMigratable_voidfn_t fn);
00673
00674 CmiBool deliverUnknown(CkArrayMessage *msg,CkDeliver_t type,int opts);
00675
00677 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00678 CkLocRec_local *createLocal(const CkArrayIndex &idx,
00679 CmiBool forMigration, CmiBool ignoreArrival,
00680 CmiBool notifyHome,int dummy=0);
00681 #else
00682 CkLocRec_local *createLocal(const CkArrayIndex &idx,
00683 CmiBool forMigration, CmiBool ignoreArrival,
00684 CmiBool notifyHome);
00685 #endif
00686
00687
00688
00689 class ManagerRec {
00690 public:
00691 ManagerRec *next;
00692 CkArrMgr *mgr;
00693 CkMigratableList elts;
00694 ManagerRec() {
00695 next=NULL;
00696 mgr=NULL;
00697 }
00698 void init(void) { next=NULL; mgr=NULL; }
00699 CkMigratable *element(int localIdx) {
00700 return elts.get(localIdx);
00701 }
00702 };
00703 GroupIdxArray<ManagerRec *> managers;
00704 int nManagers;
00705 ManagerRec *firstManager;
00706
00707 CmiBool addElementToRec(CkLocRec_local *rec,ManagerRec *m,
00708 CkMigratable *elt,int ctorIdx,void *ctorMsg);
00709
00710
00711 CkVec<int> freeList;
00712 int firstFree;
00713 int localLen;
00714 int nextFree(void);
00715
00716 CProxy_CkLocMgr thisProxy;
00717 CProxyElement_CkLocMgr thislocalproxy;
00719 CkHashtableT<CkArrayIndex,CkLocRec *> hash;
00720 CmiImmediateLockType hashImmLock;
00721
00723 CmiBool duringMigration;
00724
00725
00726 static void staticSpringCleaning(void *mgr,double curWallTime);
00727 void springCleaning(void);
00728 int nSprings;
00729
00730
00731 CkGroupID mapID;
00732 int mapHandle;
00733 CkArrayMap *map;
00734
00735 CkGroupID lbdbID;
00736 #if CMK_LBDB_ON
00737 LBDatabase *the_lbdb;
00738 LDBarrierClient dummyBarrierHandle;
00739 static void staticDummyResumeFromSync(void* data);
00740 void dummyResumeFromSync(void);
00741 static void staticRecvAtSync(void* data);
00742 void recvAtSync(void);
00743 LDOMHandle myLBHandle;
00744 #endif
00745 void initLB(CkGroupID lbdbID);
00746
00747 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00748 public:
00749 void callForAllRecords(CkLocFn,CkArray *,void *);
00750 int homeElementCount;
00751 #endif
00752
00753 };
00754
00755
00756
00757
00758
00760 bool haveConfigurableRRMap();
00761
00762
00763
00764
00767 #endif