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 "ckmemcheckpoint.h"
00031
00032
00033
00034
00035 extern void _registerCkArray(void);
00036 CpvExtern (int ,serializer);
00037
00038 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00039 #define _MLOG_BCAST_TREE_ 1
00040 #define _MLOG_BCAST_BFACTOR_ 8
00041 #endif
00042
00046 extern bool _isAnytimeMigration;
00047
00051 extern bool _isStaticInsertion;
00052
00057 extern bool _isNotifyChildInRed;
00058
00066
00067 typedef int CkIndex1D;
00068 typedef struct {int x,y;} CkIndex2D;
00069 inline void operator|(PUP::er &p,CkIndex2D &i) {p(i.x); p(i.y);}
00070 typedef struct {int x,y,z;} CkIndex3D;
00071 inline void operator|(PUP::er &p,CkIndex3D &i) {p(i.x); p(i.y); p(i.z);}
00072 typedef struct {short int w,x,y,z;} CkIndex4D;
00073 inline void operator|(PUP::er &p,CkIndex4D &i) {p(i.w); p(i.x); p(i.y); p(i.z);}
00074 typedef struct {short int v,w,x,y,z;} CkIndex5D;
00075 inline void operator|(PUP::er &p,CkIndex5D &i) {p(i.v); p(i.w); p(i.x); p(i.y); p(i.z);}
00076 typedef struct {short int x1,y1,z1,x2,y2,z2;} CkIndex6D;
00077 inline void operator|(PUP::er &p,CkIndex6D &i) {p(i.x1); p(i.y1); p(i.z1); p(i.x2); p(i.y2); p(i.z2);}
00078 typedef struct {int data[CK_ARRAYINDEX_MAXLEN];} CkIndexMax;
00079 inline void operator|(PUP::er &p,CkIndexMax &i) {
00080 for (int j=0;j<CK_ARRAYINDEX_MAXLEN;j++) {
00081 p|i.data[j];
00082 }
00083 }
00084
00086 class CkArrayIndex1D : public CkArrayIndex {
00087 public:
00088 CkArrayIndex1D() {}
00089
00090 CkArrayIndex1D(int i0) { init(1, 1, i0); }
00091 };
00092 class CkArrayIndex2D : public CkArrayIndex {
00093 public:
00094 CkArrayIndex2D() {}
00095 CkArrayIndex2D(int i0,int i1) { init(2, 2, i0, i1); }
00096 CkArrayIndex2D(CkIndex2D idx) { init(2, 2, idx.x, idx.y); }
00097 };
00098 class CkArrayIndex3D : public CkArrayIndex {
00099 public:
00100 CkArrayIndex3D() {}
00101 CkArrayIndex3D(int i0,int i1,int i2) { init(3, 3, i0, i1, i2); }
00102 CkArrayIndex3D(CkIndex3D idx) { init(3, 3, idx.x, idx.y, idx.z); }
00103 };
00104 class CkArrayIndex4D : public CkArrayIndex {
00105 public:
00106 CkArrayIndex4D(){}
00107 CkArrayIndex4D(short int i0,short int i1,short int i2,short int i3) { init(2, 4, i0, i1, i2, i3); }
00108 CkArrayIndex4D(CkIndex4D idx) { init(2, 4, idx.w, idx.x, idx.y, idx.z); }
00109 };
00110 class CkArrayIndex5D : public CkArrayIndex {
00111 public:
00112 CkArrayIndex5D() {}
00113 CkArrayIndex5D(short int i0,short int i1,short int i2,short int i3,short int i4) { init(3, 5, i0, i1, i2, i3, i4); }
00114 CkArrayIndex5D(CkIndex5D idx) { init(3, 5, idx.v, idx.w, idx.x, idx.y, idx.z); }
00115 };
00116 class CkArrayIndex6D : public CkArrayIndex {
00117 public:
00118 CkArrayIndex6D(){}
00119 CkArrayIndex6D(short int i0,short int i1,short int i2,short int i3,short int i4,short int i5) { init(3, 6, i0, i1, i2, i3, i4, i5); }
00120 CkArrayIndex6D(CkIndex6D idx) { init(3, 6, idx.x1, idx.y1, idx.z1, idx.x2, idx.y2, idx.z2); }
00121 };
00122
00126 template <class object>
00127 class CkArrayIndexT : public CkArrayIndex {
00128 public:
00129 object obj;
00130 CkArrayIndexT(const object &srcObj) {obj=srcObj;
00131 nInts=sizeof(obj)/sizeof(int);
00132 dimension=0; }
00133 };
00134
00135
00139 class ArrayElement;
00140 class CkArrayListener : public PUP::able {
00141 int nInts;
00142 int dataOffset;
00143 public:
00144 CkArrayListener(int nInts_);
00145 CkArrayListener(CkMigrateMessage *m);
00146 virtual void pup(PUP::er &p);
00147 PUPable_abstract(CkArrayListener)
00148
00149
00150 virtual void ckRegister(CkArray *arrMgr,int dataOffset_);
00151
00153 inline int ckGetLen(void) const {return nInts;}
00155 inline int ckGetOffset(void) const {return dataOffset;}
00157 inline int *ckGetData(ArrayElement *el) const;
00158
00160 virtual void ckBeginInserting(void) {}
00162 virtual void ckEndInserting(void) {}
00163
00164
00165
00167 virtual void ckElementStamp(int *eltInfo) {}
00169 virtual void ckElementCreating(ArrayElement *elt) {}
00172 virtual CmiBool ckElementCreated(ArrayElement *elt)
00173 { return CmiTrue; }
00174
00176 virtual void ckElementDied(ArrayElement *elt) {}
00177
00178
00180 virtual void ckElementLeaving(ArrayElement *elt) {}
00181
00184 virtual CmiBool ckElementArriving(ArrayElement *elt)
00185 { return CmiTrue; }
00186
00188 virtual void flushState() {}
00189 };
00190
00193
00194 class CkVerboseListener : public CkArrayListener {
00195 public:
00196 CkVerboseListener(void);
00197 CkVerboseListener(CkMigrateMessage *m):CkArrayListener(m) {}
00198 PUPable_decl(CkVerboseListener);
00199
00200 virtual void ckRegister(CkArray *arrMgr,int dataOffset_);
00201 virtual void ckBeginInserting(void);
00202 virtual void ckEndInserting(void);
00203
00204 virtual void ckElementStamp(int *eltInfo);
00205 virtual void ckElementCreating(ArrayElement *elt);
00206 virtual CmiBool ckElementCreated(ArrayElement *elt);
00207 virtual void ckElementDied(ArrayElement *elt);
00208
00209 virtual void ckElementLeaving(ArrayElement *elt);
00210 virtual CmiBool ckElementArriving(ArrayElement *elt);
00211 };
00212
00217
00219 class CkArrayOptions {
00220 friend class CkArray;
00221
00222 CkArrayIndex numInitial;
00223 CkGroupID map;
00224 CkGroupID locMgr;
00225 CkPupAblePtrVec<CkArrayListener> arrayListeners;
00226 CkCallback reductionClient;
00227 bool anytimeMigration;
00228 bool disableNotifyChildInRed;
00229 bool staticInsertion;
00230 bool broadcastViaScheduler;
00231
00233 void init();
00234
00235 public:
00236
00237 CkArrayOptions(void);
00238 CkArrayOptions(int ni1_);
00239 CkArrayOptions(int ni1_, int ni2_);
00240 CkArrayOptions(int ni1_, int ni2_, int ni3);
00241
00242
00243
00244
00250
00251 CkArrayOptions &setNumInitial(int ni)
00252 {numInitial=CkArrayIndex1D(ni); return *this;}
00254 CkArrayOptions &setNumInitial(int ni1, int ni2)
00255 {numInitial=CkArrayIndex2D(ni1, ni2); return *this;}
00257 CkArrayOptions &setNumInitial(int ni1, int ni2, int ni3)
00258 {numInitial=CkArrayIndex3D(ni1 ,ni2, ni3); return *this;}
00259
00261
00262
00264
00265
00267
00268
00269
00270
00272 CkArrayOptions &setMap(const CkGroupID &m)
00273 {map=m; return *this;}
00274
00276 CkArrayOptions &bindTo(const CkArrayID &b);
00277
00279 CkArrayOptions &setLocationManager(const CkGroupID &l)
00280 {locMgr=l; return *this;}
00281
00283 CkArrayOptions &addListener(CkArrayListener *listener);
00284
00285 CkArrayOptions &setAnytimeMigration(bool b) { anytimeMigration = b; return *this; }
00286 CkArrayOptions &setStaticInsertion(bool b);
00287 CkArrayOptions &setBroadcastViaScheduler(bool b) { broadcastViaScheduler = b; return *this; }
00288 CkArrayOptions &setReductionClient(CkCallback cb)
00289 { reductionClient = cb; return *this; }
00290
00291
00292 const CkArrayIndex &getNumInitial(void) const {return numInitial;}
00293 const CkGroupID &getMap(void) const {return map;}
00294 const CkGroupID &getLocationManager(void) const {return locMgr;}
00295 int getListeners(void) const {return arrayListeners.size();}
00296 CkArrayListener *getListener(int listenerNum) {
00297 CkArrayListener *ret=arrayListeners[listenerNum];
00298 arrayListeners[listenerNum]=NULL;
00299 return ret;
00300 }
00301
00302 void pup(PUP::er &p);
00303 };
00304 PUPmarshall(CkArrayOptions)
00305
00306
00307
00308
00309 class ArrayBase { };
00310 class ArrayElement;
00311
00317 class CProxy_ArrayBase :public CProxy {
00318 private:
00319 CkArrayID _aid;
00320 public:
00321 CProxy_ArrayBase() {
00322 #if CMK_ERROR_CHECKING
00323 _aid.setZero();
00324 #endif
00325 }
00326 CProxy_ArrayBase(const CkArrayID &aid,CK_DELCTOR_PARAM)
00327 :CProxy(CK_DELCTOR_ARGS), _aid(aid) { }
00328 CProxy_ArrayBase(const CkArrayID &aid)
00329 :CProxy(), _aid(aid) { }
00330 CProxy_ArrayBase(const ArrayElement *e);
00331
00332 #if CMK_ERROR_CHECKING
00333 inline void ckCheck(void) const{
00334 if (_aid.isZero())
00335 CkAbort("Error! This array proxy has not been initialized!");
00336 }
00337 #else
00338 inline void ckCheck(void) const {}
00339 #endif
00340
00341 static CkArrayID ckCreateEmptyArray(void);
00342 static CkArrayID ckCreateArray(CkArrayMessage *m,int ctor,const CkArrayOptions &opts);
00343
00344 void ckInsertIdx(CkArrayMessage *m,int ctor,int onPe,const CkArrayIndex &idx);
00345 void ckBroadcast(CkArrayMessage *m, int ep, int opts=0) const;
00346 CkArrayID ckGetArrayID(void) const { return _aid; }
00347 CkArray *ckLocalBranch(void) const { return _aid.ckLocalBranch(); }
00348 CkLocMgr *ckLocMgr(void) const;
00349 inline operator CkArrayID () const {return ckGetArrayID();}
00350 unsigned int numLocalElements() const { return ckLocMgr()->numLocalElements(); }
00351
00352 void doneInserting(void);
00353
00354 CK_REDUCTION_CLIENT_DECL
00355
00356 void pup(PUP::er &p);
00357 };
00358 PUPmarshall(CProxy_ArrayBase)
00359
00360 class CProxyElement_ArrayBase:public CProxy_ArrayBase {
00361 private:
00362 CkArrayIndex _idx;
00363 public:
00364 CProxyElement_ArrayBase() { }
00365 CProxyElement_ArrayBase(const CkArrayID &aid,
00366 const CkArrayIndex &idx,CK_DELCTOR_PARAM)
00367 :CProxy_ArrayBase(aid,CK_DELCTOR_ARGS), _idx(idx) { }
00368 CProxyElement_ArrayBase(const CkArrayID &aid, const CkArrayIndex &idx)
00369 :CProxy_ArrayBase(aid), _idx(idx) { }
00370 CProxyElement_ArrayBase(const ArrayElement *e);
00371
00372 void ckInsert(CkArrayMessage *m,int ctor,int onPe);
00373 void ckSend(CkArrayMessage *m, int ep, int opts = 0) const;
00374
00375 static void ckSendWrapper(CkArrayID _aid, CkArrayIndex _idx, void *m, int ep, int opts);
00376 void *ckSendSync(CkArrayMessage *m, int ep) const;
00377 const CkArrayIndex &ckGetIndex() const {return _idx;}
00378
00379 ArrayElement *ckLocal(void) const;
00380 void pup(PUP::er &p);
00381 };
00382 PUPmarshall(CProxyElement_ArrayBase)
00383
00384 class CProxySection_ArrayBase:public CProxy_ArrayBase {
00385 private:
00386 int _nsid;
00387 CkSectionID *_sid;
00388 public:
00389 CProxySection_ArrayBase(): _nsid(0), _sid(NULL) {}
00390 CProxySection_ArrayBase(const CkArrayID &aid,
00391 const CkArrayIndex *elems, const int nElems)
00392 :CProxy_ArrayBase(aid), _nsid(1) { _sid = new CkSectionID(aid, elems, nElems); }
00393 CProxySection_ArrayBase(const CkArrayID &aid,
00394 const CkArrayIndex *elems, const int nElems, CK_DELCTOR_PARAM)
00395 :CProxy_ArrayBase(aid,CK_DELCTOR_ARGS), _nsid(1) { _sid = new CkSectionID(aid, elems, nElems); }
00396 CProxySection_ArrayBase(const CkSectionID &sid)
00397 :CProxy_ArrayBase(sid._cookie.get_aid()), _nsid(1) { _sid = new CkSectionID(sid); }
00398 CProxySection_ArrayBase(const CkSectionID &sid, CK_DELCTOR_PARAM)
00399 :CProxy_ArrayBase(sid._cookie.get_aid(), CK_DELCTOR_ARGS), _nsid(1) { _sid = new CkSectionID(sid); }
00400 CProxySection_ArrayBase(const CProxySection_ArrayBase &cs)
00401 :CProxy_ArrayBase(cs.ckGetArrayID()), _nsid(cs._nsid) {
00402 if (_nsid == 1) _sid = new CkSectionID(cs.ckGetArrayID(), cs.ckGetArrayElements(), cs.ckGetNumElements());
00403 else if (_nsid > 1) {
00404 _sid = new CkSectionID[_nsid];
00405 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00406 } else _sid = NULL;
00407 }
00408 CProxySection_ArrayBase(const CProxySection_ArrayBase &cs, CK_DELCTOR_PARAM)
00409 :CProxy_ArrayBase(cs.ckGetArrayID(),CK_DELCTOR_ARGS), _nsid(cs._nsid) {
00410 if (_nsid == 1) _sid = new CkSectionID(cs.ckGetArrayID(), cs.ckGetArrayElements(), cs.ckGetNumElements());
00411 else if (_nsid > 1) {
00412 _sid = new CkSectionID[_nsid];
00413 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00414 } else _sid = NULL;
00415 }
00416 CProxySection_ArrayBase(const int n, const CkArrayID *aid, CkArrayIndex const * const *elems, const int *nElems)
00417 :CProxy_ArrayBase(aid[0]), _nsid(n) {
00418 if (_nsid == 1) _sid = new CkSectionID(aid[0], elems[0], nElems[0]);
00419 else if (_nsid > 1) {
00420 _sid = new CkSectionID[n];
00421 for (int i=0; i<n; ++i) _sid[i] = CkSectionID(aid[i], elems[i], nElems[i]);
00422 } else _sid = NULL;
00423 }
00424 CProxySection_ArrayBase(const int n, const CkArrayID *aid, CkArrayIndex const * const *elems, const int *nElems,CK_DELCTOR_PARAM)
00425 :CProxy_ArrayBase(aid[0],CK_DELCTOR_ARGS), _nsid(n) {
00426 if (_nsid == 1) _sid = new CkSectionID(aid[0], elems[0], nElems[0]);
00427 else if (_nsid > 1) {
00428 _sid = new CkSectionID[n];
00429 for (int i=0; i<n; ++i) _sid[i] = CkSectionID(aid[i], elems[i], nElems[i]);
00430 } else _sid = NULL;
00431 }
00432
00433 ~CProxySection_ArrayBase() {
00434 if (_nsid == 1) delete _sid;
00435 else if (_nsid > 1) delete[] _sid;
00436 }
00437
00438 CProxySection_ArrayBase &operator=(const CProxySection_ArrayBase &cs) {
00439 CProxy_ArrayBase::operator=(cs);
00440 _nsid = cs._nsid;
00441 if (_nsid == 1) _sid = new CkSectionID(*cs._sid);
00442 else if (_nsid > 1) {
00443 _sid = new CkSectionID[_nsid];
00444 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00445 } else _sid = NULL;
00446 return *this;
00447 }
00448
00449 void ckSectionDelegate(CkDelegateMgr *d)
00450 { ckDelegate(d); d->initDelegateMgr(this); }
00451
00452 void ckSend(CkArrayMessage *m, int ep, int opts = 0) ;
00453
00454
00455 inline int ckGetNumSubSections() const { return _nsid; }
00456 inline CkSectionInfo &ckGetSectionInfo() {return _sid->_cookie;}
00457 inline CkSectionID *ckGetSectionIDs() {return _sid;}
00458 inline CkSectionID &ckGetSectionID() {return _sid[0];}
00459 inline CkSectionID &ckGetSectionID(int i) {return _sid[i];}
00460 inline CkArrayID ckGetArrayIDn(int i) const {return _sid[i]._cookie.get_aid();}
00461 inline CkArrayIndex *ckGetArrayElements() const {return _sid[0]._elems;}
00462 inline CkArrayIndex *ckGetArrayElements(int i) const {return _sid[i]._elems;}
00463 inline int ckGetNumElements() const { return _sid[0]._nElems; }
00464 inline int ckGetNumElements(int i) const { return _sid[i]._nElems; }
00465 void pup(PUP::er &p);
00466 };
00467 PUPmarshall(CProxySection_ArrayBase)
00468
00469
00470 void CkSendMsgArray(int entryIndex, void *msg, CkArrayID aID, const CkArrayIndex &idx, int opts=0);
00471 void CkSendMsgArrayInline(int entryIndex, void *msg, CkArrayID aID, const CkArrayIndex &idx, int opts=0);
00472 void CkBroadcastMsgArray(int entryIndex, void *msg, CkArrayID aID, int opts=0);
00473 void CkBroadcastMsgSection(int entryIndex, void *msg, CkSectionID sID, int opts= 0);
00474
00481 class ArrayElement : public CkMigratable
00482 {
00483 friend class CkArray;
00484 friend class CkArrayListener;
00485 int numInitialElements;
00486 void initBasics(void);
00487 #ifdef _PIPELINED_ALLREDUCE_
00488 AllreduceMgr * allredMgr;
00489 #endif
00490 public:
00491 ArrayElement(void);
00492 ArrayElement(CkMigrateMessage *m);
00493 virtual ~ArrayElement();
00494
00496 virtual void pup(PUP::er &p);
00497
00498
00500 virtual void ckAboutToMigrate(void);
00501 virtual void ckJustMigrated(void);
00502
00503 virtual void ckJustRestored(void);
00504
00505 virtual void ckDestroy(void);
00506 virtual char *ckDebugChareName(void);
00507 virtual int ckDebugChareID(char*, int);
00508
00510 inline void migrateMe(int toPe) {ckMigrate(toPe);}
00511
00512 #ifdef _PIPELINED_ALLREDUCE_
00513 void contribute2(CkArrayIndex myIndex, int dataSize,const void *data,CkReduction::reducerType type,
00514 const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00515 void contribute2(int dataSize,const void *data,CkReduction::reducerType type,
00516 CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00517 void contribute2(int dataSize,const void *data,CkReduction::reducerType type,
00518 const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00519 void contribute2(CkReductionMsg *msg);
00520 void contribute2(const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00521 void contribute2(CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1);
00522 #else
00523 CK_REDUCTION_CONTRIBUTE_METHODS_DECL
00524 #endif
00525
00526 inline void defrag(CkReductionMsg* msg);
00527 inline const CkArrayID &ckGetArrayID(void) const {return thisArrayID;}
00528
00529 inline int ckGetArraySize(void) const { return numInitialElements; }
00530 protected:
00531 CkArray *thisArray;
00532 CkArrayID thisArrayID;
00533
00534
00535 virtual void CkAbort(const char *str) const;
00536
00537 private:
00538
00539 #ifndef CK_ARRAYLISTENER_MAXLEN
00540 # define CK_ARRAYLISTENER_MAXLEN 3
00541 #endif
00542 int listenerData[CK_ARRAYLISTENER_MAXLEN];
00543
00544 #if CMK_MEM_CHECKPOINT
00545 friend class CkMemCheckPT;
00546 protected:
00547 int budPEs[2];
00548 private:
00549 void init_checkpt();
00550 #endif
00551 public:
00552 void inmem_checkpoint(CkArrayCheckPTReqMessage *m);
00553 void recvBroadcast(CkMessage *);
00554
00555 #if CMK_GRID_QUEUE_AVAILABLE
00556 public:
00557 int grid_queue_interval;
00558 int grid_queue_threshold;
00559 int msg_count;
00560 int msg_count_grid;
00561 int border_flag;
00562 #endif
00563 };
00564 inline int *CkArrayListener::ckGetData(ArrayElement *el) const
00565 {return &el->listenerData[dataOffset];}
00566
00570 template <class T>
00571 class ArrayElementT : public ArrayElement
00572 {
00573 public:
00574 ArrayElementT(void): thisIndex(*(const T *)thisIndexMax.data()) {
00575 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00576 mlogData->objID.data.array.idx=thisIndexMax;
00577 #endif
00578 }
00579 #ifdef _PIPELINED_ALLREDUCE_
00580 void contribute(int dataSize,const void *data,CkReduction::reducerType type,
00581 CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1)
00582 {
00583 contribute2( dataSize,data, type, userFlag);
00584
00585 }
00586 void contribute(int dataSize,const void *data,CkReduction::reducerType type,
00587 const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1)
00588 {
00589 contribute2((CkArrayIndex)(thisIndex) ,dataSize, data, type, cb, userFlag);
00590 }
00591 void contribute(CkReductionMsg *msg)
00592 {
00593 contribute2(msg);
00594 }
00595 void contribute(const CkCallback &cb,CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1)
00596 {
00597 contribute2(cb ,userFlag);
00598 }
00599 void contribute(CMK_REFNUM_TYPE userFlag=(CMK_REFNUM_TYPE)-1)
00600 {
00601 contribute2(userFlag);
00602 }
00603 #endif
00604 ArrayElementT(CkMigrateMessage *msg)
00605 :ArrayElement(msg),
00606 thisIndex(*(const T *)thisIndexMax.data()) {}
00607
00608 const T thisIndex;
00609 };
00610
00611 typedef ArrayElementT<CkIndex1D> ArrayElement1D;
00612 typedef ArrayElementT<CkIndex2D> ArrayElement2D;
00613 typedef ArrayElementT<CkIndex3D> ArrayElement3D;
00614 typedef ArrayElementT<CkIndex4D> ArrayElement4D;
00615 typedef ArrayElementT<CkIndex5D> ArrayElement5D;
00616 typedef ArrayElementT<CkIndex6D> ArrayElement6D;
00617 typedef ArrayElementT<CkIndexMax> ArrayElementMax;
00618
00622
00627
00628 #include "CkArray.decl.h"
00629 #include "CkArrayReductionMgr.decl.h"
00630
00631 class CkArrayBroadcaster;
00632 class CkArrayReducer;
00633
00634 void _ckArrayInit(void);
00635
00636
00637
00638 class CkArray : public CkReductionMgr, public CkArrMgr {
00639 friend class ArrayElement;
00640 friend class CProxy_ArrayBase;
00641 friend class CProxyElement_ArrayBase;
00642
00643 CkMagicNumber<ArrayElement> magic;
00644 CkLocMgr *locMgr;
00645 CkGroupID locMgrID;
00646 CProxy_CkArray thisProxy;
00647 typedef CkMigratableListT<ArrayElement> ArrayElementList;
00648 ArrayElementList *elements;
00649 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00650 int *children;
00651 int numChildren;
00652 #endif
00653 private:
00654 bool stableLocations;
00655
00656 public:
00657
00658 CkArray(CkArrayOptions &c,CkMarshalledMessage &initMsg,CkNodeGroupID nodereductionProxy);
00659 CkArray(CkMigrateMessage *m);
00660 CkGroupID &getGroupID(void) {return thisgroup;}
00661
00662
00663 inline CkLocMgr *getLocMgr(void) {return locMgr;}
00664 inline const CkArrayIndex &getNumInitial(void) const {return numInitial;}
00665 inline int homePe(const CkArrayIndex &idx) const {return locMgr->homePe(idx);}
00666 inline int procNum(const CkArrayIndex &idx) const {return locMgr->procNum(idx);}
00667
00670 inline int lastKnown(const CkArrayIndex &idx) const
00671 {return locMgr->lastKnown(idx);}
00674 inline int deliver(CkMessage *m,CkDeliver_t type,int opts=0)
00675 {return locMgr->deliver(m,type,opts);}
00677 inline ArrayElement *lookup(const CkArrayIndex &index)
00678 {return (ArrayElement *)locMgr->lookup(index,thisgroup);}
00679
00680
00682 virtual CkMigratable *allocateMigrated(int elChareType,const CkArrayIndex &idx,
00683 CkElementCreation_t type);
00684
00686 void prepareCtorMsg(CkMessage *m,int &onPe,const CkArrayIndex &idx);
00687
00689 virtual void insertInitial(const CkArrayIndex &idx,void *ctorMsg,int local=1);
00690 virtual void doneInserting(void);
00691 void remoteDoneInserting(void);
00692
00694 virtual CmiBool insertElement(CkMessage *);
00695
00697 CmiBool demandCreateElement(const CkArrayIndex &idx,
00698 int onPe,int ctor,CkDeliver_t type);
00699
00701 void sendBroadcast(CkMessage *msg);
00702 void recvBroadcast(CkMessage *msg);
00703 void sendExpeditedBroadcast(CkMessage *msg);
00704 void recvExpeditedBroadcast(CkMessage *msg) { recvBroadcast(msg); }
00705 void recvBroadcastViaTree(CkMessage *msg);
00706
00707 void pup(PUP::er &p);
00708 void ckJustMigrated(void){ doneInserting(); }
00709
00710
00711
00712
00713
00714
00715 virtual CmiBool isArrMgr(void) {return CmiTrue;}
00716
00717 private:
00718 CkArrayIndex numInitial;
00719 CmiBool isInserting;
00720
00722 ArrayElement *allocate(int elChareType,const CkArrayIndex &idx,
00723 CkMessage *msg,CmiBool fromMigration);
00724
00725
00726 void springCleaning(void);
00727 static void staticSpringCleaning(void *forWhom,double curWallTime);
00728
00729
00730
00731 #define CK_ARRAYLISTENER_LOOP(listVec,inside) \
00732 do { \
00733 int lIdx,lMax=listVec.size();\
00734 for (lIdx=0;lIdx<lMax;lIdx++) { \
00735 CkArrayListener *l=listVec[lIdx];\
00736 inside;\
00737 }\
00738 } while(0)
00739
00740 CkPupAblePtrVec<CkArrayListener> listeners;
00741 int listenerDataOffset;
00742 public:
00743 void addListener(CkArrayListener *l) {
00744 l->ckRegister(this,listenerDataOffset);
00745 listenerDataOffset+=l->ckGetLen();
00746 listeners.push_back(l);
00747 if (listenerDataOffset>CK_ARRAYLISTENER_MAXLEN)
00748 CkAbort("Too much array listener data!\n"
00749 "You'll have to either use fewer array listeners, or increase the compile-time\n"
00750 "constant CK_ARRAYLISTENER_MAXLEN!\n");
00751 }
00752 private:
00753
00754 CkArrayReducer *reducer;
00755 CkArrayBroadcaster *broadcaster;
00756 public:
00757 void flushStates() { CkReductionMgr::flushStates(0); CK_ARRAYLISTENER_LOOP(listeners, l->flushState()); }
00758 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00759
00760 virtual int numberReductionMessages(){CkAssert(CkMyPe() == 0);return numInitial.data()[0];}
00761 void broadcastHomeElements(void *data,CkLocRec *rec,CkArrayIndex *index);
00762 static void staticBroadcastHomeElements(CkArray *arr,void *data,CkLocRec *rec,CkArrayIndex *index);
00763 #endif
00764
00765 };
00766
00767
00768
00771 #endif