2 Location manager: keeps track of an indexed set of migratable
3 objects. Used by the array manager to locate array elements,
4 interact with the load balancer, and perform migrations.
6 Does not handle reductions (see ckreduction.h), broadcasts,
7 array proxies, or the details of element creation (see ckarray.h).
10 #define __CKLOCATION_H
14 /*********************** Array Messages ************************/
15 class CkArrayMessage
: public CkMessage
{
17 //These routines are implementation utilities
18 CmiUInt8
array_element_id(void);
19 unsigned short &array_ep(void);
20 unsigned short &array_ep_bcast(void);
21 unsigned char &array_hops(void);
22 unsigned int array_getSrcPe(void);
23 unsigned int array_ifNotThere(void);
24 void array_setIfNotThere(unsigned int);
26 //This allows us to delete bare CkArrayMessages
27 void operator delete(void *p
){CkFreeMsg(p
);}
32 #include "LBDatabase.h"
33 #include "MetaBalancer.h"
37 //Forward declarations
40 //What to do if an entry method is invoked on
41 // an array element that does not (yet) exist:
43 CkArray_IfNotThere_buffer
=0, //Wait for it to be created
44 CkArray_IfNotThere_createhere
=1, //Make it on sending Pe
45 CkArray_IfNotThere_createhome
=2 //Make it on (a) home Pe
48 /// How to do a message delivery:
50 CkDeliver_queue
=0, //Deliver via the scheduler's queue
51 CkDeliver_inline
=1 //Deliver via a regular call
55 #include "CkLocation.decl.h"
57 /************************** Array Messages ****************************/
59 * This is the message type used to actually send a migrating array element.
62 class CkArrayElementMigrateMessage
: public CMessage_CkArrayElementMigrateMessage
{
64 CkArrayElementMigrateMessage(CkArrayIndex idx_
, CmiUInt8 id_
, bool ignoreArrival_
, int length_
,
65 int nManagers_
, bool bounced_
)
66 : idx(idx_
), id(id_
), ignoreArrival(ignoreArrival_
), length(length_
), nManagers(nManagers_
), bounced(bounced_
)
69 CkArrayIndex idx
; // Array index that is migrating
70 CmiUInt8 id
; // ID of the elements with this index in this collection
71 bool ignoreArrival
; // if to inform LB of arrival
72 int length
;//Size in bytes of the packed data
73 int nManagers
; // Number of associated array managers
74 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
75 CkGroupID gid
; //gid of location manager
77 bool bounced
; // Fault evac related?
81 /******************* Map object ******************/
83 extern CkGroupID _defaultArrayMapID
;
84 extern CkGroupID _fastArrayMapID
;
93 /** The "map" is used by the array manager to map an array index to
94 * a home processor number.
96 class CkArrayMap
: public IrrGroup
// : public CkGroupReadyCallback
100 CkArrayMap(CkMigrateMessage
*m
): IrrGroup(m
) {}
101 virtual ~CkArrayMap();
102 virtual int registerArray(const CkArrayIndex
& numElements
, CkArrayID aid
);
103 virtual void unregisterArray(int idx
);
104 virtual void populateInitial(int arrayHdl
,CkArrayOptions
& options
,void *ctorMsg
,CkArray
*mgr
);
105 virtual int procNum(int arrayHdl
,const CkArrayIndex
&element
) =0;
106 virtual int homePe(int arrayHdl
,const CkArrayIndex
&element
)
107 { return procNum(arrayHdl
, element
); }
112 \addtogroup CkArrayImpl
113 \brief Migratable Chare Arrays: Implementation classes.
116 static inline CkGroupID
CkCreatePropMap(void)
118 return CProxy_PropMap::ckNew();
121 extern void _propMapInit(void);
122 extern void _CkMigratable_initInfoInit(void);
124 #include "cklocrec.h"
126 /*********************** CkMigratable ******************************/
127 /** This is the superclass of all migratable parallel objects.
128 * Currently, that's just array elements.
131 # include "conv-ooc.h"
132 extern CooPrefetchManager CkArrayElementPrefetcher
;
133 // If this flag is set, this creation/deletion is just
134 // a "fake" constructor/destructor call for prefetching.
135 CkpvExtern(int,CkSaveRestorePrefetch
);
138 #include "ckmigratable.h"
142 /********************** CkLocMgr ********************/
143 /// A tiny class for detecting heap corruption
144 class CkMagicNumber_impl
{
147 void badMagicNumber(int expected
,const char *file
,int line
,void *obj
) const;
148 CkMagicNumber_impl(int m
);
151 class CkMagicNumber
: public CkMagicNumber_impl
{
152 enum {good
=sizeof(T
)^0x7EDC0000};
154 CkMagicNumber(void) :CkMagicNumber_impl(good
) {}
155 inline void check(const char *file
,int line
,void *obj
) const {
156 if (magic
!=good
) badMagicNumber(good
,file
,line
,obj
);
158 #if CMK_ERROR_CHECKING
159 # define CK_MAGICNUMBER_CHECK magic.check(__FILE__,__LINE__,this);
161 # define CK_MAGICNUMBER_CHECK /*empty, for speed*/
166 * The "data" class passed to a CkLocIterator, which refers to a bound
167 * glob of array elements.
168 * This is a transient class-- do not attempt to store it or send
169 * it across processors.
177 CkLocation(CkLocMgr
*mgr_
, CkLocRec
*rec_
);
179 /// Find our location manager
180 inline CkLocMgr
*getManager(void) const {return mgr
;}
182 /// Find the local record that refers to this element
183 inline CkLocRec
*getLocalRecord(void) const {return rec
;}
185 /// Look up and return the array index of this location.
186 const CkArrayIndex
&getIndex(void) const;
187 CmiUInt8
getID() const;
191 /// Pup all the array elements at this location.
192 void pup(PUP::er
&p
);
196 * This interface describes the destination for an iterator over
197 * the locations in an array.
199 class CkLocIterator
{
201 virtual ~CkLocIterator();
203 /// This location is part of the calling location manager.
204 virtual void addLocation(CkLocation
&loc
) =0;
207 enum CkElementCreation_t
{
208 CkElementCreation_migrate
=2, // Create object for normal migration arrival
209 CkElementCreation_resume
=3, // Create object after checkpoint
210 CkElementCreation_restore
=4 // Create object after checkpoint, skip listeners
214 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
215 typedef void (*CkLocFn
)(CkArray
*,void *,CkLocRec
*,CkArrayIndex
*);
220 * A group which manages the location of an indexed set of
221 * migratable objects. Knows about insertions, deletions,
222 * home processors, migration, and message forwarding.
224 class CkLocMgr
: public IrrGroup
{
225 CkMagicNumber
<CkMigratable
> magic
; //To detect heap corruption
227 CkLocMgr(CkArrayOptions opts
);
228 CkLocMgr(CkMigrateMessage
*m
);
231 inline bool isLocMgr(void) { return true; }
232 CkGroupID
&getGroupID(void) {return thisgroup
;}
233 inline CProxy_CkLocMgr
&getProxy(void) {return thisProxy
;}
234 inline CProxyElement_CkLocMgr
&getLocalProxy(void) {return thislocalproxy
;}
236 //Interface used by external users:
238 inline int homePe(const CkArrayIndex
&idx
) const {return map
->homePe(mapHandle
,idx
);}
239 inline int homePe(const CmiUInt8 id
) const {
241 return homePe(compressor
->decompress(id
));
245 inline int procNum(const CkArrayIndex
&idx
) const {return map
->procNum(mapHandle
,idx
);}
246 inline bool isHome (const CkArrayIndex
&idx
) const {return (bool)(homePe(idx
)==CkMyPe());}
247 int whichPE(const CkArrayIndex
&idx
) const;
248 int whichPE(const CmiUInt8 id
) const;
249 /// Return the "last-known" location (returns a processor number)
250 int lastKnown(const CkArrayIndex
&idx
);
251 int lastKnown(CmiUInt8 id
);
253 inline CmiUInt8
lookupID(const CkArrayIndex
&idx
) const {
255 return compressor
->compress(idx
);
257 CkLocMgr::IdxIdMap::const_iterator itr
= idx2id
.find(idx
);
258 CkAssert(itr
!= idx2id
.end());
263 inline bool lookupID(const CkArrayIndex
&idx
, CmiUInt8
& id
) const {
265 id
= compressor
->compress(idx
);
268 CkLocMgr::IdxIdMap::const_iterator itr
= idx2id
.find(idx
);
269 if (itr
== idx2id
.end()) {
278 //Look up array element in hash table. Index out-of-bounds if not found.
279 CkLocRec
*elementRec(const CkArrayIndex
&idx
);
280 //Look up array element in hash table. Return NULL if not there.
281 CkLocRec
*elementNrec(const CmiUInt8 id
);
283 /// Return true if this array element lives on another processor
284 bool isRemote(const CkArrayIndex
&idx
,int *onPe
) const;
286 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
287 //mark the duringMigration variable .. used for parallel restart
288 void setDuringMigration(bool _duringMigration
);
291 void setDuringDestruction(bool _duringDestruction
);
293 /// Pass each of our locations (each separate array index) to this destination.
294 void iterate(CkLocIterator
&dest
);
296 /// Insert and unpack this array element from this checkpoint (e.g., from CkLocation::pup), skip listeners
297 void restore(const CkArrayIndex
&idx
, CmiUInt8 id
, PUP::er
&p
);
298 /// Insert and unpack this array element from this checkpoint (e.g., from CkLocation::pup)
299 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
300 void resume(const CkArrayIndex
&idx
, CmiUInt8 id
, PUP::er
&p
, bool create
, int dummy
=0);
302 void resume(const CkArrayIndex
&idx
, CmiUInt8 id
, PUP::er
&p
, bool notify
=true,bool=false);
305 //Interface used by array manager and proxies
306 /// Add a new local array manager to our list.
307 void addManager(CkArrayID aid
,CkArray
*mgr
);
308 void deleteManager(CkArrayID aid
, CkArray
*mgr
);
310 /// Populate this array with initial elements
311 void populateInitial(CkArrayOptions
& options
,void *initMsg
,CkArray
*mgr
)
312 { map
->populateInitial(mapHandle
,options
,initMsg
,mgr
); }
314 /// Add a new local array element, calling element's constructor
315 /// Returns true if the element was successfully added; false if the element migrated away or deleted itself.
316 bool addElement(CkArrayID aid
,const CkArrayIndex
&idx
, CkMigratable
*elt
,int ctorIdx
,void *ctorMsg
);
318 ///Done inserting elements for now
319 void doneInserting(void);
320 void startInserting(void);
322 // How many elements of each associated array are local to this PE?
323 // If this returns n, and there are k associated arrays, that
324 // means k*n elements are living here
325 unsigned int numLocalElements();
327 ///Deliver message to this element:
328 //int deliverMsg(CkMessage *m, CkArrayID mgr, const CkArrayIndex &idx, CkDeliver_t type, int opts = 0);
329 int deliverMsg(CkArrayMessage
*m
, CkArrayID mgr
, CmiUInt8 id
, const CkArrayIndex
* idx
, CkDeliver_t type
, int opts
= 0);
331 void sendMsg(CkArrayMessage
*msg
, CkArrayID mgr
, const CkArrayIndex
&idx
, CkDeliver_t type
, int opts
);
334 ///This index now lives on the given processor-- update local records
335 void inform(const CkArrayIndex
&idx
, CmiUInt8 id
, int nowOnPe
);
336 void inform(CmiUInt8 id
, int nowOnPe
);
338 ///This index now lives on the given processor-- tell the home processor
339 void informHome(const CkArrayIndex
&idx
,int nowOnPe
);
341 ///This message took several hops to reach us-- fix it
342 void multiHop(CkArrayMessage
*m
);
344 //Interface used by CkLocRec
346 //Migrate us to another processor
347 void emigrate(CkLocRec
*rec
,int toPe
);
348 void informLBPeriod(CkLocRec
*rec
, int lb_ideal_period
);
349 void metaLBCallLB(CkLocRec
*rec
);
352 LBDatabase
*getLBDB(void) const { return the_lbdb
; }
353 MetaBalancer
*getMetaBalancer(void) const { return the_metalb
;}
354 const LDOMHandle
&getOMHandle(void) const { return myLBHandle
; }
357 //This index will no longer be used-- delete the associated elements
358 void reclaim(const CkArrayIndex
&idx
);
360 bool demandCreateElement(CkArrayMessage
*msg
, const CkArrayIndex
&idx
, int onPe
, CkDeliver_t type
);
361 void demandCreateElement(const CkArrayIndex
&idx
, int chareType
, int onPe
, CkArrayID mgr
);
364 void immigrate(CkArrayElementMigrateMessage
*msg
);
365 void requestLocation(const CkArrayIndex
&idx
, int peToTell
, bool suppressIfHere
, int ifNonExistent
, int chareType
, CkArrayID mgr
);
366 void requestLocation(CmiUInt8 id
, int peToTell
, bool suppressIfHere
);
367 void updateLocation(const CkArrayIndex
&idx
, CmiUInt8 id
, int nowOnPe
);
368 void updateLocation(CmiUInt8 id
, int nowOnPe
);
369 void reclaimRemote(const CkArrayIndex
&idx
,int deletedOnPe
);
370 void dummyAtSync(void);
372 /// return a list of migratables in this local record
373 void migratableList(CkLocRec
*rec
, CkVec
<CkMigratable
*> &list
);
375 void flushAllRecs(void);
376 void flushLocalRecs(void);
377 void pup(PUP::er
&p
);
381 //Internal interface:
382 //Add given element array record at idx, replacing the existing record
383 void insertRec(CkLocRec
*rec
,const CmiUInt8
&id
);
385 //Remove this entry from the table (does not delete record)
386 void removeFromTable(const CmiUInt8 id
);
388 friend class CkLocation
; //so it can call pupElementsFor
389 friend class ArrayElement
;
390 friend class MemElementPacker
;
391 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
392 void pupElementsFor(PUP::er
&p
,CkLocRec
*rec
,
393 CkElementCreation_t type
, bool create
=true, int dummy
=0);
395 void pupElementsFor(PUP::er
&p
,CkLocRec
*rec
,
396 CkElementCreation_t type
,bool rebuild
= false);
399 /// Call this member function on each element of this location:
400 typedef void (CkMigratable::* CkMigratable_voidfn_t
)(void);
402 typedef void (CkMigratable::* CkMigratable_voidfn_arg_t
)(void*);
403 void callMethod(CkLocRec
*rec
,CkMigratable_voidfn_arg_t fn
, void*);
405 void deliverUnknown(CkArrayMessage
*msg
, const CkArrayIndex
* idx
, CkDeliver_t type
, int opts
);
406 typedef std::map
<CmiUInt8
, std::vector
<CkArrayMessage
*> > MsgBuffer
;
407 /// Deliver any buffered msgs to a newly created array element
408 void deliverAnyBufferedMsgs(CmiUInt8
, MsgBuffer
&buffer
);
410 /// Create a new local record at this array index.
411 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
412 CkLocRec
*createLocal(const CkArrayIndex
&idx
,
413 bool forMigration
, bool ignoreArrival
,
414 bool notifyHome
,int dummy
=0);
416 CkLocRec
*createLocal(const CkArrayIndex
&idx
,
417 bool forMigration
, bool ignoreArrival
,
421 std::map
<CkArrayIndex
, std::vector
<std::pair
<int, bool> > > bufferedLocationRequests
;
424 void callMethod(CkLocRec
*rec
,CkMigratable_voidfn_t fn
);
427 //Map array ID to manager and elements
428 std::map
<CkArrayID
, CkArray
*> managers
;
429 // Map object ID to location
430 std::map
<CmiUInt8
, int> id2pe
;
432 typedef std::map
<CkArrayIndex
, CmiUInt8
> IdxIdMap
;
434 // Map array element index to object ID
436 // Next ID to assign newly constructed array elements
438 CmiUInt8
getNewObjectID(const CkArrayIndex
&idx
);
440 /// Map idx to undelivered msgs
441 /// @todo: We should not buffer msgs for uncreated array elements forever.
442 /// After some timeout or other policy, we should throw errors or warnings
443 /// or at least report and discard any msgs addressed to uncreated array elements
444 MsgBuffer bufferedMsgs
;
445 MsgBuffer bufferedRemoteMsgs
;
446 MsgBuffer bufferedShadowElemMsgs
;
448 std::map
<CkArrayIndex
, std::vector
<CkArrayMessage
*> > bufferedIndexMsgs
;
450 bool addElementToRec(CkLocRec
*rec
,CkArray
*m
,
451 CkMigratable
*elt
,int ctorIdx
,void *ctorMsg
);
453 CProxy_CkLocMgr thisProxy
;
454 CProxyElement_CkLocMgr thislocalproxy
;
456 /// This flag is set while we delete an old copy of a migrator
457 bool duringMigration
;
458 /// This flag is set while we are deleting location manager
459 bool duringDestruction
;
462 /// The core of the location manager: map array index to element representative
463 CkHashtableT
<CkHashtableAdaptorT
<CmiUInt8
>, CkLocRec
*> hash
;
464 CmiImmediateLockType hashImmLock
;
474 ck::ArrayIndexCompressor
*compressor
;
476 void checkInBounds(const CkArrayIndex
&idx
);
479 LBDatabase
*the_lbdb
;
480 MetaBalancer
*the_metalb
;
481 LDBarrierClient dummyBarrierHandle
;
482 static void staticDummyResumeFromSync(void* data
);
483 void dummyResumeFromSync(void);
484 static void staticRecvAtSync(void* data
);
485 void recvAtSync(void);
486 LDOMHandle myLBHandle
;
487 LDBarrierReceiver lbBarrierReceiver
;
490 void initLB(CkGroupID lbdbID
, CkGroupID metalbID
);
492 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
494 void callForAllRecords(CkLocFn
,CkArray
*,void *);
495 int homeElementCount
;
504 /// check the command line arguments to determine if we can use ConfigurableRRMap
505 bool haveConfigurableRRMap();
512 #endif /*def(thisHeader)*/