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