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