ckarrayindex: Move to new header
[charm.git] / src / ck-core / charm++.h
1 #ifndef _CHARMPP_H_
2 #define _CHARMPP_H_
3
4 #include <stdlib.h>
5 #include <memory.h>
6
7 #include "charm.h"
8 #include "middle.h"
9
10 #if CMK_HAS_STRINGS_H
11   #include <strings.h>            /* defines bzero */
12 #else
13   #define bzero(s,n)   memset(s,0,n)
14 #endif
15
16 class CMessage_CkArgMsg {
17 public: static int __idx;
18 };
19 #define CK_ALIGN(val,to) (((val)+(to)-1)&~((to)-1))
20
21 #ifdef __GNUC__
22 #define UNUSED __attribute__ ((unused))
23 #else
24 #define UNUSED
25 #endif
26
27 #include "pup.h"
28 #include "cklists.h"
29 #include "ckbitvector.h"
30 #include "init.h"
31 #include "debug-charm.h"
32 #ifndef __CUDACC__
33 #include "simd.h"
34 #endif
35
36 PUPbytes(CkChareID)
37 PUPbytes(CkGroupID)
38 PUPbytes(CmiGroup)
39   
40 /**
41  * CkMessage is the superclass of all Charm++ messages.
42  * Typically, a message foo inherits from CMessage_foo, which
43  * inherits from CkMessage.  In the internals of Charm++,
44  * messages are often represented by bare "void *"s, which is 
45  * silly and dangerous.
46  */
47 class CkMessage { 
48         //Don't use these: use CkCopyMsg
49         CkMessage(const CkMessage &);
50         void operator=(const CkMessage &);
51 public:
52         CkMessage() {}
53         void operator delete(void *ptr) { CkFreeMsg(ptr); }
54         
55         /* This pup routine only packs the message itself, *not* the
56         message header.  Use CkPupMessage instead of calling this directly. */
57         void pup(PUP::er &p);
58         
59         /// This is used to display message contents in the debugger.
60         static void ckDebugPup(PUP::er &p,void *msg);
61 };
62 class CMessage_CkMessage {
63 public:
64         static int __idx;
65 };
66
67 CkpvExtern(size_t *, _offsets);
68
69 /// CkArgMsg is passed to the mainchare's constructor.
70 class CkArgMsg : public CkMessage {
71 public:
72   int argc;
73   char **argv;
74 };
75
76 class CkArray;
77
78 void CkPupMessage(PUP::er &p,void **atMsg,int pack_detail=1);
79
80 //This is for passing a single Charm++ message via parameter marshalling
81 class CkMarshalledMessage {
82         void *msg;
83         //Don't use these: only pass by reference
84         void operator=(const CkMarshalledMessage &);
85  public:
86         CkMarshalledMessage(void): msg(NULL) {}
87         CkMarshalledMessage(CkMessage *m): msg(m) {} //Takes ownership of message
88         CkMarshalledMessage(const CkMarshalledMessage &);
89         ~CkMarshalledMessage() {if (msg) CkFreeMsg(msg);}
90         CkMessage *getMessage(void) {void *ret=msg; msg=NULL; return (CkMessage *)ret;}
91         void pup(PUP::er &p) {CkPupMessage(p,&msg,1);}
92 };
93 PUPmarshall(CkMarshalledMessage)
94
95 /**
96  * CkEntryOptions describes the options associated
97  * with an entry method invocation, which include
98  * the message priority and queuing strategy.
99  * It is only used with parameter marshalling.
100  */
101 class CkEntryOptions : public CkNoncopyable {
102         int queueingtype; //CK_QUEUEING type
103         int prioBits; //Number of bits of priority to use
104         typedef unsigned int prio_t; //Datatype used to represent priorities
105         prio_t *prioPtr; //Points to message priority values
106         prio_t prioStore; //For short priorities, stores the priority value
107         CkGroupID  depGroupID;  // group dependence
108 public:
109         CkEntryOptions(void): queueingtype(CK_QUEUEING_FIFO), prioBits(0), 
110                               prioPtr(NULL), prioStore(0) { depGroupID.setZero(); }
111
112         ~CkEntryOptions() {
113                 if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
114                      queueingtype != CK_QUEUEING_ILIFO ) {
115                         delete [] prioPtr;
116                         prioBits = 0;
117                 }
118         }
119         
120         inline void setPriority(prio_t integerPrio) {
121                 queueingtype=CK_QUEUEING_IFIFO;
122                 prioBits=8*sizeof(integerPrio);
123                 prioPtr=&prioStore;
124                 prioStore=integerPrio;
125         }
126         inline void setPriority(int prioBits_,const prio_t *prioPtr_) {
127                 if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
128                      queueingtype != CK_QUEUEING_ILIFO ) {
129                         delete [] prioPtr;
130                         prioBits = 0;
131                 }
132                 queueingtype=CK_QUEUEING_BFIFO;
133                 prioBits=prioBits_;
134                 int dataLength = (prioBits + (sizeof(prio_t)*8 - 1)) /
135                                  (sizeof(prio_t)*8);
136                 prioPtr = new prio_t[dataLength];
137                 memcpy((void *)prioPtr, prioPtr_, dataLength*sizeof(unsigned int));
138         }
139         inline void setPriority(const CkBitVector &cbv) {
140                 if ( cbv.data != NULL ) {
141                         if ( prioPtr != NULL && queueingtype != CK_QUEUEING_IFIFO &&
142                              queueingtype != CK_QUEUEING_ILIFO ) {
143                                 delete [] prioPtr;
144                                 prioBits = 0;
145                         }
146                         queueingtype=CK_QUEUEING_BFIFO;
147                         prioBits=cbv.usedBits;
148                         int dataLength = (prioBits + (sizeof(prio_t)*8 - 1)) /
149                                         (sizeof(prio_t)*8);
150                         prioPtr = new prio_t[dataLength];
151                         memcpy((void *)prioPtr, cbv.data, dataLength*sizeof(prio_t));
152                 } else {
153                         queueingtype=CK_QUEUEING_BFIFO;
154                         prioBits=0;
155                         int dataLength = 1;
156                         prioPtr = new prio_t[dataLength];
157                         prioPtr[0] = 0;
158                 }
159         }
160         
161         inline void setQueueing(int queueingtype_) {queueingtype=queueingtype_;}
162         inline void setGroupDepID(const CkGroupID &gid) { depGroupID = gid; }
163
164         ///These are used by CkAllocateMarshallMsg, below:
165         inline int getQueueing(void) const {return queueingtype;}
166         inline int getPriorityBits(void) const {return prioBits;}
167         inline const prio_t *getPriorityPtr(void) const {return prioPtr;}
168         inline const CkGroupID getGroupDepID() const { return depGroupID; }
169 };
170
171 #include "CkMarshall.decl.h"
172 //This is the message type marshalled parameters get packed into:
173 class CkMarshallMsg : public CMessage_CkMarshallMsg {
174 public: 
175         char *msgBuf;
176 };
177
178
179
180 //A queue-of-messages, like CkMsgQ<CkReductionMsg>
181 template <class MSG>
182 class CkMsgQ : public CkQ<MSG *> {
183 public:
184         ~CkMsgQ() { //Delete the messages in the queue:
185                 MSG *m;
186                 while (NULL!=(m=this->deq())) delete m;
187         }
188         void pup(PUP::er &p) {
189                 int l=this->length();
190                 p(l);
191                 for (int i=0;i<l;i++) {
192                         MSG *m=NULL;
193                         if (!p.isUnpacking()) m=this->deq();
194                         CkPupMessage(p,(void **)&m);
195                         this->enq(m);
196                 }
197         }
198         friend void operator|(PUP::er &p,CkMsgQ<MSG> &v) {v.pup(p);}
199 };
200
201
202
203 #include "ckhashtable.h"
204 #include "ckarrayindex.h"
205
206 class CkArrayID {
207         CkGroupID _gid;
208 public:
209         CkArrayID() : _gid() { }
210         CkArrayID(CkGroupID g) :_gid(g) {}
211         inline void setZero(void) {_gid.setZero();}
212         inline int isZero(void) const {return _gid.isZero();}
213         operator CkGroupID() const {return _gid;}
214         CkArray *ckLocalBranch(void) const
215                 { return (CkArray *)CkLocalBranch(_gid); }
216         static CkArray *CkLocalBranch(CkArrayID id) 
217                 { return (CkArray *)::CkLocalBranch(id); }
218         void pup(PUP::er &p) {p | _gid; }
219         int operator == (const CkArrayID& other) const {
220                 return (_gid == other._gid);
221         }
222 };
223 PUPmarshall(CkArrayID)
224
225 #include "cksection.h"
226
227 #include "ckcallback.h"
228
229 /********************* Superclass of all Chares ******************/
230 #if CMK_MULTIPLE_DELETE
231 #define CHARM_INPLACE_NEW \
232     void *operator new(size_t, void *ptr) { return ptr; }; \
233     void operator delete(void*, void*) {}; \
234     void *operator new(size_t s) { return malloc(s); } \
235     void operator delete(void *ptr) { free(ptr); }
236 #else
237 #define CHARM_INPLACE_NEW \
238     void *operator new(size_t, void *ptr) { return ptr; }; \
239     void *operator new(size_t s) { return malloc(s); } \
240     void operator delete(void *ptr) { free(ptr); }
241 #endif
242
243 // for object message queue
244 #include "ckobjQ.h"
245
246
247 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
248 class ChareMlogData;
249 #endif
250
251
252 /**
253   The base class of all parallel objects in Charm++,
254   including Array Elements, Groups, and NodeGroups.
255 */
256 class Chare {
257   protected:
258     CkChareID thishandle;
259 #if CMK_OBJECT_QUEUE_AVAILABLE
260     CkObjectMsgQ objQ;                // object message queue
261 #endif
262   public:
263 #ifndef CMK_CHARE_USE_PTR
264     int chareIdx;                  // index in the chare obj table (chare_objs)
265 #endif
266 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
267     ChareMlogData *mlogData;
268 #endif
269     Chare(CkMigrateMessage *m);
270     Chare();
271     virtual ~Chare(); //<- needed for *any* child to have a virtual destructor
272     virtual void pup(PUP::er &p);//<- pack/unpack routine
273     inline const CkChareID &ckGetChareID(void) const {return thishandle;}
274     inline void CkGetChareID(CkChareID *dest) const {*dest=thishandle;}
275     // object message queue
276     void  CkEnableObjQ();
277 #if CMK_OBJECT_QUEUE_AVAILABLE
278     inline CkObjectMsgQ &CkGetObjQueue() { return objQ; }
279 #endif
280     CHARM_INPLACE_NEW
281     /// Return the type of this chare, as present in _chareTable
282     virtual int ckGetChareType() const;
283     /// Return a strdup'd array containing this object's string name.
284     virtual char *ckDebugChareName(void);
285     /// Place into str a copy of the id of this object up to limit bytes, return
286     /// the number of bytes used for the id
287     virtual int ckDebugChareID(char *str, int limit);
288     virtual void ckDebugPup(PUP::er &p);
289     /// Called when a [threaded] charm entry method is created:
290     virtual void CkAddThreadListeners(CthThread tid, void *msg);
291 };
292
293 //Superclass of all Groups that cannot participate in reductions.
294 //  Undocumented: should only be used inside Charm++.
295 /*forward*/ class Group;
296 class IrrGroup : public Chare {
297   protected:
298     CkGroupID thisgroup;
299   public:
300     IrrGroup(CkMigrateMessage *m): Chare(m) { }
301     IrrGroup();
302     virtual ~IrrGroup(); //<- needed for *any* child to have a virtual destructor
303
304     virtual void pup(PUP::er &p);//<- pack/unpack routine
305     virtual void ckJustMigrated(void);
306     inline const CkGroupID &ckGetGroupID(void) const {return thisgroup;}
307     inline CkGroupID CkGetGroupID(void) const {return thisgroup;}
308     virtual int ckGetChareType() const;
309     virtual char *ckDebugChareName();
310     virtual int ckDebugChareID(char *, int);
311
312     // Silly run-time type information
313     virtual int isNodeGroup() { return 0; };
314     virtual CmiBool isLocMgr(void){ return CmiFalse; }
315     virtual CmiBool isArrMgr(void){ return CmiFalse; }
316     virtual CmiBool isReductionMgr(void){ return CmiFalse; }
317     static int isIrreducible(){ return 1;}
318     virtual void flushStates() {}
319                 /*
320                         FAULT_EVAC
321                 */
322                 virtual void evacuate(){};
323                 virtual void doneEvacuate(){};
324     virtual void CkAddThreadListeners(CthThread tid, void *msg);
325 };
326
327 #define CBASE_PROXY_MEMBERS(CProxy_Derived) \
328         typedef typename CProxy_Derived::local_t local_t; \
329         typedef typename CProxy_Derived::index_t index_t; \
330         typedef typename CProxy_Derived::proxy_t proxy_t; \
331         typedef typename CProxy_Derived::element_t element_t; \
332         CProxy_Derived thisProxy; 
333
334
335 /*Templated implementation of CBase_* classes.*/
336 template <class Parent,class CProxy_Derived>
337 class CBaseT1 : public Parent {
338 public:
339         CBASE_PROXY_MEMBERS(CProxy_Derived)
340
341         CBaseT1(void) :Parent()  { thisProxy=this; }
342         CBaseT1(CkMigrateMessage *m) :Parent(m) { thisProxy=this; }
343         void pup(PUP::er &p) {
344                 Parent::pup(p);
345                 p|thisProxy;
346         }
347 };
348
349 /*Templated version of above for multiple (at least duplicate) inheritance:*/
350 template <class Parent1,class Parent2,class CProxy_Derived>
351 class CBaseT2 : public Parent1, public Parent2 {
352 public:
353         CBASE_PROXY_MEMBERS(CProxy_Derived)
354
355         CBaseT2(void) :Parent1(), Parent2()
356                 { thisProxy = (Parent1 *)this; }
357         CBaseT2(CkMigrateMessage *m) :Parent1(m), Parent2(m)
358                 { thisProxy = (Parent1 *)this; } 
359         void pup(PUP::er &p) {
360                 Parent1::pup(p);
361                 Parent2::pup(p);
362                 p|thisProxy;
363         }
364
365 //These overloads are needed to prevent ambiguity for multiple inheritance:
366         inline const CkChareID &ckGetChareID(void) const
367                 {return ((Parent1 *)this)->ckGetChareID();}
368         static int isIrreducible(){ return (Parent1::isIrreducible() && Parent2::isIrreducible());}
369         CHARM_INPLACE_NEW
370 };
371
372 #define BASEN(n) CMK_CONCAT(CBaseT, n)
373 #define PARENTN(n) CMK_CONCAT(Parent,n)
374
375 #define CBASETN(n)                                                    \
376   BASEN(n)() : base(), PARENTN(n)() {}                                \
377   BASEN(n)(CkMigrateMessage *m)                                       \
378           : base(m), PARENTN(n)(m) {}                                 \
379   void pup(PUP::er &p) {                                              \
380     base::pup(p);                                                     \
381     PARENTN(n)::pup(p);                                               \
382   }                                                                   \
383   static int isIrreducible() {                                        \
384     return (base::isIrreducible() && PARENTN(n)::isIrreducible());    \
385   }
386
387
388 template <class Parent1, class Parent2, class Parent3, class CProxy_Derived>
389 struct CBaseT3 : public CBaseT2<Parent1, Parent2, CProxy_Derived>,
390                  public Parent3
391 {
392   typedef CBaseT2<Parent1, Parent2, CProxy_Derived> base;
393   CBASETN(3)
394 };
395
396 template <class Parent1, class Parent2, class Parent3, class Parent4,
397   class CProxy_Derived>
398   struct CBaseT4 : public CBaseT3<Parent1, Parent2, Parent3, 
399   CProxy_Derived>,
400                  public Parent4
401 {
402   typedef CBaseT3<Parent1, Parent2, Parent3, CProxy_Derived> base;
403   CBASETN(4)
404 };
405
406 template <class Parent1, class Parent2, class Parent3, class Parent4,
407   class Parent5, class CProxy_Derived>
408   struct CBaseT5 : public CBaseT4<Parent1, Parent2, Parent3, 
409   Parent4, CProxy_Derived>,
410                  public Parent5
411 {
412   typedef CBaseT4<Parent1, Parent2, Parent3, Parent4, CProxy_Derived> base;
413   CBASETN(5)
414 };
415
416 template <class Parent1, class Parent2, class Parent3, class Parent4,
417   class Parent5, class Parent6, class CProxy_Derived>
418   struct CBaseT6 : public CBaseT5<Parent1, Parent2, Parent3, 
419   Parent4, Parent5, CProxy_Derived>,
420                  public Parent6
421 {
422   typedef CBaseT5<Parent1, Parent2, Parent3, Parent4, Parent5, 
423     CProxy_Derived> base;
424   CBASETN(6)
425 };
426
427 template <class Parent1, class Parent2, class Parent3, class Parent4,
428   class Parent5, class Parent6, class Parent7, class CProxy_Derived>
429   struct CBaseT7 : public CBaseT6<Parent1, Parent2, Parent3, 
430   Parent4, Parent5, Parent6, CProxy_Derived>,
431                  public Parent7
432 {
433   typedef CBaseT6<Parent1, Parent2, Parent3, Parent4, Parent5, 
434     Parent6, CProxy_Derived> base;
435   CBASETN(7)
436 };
437
438 template <class Parent1, class Parent2, class Parent3, class Parent4,
439   class Parent5, class Parent6, class Parent7, class Parent8, class CProxy_Derived>
440   struct CBaseT8 : public CBaseT7<Parent1, Parent2, Parent3, 
441   Parent4, Parent5, Parent6, Parent7, CProxy_Derived>,
442                  public Parent8
443 {
444   typedef CBaseT7<Parent1, Parent2, Parent3, Parent4, Parent5, Parent6, Parent7, CProxy_Derived> base;
445   CBASETN(8)
446 };
447
448 template <class Parent1, class Parent2, class Parent3, class Parent4,
449   class Parent5, class Parent6, class Parent7, class Parent8, class Parent9, class CProxy_Derived>
450   struct CBaseT9 : public CBaseT8<Parent1, Parent2, Parent3, 
451   Parent4, Parent5, Parent6, Parent7, Parent8, CProxy_Derived>,
452                  public Parent9
453 {
454   typedef CBaseT8<Parent1, Parent2, Parent3, Parent4, Parent5, Parent6, Parent7, Parent8, CProxy_Derived> base;
455   CBASETN(9)
456 };
457
458 #undef CBASETN
459 #undef BASEN
460 #undef PARENTN
461
462 /**************************** CkDelegateMgr **************************/
463
464 class CProxy;
465
466 /**
467  Per-proxy data storage for delegation.  A CkDelegateMgr
468  inherits from this class and adds his per-proxy data. 
469  This class is reference counted.
470 */
471 class CkDelegateData : public CkNoncopyable {
472         int refcount; // reference count
473 public:
474         CkDelegateData() :refcount(0) {}
475         virtual ~CkDelegateData();
476         
477         //Child class constructor may have to set this.
478         inline void reset() {
479             refcount = 0;
480         }
481         
482         /// Add a reference to this delegation data.  Just increments the refcount.
483         ///   Only CProxy should ever have to call this routine.
484         /// Actually now the delegate manager calls it.
485         inline void ref(void) {refcount++;}
486         
487         /// Remove our reference from this data.  If the refcount
488         ///  reaches 0, deletes the delegateData.
489         ///   Only CProxy should ever have to call this routine.
490         /// Actually now the delegate manager calls it.
491         inline void unref(void) {
492                 refcount--;
493                 if (refcount==0) delete this;
494         }
495 };
496
497 /**
498 Message delegation support, where you send a message via
499 a proxy normally, but the message ends up routed via this
500 special delegateMgr group.
501
502 An "interface" class-- all delegated messages are routed via 
503 this class.  The default action is to deliver the message directly.
504 */
505 class CkDelegateMgr : public IrrGroup {
506   public:
507     virtual ~CkDelegateMgr(); //<- so children can have virtual destructor
508     virtual void ChareSend(CkDelegateData *pd,int ep,void *m,const CkChareID *c,int onPE);
509
510     virtual void GroupSend(CkDelegateData *pd,int ep,void *m,int onPE,CkGroupID g);
511     virtual void GroupBroadcast(CkDelegateData *pd,int ep,void *m,CkGroupID g);
512     virtual void GroupSectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s);
513
514     virtual void NodeGroupSend(CkDelegateData *pd,int ep,void *m,int onNode,CkNodeGroupID g);
515     virtual void NodeGroupBroadcast(CkDelegateData *pd,int ep,void *m,CkNodeGroupID g);
516     virtual void NodeGroupSectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s);
517
518     virtual void ArrayCreate(CkDelegateData *pd,int ep,void *m,const CkArrayIndex &idx,int onPE,CkArrayID a);
519     virtual void ArraySend(CkDelegateData *pd,int ep,void *m,const CkArrayIndex &idx,CkArrayID a);
520     virtual void ArrayBroadcast(CkDelegateData *pd,int ep,void *m,CkArrayID a);
521     virtual void ArraySectionSend(CkDelegateData *pd,int ep,void *m,int nsid,CkSectionID *s,int opts);
522     virtual void initDelegateMgr(CProxy *proxy)  {}
523     virtual CkDelegateData* ckCopyDelegateData(CkDelegateData *data) {
524         data->ref();
525         return data;
526     } 
527     
528     /**
529      Management of per-proxy data: pup this delegate's data.
530      If p.isUnpacking, allocate and return a new set of delegate data.
531      Never delete (or unref) the data-- the proxy will do that itself
532         when it is required.
533      The default implementation just ignores this call.
534      
535      A typical implementation that uses CkDelegateData might look like this:
536      <code>
537        myData *d=(myData *)pd;
538        if (p.isUnpacking()) d=new myData();
539        p|d->myField1;
540        p|d->myField2;
541        return d;
542      </code>
543     */
544     virtual CkDelegateData *DelegatePointerPup(PUP::er &p,CkDelegateData *pd);
545 };
546
547
548 /**************************** Proxies **************************/
549
550 /*Message delegation support, where you send a message via
551 a proxy normally, but the message ends up routed via a 
552 special delegateMgr group.
553 */
554 class CkDelegateMgr;
555
556 /** 
557   A proxy is a local handle to a remote object.  This is the superclass
558   of all proxies: CProxy_Array, CProxy_Group, etc. inherit from this class.
559   
560   Real proxies for user classes are generated by the .ci file translator charmxi
561   and put in the generated .decl.h headers.
562 */
563 class CProxy {
564   private:
565     CkDelegateMgr *delegatedMgr; // can be either a group or a nodegroup
566     CkDelegateData *delegatedPtr; // private data for use by delegatedMgr.
567   protected: //Never allocate CProxy's-- only subclass them.
568     CProxy() :delegatedMgr(0), delegatedPtr(0) { }
569
570 #define CK_DELCTOR_PARAM CkDelegateMgr *dTo,CkDelegateData *dPtr
571 #define CK_DELCTOR_ARGS dTo,dPtr
572 #define CK_DELCTOR_CALL ckDelegatedTo(),ckDelegatedPtr()
573 /// Delegation constructor: used when building 
574 ///   an element proxy from a collective proxy, like in "aProxy[i]".
575     CProxy(CK_DELCTOR_PARAM)
576         :delegatedMgr(dTo)
577         {
578             delegatedPtr = NULL;
579             if(delegatedMgr != NULL && dPtr != NULL) 
580                 delegatedPtr = dTo->ckCopyDelegateData(dPtr);            
581         }
582   public:
583     /// Copy constructor.  Only needed for delegated proxies.
584     CProxy(const CProxy &src);
585     /// Assignment operator.  Only needed for delegated proxies.
586     CProxy& operator=(const CProxy &src);
587     /// Destructor.  Only needed for delegated proxies. 
588     ~CProxy() {
589         if (delegatedPtr) delegatedPtr->unref();
590     }
591     
592     /**
593       Delegation allows a class, called a CkDelegateMgr, to 
594       intercept calls made to this proxy for further processing.
595       
596       "ptr" is any delegator-specific data the CkDelegateMgr wants
597       to associate with this proxy: the pointer is owned by this 
598       proxy, but will be copied and pupped by calling delegator routines.
599       
600       This interface should only be used by library writers,
601       not ordinary user code.
602     */
603     void ckDelegate(CkDelegateMgr *to,CkDelegateData *pd=NULL);
604     
605     /// Remove delegation from this proxy.
606     void ckUndelegate(void);
607     
608     /// Return true if this proxy is delegated.
609     int ckIsDelegated(void) const { return(delegatedMgr!=NULL);}
610     
611     /// Return the delegator of this proxy, to which the proxies' messages
612     ///  are actually sent.
613     inline CkDelegateMgr *ckDelegatedTo(void) const { return delegatedMgr; }
614     
615     /// Return the delegator's local data associated with this proxy.
616     inline CkDelegateData *ckDelegatedPtr(void) const {return delegatedPtr;}
617     
618     /// Return the groupID of our delegator.
619     ///   Note that this can be a GroupID or a NodeGroupID, so be careful!
620     CkGroupID ckDelegatedIdx(void) const {
621         if (delegatedMgr) return delegatedMgr->CkGetGroupID();
622         else {
623           CkGroupID gid; gid.setZero();
624           return gid;
625         }
626     }
627     
628     /// Pup the data for this proxy.  Only needed for delegated proxies.
629     void pup(PUP::er &p);
630 };
631
632 PUPmarshall(CProxy)
633
634
635 /*The base classes of each proxy type
636 */
637 class CProxy_Chare : public CProxy {
638   private:
639     CkChareID _ck_cid;
640   public:
641     CProxy_Chare() {
642 #if CMK_ERROR_CHECKING
643         _ck_cid.onPE=0; _ck_cid.objPtr=0;
644 #endif
645     }
646 #if CMK_ERROR_CHECKING
647     inline void ckCheck(void) const  {   //Make sure this proxy has a value
648 #ifdef CMK_CHARE_USE_PTR
649         if (_ck_cid.objPtr==0)
650                 CkAbort("Error! This chare proxy has not been initialized!");
651 #endif
652     }
653 #else
654     inline void ckCheck() const {}
655 #endif
656     CProxy_Chare(const CkChareID &c) : _ck_cid(c) {}
657     CProxy_Chare(const Chare *c) : _ck_cid(c->ckGetChareID()) {}
658     const CkChareID &ckGetChareID(void) const {return _ck_cid;}
659     operator const CkChareID &(void) const {return ckGetChareID();}
660     void ckSetChareID(const CkChareID &c) {_ck_cid=c;}
661     void pup(PUP::er &p) {
662         CProxy::pup(p);
663         p(_ck_cid.onPE);
664         //Copy the pointer as straight bytes
665         p((char *)&_ck_cid.objPtr,sizeof(_ck_cid.objPtr));
666     }
667 };
668 PUPmarshall(CProxy_Chare)
669
670 /******************* Reduction Declarations ****************/
671 //Silly: need the type of a reduction client here so it can be used by proxies.
672 //A clientFn is called on PE 0 when all contributions
673 // have been received and reduced.
674 //  param can be ignored, or used to pass any client-specific data you $
675 //  dataSize gives the size (in bytes) of the data array
676 //  data gives the reduced contributions--
677 //       it will be disposed of after this procedure returns.
678 typedef void (*CkReductionClientFn)(void *param,int dataSize,void *data);
679
680 /// Tiny utility class used by CkReductionClientAdaptor--
681 /// lets us keep backward compatability with the old C-style interface.
682 class CkReductionClientBundle : public CkCallback {
683         CkReductionClientFn fn;
684         void *param;
685  public:
686         static void callbackCfn(void *thisPtr,void *reductionMsg);
687         CkReductionClientBundle(): fn(NULL), param(NULL) {}
688         CkReductionClientBundle(CkReductionClientFn fn_,void *param_);
689 };
690 PUPbytes(CkReductionClientBundle)
691
692 #define CK_REDUCTION_CLIENT_DECL \
693         void setReductionClient(CkReductionClientFn fn,void *param=NULL) const\
694                 { ckSetReductionClient(fn,param); } \
695         void ckSetReductionClient(CkReductionClientFn fn,void *param=NULL) const \
696                 { ckSetReductionClient(new CkReductionClientBundle(fn,param)); } \
697         void ckSetReductionClient(CkCallback *cb) const;\
698
699 #define CK_REDUCTION_CLIENT_DEF(className,mgr) \
700         void className::ckSetReductionClient(CkCallback *cb) const \
701                 { (mgr)->ckSetReductionClient(cb); }\
702
703
704 class CProxy_NodeGroup;
705 class CProxy_CkArrayReductionMgr;
706 class CProxy_Group : public CProxy {
707   private:
708     CkGroupID _ck_gid;
709
710   public:
711     CProxy_Group() {
712 #if CMK_ERROR_CHECKING
713         _ck_gid.setZero();
714 #endif
715         //CkPrintf(" In CProxy_Group Constructor\n");
716     }
717     CProxy_Group(CkGroupID g)
718        :CProxy(),_ck_gid(g) {
719        //CkPrintf(" In CProxy_Group Constructor\n");
720        }
721     CProxy_Group(CkGroupID g,CK_DELCTOR_PARAM)
722         :CProxy(CK_DELCTOR_ARGS),_ck_gid(g) {
723         //CkPrintf(" In CProxy_Group Constructor\n");
724         }
725     CProxy_Group(const IrrGroup *g)
726         :CProxy(), _ck_gid(g->ckGetGroupID()) {
727         //CkPrintf(" In CProxy_Group Constructor\n");
728         }
729 /*    CProxy_Group(const NodeGroup *g)  //<- for compatability with NodeGroups
730         :CProxy(), _ck_gid(g->ckGetGroupID()) {}*/
731
732 #if CMK_ERROR_CHECKING
733     inline void ckCheck(void) const {   //Make sure this proxy has a value
734         if (_ck_gid.isZero())
735                 CkAbort("Error! This group proxy has not been initialized!");
736     }
737 #else
738     inline void ckCheck() const {}
739 #endif
740
741     CkChareID ckGetChareID(void) const {
742         CkChareID ret;
743         ret.onPE=CkMyPe();
744         ret.objPtr=CkLocalBranch(_ck_gid);
745         return ret;
746     }
747     CkGroupID ckGetGroupID(void) const {return _ck_gid;}
748     operator CkGroupID () const {return ckGetGroupID();}
749     void ckSetGroupID(CkGroupID g) {_ck_gid=g;}
750     void pup(PUP::er &p) {
751         CProxy::pup(p);
752         p|_ck_gid;
753     }
754     CK_REDUCTION_CLIENT_DECL
755 };
756 PUPmarshall(CProxy_Group)
757
758 class CProxyElement_Group : public CProxy_Group {
759   private:
760     int _onPE;
761   public:
762     CProxyElement_Group() { }
763     CProxyElement_Group(CkGroupID g,int onPE)
764        : CProxy_Group(g),_onPE(onPE) {}
765     CProxyElement_Group(CkGroupID g,int onPE,CK_DELCTOR_PARAM)
766         : CProxy_Group(g,CK_DELCTOR_ARGS),_onPE(onPE) {}
767     CProxyElement_Group(const IrrGroup *g)
768         :CProxy_Group(g), _onPE(CkMyPe()) {}
769     /*CProxyElement_Group(const NodeGroup *g)  //<- for compatability with NodeGroups
770         :CProxy_Group(g), _onPE(CkMyPe()) {}*/
771
772     int ckGetGroupPe(void) const {return _onPE;}
773     void pup(PUP::er &p) {
774         CProxy_Group::pup(p);
775         p(_onPE);
776     }
777 };
778 PUPmarshall(CProxyElement_Group)
779
780 class CProxySection_Group : public CProxy_Group {
781 private:
782   int _nsid;
783   CkSectionID *_sid;
784 public:
785   CProxySection_Group() { }
786   CProxySection_Group(const CkGroupID &gid, const int *elems, const int nElems)
787       :CProxy_Group(gid), _nsid(1) { _sid = new CkSectionID(gid, elems, nElems); }
788   CProxySection_Group(const CkGroupID &gid, const int *elems, const int nElems,CK_DELCTOR_PARAM)
789       :CProxy_Group(gid,CK_DELCTOR_ARGS), _nsid(1) { _sid = new CkSectionID(gid, elems, nElems); }
790   CProxySection_Group(const CProxySection_Group &cs)
791       :CProxy_Group(cs.ckGetGroupID()), _nsid(cs._nsid) {
792     if (_nsid == 1) _sid = new CkSectionID(cs.ckGetGroupID(), cs.ckGetElements(), cs.ckGetNumElements());
793     else if (_nsid > 1) {
794       _sid = new CkSectionID[_nsid];
795       for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
796     } else _sid = NULL;
797   }
798   CProxySection_Group(const CProxySection_Group &cs,CK_DELCTOR_PARAM)
799       :CProxy_Group(cs.ckGetGroupID(),CK_DELCTOR_ARGS), _nsid(cs._nsid) {
800     if (_nsid == 1) _sid = new CkSectionID(cs.ckGetGroupID(), cs.ckGetElements(), cs.ckGetNumElements());
801     else if (_nsid > 1) {
802       _sid = new CkSectionID[_nsid];
803       for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
804     } else _sid = NULL;
805   }
806   CProxySection_Group(const IrrGroup *g)
807       :CProxy_Group(g), _nsid(0) {}
808   CProxySection_Group(const int n, const CkGroupID *gid,  int const * const *elems, const int *nElems)
809       :CProxy_Group(gid[0]), _nsid(n) {
810     _sid = new CkSectionID[n];
811     for (int i=0; i<n; ++i) _sid[i] = CkSectionID(gid[i], elems[i], nElems[i]);
812   }
813   CProxySection_Group(const int n, const CkGroupID *gid, int const * const *elems, const int *nElems,CK_DELCTOR_PARAM)
814       :CProxy_Group(gid[0],CK_DELCTOR_ARGS), _nsid(n) {
815     _sid = new CkSectionID[n];
816     for (int i=0; i<n; ++i) _sid[i] = CkSectionID(gid[i], elems[i], nElems[i]);
817   }
818   
819   ~CProxySection_Group() {
820     if (_nsid == 1) delete _sid;
821     else if (_nsid > 1) delete[] _sid;
822   }
823   
824   CProxySection_Group &operator=(const CProxySection_Group &cs) {
825     CProxy_Group::operator=(cs);
826     _nsid = cs._nsid;
827     if (_nsid == 1) _sid = new CkSectionID(*cs._sid);
828     else if (_nsid > 1) {
829       _sid = new CkSectionID[_nsid];
830       for (int i=0; i<_nsid; ++i) _sid[i] = cs._sid[i];
831     } else _sid = NULL;
832     return *this;
833   }
834   
835   //void ckSend(CkArrayMessage *m, int ep, int opts = 0) ;
836
837   inline int ckGetNumSections() const {return _nsid;}
838   inline CkSectionInfo &ckGetSectionInfo() {return _sid[0]._cookie;}
839   inline CkSectionID *ckGetSectionIDs() {return _sid; }
840   inline CkSectionID &ckGetSectionID() {return _sid[0]; }
841   inline CkSectionID &ckGetSectionID(int i) {return _sid[i]; }
842   inline CkGroupID ckGetGroupIDn(int i) const {return (CkGroupID)_sid[i]._cookie.aid;}
843   inline int *ckGetElements() const {return _sid[0].pelist;}
844   inline int *ckGetElements(int i) const {return _sid[i].pelist;}
845   inline int ckGetNumElements() const { return _sid[0].npes; }
846   inline int ckGetNumElements(int i) const { return _sid[i].npes; }
847   void pup(PUP::er &p) {
848     CProxy_Group::pup(p);
849     p | _nsid;
850     if (p.isUnpacking()) {
851       if (_nsid == 1) _sid = new CkSectionID;
852       else if (_nsid > 1) _sid = new CkSectionID[_nsid];
853       else _sid = NULL;
854     }
855     for (int i=0; i<_nsid; ++i) p | _sid[i];
856   }
857 };
858 PUPmarshall(CProxySection_Group)
859
860 /* These classes exist to provide chare indices for the basic
861  chare types.*/
862 class CkIndex_Chare { public:
863     static int __idx;//Fake chare index for registration
864 };
865 class CkIndex_ArrayBase { public:
866     static int __idx;//Fake chare index for registration
867 };
868 class CkIndex_Group { public:
869     static int __idx;//Fake chare index for registration
870 };
871
872 typedef CkIndex_Group CkIndex_NodeGroup;
873 typedef CkIndex_Group CkIndex_IrrGroup;
874
875
876 //typedef CProxy_Group CProxy_NodeGroup;
877 class CProxy_NodeGroup : public CProxy{
878
879   private:
880     CkGroupID _ck_gid;
881   public:
882     CProxy_NodeGroup() {
883 #if CMK_ERROR_CHECKING
884         _ck_gid.setZero();
885 #endif
886         //CkPrintf("In CProxy_NodeGroup0 Constructor %d\n",CkLocalNodeBranch(_ck_gid));
887     }
888     CProxy_NodeGroup(CkGroupID g)
889        :CProxy(),_ck_gid(g) {/*CkPrintf("In CProxy_NodeGroup1 Constructor %d\n",CkLocalNodeBranch(_ck_gid));*/}
890     CProxy_NodeGroup(CkGroupID g,CK_DELCTOR_PARAM)
891         :CProxy(CK_DELCTOR_ARGS),_ck_gid(g) {/*CkPrintf("In CProxy_NodeGroup2 Constructor %d\n",CkLocalNodeBranch(_ck_gid));*/}
892     CProxy_NodeGroup(const IrrGroup *g)
893         :CProxy(), _ck_gid(g->ckGetGroupID()) {/*CkPrintf("In CProxy_NodeGroup3 Constructor %d\n",CkLocalNodeBranch(_ck_gid));*/}
894 /*    CProxy_Group(const NodeGroup *g)  //<- for compatability with NodeGroups
895         :CProxy(), _ck_gid(g->ckGetGroupID()) {}*/
896
897 #if CMK_ERROR_CHECKING
898     inline void ckCheck(void) const {   //Make sure this proxy has a value
899         if (_ck_gid.isZero())
900                 CkAbort("Error! This group proxy has not been initialized!");
901     }
902 #else
903     inline void ckCheck() const {}
904 #endif
905
906     CkChareID ckGetChareID(void) const {
907         CkChareID ret;
908         ret.onPE=CkMyPe();
909         ret.objPtr=CkLocalBranch(_ck_gid);
910         return ret;
911     }
912     CkGroupID ckGetGroupID(void) const {return _ck_gid;}
913     operator CkGroupID () const {return ckGetGroupID();}
914     void ckSetGroupID(CkGroupID g) {_ck_gid=g;}
915     void pup(PUP::er &p) {
916         CProxy::pup(p);
917         p | _ck_gid;
918     }
919     CK_REDUCTION_CLIENT_DECL
920
921 };
922
923 typedef CProxy_Group CProxy_IrrGroup;
924 typedef CProxyElement_Group CProxyElement_NodeGroup;
925 typedef CProxyElement_Group CProxyElement_IrrGroup;
926 typedef CProxySection_Group CProxySection_NodeGroup;
927 typedef CProxySection_Group CProxySection_IrrGroup;
928
929
930 //(CProxy_ArrayBase is defined in ckarray.h)
931
932 //Defines the actual "Group"
933 #include "ckreduction.h"
934
935 class CkQdMsg {
936   public:
937     void *operator new(size_t s) { return CkAllocMsg(0,(int)s,0); }
938     void operator delete(void* ptr) { CkFreeMsg(ptr); }
939     static void *alloc(int, size_t s, int*, int) {
940       return CkAllocMsg(0,(int)s,0);
941     }
942     static void *pack(CkQdMsg *m) { return (void*) m; }
943     static CkQdMsg *unpack(void *buf) { return (CkQdMsg*) buf; }
944 };
945
946 class CkThrCallArg {
947   public:
948     void *msg;
949     void *obj;
950     CkThrCallArg(void *m, void *o) : msg(m), obj(o) {}
951 };
952
953 extern void CkStartQD(const CkCallback& cb);
954 #define CkExitAfterQuiescence() CkStartQD(CkCallback(CkCallback::ckExit))
955
956
957 #if !CMK_MACHINE_PROGRESS_DEFINED
958 #define CkNetworkProgress() 
959 #define CkNetworkProgressAfter(p) 
960
961 #else
962 void CmiMachineProgressImpl();
963
964 #define CkNetworkProgress() {CpvAccess(networkProgressCount) ++; \
965 if(CpvAccess(networkProgressCount) >=  networkProgressPeriod)  \
966     if (LBDatabaseObj()->getLBDB()->StatsOn() == 0) { \
967         CmiMachineProgressImpl(); \
968         CpvAccess(networkProgressCount) = 0; \
969     } \
970 } \
971
972 #define CkNetworkProgressAfter(p) {CpvAccess(networkProgressCount) ++; \
973 if(CpvAccess(networkProgressCount) >=  p)  \
974     if (LBDatabaseObj()->getLBDB()->StatsOn() == 0) { \
975         CmiMachineProgressImpl(); \
976         CpvAccess(networkProgressCount) = 0; \
977     } \
978 } \
979
980 #endif
981
982
983 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
984 #include "ckmessagelogging.h"
985 #endif
986 #include "ckmemcheckpoint.h"
987 #include "readonly.h"
988 #include "ckarray.h"
989 #include "ckstream.h"
990 #include "CkFutures.decl.h"
991 #include "charisma.h"
992 #include "tempo.h"
993 #include "waitqd.h"
994 #include "sdag.h"
995 #include "ckcheckpoint.h"
996 #include "ckevacuation.h"
997 #include "ckarrayreductionmgr.h"
998 #include "trace.h"
999 #include "envelope.h"
1000
1001
1002
1003
1004
1005
1006 CkMarshallMsg *CkAllocateMarshallMsgNoninline(int size,const CkEntryOptions *opts);
1007 inline CkMarshallMsg *CkAllocateMarshallMsg(int size,const CkEntryOptions *opts=NULL)
1008 {
1009         if (opts==NULL) {
1010           CkMarshallMsg *newMemory = new (size,0)CkMarshallMsg;
1011           setMemoryTypeMessage(UsrToEnv(newMemory));
1012           return newMemory;
1013         }
1014         else return CkAllocateMarshallMsgNoninline(size,opts);
1015 }
1016
1017
1018
1019
1020
1021
1022
1023 template <typename T> 
1024 inline T *CkAllocateMarshallMsgT(int size,const CkEntryOptions *opts) 
1025
1026   int priobits = 0; 
1027   if (opts!=NULL) priobits = opts->getPriorityBits(); 
1028   //Allocate the message 
1029   T *m=new (size,priobits)T; 
1030   //Copy the user's priority data into the message 
1031   envelope *env=UsrToEnv(m); 
1032   setMemoryTypeMessage(env); 
1033   if (opts!=NULL) { 
1034     CmiMemcpy(env->getPrioPtr(),opts->getPriorityPtr(),env->getPrioBytes()); 
1035     //Set the message's queueing type 
1036     env->setQueueing((unsigned char)opts->getQueueing()); 
1037   } 
1038   return m; 
1039
1040
1041
1042
1043
1044
1045 /************************** Debugging Utilities **************/
1046
1047 CkpvExtern(DebugEntryTable, _debugEntryTable);
1048
1049 //For debugging: convert given index to a string (NOT threadsafe)
1050 static const char *idx2str(const CkArrayIndex &ind) {
1051   static char retBuf[80];
1052   retBuf[0]=0;
1053   if (ind.dimension <= 3) {
1054     for (int i=0;i<ind.nInts;i++) {
1055       if (i>0) strcat(retBuf,";");
1056       sprintf(&retBuf[strlen(retBuf)],"%d",ind.data()[i]);
1057     }
1058   } else {
1059     const short int *idx = (const short int*)ind.data();
1060     for (int i=0;i<ind.dimension;i++) {
1061       if (i>0) strcat(retBuf,";");
1062       sprintf(&retBuf[strlen(retBuf)],"%hd",idx[i]);
1063     }
1064   }
1065   return retBuf;
1066 }
1067
1068 static const char *idx2str(const ArrayElement *el) UNUSED;
1069 static const char *idx2str(const ArrayElement* el) {
1070   return idx2str(el->thisIndexMax);
1071 }
1072
1073
1074
1075 class CkConditional {
1076   int refcount;
1077 public:
1078   CkConditional() : refcount(1) { }
1079   virtual ~CkConditional() { }
1080     /*
1081   void* operator new(size_t s) {
1082     return malloc(s);
1083   }
1084     */
1085   void deallocate() {
1086     //CkPrintf("CkConditional::delete %d\n",refcount);
1087     if (--refcount == 0) {
1088       //((CkConditional*)p)->~CkConditional();
1089       delete this;
1090     }
1091   }
1092   void copyreference(void) {
1093     ++refcount;
1094   }
1095 };
1096
1097 PUPbytes(CkFuture)
1098
1099 #endif
1100
1101
1102