00001 #ifndef _CHARMPP_H_
00002 #define _CHARMPP_H_
00003
00004 #include <stdlib.h>
00005 #include <memory.h>
00006 #include <vector>
00007
00008 #include "charm.h"
00009 #include "middle.h"
00010
00011 class CMessage_CkArgMsg {
00012 public: static int __idx;
00013 };
00014 #define CK_ALIGN(val,to) (((val)+(to)-1)&~((to)-1))
00015
00016 #ifdef __GNUC__
00017 #define UNUSED __attribute__ ((unused))
00018 #else
00019 #define UNUSED
00020 #endif
00021
00022 #include "pup.h"
00023 #include "cklists.h"
00024 #include "ckbitvector.h"
00025 #include "init.h"
00026 #include "debug-charm.h"
00027 #ifndef __CUDACC__
00028 #include "simd.h"
00029 #endif
00030
00031 #include <ckmessage.h>
00032
00033 PUPbytes(CkChareID)
00034 PUPbytes(CkGroupID)
00035 PUPbytes(CmiGroup)
00036
00037 CkpvExtern(size_t *, _offsets);
00038
00039 class CkArray;
00040
00041
00042 class CkMarshalledMessage {
00043 void *msg;
00044 public:
00045 CkMarshalledMessage(void): msg(NULL) {}
00046 CkMarshalledMessage(CkMessage *m): msg(m) {}
00047
00048 CkMarshalledMessage(const CkMarshalledMessage &) = delete;
00049 void operator= (const CkMarshalledMessage &) = delete;
00050 CkMarshalledMessage(CkMarshalledMessage &&rhs) { msg = rhs.msg; rhs.msg = NULL; }
00051 void operator= (CkMarshalledMessage &&rhs) { msg = rhs.msg; rhs.msg = NULL; }
00052 ~CkMarshalledMessage() { if (msg) CkFreeMsg(msg); }
00053
00054 CkMessage *getMessage(void) {
00055 void *ret = msg;
00056 msg = nullptr;
00057 return (CkMessage *)ret;
00058 }
00059 void pup(PUP::er &p) {CkPupMessage(p,&msg,1);}
00060 };
00061 PUPmarshall(CkMarshalledMessage)
00062
00063
00069 class CkEntryOptions : public CkNoncopyable {
00070 int queueingtype;
00071 int prioBits;
00072 typedef unsigned int prio_t;
00073 prio_t *prioPtr;
00074 prio_t prioStore;
00075 std::vector<CkGroupID> depGroupIDs;
00076 public:
00077 CkEntryOptions(void): queueingtype(CK_QUEUEING_FIFO), prioBits(0),
00078 prioPtr(NULL), prioStore(0) {
00079 }
00080
00081 ~CkEntryOptions() {
00082 if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
00083 queueingtype != CK_QUEUEING_ILIFO ) {
00084 delete [] prioPtr;
00085 prioBits = 0;
00086 }
00087 }
00088
00089 inline CkEntryOptions& setPriority(prio_t integerPrio) {
00090 queueingtype=CK_QUEUEING_IFIFO;
00091 prioBits=8*sizeof(integerPrio);
00092 prioPtr=&prioStore;
00093 prioStore=integerPrio;
00094 return *this;
00095 }
00096 inline CkEntryOptions& setPriority(int prioBits_,const prio_t *prioPtr_) {
00097 if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
00098 queueingtype != CK_QUEUEING_ILIFO ) {
00099 delete [] prioPtr;
00100 prioBits = 0;
00101 }
00102 queueingtype=CK_QUEUEING_BFIFO;
00103 prioBits=prioBits_;
00104 int dataLength = (prioBits + (sizeof(prio_t)*8 - 1)) /
00105 (sizeof(prio_t)*8);
00106 prioPtr = new prio_t[dataLength];
00107 memcpy((void *)prioPtr, prioPtr_, dataLength*sizeof(unsigned int));
00108 return *this;
00109 }
00110 inline CkEntryOptions& setPriority(const CkBitVector &cbv) {
00111 if ( cbv.data != NULL ) {
00112 if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
00113 queueingtype != CK_QUEUEING_ILIFO ) {
00114 delete [] prioPtr;
00115 prioBits = 0;
00116 }
00117 queueingtype=CK_QUEUEING_BFIFO;
00118 prioBits=cbv.usedBits;
00119 int dataLength = (prioBits + (sizeof(prio_t)*8 - 1)) /
00120 (sizeof(prio_t)*8);
00121 prioPtr = new prio_t[dataLength];
00122 memcpy((void *)prioPtr, cbv.data, dataLength*sizeof(prio_t));
00123 } else {
00124 queueingtype=CK_QUEUEING_BFIFO;
00125 prioBits=0;
00126 int dataLength = 1;
00127 prioPtr = new prio_t[dataLength];
00128 prioPtr[0] = 0;
00129 }
00130 return *this;
00131 }
00132
00133 inline CkEntryOptions& setQueueing(int queueingtype_) { queueingtype=queueingtype_; return *this; }
00134 inline CkEntryOptions& setGroupDepID(const CkGroupID &gid) {
00135 depGroupIDs.clear();
00136 depGroupIDs.push_back(gid);
00137 return *this;
00138 }
00139 inline CkEntryOptions& addGroupDepID(const CkGroupID &gid) { depGroupIDs.push_back(gid); return *this; }
00140
00142 inline int getQueueing(void) const {return queueingtype;}
00143 inline int getPriorityBits(void) const {return prioBits;}
00144 inline const prio_t *getPriorityPtr(void) const {return prioPtr;}
00145 inline CkGroupID getGroupDepID() const { return depGroupIDs[0]; }
00146 inline CkGroupID getGroupDepID(int index) const { return depGroupIDs[index]; }
00147 inline int getGroupDepSize() const { return sizeof(CkGroupID)*(depGroupIDs.size()); }
00148 inline int getGroupDepNum() const { return depGroupIDs.size(); }
00149 inline const CkGroupID *getGroupDepPtr() const { return &(depGroupIDs[0]); }
00150 };
00151
00152 #include "CkMarshall.decl.h"
00153
00154 class CkMarshallMsg : public CMessage_CkMarshallMsg {
00155 public:
00156 char *msgBuf;
00157 };
00158
00159
00160
00161
00162 template <class MSG>
00163 class CkMsgQ : public CkQ<MSG *> {
00164 public:
00165 CkMsgQ() = default;
00166 CkMsgQ(CkMsgQ&&) = default;
00167 CkMsgQ(const CkMsgQ&) = delete;
00168 void operator=(CkMsgQ&&) = delete;
00169 void operator=(const CkMsgQ&) = delete;
00170 ~CkMsgQ() {
00171 MSG *m;
00172 while (NULL!=(m=this->deq())) delete m;
00173 }
00174 void pup(PUP::er &p) {
00175 int l=this->length();
00176 p(l);
00177 for (int i=0;i<l;i++) {
00178 MSG *m=NULL;
00179 if (!p.isUnpacking()) m=this->deq();
00180 CkPupMessage(p,(void **)&m);
00181 this->enq(m);
00182 }
00183 }
00184 friend void operator|(PUP::er &p,CkMsgQ<MSG> &v) {v.pup(p);}
00185 };
00186
00187
00188
00189 #include "ckarrayindex.h"
00190
00191 #include "cksection.h"
00192
00193 #include "ckcallback.h"
00194
00195 #include "ckrdma.h"
00196
00197
00198 #if CMK_MULTIPLE_DELETE
00199 #define CHARM_INPLACE_NEW \
00200 void *operator new(size_t, void *ptr) { return ptr; }; \
00201 void operator delete(void*, void*) {}; \
00202 void *operator new(size_t s) { return malloc(s); } \
00203 void operator delete(void *ptr) { free(ptr); }
00204 #else
00205 #define CHARM_INPLACE_NEW \
00206 void *operator new(size_t, void *ptr) { return ptr; }; \
00207 void *operator new(size_t s) { return malloc(s); } \
00208 void operator delete(void *ptr) { free(ptr); }
00209 #endif
00210
00211
00212 #include "ckobjQ.h"
00213 #if CMK_SMP && CMK_TASKQUEUE
00214 #include "conv-taskQ.h"
00215 #endif
00216 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00217 class ChareMlogData;
00218 #endif
00219
00220 #define CHARE_MAGIC 0x201201
00221
00226 class Chare {
00227 protected:
00228 CkChareID thishandle;
00229 #if CMK_OBJECT_QUEUE_AVAILABLE
00230 CkObjectMsgQ objQ;
00231 #endif
00232 public:
00233 #if CMK_ERROR_CHECKING
00234 int magic;
00235 #endif
00236 #ifndef CMK_CHARE_USE_PTR
00237 int chareIdx;
00238 #endif
00239 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00240 ChareMlogData *mlogData;
00241 #endif
00242 Chare(CkMigrateMessage *m);
00243 Chare();
00244 virtual ~Chare();
00245
00248 virtual void pup(PUP::er &p);
00253 virtual void virtual_pup(PUP::er &p) { pup(p); }
00254 void parent_pup(PUP::er &p) {
00255 (void)p;
00256 CkAbort("Should never get here - only called in generated CBase code");
00257 }
00258
00259 inline const CkChareID &ckGetChareID(void) const {return thishandle;}
00260 inline void CkGetChareID(CkChareID *dest) const {*dest=thishandle;}
00261
00262 void CkEnableObjQ();
00263 #if CMK_OBJECT_QUEUE_AVAILABLE
00264 inline CkObjectMsgQ &CkGetObjQueue() { return objQ; }
00265 #endif
00266 CHARM_INPLACE_NEW
00268 virtual int ckGetChareType() const;
00270 virtual char *ckDebugChareName(void);
00273 virtual int ckDebugChareID(char *str, int limit);
00274 virtual void ckDebugPup(PUP::er &p);
00276 virtual void CkAddThreadListeners(CthThread tid, void *msg);
00277 #if CMK_ERROR_CHECKING
00278 inline void sanitycheck() {
00279 if (magic != CHARE_MAGIC)
00280 CmiAbort("Charm++ Fatal Error> Chare magic number does not agree, possibly due to pup functions not calling parent class.");
00281 }
00282 #endif
00283 };
00284
00285 #if CMK_HAS_IS_CONSTRUCTIBLE
00286 #include <type_traits>
00287
00288 template <typename T, bool has_migration_constructor = std::is_constructible<T, CkMigrateMessage*>::value>
00289 struct call_migration_constructor
00290 {
00291 call_migration_constructor(void* t);
00292 void operator()(void* impl_msg);
00293 };
00294
00295 template <typename T>
00296 struct call_migration_constructor<T, true>
00297 {
00298 void *impl_obj;
00299 call_migration_constructor(void* t) : impl_obj(t) { }
00300 void operator()(void* impl_msg)
00301 {
00302 new (impl_obj) T((CkMigrateMessage *)impl_msg);
00303 }
00304 };
00305
00306 template <typename T>
00307 struct call_migration_constructor<T, false>
00308 {
00309 void *impl_obj;
00310 call_migration_constructor(void* t) : impl_obj(t) { }
00311 void operator()(void* impl_msg)
00312 {
00313 CkAbort("Attempted to migrate a type that lacks a migration constructor");
00314 }
00315 };
00316 #else
00317 template <typename T>
00318 struct call_migration_constructor
00319 {
00320 void *impl_obj;
00321 call_migration_constructor(void* t) : impl_obj(t) { }
00322 void operator()(void* impl_msg)
00323 {
00324 new (impl_obj) T((CkMigrateMessage *)impl_msg);
00325 }
00326 };
00327 #endif
00328
00329
00330
00331
00332 class Group;
00333 class IrrGroup : public Chare {
00334 protected:
00335 CkGroupID thisgroup;
00336 public:
00337 IrrGroup(CkMigrateMessage *m): Chare(m) { }
00338 IrrGroup();
00339 virtual ~IrrGroup();
00340
00341 virtual void pup(PUP::er &p);
00342 virtual void ckJustMigrated(void);
00343 inline const CkGroupID &ckGetGroupID(void) const {return thisgroup;}
00344 inline CkGroupID CkGetGroupID(void) const {return thisgroup;}
00345 virtual int ckGetChareType() const;
00346 virtual char *ckDebugChareName();
00347 virtual int ckDebugChareID(char *, int);
00348
00349
00350 virtual bool isNodeGroup() { return false; };
00351 virtual bool isLocMgr(void){ return false; }
00352 virtual bool isArrMgr(void){ return false; }
00353 virtual bool isReductionMgr(void){ return false; }
00354 static bool isIrreducible(){ return true;}
00355 virtual void flushStates() {}
00356
00357 virtual void CkAddThreadListeners(CthThread tid, void *msg);
00358
00359 #if CMK_FAULT_EVAC
00360 virtual void evacuate(){};
00361 virtual void doneEvacuate(){};
00362 #endif
00363 };
00364
00365 extern void (*GroupMsgRecvExtCallback)(int, int, int, char *, int);
00366 extern void (*ChareMsgRecvExtCallback)(int, void*, int, int, char *, int);
00367
00369 class ReadOnlyExt {
00370 public:
00371 static void *ro_data;
00372 static size_t data_size;
00373
00374 static void setData(void *msg, size_t msgSize);
00375 static void _roPup(void *pup_er);
00376 };
00377
00380 class MainchareExt: public Chare {
00381 public:
00382 MainchareExt(CkArgMsg *m);
00383
00384 static void __Ctor_CkArgMsg(void *impl_msg, void *impl_obj_void) {
00385 new (impl_obj_void) MainchareExt((CkArgMsg*)impl_msg);
00386 }
00387
00388 static void __entryMethod(void *impl_msg, void *impl_obj_void) {
00389
00390 MainchareExt *obj = static_cast<MainchareExt *>(impl_obj_void);
00391 CkMarshallMsg *impl_msg_typed = (CkMarshallMsg *)impl_msg;
00392 char *impl_buf = impl_msg_typed->msgBuf;
00393 PUP::fromMem implP(impl_buf);
00394 int msgSize; implP|msgSize;
00395 int ep; implP|ep;
00396 int dcopy_start; implP|dcopy_start;
00397
00398 ChareMsgRecvExtCallback(obj->thishandle.onPE, obj->thishandle.objPtr, ep, msgSize,
00399 impl_buf+(3*sizeof(int)), dcopy_start);
00400 }
00401 };
00402
00403
00404
00405 template<typename D, typename B>
00406 class IsDerivedFrom
00407 {
00408 class No { };
00409 class Yes { No no[3]; };
00410
00411 static Yes Test( B* );
00412 static No Test( ... );
00413
00414 static void Constraints(D* p) { B* pb = p; pb = p; }
00415
00416 public:
00417 enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
00418
00419 IsDerivedFrom() { void(*p)(D*) = Constraints; }
00420 };
00421
00431 struct CBase { };
00432 template <typename T, int automatic>
00433 struct recursive_pup_impl {
00434 void operator()(T *obj, PUP::er &p);
00435 };
00436
00437 template <typename T>
00438 struct recursive_pup_impl<T, 1> {
00439 void operator()(T *obj, PUP::er &p) {
00440 obj->parent_pup(p);
00441 obj->_sdag_pup(p);
00442 obj->T::pup(p);
00443 }
00444 };
00445
00446 template <typename T>
00447 struct recursive_pup_impl<T, 0> {
00448 void operator()(T *obj, PUP::er &p) {
00449 obj->T::pup(p);
00450 }
00451 };
00452 template <typename T>
00453 void recursive_pup(T *obj, PUP::er &p) {
00454 recursive_pup_impl<T, IsDerivedFrom<T, CBase>::Is>()(obj, p);
00455 }
00456
00457
00458
00459
00460
00461 #define CBASE_MEMBERS \
00462 typedef typename CProxy_Derived::local_t local_t; \
00463 typedef typename CProxy_Derived::index_t index_t; \
00464 typedef typename CProxy_Derived::proxy_t proxy_t; \
00465 typedef typename CProxy_Derived::element_t element_t; \
00466 CProxy_Derived thisProxy; \
00467 void pup(PUP::er &p) { (void)p; } \
00468 inline void _sdag_pup(PUP::er &p) { (void)p; } \
00469 void virtual_pup(PUP::er &p)
00470
00471
00472 template <class Parent,class CProxy_Derived>
00473 struct CBaseT1 : Parent, virtual CBase {
00474 CBASE_MEMBERS;
00475
00476 #if CMK_HAS_RVALUE_REFERENCES
00477 template <typename... Args>
00478 CBaseT1(Args&&... args) : Parent(std::forward<Args>(args)...) { thisProxy = this; }
00479 #else
00480 template <typename... Args>
00481 CBaseT1(Args... args) : Parent(args...) { thisProxy = this; }
00482 #endif
00483
00484 void parent_pup(PUP::er &p) {
00485 recursive_pup<Parent>(this, p);
00486 p|thisProxy;
00487 }
00488 };
00489
00490
00491 template <class Parent1,class Parent2,class CProxy_Derived>
00492 struct CBaseT2 : public Parent1, public Parent2, virtual CBase {
00493 CBASE_MEMBERS;
00494
00495 CBaseT2(void) :Parent1(), Parent2()
00496 { thisProxy = (Parent1 *)this; }
00497 CBaseT2(CkMigrateMessage *m) :Parent1(m), Parent2(m)
00498 { thisProxy = (Parent1 *)this; }
00499
00500 void parent_pup(PUP::er &p) {
00501 recursive_pup<Parent1>(this, p);
00502 recursive_pup<Parent2>(this, p);
00503 p|thisProxy;
00504 }
00505
00506
00507 inline const CkChareID &ckGetChareID(void) const
00508 {return ((Parent1 *)this)->ckGetChareID();}
00509 static bool isIrreducible(){ return (Parent1::isIrreducible() && Parent2::isIrreducible());}
00510 CHARM_INPLACE_NEW
00511 };
00512
00513 #define BASEN(n) CMK_CONCAT(CBaseT, n)
00514 #define PARENTN(n) CMK_CONCAT(Parent,n)
00515
00516 #define CBASETN(n) \
00517 BASEN(n)() : base(), PARENTN(n)() {} \
00518 BASEN(n)(CkMigrateMessage *m) \
00519 : base(m), PARENTN(n)(m) {} \
00520 void parent_pup(PUP::er &p) { \
00521 recursive_pup<base>(this, p); \
00522 recursive_pup<PARENTN(n)>(this, p); \
00523 } \
00524 static bool isIrreducible() { \
00525 return (base::isIrreducible() && PARENTN(n)::isIrreducible()); \
00526 }
00527
00528
00529 template <class Parent1, class Parent2, class Parent3, class CProxy_Derived>
00530 struct CBaseT3 : public CBaseT2<Parent1, Parent2, CProxy_Derived>,
00531 public Parent3
00532 {
00533 typedef CBaseT2<Parent1, Parent2, CProxy_Derived> base;
00534 CBASETN(3)
00535 };
00536
00537 template <class Parent1, class Parent2, class Parent3, class Parent4,
00538 class CProxy_Derived>
00539 struct CBaseT4 : public CBaseT3<Parent1, Parent2, Parent3,
00540 CProxy_Derived>,
00541 public Parent4
00542 {
00543 typedef CBaseT3<Parent1, Parent2, Parent3, CProxy_Derived> base;
00544 CBASETN(4)
00545 };
00546
00547 template <class Parent1, class Parent2, class Parent3, class Parent4,
00548 class Parent5, class CProxy_Derived>
00549 struct CBaseT5 : public CBaseT4<Parent1, Parent2, Parent3,
00550 Parent4, CProxy_Derived>,
00551 public Parent5
00552 {
00553 typedef CBaseT4<Parent1, Parent2, Parent3, Parent4, CProxy_Derived> base;
00554 CBASETN(5)
00555 };
00556
00557 template <class Parent1, class Parent2, class Parent3, class Parent4,
00558 class Parent5, class Parent6, class CProxy_Derived>
00559 struct CBaseT6 : public CBaseT5<Parent1, Parent2, Parent3,
00560 Parent4, Parent5, CProxy_Derived>,
00561 public Parent6
00562 {
00563 typedef CBaseT5<Parent1, Parent2, Parent3, Parent4, Parent5,
00564 CProxy_Derived> base;
00565 CBASETN(6)
00566 };
00567
00568 template <class Parent1, class Parent2, class Parent3, class Parent4,
00569 class Parent5, class Parent6, class Parent7, class CProxy_Derived>
00570 struct CBaseT7 : public CBaseT6<Parent1, Parent2, Parent3,
00571 Parent4, Parent5, Parent6, CProxy_Derived>,
00572 public Parent7
00573 {
00574 typedef CBaseT6<Parent1, Parent2, Parent3, Parent4, Parent5,
00575 Parent6, CProxy_Derived> base;
00576 CBASETN(7)
00577 };
00578
00579 template <class Parent1, class Parent2, class Parent3, class Parent4,
00580 class Parent5, class Parent6, class Parent7, class Parent8, class CProxy_Derived>
00581 struct CBaseT8 : public CBaseT7<Parent1, Parent2, Parent3,
00582 Parent4, Parent5, Parent6, Parent7, CProxy_Derived>,
00583 public Parent8
00584 {
00585 typedef CBaseT7<Parent1, Parent2, Parent3, Parent4, Parent5, Parent6, Parent7, CProxy_Derived> base;
00586 CBASETN(8)
00587 };
00588
00589 template <class Parent1, class Parent2, class Parent3, class Parent4,
00590 class Parent5, class Parent6, class Parent7, class Parent8, class Parent9, class CProxy_Derived>
00591 struct CBaseT9 : public CBaseT8<Parent1, Parent2, Parent3,
00592 Parent4, Parent5, Parent6, Parent7, Parent8, CProxy_Derived>,
00593 public Parent9
00594 {
00595 typedef CBaseT8<Parent1, Parent2, Parent3, Parent4, Parent5, Parent6, Parent7, Parent8, CProxy_Derived> base;
00596 CBASETN(9)
00597 };
00598
00599 #undef CBASETN
00600 #undef BASEN
00601 #undef PARENTN
00602
00603
00604
00605 class CProxy;
00606
00612 class CkDelegateData : public CkNoncopyable {
00613 int refcount;
00614 public:
00615 CkDelegateData() :refcount(0) {}
00616 virtual ~CkDelegateData();
00617
00618
00619 inline void reset() {
00620 refcount = 0;
00621 }
00622
00626 inline void ref(void) {refcount++;}
00627
00632 inline void unref(void) {
00633 refcount--;
00634 if (refcount==0) delete this;
00635 }
00636 };
00637
00646 class CkDelegateMgr : public IrrGroup {
00647 public:
00648 virtual ~CkDelegateMgr();
00649 virtual void ChareSend(CkDelegateData *pd,int ep,void *m,const CkChareID *c,int onPE);
00650
00651 virtual void GroupSend(CkDelegateData *pd,int ep,void *m,int onPE,CkGroupID g);
00652 virtual void GroupBroadcast(CkDelegateData *pd,int ep,void *m,CkGroupID g);
00653 virtual void GroupSectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s);
00654
00655 virtual void NodeGroupSend(CkDelegateData *pd,int ep,void *m,int onNode,CkNodeGroupID g);
00656 virtual void NodeGroupBroadcast(CkDelegateData *pd,int ep,void *m,CkNodeGroupID g);
00657 virtual void NodeGroupSectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s);
00658
00659 virtual void ArrayCreate(CkDelegateData *pd,int ep,void *m,const CkArrayIndex &idx,int onPE,CkArrayID a);
00660 virtual void ArraySend(CkDelegateData *pd,int ep,void *m,const CkArrayIndex &idx,CkArrayID a);
00661 virtual void ArrayBroadcast(CkDelegateData *pd,int ep,void *m,CkArrayID a);
00662 virtual void ArraySectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s,int opts);
00663 virtual void initDelegateMgr(CProxy *proxy, int opts=0) { (void)proxy; }
00664 virtual CkDelegateData* ckCopyDelegateData(CkDelegateData *data) {
00665 data->ref();
00666 return data;
00667 }
00668
00685 virtual CkDelegateData *DelegatePointerPup(PUP::er &p,CkDelegateData *pd);
00686 };
00687
00688
00689
00690
00698 class CProxy {
00699 private:
00700 mutable CkDelegateMgr *delegatedMgr;
00701 CkDelegateData *delegatedPtr;
00702 CkGroupID delegatedGroupId;
00703 bool isNodeGroup;
00704 protected:
00705 CProxy() : delegatedMgr(0), delegatedPtr(0), isNodeGroup(false)
00706 {delegatedGroupId.setZero(); }
00707
00708 #define CK_DELCTOR_PARAM CkDelegateMgr *dTo,CkDelegateData *dPtr
00709 #define CK_DELCTOR_ARGS dTo,dPtr
00710 #define CK_DELCTOR_CALL ckDelegatedTo(),ckDelegatedPtr()
00713 CProxy(CK_DELCTOR_PARAM)
00714 :delegatedMgr(dTo)
00715 {
00716 delegatedPtr = NULL;
00717 if(delegatedMgr != NULL && dPtr != NULL) {
00718 delegatedPtr = delegatedMgr->ckCopyDelegateData(dPtr);
00719 delegatedGroupId = delegatedMgr->CkGetGroupID();
00720 isNodeGroup = delegatedMgr->isNodeGroup();
00721 }
00722 }
00723 public:
00725 CProxy(const CProxy &src);
00727 CProxy& operator=(const CProxy &src);
00729 ~CProxy() {
00730 if (delegatedPtr) delegatedPtr->unref();
00731 }
00732
00744 void ckDelegate(CkDelegateMgr *to,CkDelegateData *pd=NULL);
00745
00747 void ckUndelegate(void);
00748
00750 int ckIsDelegated(void) const { return(delegatedMgr!=NULL);}
00751
00754 inline CkDelegateMgr *ckDelegatedTo(void) const {
00755
00756
00757
00758 if (delegatedMgr == NULL && !delegatedGroupId.isZero()) {
00759 if (isNodeGroup) {
00760 delegatedMgr=(CkDelegateMgr *)CkLocalNodeBranch(delegatedGroupId);
00761 }
00762 else {
00763 delegatedMgr=(CkDelegateMgr *)CkLocalBranch(delegatedGroupId);
00764 }
00765 }
00766
00767 return delegatedMgr;
00768 }
00769
00770
00771
00773 inline CkDelegateData *ckDelegatedPtr(void) const {return delegatedPtr;}
00774
00777 CkGroupID ckDelegatedIdx(void) const {
00778 if (delegatedMgr) return delegatedMgr->CkGetGroupID();
00779 else {
00780 CkGroupID gid; gid.setZero();
00781 return gid;
00782 }
00783 }
00784
00786 void pup(PUP::er &p);
00787 };
00788
00789 PUPmarshall(CProxy)
00790
00791
00792
00793
00794 class CProxy_Chare : public CProxy {
00795 private:
00796 CkChareID _ck_cid;
00797 public:
00798 CProxy_Chare() {
00799 #if CMK_ERROR_CHECKING
00800 _ck_cid.onPE=0; _ck_cid.objPtr=0;
00801 #endif
00802 }
00803 #if CMK_ERROR_CHECKING
00804 inline void ckCheck(void) const {
00805 #ifdef CMK_CHARE_USE_PTR
00806 if (_ck_cid.objPtr==0)
00807 CkAbort("Error! This chare proxy has not been initialized!");
00808 #endif
00809 }
00810 #else
00811 inline void ckCheck() const {}
00812 #endif
00813 CProxy_Chare(const CkChareID &c) : _ck_cid(c) {}
00814 CProxy_Chare(const Chare *c) : _ck_cid(c->ckGetChareID()) {}
00815 const CkChareID &ckGetChareID(void) const {return _ck_cid;}
00816 operator const CkChareID &(void) const {return ckGetChareID();}
00817 void ckSetChareID(const CkChareID &c) {_ck_cid=c;}
00818 void pup(PUP::er &p) {
00819 CProxy::pup(p);
00820 p(_ck_cid.onPE);
00821
00822 p((char *)&_ck_cid.objPtr,sizeof(_ck_cid.objPtr));
00823 }
00824 };
00825 PUPmarshall(CProxy_Chare)
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835 typedef void (*CkReductionClientFn)(void *param,int dataSize,void *data);
00836
00839 class CkReductionClientBundle : public CkCallback {
00840 CkReductionClientFn fn;
00841 void *param;
00842 public:
00843 static void callbackCfn(void *thisPtr,void *reductionMsg);
00844 CkReductionClientBundle(): fn(NULL), param(NULL) {}
00845 CkReductionClientBundle(CkReductionClientFn fn_,void *param_);
00846 };
00847 PUPbytes(CkReductionClientBundle)
00848
00849 #define CK_REDUCTION_CLIENT_DECL \
00850 void setReductionClient(CkReductionClientFn fn,void *param=NULL) const\
00851 { ckSetReductionClient(fn,param); } \
00852 void ckSetReductionClient(CkReductionClientFn fn,void *param=NULL) const \
00853 { ckSetReductionClient(new CkReductionClientBundle(fn,param)); } \
00854 void ckSetReductionClient(CkCallback *cb) const;\
00855
00856 #define CK_REDUCTION_CLIENT_DEF(className,mgr) \
00857 void className::ckSetReductionClient(CkCallback *cb) const \
00858 { (mgr)->ckSetReductionClient(cb); }\
00859
00860
00861 class CProxy_NodeGroup;
00862 class CProxy_Group : public CProxy {
00863 private:
00864 CkGroupID _ck_gid;
00865
00866 public:
00867 CProxy_Group() {
00868 #if CMK_ERROR_CHECKING
00869 _ck_gid.setZero();
00870 #endif
00871
00872 }
00873 CProxy_Group(CkGroupID g)
00874 :CProxy(),_ck_gid(g) {
00875
00876 }
00877 CProxy_Group(CkGroupID g,CK_DELCTOR_PARAM)
00878 :CProxy(CK_DELCTOR_ARGS),_ck_gid(g) {
00879
00880 }
00881 CProxy_Group(const IrrGroup *g)
00882 :CProxy(), _ck_gid(g->ckGetGroupID()) {
00883
00884 }
00885
00886
00887
00888 bool operator==(const CProxy_Group& other) {
00889 return ckGetGroupID() == other.ckGetGroupID();
00890 }
00891
00892 #if CMK_ERROR_CHECKING
00893 inline void ckCheck(void) const {
00894 if (_ck_gid.isZero())
00895 CkAbort("Error! This group proxy has not been initialized!");
00896 }
00897 #else
00898 inline void ckCheck() const {}
00899 #endif
00900
00901 CkChareID ckGetChareID(void) const {
00902 CkChareID ret;
00903 ret.onPE=CkMyPe();
00904 ret.objPtr=CkLocalBranch(_ck_gid);
00905 return ret;
00906 }
00907 CkGroupID ckGetGroupID(void) const {return _ck_gid;}
00908 operator CkGroupID () const {return ckGetGroupID();}
00909 void ckSetGroupID(CkGroupID g) {_ck_gid=g;}
00910 void pup(PUP::er &p) {
00911 CProxy::pup(p);
00912 p|_ck_gid;
00913 }
00914 CK_REDUCTION_CLIENT_DECL
00915 };
00916 PUPmarshall(CProxy_Group)
00917
00918 class CProxyElement_Group : public CProxy_Group {
00919 private:
00920 int _onPE;
00921 public:
00922 CProxyElement_Group() { }
00923 CProxyElement_Group(CkGroupID g,int onPE)
00924 : CProxy_Group(g),_onPE(onPE) {}
00925 CProxyElement_Group(CkGroupID g,int onPE,CK_DELCTOR_PARAM)
00926 : CProxy_Group(g,CK_DELCTOR_ARGS),_onPE(onPE) {}
00927 CProxyElement_Group(const IrrGroup *g)
00928 :CProxy_Group(g), _onPE(CkMyPe()) {}
00929
00930
00931
00932 bool operator==(const CProxyElement_Group& other) {
00933 return ckGetGroupID() == other.ckGetGroupID() &&
00934 ckGetGroupPe() == other.ckGetGroupPe();
00935 }
00936
00937 int ckGetGroupPe(void) const {return _onPE;}
00938 void pup(PUP::er &p) {
00939 CProxy_Group::pup(p);
00940 p(_onPE);
00941 }
00942 };
00943 PUPmarshall(CProxyElement_Group)
00944
00945 #define GROUP_SECTION_PROXY 1
00946 class CProxySection_Group : public CProxy_Group {
00947 private:
00948 int _nsid;
00949 CkSectionID *_sid;
00950 public:
00951 CProxySection_Group() { }
00952 CProxySection_Group(const CkGroupID &gid, const int *elems, const int nElems, int factor=USE_DEFAULT_BRANCH_FACTOR)
00953 :CProxy_Group(gid), _nsid(1) { _sid = new CkSectionID(gid, elems, nElems, factor); }
00954 CProxySection_Group(const CkGroupID &gid, const int *elems, const int nElems, CK_DELCTOR_PARAM)
00955 :CProxy_Group(gid,CK_DELCTOR_ARGS), _nsid(1) { _sid = new CkSectionID(gid, elems, nElems); }
00956 CProxySection_Group(const CProxySection_Group &cs)
00957 :CProxy_Group(cs.ckGetGroupID()), _nsid(cs._nsid) {
00958 if (_nsid == 1) _sid = new CkSectionID(cs.ckGetGroupID(), cs.ckGetElements(), cs.ckGetNumElements());
00959 else if (_nsid > 1) {
00960 _sid = new CkSectionID[_nsid];
00961 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00962 } else _sid = NULL;
00963 }
00964 CProxySection_Group(const CProxySection_Group &cs,CK_DELCTOR_PARAM)
00965 :CProxy_Group(cs.ckGetGroupID(),CK_DELCTOR_ARGS), _nsid(cs._nsid) {
00966 if (_nsid == 1) _sid = new CkSectionID(cs.ckGetGroupID(), cs.ckGetElements(), cs.ckGetNumElements());
00967 else if (_nsid > 1) {
00968 _sid = new CkSectionID[_nsid];
00969 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00970 } else _sid = NULL;
00971 }
00972 CProxySection_Group(const IrrGroup *g)
00973 :CProxy_Group(g), _nsid(0) {}
00974 CProxySection_Group(const int n, const CkGroupID *gid, int const * const *elems, const int *nElems, int factor=USE_DEFAULT_BRANCH_FACTOR)
00975 :CProxy_Group(gid[0]), _nsid(n) {
00976 _sid = new CkSectionID[n];
00977 for (int i=0; i<n; ++i) _sid[i] = CkSectionID(gid[i], elems[i], nElems[i], factor);
00978 }
00979 CProxySection_Group(const int n, const CkGroupID *gid, int const * const *elems, const int *nElems,CK_DELCTOR_PARAM)
00980 :CProxy_Group(gid[0],CK_DELCTOR_ARGS), _nsid(n) {
00981 _sid = new CkSectionID[n];
00982 for (int i=0; i<n; ++i) _sid[i] = CkSectionID(gid[i], elems[i], nElems[i]);
00983 }
00984
00985 ~CProxySection_Group() {
00986 if (_nsid == 1) delete _sid;
00987 else if (_nsid > 1) delete[] _sid;
00988 }
00989
00990 CProxySection_Group &operator=(const CProxySection_Group &cs) {
00991 CProxy_Group::operator=(cs);
00992 _nsid = cs._nsid;
00993 if (_nsid == 1) _sid = new CkSectionID(*cs._sid);
00994 else if (_nsid > 1) {
00995 _sid = new CkSectionID[_nsid];
00996 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00997 } else _sid = NULL;
00998 return *this;
00999 }
01000
01001 void ckSectionDelegate(CkDelegateMgr *d)
01002 { ckDelegate(d); d->initDelegateMgr(this, GROUP_SECTION_PROXY); }
01003
01004
01005 inline int ckGetNumSections() const {return _nsid;}
01006 inline CkSectionInfo &ckGetSectionInfo() {return _sid[0]._cookie;}
01007 inline CkSectionID *ckGetSectionIDs() {return _sid; }
01008 inline CkSectionID &ckGetSectionID() {return _sid[0]; }
01009 inline CkSectionID &ckGetSectionID(int i) {return _sid[i]; }
01010 inline CkGroupID ckGetGroupIDn(int i) const {return _sid[i]._cookie.get_aid();}
01011 inline const int *ckGetElements() const {return _sid[0].pelist.data();}
01012 inline const int *ckGetElements(int i) const {return _sid[i].pelist.data();}
01013 inline int ckGetNumElements() const { return _sid[0].pelist.size(); }
01014 inline int ckGetNumElements(int i) const { return _sid[i].pelist.size(); }
01015 inline int ckGetBfactor() const { return _sid[0].bfactor; }
01016 void pup(PUP::er &p) {
01017 CProxy_Group::pup(p);
01018 p | _nsid;
01019 if (p.isUnpacking()) {
01020 if (_nsid == 1) _sid = new CkSectionID;
01021 else if (_nsid > 1) _sid = new CkSectionID[_nsid];
01022 else _sid = NULL;
01023 }
01024 for (int i=0; i<_nsid; ++i) p | _sid[i];
01025 }
01026 };
01027 PUPmarshall(CProxySection_Group)
01028
01029
01030
01031 class CkIndex_Chare { public:
01032 static int __idx;
01033 };
01034 class CkIndex_ArrayBase { public:
01035 static int __idx;
01036 };
01037 class CkIndex_Group { public:
01038 static int __idx;
01039 };
01040
01041 typedef CkIndex_Group CkIndex_NodeGroup;
01042 typedef CkIndex_Group CkIndex_IrrGroup;
01043
01044
01045
01046 class CProxy_NodeGroup : public CProxy{
01047
01048 private:
01049 CkGroupID _ck_gid;
01050 public:
01051 CProxy_NodeGroup() {
01052 #if CMK_ERROR_CHECKING
01053 _ck_gid.setZero();
01054 #endif
01055
01056 }
01057 CProxy_NodeGroup(CkGroupID g)
01058 :CProxy(),_ck_gid(g) {}
01059 CProxy_NodeGroup(CkGroupID g,CK_DELCTOR_PARAM)
01060 :CProxy(CK_DELCTOR_ARGS),_ck_gid(g) {}
01061 CProxy_NodeGroup(const IrrGroup *g)
01062 :CProxy(), _ck_gid(g->ckGetGroupID()) {}
01063
01064
01065
01066 bool operator==(const CProxy_NodeGroup& other) {
01067 return ckGetGroupID() == other.ckGetGroupID();
01068 }
01069
01070 #if CMK_ERROR_CHECKING
01071 inline void ckCheck(void) const {
01072 if (_ck_gid.isZero())
01073 CkAbort("Error! This group proxy has not been initialized!");
01074 }
01075 #else
01076 inline void ckCheck() const {}
01077 #endif
01078
01079 CkChareID ckGetChareID(void) const {
01080 CkChareID ret;
01081 ret.onPE=CkMyPe();
01082 ret.objPtr=CkLocalBranch(_ck_gid);
01083 return ret;
01084 }
01085 CkGroupID ckGetGroupID(void) const {return _ck_gid;}
01086 operator CkGroupID () const {return ckGetGroupID();}
01087 void ckSetGroupID(CkGroupID g) {_ck_gid=g;}
01088 void pup(PUP::er &p) {
01089 CProxy::pup(p);
01090 p | _ck_gid;
01091 }
01092 CK_REDUCTION_CLIENT_DECL
01093
01094 };
01095
01096 class CProxyElement_NodeGroup : public CProxy_NodeGroup {
01097 private:
01098 int _onNode;
01099 public:
01100 CProxyElement_NodeGroup() {}
01101 CProxyElement_NodeGroup(CkGroupID g, int onNode)
01102 : CProxy_NodeGroup(g), _onNode(onNode) {}
01103 CProxyElement_NodeGroup(CkGroupID g, int onNode, CK_DELCTOR_PARAM)
01104 : CProxy_NodeGroup(g, CK_DELCTOR_ARGS), _onNode(onNode) {}
01105 CProxyElement_NodeGroup(const IrrGroup *g)
01106 : CProxy_NodeGroup(g), _onNode(CkMyNode()) {}
01107
01108 bool operator ==(const CProxyElement_NodeGroup& other) {
01109 return ckGetGroupID() == other.ckGetGroupID() &&
01110 ckGetGroupPe() == other.ckGetGroupPe();
01111 }
01112
01113 int ckGetGroupPe(void) const { return _onNode; }
01114 void pup(PUP::er &p) {
01115 CProxy_NodeGroup::pup(p);
01116 p(_onNode);
01117 }
01118 };
01119
01120 typedef CProxy_Group CProxy_IrrGroup;
01121 typedef CProxyElement_Group CProxyElement_IrrGroup;
01122 typedef CProxySection_Group CProxySection_NodeGroup;
01123 typedef CProxySection_Group CProxySection_IrrGroup;
01124
01125
01126
01127
01128
01129 #include "ckreduction.h"
01130
01133 class GroupExt: public Group {
01134 public:
01135 GroupExt(void *impl_msg);
01136
01137 static void __GroupExt(void *impl_msg, void *impl_obj_void) {
01138 new (impl_obj_void) GroupExt(impl_msg);
01139 }
01140
01141 static void __entryMethod(void *impl_msg, void *impl_obj_void) {
01142
01143 GroupExt *obj = static_cast<GroupExt *>(impl_obj_void);
01144 CkMarshallMsg *impl_msg_typed = (CkMarshallMsg *)impl_msg;
01145 char *impl_buf = impl_msg_typed->msgBuf;
01146 PUP::fromMem implP(impl_buf);
01147 int msgSize; implP|msgSize;
01148 int ep; implP|ep;
01149 int dcopy_start; implP|dcopy_start;
01150
01151 GroupMsgRecvExtCallback(obj->thisgroup.idx, ep, msgSize, impl_buf+(3*sizeof(int)),
01152 dcopy_start);
01153 }
01154 };
01155
01156 class CkQdMsg {
01157 public:
01158 void *operator new(size_t s) { return CkAllocMsg(0,(int)s,0,GroupDepNum{}); }
01159 void operator delete(void* ptr) { CkFreeMsg(ptr); }
01160 static void *alloc(int, size_t s, int*, int, int) {
01161 return CkAllocMsg(0,(int)s,0,GroupDepNum{});
01162 }
01163 static void *pack(CkQdMsg *m) { return (void*) m; }
01164 static CkQdMsg *unpack(void *buf) { return (CkQdMsg*) buf; }
01166 static void ckDebugPup(PUP::er &p,void *msg) {
01167 (void)p;
01168 (void)msg;
01169 }
01170 };
01171
01172 class CkThrCallArg {
01173 public:
01174 void *msg;
01175 void *obj;
01176 CkThrCallArg(void *m, void *o) : msg(m), obj(o) {}
01177 };
01178
01179 extern void CkStartQD(const CkCallback& cb);
01180 #define CkExitAfterQuiescence() CkStartQD(CkCallback(CkCallback::ckExit))
01181
01182
01183 #if !CMK_MACHINE_PROGRESS_DEFINED
01184 #define CkNetworkProgress()
01185 #define CkNetworkProgressAfter(p)
01186
01187 #else
01188 void CmiMachineProgressImpl();
01189
01190 #define CkNetworkProgress() {CpvAccess(networkProgressCount) ++; \
01191 if(CpvAccess(networkProgressCount) >= networkProgressPeriod) \
01192 if (LBDatabaseObj()->getLBDB()->StatsOn() == 0) { \
01193 CmiMachineProgressImpl(); \
01194 CpvAccess(networkProgressCount) = 0; \
01195 } \
01196 } \
01197
01198 #define CkNetworkProgressAfter(p) {CpvAccess(networkProgressCount) ++; \
01199 if(CpvAccess(networkProgressCount) >= p) \
01200 if (LBDatabaseObj()->getLBDB()->StatsOn() == 0) { \
01201 CmiMachineProgressImpl(); \
01202 CpvAccess(networkProgressCount) = 0; \
01203 } \
01204 } \
01205
01206 #endif
01207
01208
01209 #if defined(_FAULT_MLOG_)
01210 #include "ckmessagelogging.h"
01211 #endif
01212 #if defined(_FAULT_CAUSAL_)
01213 #include "ckcausalmlog.h"
01214 #endif
01215
01216 #include "ckmemcheckpoint.h"
01217 #include "readonly.h"
01218 #include "ckarray.h"
01219 #include "ckstream.h"
01220 #include "ckfutures.h"
01221 #include "waitqd.h"
01222 #include "sdag.h"
01223 #include "ckcheckpoint.h"
01224 #include "ckevacuation.h"
01225 #include "trace.h"
01226 #include "envelope.h"
01227 #include "pathHistory.h"
01228 #include "ckcallback-ccs.h"
01229
01230
01231 template<typename... tArgs>
01232 int CkRegisterEp(const std::string& name, CkCallFnPtr call, int msgIdx, int chareIdx, int ck_ep_flags) {
01233 std::string combined(name);
01234
01235 size_t argStart = name.find('(');
01236 if (argStart == std::string::npos)
01237 argStart = name.length();
01238
01239 #if defined(__GNUG__) || defined(__clang__)
01240 std::string functionName = __PRETTY_FUNCTION__;
01241 std::string templateString = functionName.substr(functionName.find("tArgs = ") + 8);
01242 #ifdef __clang__
01243
01244
01245 if (templateString.rfind(']') != std::string::npos)
01246 templateString.erase(templateString.rfind(']'));
01247 #else // __GNUG__
01248
01249
01250
01251 size_t openingPos = templateString.find('{'), closingPos = templateString.find('}');
01252 if (openingPos != std::string::npos && closingPos != std::string::npos && closingPos > openingPos + 1)
01253 templateString = templateString.substr(openingPos + 1, closingPos - openingPos - 1);
01254 templateString = "<" + templateString + ">";
01255 #endif
01256 #elif defined(_MSC_VER)
01257
01258
01259 std::string functionName = __FUNCSIG__;
01260 std::string templateString;
01261 size_t openingIndex = functionName.find('<');
01262 if (openingIndex != std::string::npos) {
01263 int count = 1;
01264 size_t index = openingIndex + 1;
01265 while (count > 0 && index < functionName.length()) {
01266 switch (functionName[index]) {
01267 case '<':
01268 count++;
01269 break;
01270 case '>':
01271 count--;
01272 break;
01273 default:
01274 break;
01275 }
01276
01277 index++;
01278 }
01279
01280
01281 if (count == 0) {
01282 templateString = functionName.substr(openingIndex, index - openingIndex + 1);
01283 }
01284 }
01285 #else
01286
01287 std::vector<std::string> tArgNames = { (typeid(tArgs).name())... };
01288
01289 std::string templateString = "<";
01290 for (auto it = tArgNames.begin(); it != tArgNames.end(); it++) {
01291 templateString += *it;
01292 if (it + 1 != tArgNames.end())
01293 templateString += ", ";
01294 }
01295 templateString += ">";
01296 #endif
01297
01298 combined.insert(argStart, templateString);
01299
01300 return CkRegisterEpTemplated(combined.c_str(), call, msgIdx, chareIdx, ck_ep_flags);
01301 }
01302
01303 CkMarshallMsg *CkAllocateMarshallMsgNoninline(int size,const CkEntryOptions *opts);
01304 inline CkMarshallMsg *CkAllocateMarshallMsg(int size,const CkEntryOptions *opts=NULL)
01305 {
01306 if (opts==NULL) {
01307 CkMarshallMsg *newMemory = new (size,0)CkMarshallMsg;
01308 setMemoryTypeMessage(UsrToEnv(newMemory));
01309 return newMemory;
01310 }
01311 else return CkAllocateMarshallMsgNoninline(size,opts);
01312 }
01313
01314
01315
01316
01317
01318
01319
01320 template <typename T>
01321 inline T *CkAllocateMarshallMsgT(int size,const CkEntryOptions *opts)
01322 {
01323 int priobits = 0;
01324 if (opts!=NULL) priobits = opts->getPriorityBits();
01325
01326 T *m=new (size,priobits)T;
01327
01328 envelope *env=UsrToEnv(m);
01329 setMemoryTypeMessage(env);
01330 if (opts!=NULL) {
01331 CmiMemcpy(env->getPrioPtr(),opts->getPriorityPtr(),env->getPrioBytes());
01332
01333 env->setQueueing((unsigned char)opts->getQueueing());
01334 }
01335 return m;
01336 }
01337
01338
01339
01340
01341
01342
01343
01344 CkpvExtern(DebugEntryTable, _debugEntryTable);
01345
01346
01347 static const char *idx2str(const CkArrayIndex &ind) {
01348 static char retBuf[80];
01349 retBuf[0]=0;
01350 if (ind.dimension <= 3) {
01351 for (int i=0;i<ind.nInts;i++) {
01352 if (i>0) strcat(retBuf,";");
01353 sprintf(&retBuf[strlen(retBuf)],"%d",ind.data()[i]);
01354 }
01355 } else {
01356 const short int *idx = (const short int*)ind.data();
01357 for (int i=0;i<ind.dimension;i++) {
01358 if (i>0) strcat(retBuf,";");
01359 sprintf(&retBuf[strlen(retBuf)],"%hd",idx[i]);
01360 }
01361 }
01362 return retBuf;
01363 }
01364
01365 static const char *idx2str(const ArrayElement *el) UNUSED;
01366 static const char *idx2str(const ArrayElement* el) {
01367 return idx2str(el->thisIndexMax);
01368 }
01369
01370
01371
01372 class CkConditional {
01373 int refcount;
01374 public:
01375 CkConditional() : refcount(1) { }
01376 virtual ~CkConditional() { }
01377
01378
01379
01380
01381
01382 void deallocate() {
01383
01384 if (--refcount == 0) {
01385
01386 delete this;
01387 }
01388 }
01389 void copyreference(void) {
01390 ++refcount;
01391 }
01392 };
01393
01394
01395 void checkForInitDone(bool rdmaROCompleted);
01396
01397 #endif
01398
01399
01400