Documentation #1777: Document message types in Charm++ message handler code
[charm.git] / src / ck-core / charm.h
1 /**
2 \file
3 \brief Charm Kernel--the groups and chares level of Charm++.
4 */
5 #ifndef CHARM_H
6 #define CHARM_H
7
8 #include "converse.h"
9 #include <sys/types.h> /* for size_t */
10
11 #ifdef __cplusplus
12 #include "pup.h"
13 extern "C" {
14 #endif
15
16
17 /******************************************************************************
18  *
19  * Converse Concepts, renamed to CK
20  *
21  *****************************************************************************/
22
23 /** Queueing types, for use with CkSetQueueing: */
24 #define CK_QUEUEING_FIFO   CQS_QUEUEING_FIFO
25 #define CK_QUEUEING_LIFO   CQS_QUEUEING_LIFO
26 #define CK_QUEUEING_IFIFO  CQS_QUEUEING_IFIFO
27 #define CK_QUEUEING_ILIFO  CQS_QUEUEING_ILIFO
28 #define CK_QUEUEING_BFIFO  CQS_QUEUEING_BFIFO
29 #define CK_QUEUEING_BLIFO  CQS_QUEUEING_BLIFO
30 #define CK_QUEUEING_LFIFO  CQS_QUEUEING_LFIFO
31 #define CK_QUEUEING_LLIFO  CQS_QUEUEING_LLIFO
32
33 #define CkTimer         CmiTimer
34 #define CkWallTimer     CmiWallTimer
35 #define CkCpuTimer      CmiCpuTimer
36
37 #define CkMyPe                  CmiMyPe
38 #define CkMyRank                CmiMyRank
39 #define CkMyNode                CmiMyNode
40 #define CkNumPes                CmiNumPes
41 #define CkNumNodes              CmiNumNodes
42 #define CkNumPhysicalNodes      CmiNumPhysicalNodes
43 #define CkNodeFirst             CmiNodeFirst
44 #define CkNodeSize              CmiNodeSize
45 #define CkMyNodeSize            CmiMyNodeSize
46 #define CkNodeOf                CmiNodeOf
47 #define CkRankOf                CmiRankOf
48
49 #define CkPrintf                CmiPrintf
50 #define CkScanf                 CmiScanf
51 #define CkError                 CmiError
52 #define CkAbort                 CmiAbort
53 #define CkAssert                CmiAssert
54 #define CkSetPeHelpsOtherThreads CmiSetPeHelpsOtherThreads
55
56 void realCkExit(int exitcode);
57
58 /* Optional parameter for CkExit() - based on
59 https://stackoverflow.com/a/28074198/1250282 */
60
61 #define CKEXIT_1(x) realCkExit(x)
62 #define CKEXIT_0() CKEXIT_1(0) /* Default CkExit() exit code: 0 */
63
64 #define CKEXIT_FUNC_CHOOSER(_f1, _f2, _f3, ...) _f3
65 #define CKEXIT_FUNC_RECOMPOSER(argsWithParentheses) CKEXIT_FUNC_CHOOSER argsWithParentheses
66 #define CKEXIT_CHOOSE_FROM_ARG_COUNT(...) CKEXIT_FUNC_RECOMPOSER((__VA_ARGS__, CKEXIT_2, CKEXIT_1, ))
67 #define CKEXIT_NO_ARG_EXPANDER() ,,CKEXIT_0
68 #define CKEXIT_MACRO_CHOOSER(...) CKEXIT_CHOOSE_FROM_ARG_COUNT(CKEXIT_NO_ARG_EXPANDER __VA_ARGS__ ())
69 #define CkExit(...) CKEXIT_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
70
71
72 #if CMK_SHRINK_EXPAND
73 extern void  CkCleanup(void);
74 #endif
75 extern char **CkGetArgv(void);
76 extern int  CkGetArgc(void);
77
78 /******************************************************************************
79  *
80  * Miscellaneous Constants
81  *
82  *****************************************************************************/
83
84 #define CK_PE_ALL        CLD_BROADCAST_ALL
85 #define CK_PE_ALL_BUT_ME CLD_BROADCAST
86 #define CK_PE_ANY        CLD_ANYWHERE
87
88 /******************************************************************************
89  *
90  * Message Allocation Calls
91  *
92  *****************************************************************************/
93 #ifdef __cplusplus
94 class CkEntryOptions;
95 extern void* CkAllocSysMsg(const CkEntryOptions *opts = NULL);
96 #ifndef GROUPDEPNUM_DECLARED
97 # define GROUPDEPNUM_DECLARED
98 struct GroupDepNum
99 {
100   int groupDepNum;
101   explicit GroupDepNum(int g = 0) : groupDepNum{g} { }
102   operator int() const { return groupDepNum; }
103 };
104 #endif
105 extern void* CkAllocMsg(int msgIdx, int msgBytes, int prioBits, GroupDepNum groupDepNum=GroupDepNum{});
106 #endif
107 extern void  CkFreeSysMsg(void *msg);
108 extern void* CkAllocBuffer(void *msg, int bufsize);
109 extern void  CkFreeMsg(void *msg);
110 extern void* CkCopyMsg(void **pMsg);
111 extern void  CkSetQueueing(void *msg, int strategy);
112 extern void* CkPriorityPtr(void *msg);
113
114 /******************************************************************************
115  *
116  * Functions be to called from external clients (e.g. Charm4py)
117  *
118  *****************************************************************************/
119
120 extern void registerCkRegisterMainModuleCallback(void (*cb)());
121 extern void registerMainchareCtorExtCallback(void (*cb)(int, void*, int, int, char **));
122 extern void registerReadOnlyRecvExtCallback(void (*cb)(int, char*));
123 extern void registerChareMsgRecvExtCallback(void (*cb)(int, void*, int, int, char*, int));
124 extern void registerGroupMsgRecvExtCallback(void (*cb)(int, int, int, char *, int));
125 extern void registerArrayMsgRecvExtCallback(void (*cb)(int, int, int *, int, int, char *, int));
126 extern void registerArrayElemLeaveExtCallback(int (*cb)(int, int, int *, char**, int));
127 extern void registerArrayElemJoinExtCallback(void (*cb)(int, int, int *, int, char*, int));
128 extern void registerArrayResumeFromSyncExtCallback(void (*cb)(int, int, int *));
129 extern void registerArrayMapProcNumExtCallback(int (*cb)(int, int, const int *));
130 extern void StartCharmExt(int argc, char **argv); // start Converse/Charm, argv are the command-line arguments
131 extern int CkMyPeHook();   // function equivalent of CkMyPe macro
132 extern int CkNumPesHook(); // function equivalent of CkNumPes macro
133 /// Get current redNo of specified group instance on this PE
134 extern int CkGroupGetReductionNumber(int gid);
135 /// Get current redNo of specified array element on this PE
136 extern int CkArrayGetReductionNumber(int aid, int ndims, int *index);
137 extern void registerCreateReductionTargetMsgExtCallback(void (*cb)(void*, int, int, int, char**, int*));
138 extern void registerPyReductionExtCallback(int (*cb)(char**, int*, int, char**));
139
140 /*********************************************************/
141 /**
142 \addtogroup CkRegister
143 \brief Charm Registration--keeps track of the possible chare and method types.
144
145 These are implemented in register.C.
146 */
147 /*@{*/
148 /** Message pack function: convert a message into a buffer. */
149 typedef void* (*CkPackFnPtr)(void *msg);
150 /** Message unpack function: convert a buffer into a message. */
151 typedef void* (*CkUnpackFnPtr)(void *buf);
152 /** Message dealloc function: deletes a message. */
153 typedef void (*CkDeallocFnPtr)(void *msg);
154
155 /** Register this message name, with this basic size and pack and unpack functions. */
156 extern int CkRegisterMsg(const char *name, CkPackFnPtr pack, 
157                        CkUnpackFnPtr unpack, CkDeallocFnPtr dealloc, size_t size);
158
159 /** This entry point flag indicates the method does not keep the passed-in message. */
160 #define CK_EP_NOKEEP        (1<<2) 
161 #define CK_EP_INTRINSIC     (1<<3) 
162 #define CK_EP_TRACEDISABLE  (1<<4) 
163
164 #define CK_EP_MEMCRITICAL (1<<5)
165 #define CK_EP_APPWORK     (1<<6)
166 #define CK_EP_IMMEDIATE   (1<<7)
167 #define CK_EP_INLINE      (1<<8)
168
169 /** type of a chare */
170 #if CMK_MESSAGE_LOGGING
171 typedef enum{
172         TypeInvalid=0,
173         TypeChare,
174         TypeMainChare,
175         TypeGroup,
176         TypeNodeGroup,
177         TypeArray,
178         TypeSection
179 } ChareType;
180 #else
181 typedef enum{
182         TypeInvalid=0,
183         TypeChare,
184         TypeMainChare,
185         TypeGroup,
186         TypeNodeGroup,
187         TypeArray
188 } ChareType;
189 #endif
190
191 /** A "call function" to invoke a method on an object. See EntryInfo */
192 typedef void  (*CkCallFnPtr) (void *msg, void *obj);
193 /** Register this entry point, with this call function and flags.
194     Returns the entry point's index in the _entryTable. */
195 extern int CkRegisterEp(const char *name, CkCallFnPtr call, int msgIdx,
196                         int chareIdx, int ck_ep_flags);
197 extern int CkRegisterEpTemplated(const char *name, CkCallFnPtr call, int msgIdx,
198                                  int chareIdx, int ck_ep_flags);
199
200 /** Register this type of chare (group, or array), with this size.
201     Returns the Chare's index in the _chareTable. */
202 extern int CkRegisterChare(const char *name, size_t dataSz, ChareType chareType);
203 /** Register number of array dimensions for this chare array*/
204 extern void CkRegisterArrayDimensions(int chareIndex, int ndims);
205 /** Register this chare as internal to Charm++.*/
206 extern void CkRegisterChareInCharm(int chareIndex);
207 /** Register this chare as a mainchare, with this entry point as its constructor.*/
208 extern int CkRegisterMainChare(int chareIndex, int epIndex);
209 extern void CkRegisterMainChareExt(const char *s, int numEntryMethods, int *chareIdx, int *startEpIdx);
210 /** Register a default constructor for this chare.*/
211 extern void CkRegisterDefaultCtor(int chareIndex, int ctorEpIndex);
212 /** Register a migration constructor for this chare.*/
213 extern void CkRegisterMigCtor(int chareIndex, int ctorEpIndex);
214 /** Indicate whether this group is an IrrGroup. */
215 extern void CkRegisterGroupIrr(int chareIndex,int isIrr);
216 extern void CkRegisterGroupExt(const char *s, int numEntryMethods, int *chareIdx, int *startEpIdx);
217 extern void CkRegisterArrayMapExt(const char *s, int numEntryMethods, int *chareIdx, int *startEpIdx);
218 extern void CkRegisterArrayExt(const char *s, int numEntryMethods, int *chareIdx, int *startEpIdx);
219 /** Register the chare baseIdx as a base class of the chare derivedIdx. */
220 extern void CkRegisterBase(int derivedIdx, int baseIdx);
221
222 /** This function pup's a global variable.*/
223 typedef void (*CkPupReadonlyFnPtr)(void *pup_er);
224 /** Register this readonly global variable.*/
225 extern void CkRegisterReadonly(const char *name,const char *type,
226         size_t size, void *ptr,CkPupReadonlyFnPtr pup_fn);
227 extern void CkRegisterReadonlyExt(const char *name, const char *type, size_t msgSize, char *msg);
228 /** Register this readonly message.*/
229 extern void CkRegisterReadonlyMsg(const char *name,const char *type,
230         void** pMsg);
231
232 /** A "marshall unpack" function: pups out parameters and calls a method. */
233 typedef int (*CkMarshallUnpackFn)(char *marshall_buf,void *object);
234 /** Register this marshall unpack function with this entry point.*/
235 extern void CkRegisterMarshallUnpackFn(int epIndex,CkMarshallUnpackFn m);
236 /** Lookup the marshall unpack function, if any, for this entry point.*/
237 extern CkMarshallUnpackFn CkLookupMarshallUnpackFn(int epIndex);
238
239 #ifdef __cplusplus
240 /** A "message pup" function: pups message data for debugger display. */
241 typedef void (*CkMessagePupFn)(PUP::er &p,void *userMessage);
242 /** Register this message pup function with this entry point.*/
243 extern void CkRegisterMessagePupFn(int epIndex,CkMessagePupFn m);
244 #endif
245 /*@}*/
246
247 /*********************************************************/
248 /**
249 \addtogroup Ck
250 \brief Charm Kernel--the groups and chares level of Charm++.
251
252 These routines are implemented in ck.C.
253 */
254 /*@{*/
255
256 typedef struct {
257   int   onPE;
258   void* objPtr;
259 } CkChareID;
260
261 typedef struct _ckGroupID{
262   int idx;              /* pe(processor number) is removed from the structure */
263 #ifdef __cplusplus
264   inline void pup(PUP::er &p) {  p|idx; }
265   inline bool isZero(void) const { return (idx==0); }
266   inline void setZero(void) { idx=0; }
267   inline int operator==(const struct _ckGroupID& gid) const {
268     return (gid.idx==idx);
269   }
270   inline int operator<(const struct _ckGroupID& gid) const {
271     return (gid.idx<idx);
272   }
273 #endif
274 } CkGroupID;
275
276 typedef CkGroupID CkNodeGroupID;
277
278 /******************************************************************************
279  *
280  * Object Creation Calls
281  *
282  *****************************************************************************/
283 #ifdef __cplusplus
284 class envelope;
285 #else
286 typedef struct envelope envelope;
287 #endif
288 extern void CkCreateChare(int chareIdx, int constructorIdx, void *msg,
289                           CkChareID *vid, int destPE);
290 extern CkGroupID CkCreateGroup(int chareIdx, int constructorIdx, void *msg);
291 extern CkGroupID CkCreateNodeGroup(int chareIdx, int constructorIdx, void *msg);
292 extern void CkCreateLocalGroup(CkGroupID groupID, int constructorIdx, envelope *env);
293 extern void CkCreateLocalNodeGroup(CkGroupID groupID, int constructorIdx, envelope *env);
294
295 extern int CkCreateGroupExt(int cIdx, int eIdx, int num_bufs, char **bufs, int *buf_sizes);
296 extern int CkCreateArrayExt(int cIdx, int ndims, int *dims, int eIdx, int num_bufs, char **bufs, int *buf_sizes, int map_gid, char useAtSync);
297 extern void CkInsertArrayExt(int aid, int ndims, int *index, int epIdx, int onPE, int num_bufs, char **bufs, int *buf_sizes, char useAtSync);
298 extern void CkArrayDoneInsertingExt(int aid);
299 extern void CkMigrateExt(int aid, int ndims, int *index, int toPe);
300
301
302 /******************************************************************************
303
304  This set of message type (mtype) constants
305  defines the basic class of charm++ message.
306  
307  It is very questionable whether bizarre stuff like
308  "ExitMsg", "StatMsg", "ROMsgMsg" should actually
309  share the envelope with regular user messages;
310  but it doesn't waste any space so it's probably OK.
311
312  These were formerly in envelope.h
313
314  *****************************************************************************/
315 /*** WARNING!!!! The following enum is linked to charmdebug finals in MsgInfo.java.
316  *   Make sure the two remain synchronized if changing this one.
317  ***/
318 typedef enum {
319   NewChareMsg     =1,               // Singleton chare creation message
320   NewVChareMsg    =2,               // Singleton virtual chare creation message
321   BocInitMsg      =3,               // Group creation message
322   ForChareMsg     =4,               // Singleton chare entry method message (non creation)
323   ForBocMsg       =5,               // Group entry method message (non creation)
324   ForVidMsg       =6,               // Singleton virtual chare entry method message (non creation)
325   FillVidMsg      =7,               // Message sent to fill a VidBlock on a virtual chare PE
326   DeleteVidMsg    =8,               // Message sent to delete a VidBlock on a virtual chare PE
327   RODataMsg       =9,               // Readonly Data Message (for user declared readonly variables)
328   ROMsgMsg        =10,              // Readonly message Message (for user declared readonly messages)
329   StartExitMsg    =11,              // Exit sequence trigger message
330   ExitMsg         =12,              // Exit sequence trigger message using user registered exit function
331   ReqStatMsg      =13,              // Request stats and warnings message
332   StatMsg         =14,              // Stats data message (Reduction)
333   StatDoneMsg     =15,              // Signal completion of stats reduction (Broadcast)
334   NodeBocInitMsg  =16,              // Nodegroup creation message
335   ForNodeBocMsg   =17,              // Nodegroup entry method message (non creation)
336   ArrayEltInitMsg =18,              // Array Element Initialization message
337   ForArrayEltMsg  =19,              // Array Element entry method message
338   ForIDedObjMsg   =20,
339 #if CMK_LOCKLESS_QUEUE
340   WarnMsg         =21,              // Warning data message (Reduction)
341   WarnDoneMsg     =22,              // Signal completion of warnings reduction (Broadcast)
342   LAST_CK_ENVELOPE_TYPE =23         // Used for error-checking
343 #else
344   LAST_CK_ENVELOPE_TYPE =21         // Used for error-checking
345 #endif
346 } CkEnvelopeType;
347
348
349
350 /******************************************************************************
351  *
352  * Asynchronous Remote Method Invocation Calls
353  *
354  *****************************************************************************/
355
356 #define CK_MSG_INLINE           0x1
357 #define CK_MSG_IMMEDIATE        0x2
358 #define CK_MSG_EXPEDITED        0x4
359 #define CK_MSG_KEEP             0x8    /* send without freeing message */
360 #define CK_MSG_LB_NOTRACE       0x10   /* load balancer doesn't trace */
361
362 #ifdef __cplusplus
363 #define CK_MSGOPTIONAL =0
364 #else
365 #define CK_MSGOPTIONAL
366 #endif
367
368 extern void CkSendMsg(int entryIndex, void *msg, const CkChareID *chare, int opts CK_MSGOPTIONAL);
369 extern void CkSendMsgBranch(int eIdx, void *msg, int destPE, CkGroupID gID, int opts CK_MSGOPTIONAL);
370 extern void CkSendMsgInline(int entryIndex, void *msg, const CkChareID *chare, int opts CK_MSGOPTIONAL);
371 extern void CkSendMsgBranchInline(int eIdx, void *msg, int destPE, CkGroupID gID, int opts CK_MSGOPTIONAL);
372 extern void CkSendMsgBranchMulti(int eIdx, void *msg, CkGroupID gID, int npes, int *pes, int opts CK_MSGOPTIONAL);
373 extern void CkSendMsgBranchGroup(int eIdx,void *msg,CkGroupID gID,CmiGroup grp, int opts CK_MSGOPTIONAL);
374 extern void CkSendMsgNodeBranch(int eIdx, void *msg, int destNode, CkGroupID gID, int opts CK_MSGOPTIONAL);
375 extern void CkSendMsgNodeBranchInline(int eIdx, void *msg, int destNode, CkGroupID gID, int opts CK_MSGOPTIONAL);
376 extern void CkSendMsgNodeBranchMulti(int eIdx, void *msg, CkGroupID gID, int npes, int *nodes, int opts CK_MSGOPTIONAL);
377 extern void CkBroadcastMsgBranch(int eIdx, void *msg, CkGroupID gID, int opts CK_MSGOPTIONAL);
378 extern void CkBroadcastMsgNodeBranch(int eIdx, void *msg, CkGroupID gID, int opts CK_MSGOPTIONAL);
379
380 extern int  CkChareMsgPrep(int eIdx, void *msg,const CkChareID *pCid);
381 extern void CkGroupMsgPrep(int eIdx, void *msg, CkGroupID gID);
382 extern void CkNodeGroupMsgPrep(int eIdx, void *msg, CkGroupID gID);
383
384 extern void CkSetRefNum(void *msg, CMK_REFNUM_TYPE ref);
385 extern CMK_REFNUM_TYPE  CkGetRefNum(void *msg);
386 extern int  CkGetSrcPe(void *msg);
387 extern int  CkGetSrcNode(void *msg);
388
389 extern void CkDeliverMessageFree(int epIdx,void *msg,void *object);
390 extern void CkDeliverMessageReadonly(int epIdx,const void *msg,void *object);
391
392 extern void *CkLocalBranch(CkGroupID gID);
393 extern void *CkLocalNodeBranch(CkGroupID gID);
394 extern void *CkLocalChare(const CkChareID *chare);
395
396 extern void CkArrayManagerDeliver(int onPe,void *msg, int opts CK_MSGOPTIONAL);
397
398 /// Send msg to chare with ID (onPe,objPtr) to entry method 'epIdx'
399 extern void CkChareExtSend(int onPE, void *objPtr, int epIdx, char *msg, int msgSize);
400 /// Send msg to chare copying data into CkMessage from multiple input buffers
401 extern void CkChareExtSend_multi(int onPE, void *objPtr, int epIdx, int num_bufs, char **bufs, int *buf_sizes);
402 /// Send msg to group with ID 'gid'. if pe == -1, msg will be broadcasted, else
403 /// it will go to the group instance in that PE
404 extern void CkGroupExtSend(int gid, int pe, int epIdx, char *msg, int msgSize);
405 /// Send msg to group copying data into CkMessage from multiple input buffers
406 extern void CkGroupExtSend_multi(int gid, int pe, int epIdx, int num_bufs, char **bufs, int *buf_sizes);
407 /// Send msg to array with ID 'aid'. idx is index of destination and ndims the number
408 /// of dimensions of the index. If ndims <= 0, msg will be broadcasted to all array elements
409 extern void CkArrayExtSend(int aid, int *idx, int ndims, int epIdx, char *msg, int msgSize);
410 /// Send msg to array copying data into CkMessage from multiple input buffers
411 extern void CkArrayExtSend_multi(int aid, int *idx, int ndims, int epIdx, int num_bufs, char **bufs, int *buf_sizes);
412
413 /*@}*/
414
415
416
417 /******************************************************************************
418  *
419  * Semaphore calls
420  *
421  *****************************************************************************/
422
423 typedef struct _ckSemaID {
424   int pe;
425   int idx;
426 #ifdef __cplusplus
427   public:
428     void pup(PUP::er &p) { p(pe); p(idx); }
429 #endif
430 } CkSemaID;
431
432 extern CkSemaID CkSemaCreate(void);
433 extern void *CkSemaWait(CkSemaID id);
434 extern void CkSemaWaitN(CkSemaID id, int n, void *marray[]);
435 extern void CkSemaSignal(CkSemaID id, void *m);
436 extern void CkSemaDestroy(CkSemaID id);
437 /*@}*/
438
439
440 /******************************************************************************
441  *
442  * Quiescence Calls
443  *
444  *****************************************************************************/
445 /**
446 \addtogroup CkQD
447 \brief Quiescence Detection--a way to tell when nothing is happening.
448
449 These routines are implemented in qd.C and waitqd.C.
450 */
451 /*@{*/
452
453 /** When quiescence occurs, send a message to this entry point of this Chare. */
454 extern void CkStartQD(int eIdx,const CkChareID *chare);
455 /** Block until quiescence occurs. */
456 extern void CkWaitQD(void);
457 /*@}*/
458
459 /******************************************************************************
460  *
461  * Miscellaneous Calls
462  *
463  *****************************************************************************/
464
465 extern int CkMessageToEpIdx(void *msg);
466 extern void CkPrintEntryMethod(int epIdx);
467 extern void CkPrintChareName(int chareIdx);
468 extern void CkSummary_MarkEvent(int);
469 extern void CkSummary_StartPhase(int);
470 extern int CkDisableTracing(int epIdx);
471 extern void CkEnableTracing(int epIdx);
472
473 #ifdef __cplusplus
474 }
475 #endif
476 #endif