3 \brief Charm Kernel--the groups and chares level of Charm++.
9 #include <sys/types.h> /* for size_t */
17 /******************************************************************************
19 * Converse Concepts, renamed to CK
21 *****************************************************************************/
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
33 #define CkTimer CmiTimer
34 #define CkWallTimer CmiWallTimer
35 #define CkCpuTimer CmiCpuTimer
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
48 #define CkPrintf CmiPrintf
49 #define CkScanf CmiScanf
50 #define CkError CmiError
51 #define CkAbort CmiAbort
52 #define CkAssert CmiAssert
53 #define CkSetPeHelpsOtherThreads CmiSetPeHelpsOtherThreads
55 void realCkExit(int exitcode
);
57 /* Optional parameter for CkExit() - based on
58 https://stackoverflow.com/a/28074198/1250282 */
60 #define CKEXIT_1(x) realCkExit(x)
61 #define CKEXIT_0() CKEXIT_1(0) /* Default CkExit() exit code: 0 */
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__)
72 extern void CkCleanup(void);
74 extern char **CkGetArgv(void);
75 extern int CkGetArgc(void);
77 /******************************************************************************
79 * Miscellaneous Constants
81 *****************************************************************************/
83 #define CK_PE_ALL CLD_BROADCAST_ALL
84 #define CK_PE_ALL_BUT_ME CLD_BROADCAST
85 #define CK_PE_ANY CLD_ANYWHERE
87 /******************************************************************************
89 * Message Allocation Calls
91 *****************************************************************************/
94 extern void* CkAllocSysMsg(const CkEntryOptions
*opts
= NULL
);
95 #ifndef GROUPDEPNUM_DECLARED
96 # define GROUPDEPNUM_DECLARED
100 explicit GroupDepNum(int g
= 0) : groupDepNum
{g
} { }
101 operator int() const { return groupDepNum
; }
104 extern void* CkAllocMsg(int msgIdx
, int msgBytes
, int prioBits
, GroupDepNum groupDepNum
=GroupDepNum
{});
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
);
113 /******************************************************************************
115 * Functions be to called from external clients (e.g. Charm4py)
117 *****************************************************************************/
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
);
137 /*********************************************************/
139 \addtogroup CkRegister
140 \brief Charm Registration--keeps track of the possible chare and method types.
142 These are implemented in register.C.
145 /** Message pack function: convert a message into a buffer. */
146 typedef void* (*CkPackFnPtr
)(void *msg
);
147 /** Message unpack function: convert a buffer into a message. */
148 typedef void* (*CkUnpackFnPtr
)(void *buf
);
149 /** Message dealloc function: deletes a message. */
150 typedef void (*CkDeallocFnPtr
)(void *msg
);
152 /** Register this message name, with this basic size and pack and unpack functions. */
153 extern int CkRegisterMsg(const char *name
, CkPackFnPtr pack
,
154 CkUnpackFnPtr unpack
, CkDeallocFnPtr dealloc
, size_t size
);
156 /** This entry point flag indicates the method does not keep the passed-in message. */
157 #define CK_EP_NOKEEP (1<<2)
158 #define CK_EP_INTRINSIC (1<<3)
159 #define CK_EP_TRACEDISABLE (1<<4)
161 #define CK_EP_MEMCRITICAL (1<<5)
162 #define CK_EP_APPWORK (1<<6)
163 #define CK_EP_IMMEDIATE (1<<7)
164 #define CK_EP_INLINE (1<<8)
166 /** type of a chare */
167 #if CMK_MESSAGE_LOGGING
188 /** A "call function" to invoke a method on an object. See EntryInfo */
189 typedef void (*CkCallFnPtr
) (void *msg
, void *obj
);
190 /** Register this entry point, with this call function and flags.
191 Returns the entry point's index in the _entryTable. */
192 extern int CkRegisterEp(const char *name
, CkCallFnPtr call
, int msgIdx
,
193 int chareIdx
, int ck_ep_flags
);
194 extern int CkRegisterEpTemplated(const char *name
, CkCallFnPtr call
, int msgIdx
,
195 int chareIdx
, int ck_ep_flags
);
197 /** Register this type of chare (group, or array), with this size.
198 Returns the Chare's index in the _chareTable. */
199 extern int CkRegisterChare(const char *name
, size_t dataSz
, ChareType chareType
);
200 /** Register number of array dimensions for this chare array*/
201 extern void CkRegisterArrayDimensions(int chareIndex
, int ndims
);
202 /** Register this chare as internal to Charm++.*/
203 extern void CkRegisterChareInCharm(int chareIndex
);
204 /** Register this chare as a mainchare, with this entry point as its constructor.*/
205 extern int CkRegisterMainChare(int chareIndex
, int epIndex
);
206 extern void CkRegisterMainChareExt(const char *s
, int numEntryMethods
, int *chareIdx
, int *startEpIdx
);
207 /** Register a default constructor for this chare.*/
208 extern void CkRegisterDefaultCtor(int chareIndex
, int ctorEpIndex
);
209 /** Register a migration constructor for this chare.*/
210 extern void CkRegisterMigCtor(int chareIndex
, int ctorEpIndex
);
211 /** Indicate whether this group is an IrrGroup. */
212 extern void CkRegisterGroupIrr(int chareIndex
,int isIrr
);
213 extern void CkRegisterGroupExt(const char *s
, int numEntryMethods
, int *chareIdx
, int *startEpIdx
);
214 extern void CkRegisterArrayMapExt(const char *s
, int numEntryMethods
, int *chareIdx
, int *startEpIdx
);
215 extern void CkRegisterArrayExt(const char *s
, int numEntryMethods
, int *chareIdx
, int *startEpIdx
);
216 /** Register the chare baseIdx as a base class of the chare derivedIdx. */
217 extern void CkRegisterBase(int derivedIdx
, int baseIdx
);
219 /** This function pup's a global variable.*/
220 typedef void (*CkPupReadonlyFnPtr
)(void *pup_er
);
221 /** Register this readonly global variable.*/
222 extern void CkRegisterReadonly(const char *name
,const char *type
,
223 size_t size
, void *ptr
,CkPupReadonlyFnPtr pup_fn
);
224 extern void CkRegisterReadonlyExt(const char *name
, const char *type
, size_t msgSize
, char *msg
);
225 /** Register this readonly message.*/
226 extern void CkRegisterReadonlyMsg(const char *name
,const char *type
,
229 /** A "marshall unpack" function: pups out parameters and calls a method. */
230 typedef int (*CkMarshallUnpackFn
)(char *marshall_buf
,void *object
);
231 /** Register this marshall unpack function with this entry point.*/
232 extern void CkRegisterMarshallUnpackFn(int epIndex
,CkMarshallUnpackFn m
);
233 /** Lookup the marshall unpack function, if any, for this entry point.*/
234 extern CkMarshallUnpackFn
CkLookupMarshallUnpackFn(int epIndex
);
237 /** A "message pup" function: pups message data for debugger display. */
238 typedef void (*CkMessagePupFn
)(PUP::er
&p
,void *userMessage
);
239 /** Register this message pup function with this entry point.*/
240 extern void CkRegisterMessagePupFn(int epIndex
,CkMessagePupFn m
);
244 /*********************************************************/
247 \brief Charm Kernel--the groups and chares level of Charm++.
249 These routines are implemented in ck.C.
258 typedef struct _ckGroupID
{
259 int idx
; /* pe(processor number) is removed from the structure */
261 inline void pup(PUP::er
&p
) { p
|idx
; }
262 inline bool isZero(void) const { return (idx
==0); }
263 inline void setZero(void) { idx
=0; }
264 inline int operator==(const struct _ckGroupID
& gid
) const {
265 return (gid
.idx
==idx
);
267 inline int operator<(const struct _ckGroupID
& gid
) const {
268 return (gid
.idx
<idx
);
273 typedef CkGroupID CkNodeGroupID
;
275 /******************************************************************************
277 * Object Creation Calls
279 *****************************************************************************/
283 typedef struct envelope envelope
;
285 extern void CkCreateChare(int chareIdx
, int constructorIdx
, void *msg
,
286 CkChareID
*vid
, int destPE
);
287 extern CkGroupID
CkCreateGroup(int chareIdx
, int constructorIdx
, void *msg
);
288 extern CkGroupID
CkCreateNodeGroup(int chareIdx
, int constructorIdx
, void *msg
);
289 extern void CkCreateLocalGroup(CkGroupID groupID
, int constructorIdx
, envelope
*env
);
290 extern void CkCreateLocalNodeGroup(CkGroupID groupID
, int constructorIdx
, envelope
*env
);
292 extern int CkCreateGroupExt(int cIdx
, int eIdx
, int num_bufs
, char **bufs
, int *buf_sizes
);
293 extern int CkCreateArrayExt(int cIdx
, int ndims
, int *dims
, int eIdx
, int num_bufs
, char **bufs
, int *buf_sizes
, int map_gid
, char useAtSync
);
294 extern void CkInsertArrayExt(int aid
, int ndims
, int *index
, int epIdx
, int onPE
, int num_bufs
, char **bufs
, int *buf_sizes
, char useAtSync
);
295 extern void CkArrayDoneInsertingExt(int aid
);
296 extern void CkMigrateExt(int aid
, int ndims
, int *index
, int toPe
);
299 /******************************************************************************
301 This set of message type (mtype) constants
302 defines the basic class of charm++ message.
304 It is very questionable whether bizarre stuff like
305 "ExitMsg", "StatMsg", "ROMsgMsg" should actually
306 share the envelope with regular user messages;
307 but it doesn't waste any space so it's probably OK.
309 These were formerly in envelope.h
311 *****************************************************************************/
312 /*** WARNING!!!! The following enum is linked to charmdebug finals in MsgInfo.java.
313 * Make sure the two remain synchronized if changing this one.
336 #if CMK_LOCKLESS_QUEUE
339 LAST_CK_ENVELOPE_TYPE
=23
341 LAST_CK_ENVELOPE_TYPE
=21
347 /******************************************************************************
349 * Asynchronous Remote Method Invocation Calls
351 *****************************************************************************/
353 #define CK_MSG_INLINE 0x1
354 #define CK_MSG_IMMEDIATE 0x2
355 #define CK_MSG_EXPEDITED 0x4
356 #define CK_MSG_KEEP 0x8 /* send without freeing message */
357 #define CK_MSG_LB_NOTRACE 0x10 /* load balancer doesn't trace */
360 #define CK_MSGOPTIONAL =0
362 #define CK_MSGOPTIONAL
365 extern void CkSendMsg(int entryIndex
, void *msg
, const CkChareID
*chare
, int opts CK_MSGOPTIONAL
);
366 extern void CkSendMsgBranch(int eIdx
, void *msg
, int destPE
, CkGroupID gID
, int opts CK_MSGOPTIONAL
);
367 extern void CkSendMsgInline(int entryIndex
, void *msg
, const CkChareID
*chare
, int opts CK_MSGOPTIONAL
);
368 extern void CkSendMsgBranchInline(int eIdx
, void *msg
, int destPE
, CkGroupID gID
, int opts CK_MSGOPTIONAL
);
369 extern void CkSendMsgBranchMulti(int eIdx
, void *msg
, CkGroupID gID
, int npes
, int *pes
, int opts CK_MSGOPTIONAL
);
370 extern void CkSendMsgBranchGroup(int eIdx
,void *msg
,CkGroupID gID
,CmiGroup grp
, int opts CK_MSGOPTIONAL
);
371 extern void CkSendMsgNodeBranch(int eIdx
, void *msg
, int destNode
, CkGroupID gID
, int opts CK_MSGOPTIONAL
);
372 extern void CkSendMsgNodeBranchInline(int eIdx
, void *msg
, int destNode
, CkGroupID gID
, int opts CK_MSGOPTIONAL
);
373 extern void CkSendMsgNodeBranchMulti(int eIdx
, void *msg
, CkGroupID gID
, int npes
, int *nodes
, int opts CK_MSGOPTIONAL
);
374 extern void CkBroadcastMsgBranch(int eIdx
, void *msg
, CkGroupID gID
, int opts CK_MSGOPTIONAL
);
375 extern void CkBroadcastMsgNodeBranch(int eIdx
, void *msg
, CkGroupID gID
, int opts CK_MSGOPTIONAL
);
377 extern int CkChareMsgPrep(int eIdx
, void *msg
,const CkChareID
*pCid
);
378 extern void CkGroupMsgPrep(int eIdx
, void *msg
, CkGroupID gID
);
379 extern void CkNodeGroupMsgPrep(int eIdx
, void *msg
, CkGroupID gID
);
381 extern void CkSetRefNum(void *msg
, CMK_REFNUM_TYPE ref
);
382 extern CMK_REFNUM_TYPE
CkGetRefNum(void *msg
);
383 extern int CkGetSrcPe(void *msg
);
384 extern int CkGetSrcNode(void *msg
);
386 extern void CkDeliverMessageFree(int epIdx
,void *msg
,void *object
);
387 extern void CkDeliverMessageReadonly(int epIdx
,const void *msg
,void *object
);
389 extern void *CkLocalBranch(CkGroupID gID
);
390 extern void *CkLocalNodeBranch(CkGroupID gID
);
391 extern void *CkLocalChare(const CkChareID
*chare
);
393 extern void CkArrayManagerDeliver(int onPe
,void *msg
, int opts CK_MSGOPTIONAL
);
395 /// Send msg to chare with ID (onPe,objPtr) to entry method 'epIdx'
396 extern void CkChareExtSend(int onPE
, void *objPtr
, int epIdx
, char *msg
, int msgSize
);
397 /// Send msg to chare copying data into CkMessage from multiple input buffers
398 extern void CkChareExtSend_multi(int onPE
, void *objPtr
, int epIdx
, int num_bufs
, char **bufs
, int *buf_sizes
);
399 /// Send msg to group with ID 'gid'. if pe == -1, msg will be broadcasted, else
400 /// it will go to the group instance in that PE
401 extern void CkGroupExtSend(int gid
, int pe
, int epIdx
, char *msg
, int msgSize
);
402 /// Send msg to group copying data into CkMessage from multiple input buffers
403 extern void CkGroupExtSend_multi(int gid
, int pe
, int epIdx
, int num_bufs
, char **bufs
, int *buf_sizes
);
404 /// Send msg to array with ID 'aid'. idx is index of destination and ndims the number
405 /// of dimensions of the index. If ndims <= 0, msg will be broadcasted to all array elements
406 extern void CkArrayExtSend(int aid
, int *idx
, int ndims
, int epIdx
, char *msg
, int msgSize
);
407 /// Send msg to array copying data into CkMessage from multiple input buffers
408 extern void CkArrayExtSend_multi(int aid
, int *idx
, int ndims
, int epIdx
, int num_bufs
, char **bufs
, int *buf_sizes
);
414 /******************************************************************************
418 *****************************************************************************/
420 typedef struct _ckSemaID
{
425 void pup(PUP::er
&p
) { p(pe
); p(idx
); }
429 extern CkSemaID
CkSemaCreate(void);
430 extern void *CkSemaWait(CkSemaID id
);
431 extern void CkSemaWaitN(CkSemaID id
, int n
, void *marray
[]);
432 extern void CkSemaSignal(CkSemaID id
, void *m
);
433 extern void CkSemaDestroy(CkSemaID id
);
437 /******************************************************************************
441 *****************************************************************************/
444 \brief Quiescence Detection--a way to tell when nothing is happening.
446 These routines are implemented in qd.C and waitqd.C.
450 /** When quiescence occurs, send a message to this entry point of this Chare. */
451 extern void CkStartQD(int eIdx
,const CkChareID
*chare
);
452 /** Block until quiescence occurs. */
453 extern void CkWaitQD(void);
456 /******************************************************************************
458 * Miscellaneous Calls
460 *****************************************************************************/
462 extern int CkMessageToEpIdx(void *msg
);
463 extern void CkPrintEntryMethod(int epIdx
);
464 extern void CkPrintChareName(int chareIdx
);
465 extern void CkSummary_MarkEvent(int);
466 extern void CkSummary_StartPhase(int);
467 extern int CkDisableTracing(int epIdx
);
468 extern void CkEnableTracing(int epIdx
);