00001 #ifndef _CHARMPP_H_
00002 #define _CHARMPP_H_
00003
00004 #include <stdlib.h>
00005 #include <memory.h>
00006
00007 #include "charm.h"
00008 #include "middle.h"
00009
00010 #if CMK_HAS_STRINGS_H
00011 #include <strings.h>
00012 #else
00013 #define bzero(s,n) memset(s,0,n)
00014 #endif
00015
00016 class CMessage_CkArgMsg {
00017 public: static int __idx;
00018 };
00019 #define CK_ALIGN(val,to) (((val)+(to)-1)&~((to)-1))
00020
00021 #ifdef __GNUC__
00022 #define UNUSED __attribute__ ((unused))
00023 #else
00024 #define UNUSED
00025 #endif
00026
00027 #include "pup.h"
00028 #include "cklists.h"
00029 #include "ckbitvector.h"
00030 #include "init.h"
00031 #include "debug-charm.h"
00032 #ifndef __CUDACC__
00033 #include "simd.h"
00034 #endif
00035
00036 PUPbytes(CkChareID)
00037 PUPbytes(CkGroupID)
00038 PUPbytes(CmiGroup)
00039
00047 class CkMessage {
00048
00049 CkMessage(const CkMessage &);
00050 void operator=(const CkMessage &);
00051 public:
00052 CkMessage() {}
00053 void operator delete(void *ptr) { CkFreeMsg(ptr); }
00054
00055
00056
00057 void pup(PUP::er &p);
00058
00060 static void ckDebugPup(PUP::er &p,void *msg);
00061 };
00062 class CMessage_CkMessage {
00063 public:
00064 static int __idx;
00065 };
00066
00067 CkpvExtern(size_t *, _offsets);
00068
00070 class CkArgMsg : public CkMessage {
00071 public:
00072 int argc;
00073 char **argv;
00074 };
00075
00076 class CkArray;
00077
00078 void CkPupMessage(PUP::er &p,void **atMsg,int pack_detail=1);
00079
00080
00081 class CkMarshalledMessage {
00082 void *msg;
00083
00084 void operator=(const CkMarshalledMessage &);
00085 public:
00086 CkMarshalledMessage(void): msg(NULL) {}
00087 CkMarshalledMessage(CkMessage *m): msg(m) {}
00088 CkMarshalledMessage(const CkMarshalledMessage &);
00089 ~CkMarshalledMessage() {if (msg) CkFreeMsg(msg);}
00090 CkMessage *getMessage(void) {void *ret=msg; msg=NULL; return (CkMessage *)ret;}
00091 void pup(PUP::er &p) {CkPupMessage(p,&msg,1);}
00092 };
00093 PUPmarshall(CkMarshalledMessage)
00094
00095
00101 class CkEntryOptions : public CkNoncopyable {
00102 int queueingtype;
00103 int prioBits;
00104 typedef unsigned int prio_t;
00105 prio_t *prioPtr;
00106 prio_t prioStore;
00107 CkGroupID depGroupID;
00108 public:
00109 CkEntryOptions(void): queueingtype(CK_QUEUEING_FIFO), prioBits(0),
00110 prioPtr(NULL), prioStore(0) { depGroupID.setZero(); }
00111
00112 ~CkEntryOptions() {
00113 if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
00114 queueingtype != CK_QUEUEING_ILIFO ) {
00115 delete [] prioPtr;
00116 prioBits = 0;
00117 }
00118 }
00119
00120 inline void setPriority(prio_t integerPrio) {
00121 queueingtype=CK_QUEUEING_IFIFO;
00122 prioBits=8*sizeof(integerPrio);
00123 prioPtr=&prioStore;
00124 prioStore=integerPrio;
00125 }
00126 inline void setPriority(int prioBits_,const prio_t *prioPtr_) {
00127 if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
00128 queueingtype != CK_QUEUEING_ILIFO ) {
00129 delete [] prioPtr;
00130 prioBits = 0;
00131 }
00132 queueingtype=CK_QUEUEING_BFIFO;
00133 prioBits=prioBits_;
00134 int dataLength = (prioBits + (sizeof(prio_t)*8 - 1)) /
00135 (sizeof(prio_t)*8);
00136 prioPtr = new prio_t[dataLength];
00137 memcpy((void *)prioPtr, prioPtr_, dataLength*sizeof(unsigned int));
00138 }
00139 inline void setPriority(const CkBitVector &cbv) {
00140 if ( cbv.data != NULL ) {
00141 if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
00142 queueingtype != CK_QUEUEING_ILIFO ) {
00143 delete [] prioPtr;
00144 prioBits = 0;
00145 }
00146 queueingtype=CK_QUEUEING_BFIFO;
00147 prioBits=cbv.usedBits;
00148 int dataLength = (prioBits + (sizeof(prio_t)*8 - 1)) /
00149 (sizeof(prio_t)*8);
00150 prioPtr = new prio_t[dataLength];
00151 memcpy((void *)prioPtr, cbv.data, dataLength*sizeof(prio_t));
00152 } else {
00153 queueingtype=CK_QUEUEING_BFIFO;
00154 prioBits=0;
00155 int dataLength = 1;
00156 prioPtr = new prio_t[dataLength];
00157 prioPtr[0] = 0;
00158 }
00159 }
00160
00161 inline void setQueueing(int queueingtype_) {queueingtype=queueingtype_;}
00162 inline void setGroupDepID(const CkGroupID &gid) { depGroupID = gid; }
00163
00165 inline int getQueueing(void) const {return queueingtype;}
00166 inline int getPriorityBits(void) const {return prioBits;}
00167 inline const prio_t *getPriorityPtr(void) const {return prioPtr;}
00168 inline const CkGroupID getGroupDepID() const { return depGroupID; }
00169 };
00170
00171 #include "CkMarshall.decl.h"
00172
00173 class CkMarshallMsg : public CMessage_CkMarshallMsg {
00174 public:
00175 char *msgBuf;
00176 };
00177
00178
00179
00180
00181 template <class MSG>
00182 class CkMsgQ : public CkQ<MSG *> {
00183 public:
00184 ~CkMsgQ() {
00185 MSG *m;
00186 while (NULL!=(m=this->deq())) delete m;
00187 }
00188 void pup(PUP::er &p) {
00189 int l=this->length();
00190 p(l);
00191 for (int i=0;i<l;i++) {
00192 MSG *m=NULL;
00193 if (!p.isUnpacking()) m=this->deq();
00194 CkPupMessage(p,(void **)&m);
00195 this->enq(m);
00196 }
00197 }
00198 friend void operator|(PUP::er &p,CkMsgQ<MSG> &v) {v.pup(p);}
00199 };
00200
00201
00202
00203 #include "ckhashtable.h"
00204 #include "ckarrayindex.h"
00205
00206 class CkArrayID {
00207 CkGroupID _gid;
00208 public:
00209 CkArrayID() : _gid() { }
00210 CkArrayID(CkGroupID g) :_gid(g) {}
00211 inline void setZero(void) {_gid.setZero();}
00212 inline int isZero(void) const {return _gid.isZero();}
00213 operator CkGroupID() const {return _gid;}
00214 CkArray *ckLocalBranch(void) const
00215 { return (CkArray *)CkLocalBranch(_gid); }
00216 static CkArray *CkLocalBranch(CkArrayID id)
00217 { return (CkArray *)::CkLocalBranch(id); }
00218 void pup(PUP::er &p) {p | _gid; }
00219 int operator == (const CkArrayID& other) const {
00220 return (_gid == other._gid);
00221 }
00222 };
00223 PUPmarshall(CkArrayID)
00224
00225 #include "cksection.h"
00226
00227 #include "ckcallback.h"
00228
00229
00230 #if CMK_MULTIPLE_DELETE
00231 #define CHARM_INPLACE_NEW \
00232 void *operator new(size_t, void *ptr) { return ptr; }; \
00233 void operator delete(void*, void*) {}; \
00234 void *operator new(size_t s) { return malloc(s); } \
00235 void operator delete(void *ptr) { free(ptr); }
00236 #else
00237 #define CHARM_INPLACE_NEW \
00238 void *operator new(size_t, void *ptr) { return ptr; }; \
00239 void *operator new(size_t s) { return malloc(s); } \
00240 void operator delete(void *ptr) { free(ptr); }
00241 #endif
00242
00243
00244 #include "ckobjQ.h"
00245
00246
00247 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00248 class ChareMlogData;
00249 #endif
00250
00251 #define CHARE_MAGIC 0x201201
00252
00257 class Chare {
00258 protected:
00259 CkChareID thishandle;
00260 #if CMK_OBJECT_QUEUE_AVAILABLE
00261 CkObjectMsgQ objQ;
00262 #endif
00263 public:
00264 #if CMK_ERROR_CHECKING
00265 int magic;
00266 #endif
00267 #ifndef CMK_CHARE_USE_PTR
00268 int chareIdx;
00269 #endif
00270 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00271 ChareMlogData *mlogData;
00272 #endif
00273 Chare(CkMigrateMessage *m);
00274 Chare();
00275 virtual ~Chare();
00276 virtual void pup(PUP::er &p);
00277 inline const CkChareID &ckGetChareID(void) const {return thishandle;}
00278 inline void CkGetChareID(CkChareID *dest) const {*dest=thishandle;}
00279
00280 void CkEnableObjQ();
00281 #if CMK_OBJECT_QUEUE_AVAILABLE
00282 inline CkObjectMsgQ &CkGetObjQueue() { return objQ; }
00283 #endif
00284 CHARM_INPLACE_NEW
00286 virtual int ckGetChareType() const;
00288 virtual char *ckDebugChareName(void);
00291 virtual int ckDebugChareID(char *str, int limit);
00292 virtual void ckDebugPup(PUP::er &p);
00294 virtual void CkAddThreadListeners(CthThread tid, void *msg);
00295 #if CMK_ERROR_CHECKING
00296 inline void sanitycheck() {
00297 if (magic != CHARE_MAGIC)
00298 CmiAbort("Charm++ Fatal Error> Chare magic number does not agree, possibly due to pup functions not calling parent class.");
00299 }
00300 #endif
00301 };
00302
00303
00304
00305 class Group;
00306 class IrrGroup : public Chare {
00307 protected:
00308 CkGroupID thisgroup;
00309 public:
00310 IrrGroup(CkMigrateMessage *m): Chare(m) { }
00311 IrrGroup();
00312 virtual ~IrrGroup();
00313
00314 virtual void pup(PUP::er &p);
00315 virtual void ckJustMigrated(void);
00316 inline const CkGroupID &ckGetGroupID(void) const {return thisgroup;}
00317 inline CkGroupID CkGetGroupID(void) const {return thisgroup;}
00318 virtual int ckGetChareType() const;
00319 virtual char *ckDebugChareName();
00320 virtual int ckDebugChareID(char *, int);
00321
00322
00323 virtual int isNodeGroup() { return 0; };
00324 virtual CmiBool isLocMgr(void){ return CmiFalse; }
00325 virtual CmiBool isArrMgr(void){ return CmiFalse; }
00326 virtual CmiBool isReductionMgr(void){ return CmiFalse; }
00327 static int isIrreducible(){ return 1;}
00328 virtual void flushStates() {}
00329
00330
00331
00332 virtual void evacuate(){};
00333 virtual void doneEvacuate(){};
00334 virtual void CkAddThreadListeners(CthThread tid, void *msg);
00335 };
00336
00337 #define CBASE_PROXY_MEMBERS(CProxy_Derived) \
00338 typedef typename CProxy_Derived::local_t local_t; \
00339 typedef typename CProxy_Derived::index_t index_t; \
00340 typedef typename CProxy_Derived::proxy_t proxy_t; \
00341 typedef typename CProxy_Derived::element_t element_t; \
00342 CProxy_Derived thisProxy;
00343
00344
00345
00346 template <class Parent,class CProxy_Derived>
00347 class CBaseT1 : public Parent {
00348 public:
00349 CBASE_PROXY_MEMBERS(CProxy_Derived)
00350
00351 CBaseT1(void) :Parent() { thisProxy=this; }
00352 CBaseT1(CkMigrateMessage *m) :Parent(m) { thisProxy=this; }
00353 void pup(PUP::er &p) {
00354 Parent::pup(p);
00355 p|thisProxy;
00356 }
00357 };
00358
00359
00360 template <class Parent1,class Parent2,class CProxy_Derived>
00361 class CBaseT2 : public Parent1, public Parent2 {
00362 public:
00363 CBASE_PROXY_MEMBERS(CProxy_Derived)
00364
00365 CBaseT2(void) :Parent1(), Parent2()
00366 { thisProxy = (Parent1 *)this; }
00367 CBaseT2(CkMigrateMessage *m) :Parent1(m), Parent2(m)
00368 { thisProxy = (Parent1 *)this; }
00369 void pup(PUP::er &p) {
00370 Parent1::pup(p);
00371 Parent2::pup(p);
00372 p|thisProxy;
00373 }
00374
00375
00376 inline const CkChareID &ckGetChareID(void) const
00377 {return ((Parent1 *)this)->ckGetChareID();}
00378 static int isIrreducible(){ return (Parent1::isIrreducible() && Parent2::isIrreducible());}
00379 CHARM_INPLACE_NEW
00380 };
00381
00382 #define BASEN(n) CMK_CONCAT(CBaseT, n)
00383 #define PARENTN(n) CMK_CONCAT(Parent,n)
00384
00385 #define CBASETN(n) \
00386 BASEN(n)() : base(), PARENTN(n)() {} \
00387 BASEN(n)(CkMigrateMessage *m) \
00388 : base(m), PARENTN(n)(m) {} \
00389 void pup(PUP::er &p) { \
00390 base::pup(p); \
00391 PARENTN(n)::pup(p); \
00392 } \
00393 static int isIrreducible() { \
00394 return (base::isIrreducible() && PARENTN(n)::isIrreducible()); \
00395 }
00396
00397
00398 template <class Parent1, class Parent2, class Parent3, class CProxy_Derived>
00399 struct CBaseT3 : public CBaseT2<Parent1, Parent2, CProxy_Derived>,
00400 public Parent3
00401 {
00402 typedef CBaseT2<Parent1, Parent2, CProxy_Derived> base;
00403 CBASETN(3)
00404 };
00405
00406 template <class Parent1, class Parent2, class Parent3, class Parent4,
00407 class CProxy_Derived>
00408 struct CBaseT4 : public CBaseT3<Parent1, Parent2, Parent3,
00409 CProxy_Derived>,
00410 public Parent4
00411 {
00412 typedef CBaseT3<Parent1, Parent2, Parent3, CProxy_Derived> base;
00413 CBASETN(4)
00414 };
00415
00416 template <class Parent1, class Parent2, class Parent3, class Parent4,
00417 class Parent5, class CProxy_Derived>
00418 struct CBaseT5 : public CBaseT4<Parent1, Parent2, Parent3,
00419 Parent4, CProxy_Derived>,
00420 public Parent5
00421 {
00422 typedef CBaseT4<Parent1, Parent2, Parent3, Parent4, CProxy_Derived> base;
00423 CBASETN(5)
00424 };
00425
00426 template <class Parent1, class Parent2, class Parent3, class Parent4,
00427 class Parent5, class Parent6, class CProxy_Derived>
00428 struct CBaseT6 : public CBaseT5<Parent1, Parent2, Parent3,
00429 Parent4, Parent5, CProxy_Derived>,
00430 public Parent6
00431 {
00432 typedef CBaseT5<Parent1, Parent2, Parent3, Parent4, Parent5,
00433 CProxy_Derived> base;
00434 CBASETN(6)
00435 };
00436
00437 template <class Parent1, class Parent2, class Parent3, class Parent4,
00438 class Parent5, class Parent6, class Parent7, class CProxy_Derived>
00439 struct CBaseT7 : public CBaseT6<Parent1, Parent2, Parent3,
00440 Parent4, Parent5, Parent6, CProxy_Derived>,
00441 public Parent7
00442 {
00443 typedef CBaseT6<Parent1, Parent2, Parent3, Parent4, Parent5,
00444 Parent6, CProxy_Derived> base;
00445 CBASETN(7)
00446 };
00447
00448 template <class Parent1, class Parent2, class Parent3, class Parent4,
00449 class Parent5, class Parent6, class Parent7, class Parent8, class CProxy_Derived>
00450 struct CBaseT8 : public CBaseT7<Parent1, Parent2, Parent3,
00451 Parent4, Parent5, Parent6, Parent7, CProxy_Derived>,
00452 public Parent8
00453 {
00454 typedef CBaseT7<Parent1, Parent2, Parent3, Parent4, Parent5, Parent6, Parent7, CProxy_Derived> base;
00455 CBASETN(8)
00456 };
00457
00458 template <class Parent1, class Parent2, class Parent3, class Parent4,
00459 class Parent5, class Parent6, class Parent7, class Parent8, class Parent9, class CProxy_Derived>
00460 struct CBaseT9 : public CBaseT8<Parent1, Parent2, Parent3,
00461 Parent4, Parent5, Parent6, Parent7, Parent8, CProxy_Derived>,
00462 public Parent9
00463 {
00464 typedef CBaseT8<Parent1, Parent2, Parent3, Parent4, Parent5, Parent6, Parent7, Parent8, CProxy_Derived> base;
00465 CBASETN(9)
00466 };
00467
00468 #undef CBASETN
00469 #undef BASEN
00470 #undef PARENTN
00471
00472
00473
00474 class CProxy;
00475
00481 class CkDelegateData : public CkNoncopyable {
00482 int refcount;
00483 public:
00484 CkDelegateData() :refcount(0) {}
00485 virtual ~CkDelegateData();
00486
00487
00488 inline void reset() {
00489 refcount = 0;
00490 }
00491
00495 inline void ref(void) {refcount++;}
00496
00501 inline void unref(void) {
00502 refcount--;
00503 if (refcount==0) delete this;
00504 }
00505 };
00506
00515 class CkDelegateMgr : public IrrGroup {
00516 public:
00517 virtual ~CkDelegateMgr();
00518 virtual void ChareSend(CkDelegateData *pd,int ep,void *m,const CkChareID *c,int onPE);
00519
00520 virtual void GroupSend(CkDelegateData *pd,int ep,void *m,int onPE,CkGroupID g);
00521 virtual void GroupBroadcast(CkDelegateData *pd,int ep,void *m,CkGroupID g);
00522 virtual void GroupSectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s);
00523
00524 virtual void NodeGroupSend(CkDelegateData *pd,int ep,void *m,int onNode,CkNodeGroupID g);
00525 virtual void NodeGroupBroadcast(CkDelegateData *pd,int ep,void *m,CkNodeGroupID g);
00526 virtual void NodeGroupSectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s);
00527
00528 virtual void ArrayCreate(CkDelegateData *pd,int ep,void *m,const CkArrayIndex &idx,int onPE,CkArrayID a);
00529 virtual void ArraySend(CkDelegateData *pd,int ep,void *m,const CkArrayIndex &idx,CkArrayID a);
00530 virtual void ArrayBroadcast(CkDelegateData *pd,int ep,void *m,CkArrayID a);
00531 virtual void ArraySectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s,int opts);
00532 virtual void initDelegateMgr(CProxy *proxy) {}
00533 virtual CkDelegateData* ckCopyDelegateData(CkDelegateData *data) {
00534 data->ref();
00535 return data;
00536 }
00537
00554 virtual CkDelegateData *DelegatePointerPup(PUP::er &p,CkDelegateData *pd);
00555 };
00556
00557
00558
00559
00567 class CProxy {
00568 private:
00569 CkGroupID delegatedGroupId;
00570 int isNodeGroup;
00571 mutable CkDelegateMgr *delegatedMgr;
00572 CkDelegateData *delegatedPtr;
00573 protected:
00574 CProxy() : isNodeGroup(0), delegatedMgr(0), delegatedPtr(0)
00575 {delegatedGroupId.setZero(); }
00576
00577 #define CK_DELCTOR_PARAM CkDelegateMgr *dTo,CkDelegateData *dPtr
00578 #define CK_DELCTOR_ARGS dTo,dPtr
00579 #define CK_DELCTOR_CALL ckDelegatedTo(),ckDelegatedPtr()
00582 CProxy(CK_DELCTOR_PARAM)
00583 :delegatedMgr(dTo)
00584 {
00585 delegatedPtr = NULL;
00586 if(delegatedMgr != NULL && dPtr != NULL) {
00587 delegatedPtr = delegatedMgr->ckCopyDelegateData(dPtr);
00588 delegatedGroupId = delegatedMgr->CkGetGroupID();
00589 isNodeGroup = delegatedMgr->isNodeGroup();
00590 }
00591 }
00592 public:
00594 CProxy(const CProxy &src);
00596 CProxy& operator=(const CProxy &src);
00598 ~CProxy() {
00599 if (delegatedPtr) delegatedPtr->unref();
00600 }
00601
00613 void ckDelegate(CkDelegateMgr *to,CkDelegateData *pd=NULL);
00614
00616 void ckUndelegate(void);
00617
00619 int ckIsDelegated(void) const { return(delegatedMgr!=NULL);}
00620
00623 inline CkDelegateMgr *ckDelegatedTo(void) const {
00624
00625
00626
00627 if (delegatedMgr == NULL && !delegatedGroupId.isZero()) {
00628 if (isNodeGroup) {
00629 delegatedMgr=(CkDelegateMgr *)CkLocalNodeBranch(delegatedGroupId);
00630 }
00631 else {
00632 delegatedMgr=(CkDelegateMgr *)CkLocalBranch(delegatedGroupId);
00633 }
00634 }
00635
00636 return delegatedMgr;
00637 }
00638
00639
00640
00642 inline CkDelegateData *ckDelegatedPtr(void) const {return delegatedPtr;}
00643
00646 CkGroupID ckDelegatedIdx(void) const {
00647 if (delegatedMgr) return delegatedMgr->CkGetGroupID();
00648 else {
00649 CkGroupID gid; gid.setZero();
00650 return gid;
00651 }
00652 }
00653
00655 void pup(PUP::er &p);
00656 };
00657
00658 PUPmarshall(CProxy)
00659
00660
00661
00662
00663 class CProxy_Chare : public CProxy {
00664 private:
00665 CkChareID _ck_cid;
00666 public:
00667 CProxy_Chare() {
00668 #if CMK_ERROR_CHECKING
00669 _ck_cid.onPE=0; _ck_cid.objPtr=0;
00670 #endif
00671 }
00672 #if CMK_ERROR_CHECKING
00673 inline void ckCheck(void) const {
00674 #ifdef CMK_CHARE_USE_PTR
00675 if (_ck_cid.objPtr==0)
00676 CkAbort("Error! This chare proxy has not been initialized!");
00677 #endif
00678 }
00679 #else
00680 inline void ckCheck() const {}
00681 #endif
00682 CProxy_Chare(const CkChareID &c) : _ck_cid(c) {}
00683 CProxy_Chare(const Chare *c) : _ck_cid(c->ckGetChareID()) {}
00684 const CkChareID &ckGetChareID(void) const {return _ck_cid;}
00685 operator const CkChareID &(void) const {return ckGetChareID();}
00686 void ckSetChareID(const CkChareID &c) {_ck_cid=c;}
00687 void pup(PUP::er &p) {
00688 CProxy::pup(p);
00689 p(_ck_cid.onPE);
00690
00691 p((char *)&_ck_cid.objPtr,sizeof(_ck_cid.objPtr));
00692 }
00693 };
00694 PUPmarshall(CProxy_Chare)
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 typedef void (*CkReductionClientFn)(void *param,int dataSize,void *data);
00705
00708 class CkReductionClientBundle : public CkCallback {
00709 CkReductionClientFn fn;
00710 void *param;
00711 public:
00712 static void callbackCfn(void *thisPtr,void *reductionMsg);
00713 CkReductionClientBundle(): fn(NULL), param(NULL) {}
00714 CkReductionClientBundle(CkReductionClientFn fn_,void *param_);
00715 };
00716 PUPbytes(CkReductionClientBundle)
00717
00718 #define CK_REDUCTION_CLIENT_DECL \
00719 void setReductionClient(CkReductionClientFn fn,void *param=NULL) const\
00720 { ckSetReductionClient(fn,param); } \
00721 void ckSetReductionClient(CkReductionClientFn fn,void *param=NULL) const \
00722 { ckSetReductionClient(new CkReductionClientBundle(fn,param)); } \
00723 void ckSetReductionClient(CkCallback *cb) const;\
00724
00725 #define CK_REDUCTION_CLIENT_DEF(className,mgr) \
00726 void className::ckSetReductionClient(CkCallback *cb) const \
00727 { (mgr)->ckSetReductionClient(cb); }\
00728
00729
00730 class CProxy_NodeGroup;
00731 class CProxy_CkArrayReductionMgr;
00732 class CProxy_Group : public CProxy {
00733 private:
00734 CkGroupID _ck_gid;
00735
00736 public:
00737 CProxy_Group() {
00738 #if CMK_ERROR_CHECKING
00739 _ck_gid.setZero();
00740 #endif
00741
00742 }
00743 CProxy_Group(CkGroupID g)
00744 :CProxy(),_ck_gid(g) {
00745
00746 }
00747 CProxy_Group(CkGroupID g,CK_DELCTOR_PARAM)
00748 :CProxy(CK_DELCTOR_ARGS),_ck_gid(g) {
00749
00750 }
00751 CProxy_Group(const IrrGroup *g)
00752 :CProxy(), _ck_gid(g->ckGetGroupID()) {
00753
00754 }
00755
00756
00757
00758 #if CMK_ERROR_CHECKING
00759 inline void ckCheck(void) const {
00760 if (_ck_gid.isZero())
00761 CkAbort("Error! This group proxy has not been initialized!");
00762 }
00763 #else
00764 inline void ckCheck() const {}
00765 #endif
00766
00767 CkChareID ckGetChareID(void) const {
00768 CkChareID ret;
00769 ret.onPE=CkMyPe();
00770 ret.objPtr=CkLocalBranch(_ck_gid);
00771 return ret;
00772 }
00773 CkGroupID ckGetGroupID(void) const {return _ck_gid;}
00774 operator CkGroupID () const {return ckGetGroupID();}
00775 void ckSetGroupID(CkGroupID g) {_ck_gid=g;}
00776 void pup(PUP::er &p) {
00777 CProxy::pup(p);
00778 p|_ck_gid;
00779 }
00780 CK_REDUCTION_CLIENT_DECL
00781 };
00782 PUPmarshall(CProxy_Group)
00783
00784 class CProxyElement_Group : public CProxy_Group {
00785 private:
00786 int _onPE;
00787 public:
00788 CProxyElement_Group() { }
00789 CProxyElement_Group(CkGroupID g,int onPE)
00790 : CProxy_Group(g),_onPE(onPE) {}
00791 CProxyElement_Group(CkGroupID g,int onPE,CK_DELCTOR_PARAM)
00792 : CProxy_Group(g,CK_DELCTOR_ARGS),_onPE(onPE) {}
00793 CProxyElement_Group(const IrrGroup *g)
00794 :CProxy_Group(g), _onPE(CkMyPe()) {}
00795
00796
00797
00798 int ckGetGroupPe(void) const {return _onPE;}
00799 void pup(PUP::er &p) {
00800 CProxy_Group::pup(p);
00801 p(_onPE);
00802 }
00803 };
00804 PUPmarshall(CProxyElement_Group)
00805
00806 class CProxySection_Group : public CProxy_Group {
00807 private:
00808 int _nsid;
00809 CkSectionID *_sid;
00810 public:
00811 CProxySection_Group() { }
00812 CProxySection_Group(const CkGroupID &gid, const int *elems, const int nElems)
00813 :CProxy_Group(gid), _nsid(1) { _sid = new CkSectionID(gid, elems, nElems); }
00814 CProxySection_Group(const CkGroupID &gid, const int *elems, const int nElems,CK_DELCTOR_PARAM)
00815 :CProxy_Group(gid,CK_DELCTOR_ARGS), _nsid(1) { _sid = new CkSectionID(gid, elems, nElems); }
00816 CProxySection_Group(const CProxySection_Group &cs)
00817 :CProxy_Group(cs.ckGetGroupID()), _nsid(cs._nsid) {
00818 if (_nsid == 1) _sid = new CkSectionID(cs.ckGetGroupID(), cs.ckGetElements(), cs.ckGetNumElements());
00819 else if (_nsid > 1) {
00820 _sid = new CkSectionID[_nsid];
00821 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00822 } else _sid = NULL;
00823 }
00824 CProxySection_Group(const CProxySection_Group &cs,CK_DELCTOR_PARAM)
00825 :CProxy_Group(cs.ckGetGroupID(),CK_DELCTOR_ARGS), _nsid(cs._nsid) {
00826 if (_nsid == 1) _sid = new CkSectionID(cs.ckGetGroupID(), cs.ckGetElements(), cs.ckGetNumElements());
00827 else if (_nsid > 1) {
00828 _sid = new CkSectionID[_nsid];
00829 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00830 } else _sid = NULL;
00831 }
00832 CProxySection_Group(const IrrGroup *g)
00833 :CProxy_Group(g), _nsid(0) {}
00834 CProxySection_Group(const int n, const CkGroupID *gid, int const * const *elems, const int *nElems)
00835 :CProxy_Group(gid[0]), _nsid(n) {
00836 _sid = new CkSectionID[n];
00837 for (int i=0; i<n; ++i) _sid[i] = CkSectionID(gid[i], elems[i], nElems[i]);
00838 }
00839 CProxySection_Group(const int n, const CkGroupID *gid, int const * const *elems, const int *nElems,CK_DELCTOR_PARAM)
00840 :CProxy_Group(gid[0],CK_DELCTOR_ARGS), _nsid(n) {
00841 _sid = new CkSectionID[n];
00842 for (int i=0; i<n; ++i) _sid[i] = CkSectionID(gid[i], elems[i], nElems[i]);
00843 }
00844
00845 ~CProxySection_Group() {
00846 if (_nsid == 1) delete _sid;
00847 else if (_nsid > 1) delete[] _sid;
00848 }
00849
00850 CProxySection_Group &operator=(const CProxySection_Group &cs) {
00851 CProxy_Group::operator=(cs);
00852 _nsid = cs._nsid;
00853 if (_nsid == 1) _sid = new CkSectionID(*cs._sid);
00854 else if (_nsid > 1) {
00855 _sid = new CkSectionID[_nsid];
00856 for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
00857 } else _sid = NULL;
00858 return *this;
00859 }
00860
00861
00862
00863 inline int ckGetNumSections() const {return _nsid;}
00864 inline CkSectionInfo &ckGetSectionInfo() {return _sid[0]._cookie;}
00865 inline CkSectionID *ckGetSectionIDs() {return _sid; }
00866 inline CkSectionID &ckGetSectionID() {return _sid[0]; }
00867 inline CkSectionID &ckGetSectionID(int i) {return _sid[i]; }
00868 inline CkGroupID ckGetGroupIDn(int i) const {return (CkGroupID)_sid[i]._cookie.info.aid;}
00869 inline int *ckGetElements() const {return _sid[0].pelist;}
00870 inline int *ckGetElements(int i) const {return _sid[i].pelist;}
00871 inline int ckGetNumElements() const { return _sid[0].npes; }
00872 inline int ckGetNumElements(int i) const { return _sid[i].npes; }
00873 void pup(PUP::er &p) {
00874 CProxy_Group::pup(p);
00875 p | _nsid;
00876 if (p.isUnpacking()) {
00877 if (_nsid == 1) _sid = new CkSectionID;
00878 else if (_nsid > 1) _sid = new CkSectionID[_nsid];
00879 else _sid = NULL;
00880 }
00881 for (int i=0; i<_nsid; ++i) p | _sid[i];
00882 }
00883 };
00884 PUPmarshall(CProxySection_Group)
00885
00886
00887
00888 class CkIndex_Chare { public:
00889 static int __idx;
00890 };
00891 class CkIndex_ArrayBase { public:
00892 static int __idx;
00893 };
00894 class CkIndex_Group { public:
00895 static int __idx;
00896 };
00897
00898 typedef CkIndex_Group CkIndex_NodeGroup;
00899 typedef CkIndex_Group CkIndex_IrrGroup;
00900
00901
00902
00903 class CProxy_NodeGroup : public CProxy{
00904
00905 private:
00906 CkGroupID _ck_gid;
00907 public:
00908 CProxy_NodeGroup() {
00909 #if CMK_ERROR_CHECKING
00910 _ck_gid.setZero();
00911 #endif
00912
00913 }
00914 CProxy_NodeGroup(CkGroupID g)
00915 :CProxy(),_ck_gid(g) {}
00916 CProxy_NodeGroup(CkGroupID g,CK_DELCTOR_PARAM)
00917 :CProxy(CK_DELCTOR_ARGS),_ck_gid(g) {}
00918 CProxy_NodeGroup(const IrrGroup *g)
00919 :CProxy(), _ck_gid(g->ckGetGroupID()) {}
00920
00921
00922
00923 #if CMK_ERROR_CHECKING
00924 inline void ckCheck(void) const {
00925 if (_ck_gid.isZero())
00926 CkAbort("Error! This group proxy has not been initialized!");
00927 }
00928 #else
00929 inline void ckCheck() const {}
00930 #endif
00931
00932 CkChareID ckGetChareID(void) const {
00933 CkChareID ret;
00934 ret.onPE=CkMyPe();
00935 ret.objPtr=CkLocalBranch(_ck_gid);
00936 return ret;
00937 }
00938 CkGroupID ckGetGroupID(void) const {return _ck_gid;}
00939 operator CkGroupID () const {return ckGetGroupID();}
00940 void ckSetGroupID(CkGroupID g) {_ck_gid=g;}
00941 void pup(PUP::er &p) {
00942 CProxy::pup(p);
00943 p | _ck_gid;
00944 }
00945 CK_REDUCTION_CLIENT_DECL
00946
00947 };
00948
00949 typedef CProxy_Group CProxy_IrrGroup;
00950 typedef CProxyElement_Group CProxyElement_NodeGroup;
00951 typedef CProxyElement_Group CProxyElement_IrrGroup;
00952 typedef CProxySection_Group CProxySection_NodeGroup;
00953 typedef CProxySection_Group CProxySection_IrrGroup;
00954
00955
00956
00957
00958
00959 #include "ckreduction.h"
00960
00961 class CkQdMsg {
00962 public:
00963 void *operator new(size_t s) { return CkAllocMsg(0,(int)s,0); }
00964 void operator delete(void* ptr) { CkFreeMsg(ptr); }
00965 static void *alloc(int, size_t s, int*, int) {
00966 return CkAllocMsg(0,(int)s,0);
00967 }
00968 static void *pack(CkQdMsg *m) { return (void*) m; }
00969 static CkQdMsg *unpack(void *buf) { return (CkQdMsg*) buf; }
00970 };
00971
00972 class CkThrCallArg {
00973 public:
00974 void *msg;
00975 void *obj;
00976 CkThrCallArg(void *m, void *o) : msg(m), obj(o) {}
00977 };
00978
00979 extern void CkStartQD(const CkCallback& cb);
00980 #define CkExitAfterQuiescence() CkStartQD(CkCallback(CkCallback::ckExit))
00981
00982
00983 #if !CMK_MACHINE_PROGRESS_DEFINED
00984 #define CkNetworkProgress()
00985 #define CkNetworkProgressAfter(p)
00986
00987 #else
00988 void CmiMachineProgressImpl();
00989
00990 #define CkNetworkProgress() {CpvAccess(networkProgressCount) ++; \
00991 if(CpvAccess(networkProgressCount) >= networkProgressPeriod) \
00992 if (LBDatabaseObj()->getLBDB()->StatsOn() == 0) { \
00993 CmiMachineProgressImpl(); \
00994 CpvAccess(networkProgressCount) = 0; \
00995 } \
00996 } \
00997
00998 #define CkNetworkProgressAfter(p) {CpvAccess(networkProgressCount) ++; \
00999 if(CpvAccess(networkProgressCount) >= p) \
01000 if (LBDatabaseObj()->getLBDB()->StatsOn() == 0) { \
01001 CmiMachineProgressImpl(); \
01002 CpvAccess(networkProgressCount) = 0; \
01003 } \
01004 } \
01005
01006 #endif
01007
01008
01009 #if defined(_FAULT_MLOG_)
01010 #include "ckmessagelogging.h"
01011 #endif
01012 #if defined(_FAULT_CAUSAL_)
01013 #include "ckcausalmlog.h"
01014 #endif
01015
01016 #include "ckmemcheckpoint.h"
01017 #include "readonly.h"
01018 #include "ckarray.h"
01019 #include "ckstream.h"
01020 #include "ckfutures.h"
01021 #include "charisma.h"
01022 #include "tempo.h"
01023 #include "waitqd.h"
01024 #include "sdag.h"
01025 #include "ckcheckpoint.h"
01026 #include "ckevacuation.h"
01027 #include "ckarrayreductionmgr.h"
01028 #include "trace.h"
01029 #include "envelope.h"
01030
01031
01032
01033
01034
01035
01036 CkMarshallMsg *CkAllocateMarshallMsgNoninline(int size,const CkEntryOptions *opts);
01037 inline CkMarshallMsg *CkAllocateMarshallMsg(int size,const CkEntryOptions *opts=NULL)
01038 {
01039 if (opts==NULL) {
01040 CkMarshallMsg *newMemory = new (size,0)CkMarshallMsg;
01041 setMemoryTypeMessage(UsrToEnv(newMemory));
01042 return newMemory;
01043 }
01044 else return CkAllocateMarshallMsgNoninline(size,opts);
01045 }
01046
01047
01048
01049
01050
01051
01052
01053 template <typename T>
01054 inline T *CkAllocateMarshallMsgT(int size,const CkEntryOptions *opts)
01055 {
01056 int priobits = 0;
01057 if (opts!=NULL) priobits = opts->getPriorityBits();
01058
01059 T *m=new (size,priobits)T;
01060
01061 envelope *env=UsrToEnv(m);
01062 setMemoryTypeMessage(env);
01063 if (opts!=NULL) {
01064 CmiMemcpy(env->getPrioPtr(),opts->getPriorityPtr(),env->getPrioBytes());
01065
01066 env->setQueueing((unsigned char)opts->getQueueing());
01067 }
01068 return m;
01069 }
01070
01071
01072
01073
01074
01075
01076
01077 CkpvExtern(DebugEntryTable, _debugEntryTable);
01078
01079
01080 static const char *idx2str(const CkArrayIndex &ind) {
01081 static char retBuf[80];
01082 retBuf[0]=0;
01083 if (ind.dimension <= 3) {
01084 for (int i=0;i<ind.nInts;i++) {
01085 if (i>0) strcat(retBuf,";");
01086 sprintf(&retBuf[strlen(retBuf)],"%d",ind.data()[i]);
01087 }
01088 } else {
01089 const short int *idx = (const short int*)ind.data();
01090 for (int i=0;i<ind.dimension;i++) {
01091 if (i>0) strcat(retBuf,";");
01092 sprintf(&retBuf[strlen(retBuf)],"%hd",idx[i]);
01093 }
01094 }
01095 return retBuf;
01096 }
01097
01098 static const char *idx2str(const ArrayElement *el) UNUSED;
01099 static const char *idx2str(const ArrayElement* el) {
01100 return idx2str(el->thisIndexMax);
01101 }
01102
01103
01104
01105 class CkConditional {
01106 int refcount;
01107 public:
01108 CkConditional() : refcount(1) { }
01109 virtual ~CkConditional() { }
01110
01111
01112
01113
01114
01115 void deallocate() {
01116
01117 if (--refcount == 0) {
01118
01119 delete this;
01120 }
01121 }
01122 void copyreference(void) {
01123 ++refcount;
01124 }
01125 };
01126
01127 #endif
01128
01129
01130