doc: clean up syntax highlighting
[charm.git] / doc / converse / manual.rst
1 ====================
2 Converse Programming
3 ====================
4
5 .. contents::
6    :depth: 3
7
8 .. _initial:
9
10 Initialization and Completion
11 =============================
12
13 The program utilizing Converse begins executing at ``main``, like any
14 other C program. The initialization process is somewhat complicated by
15 the fact that hardware vendors don’t agree about which processors should
16 execute ``main``. On some machines, every processor executes ``main``.
17 On others, only one processor executes ``main``. All processors which
18 don’t execute ``main`` are asleep when the program begins. The function
19 ``ConverseInit`` is used to start the Converse system, and to wake up the
20 sleeping processors.
21
22 .. code-block:: c++
23
24    typedef void (*CmiStartFn)(int argc, char **argv);
25    void ConverseInit(int argc, char *argv[], CmiStartFn fn, int usched, int
26    initret);
27
28 This function starts up the Converse system. It can execute in one of
29 the modes described below.
30
31 Normal Mode: ``schedmode=0, initret=0``
32
33 When the user runs a program, some of the processors automatically
34 invoke ``main``, while others remain asleep. All processors which
35 automatically invoked ``main`` must call ``ConverseInit``. This initializes
36 the entire Converse system. Converse then initiates, on *all*
37 processors, the execution of the user-supplied start-function
38 ``fn(argc, argv)``. When this function returns, Converse automatically
39 calls ``CsdScheduler``, a function that polls for messages and executes
40 their handlers (see chapter 2). Once ``CsdScheduler`` exits on all
41 processors, the Converse system shuts down, and the user’s program
42 terminates. Note that in this case, ``ConverseInit`` never returns. The user
43 is not allowed to poll for messages manually.
44
45 User-calls-scheduler Mode: ``schedmode=1, initret=0``
46
47 If the user wants to poll for messages and other events manually, this
48 mode is used to initialize Converse. In normal mode, it is assumed that
49 the user-supplied start-function ``fn(argc, argv)`` is just for
50 initialization, and that the remainder of the lifespan of the program is
51 spent in the (automatically-invoked) function ``CsdScheduler``, polling
52 for messages. In user-calls-scheduler mode, however, it is assumed that
53 the user-supplied start-function will perform the *entire computation*,
54 including polling for messages. Thus, ``ConverseInit`` will not
55 automatically call ``CsdScheduler`` for you. When the user-supplied
56 start-function ends, Converse shuts down. This mode is not supported on
57 the sim version. This mode can be combined with ConverseInit-returns
58 mode below.
59
60 ConverseInit-returns Mode: ``schedmode=1, initret=1``
61
62 This option is used when you want ``ConverseInit`` to return. All processors
63 which automatically invoked ``main`` must call ``ConverseInit``. This
64 initializes the entire Converse System. On all processors which *did
65 not* automatically invoke ``main``, Converse initiates the user-supplied
66 initialization function ``fn(argc, argv)``. Meanwhile, on those
67 processors which *did* automatically invoke ``main``, ``ConverseInit``
68 returns. Shutdown is initiated when the processors that *did*
69 automatically invoke ``main`` call ConverseExit, and when the other
70 processors return from ``fn``. The optional exit code is returned to the
71 calling shell. If no value is specified, an exit code of zero is
72 returned. In this mode, all polling for messages must be done manually
73 (probably using CsdScheduler explicitly). This option is not supported
74 by the sim version.
75
76 .. code-block:: c++
77
78   void ConverseExit(int exitcode /*optional*/)
79
80 This function is only used in ConverseInit-returns mode, described
81 above.
82
83 .. code-block:: c++
84
85   void CmiAbort(char *msg)
86
87 This function can be used portably to abnormally terminate a Converse
88 program. Before termination, it prints a message supplied as ``msg``.
89
90 .. code-block:: c++
91
92   void CmiAssert(int expr)
93
94 This macro terminates the Converse program after printing an informative
95 message if ``expr`` evaluates to 0. It can be used in place of
96 ``assert``. In order to turn off ``CmiAssert``, one should define
97 :math:`CMK\_OPTIMIZE` as 1.
98
99 Machine Interface and Scheduler
100 ===============================
101
102 This chapter describes two of Converse’s modules: the CMI, and the CSD.
103 Together, they serve to transmit messages and schedule the delivery of
104 messages. First, we describe the machine model assumed by Converse.
105
106 .. _model:
107
108 Machine Model
109 -------------
110
111 Converse treats the parallel machine as a collection of *nodes*, where
112 each node is comprised of a number of *processors* that share memory In
113 some cases, the number of processors per node may be exactly one (e.g.
114 Distributed memory multicomputers such as IBM SP.) In addition, each of
115 the processors may have multiple *threads* running on them which share
116 code and data but have different stacks. Functions and macros are
117 provided for handling shared memory across processors and querying node
118 information. These are discussed in Section :numref:`globalvars`.
119
120 .. _handler1:
121
122 Defining Handler Numbers
123 ------------------------
124
125 When a message arrives at a processor, it triggers the execution of a
126 *handler function*, not unlike a UNIX signal handler. The handler
127 function receives, as an argument, a pointer to the message. The message
128 itself specifies which handler function is to be called when the message
129 arrives. Messages are contiguous sequences of bytes. The message has two
130 parts: the header, and the data. The data may contain anything you like.
131 The header contains a *handler number*, which specifies which handler
132 function is to be executed when the message arrives. Before you can send
133 a message, you have to define the handler numbers.
134
135 Converse maintains a table mapping handler numbers to function pointers.
136 Each processor has its own copy of the mapping. There is a caution
137 associated with this approach: it is the user’s responsibility to ensure
138 that all processors have identical mappings. This is easy to do,
139 nonetheless, and the user must be aware that this is (usually) required.
140
141 The following functions are provided to define the handler numbers:
142
143 .. code-block:: c++
144
145   typedef void (*CmiHandler)(void *)
146
147 Functions that handle Converse messages must be of this type.
148
149 .. code-block:: c++
150
151   int CmiRegisterHandler(CmiHandler h)
152
153 This represents the standard technique for associating numbers with
154 functions. To use this technique, the Converse user registers each of
155 his functions, one by one, using CmiRegisterHandler. One must register
156 exactly the same functions in exactly the same order on all processors.
157 The system assigns monotonically increasing numbers to the functions,
158 the same numbers on all processors. This insures global consistency.
159 CmiRegisterHandler returns the number which was chosen for the function
160 being registered.
161
162 .. code-block:: c++
163
164   int CmiRegisterHandlerGlobal(CmiHandler h)
165
166 This represents a second registration technique. The Converse user
167 registers his functions on processor zero, using
168 CmiRegisterHandlerGlobal. The Converse user is then responsible for
169 broadcasting those handler numbers to other processors, and installing
170 them using CmiNumberHandler below. The user should take care not to
171 invoke those handlers until they are fully installed.
172
173 .. code-block:: c++
174
175   int CmiRegisterHandlerLocal(CmiHandler h)
176
177 This function is used when one wishes to register functions in a manner
178 that is not consistent across processors. This function chooses a
179 locally-meaningful number for the function, and records it locally. No
180 attempt is made to ensure consistency across processors.
181
182 .. code-block:: c++
183
184   void CmiNumberHandler(int n, CmiHandler h)
185
186 Forces the system to associate the specified handler number n with the
187 specified handler function h. If the function number n was previously
188 mapped to some other function, that old mapping is forgotten. The
189 mapping that this function creates is local to the current processor.
190 CmiNumberHandler can be useful in combination with
191 CmiRegisterGlobalHandler. It can also be used to implement user-defined
192 numbering schemes: such schemes should keep in mind that the size of the
193 table that holds the mapping is proportional to the largest handler
194 number — do not use big numbers!
195
196 (**Note:** Of the three registration methods, the CmiRegisterHandler
197 method is by far the simplest, and is strongly encouraged. The others
198 are primarily to ease the porting of systems that already use similar
199 registration techniques. One may use all three registration methods in a
200 program. The system guarantees that no numbering conflicts will occur as
201 a result of this combination.)
202
203 .. _handler2:
204
205 Writing Handler Functions
206 -------------------------
207
208 A message handler function is just a C function that accepts a void
209 pointer (to a message buffer) as an argument, and returns nothing. The
210 handler may use the message buffer for any purpose, but is responsible
211 for eventually deleting the message using CmiFree.
212
213 Building Messages
214 -----------------
215
216 To send a message, one first creates a buffer to hold the message. The
217 buffer must be large enough to hold the header and the data. The buffer
218 can be in any kind of memory: it could be a local variable, it could be
219 a global, it could be allocated with ``malloc``, and finally, it could
220 be allocated with CmiAlloc. The Converse user fills the buffer with the
221 message data. One puts a handler number in the message, thereby
222 specifying which handler function the message should trigger when it
223 arrives. Finally, one uses a message-transmission function to send the
224 message.
225
226 The following functions are provided to help build message buffers:
227
228 .. code-block:: c++
229
230   void *CmiAlloc(int size)
231
232 Allocates memory of size size in heap and returns pointer to the usable
233 space. There are some message-sending functions that accept only message
234 buffers that were allocated with CmiAlloc. Thus, this is the preferred
235 way to allocate message buffers. The returned pointer point to the
236 message header, the user data will follow it. See CmiMsgHeaderSizeBytes
237 for this.
238
239 .. code-block:: c++
240
241   void CmiFree(void *ptr)
242
243 This function frees the memory pointed to by ptr. ptr should be a
244 pointer that was previously returned by CmiAlloc.
245
246 .. code-block:: c++
247
248   #define CmiMsgHeaderSizeBytes
249
250 This constant contains the size of the message header. When one
251 allocates a message buffer, one must set aside enough space for the
252 header and the data. This macro helps you to do so. For example, if one
253 want to allocate an array of 100 int, he should call the function this
254 way:
255
256 .. code-block:: c++
257
258   void CmiSetHandler(int *MessageBuffer, int HandlerId)
259
260 This macro sets the handler number of a message to HandlerId.
261
262 .. code-block:: c++
263
264   int CmiGetHandler(int *MessageBuffer)
265
266 This call returns the handler of a message in the form of a handler
267 number.
268
269 .. code-block:: c++
270
271   CmiHandler CmiGetHandlerFunction(int *MessageBuffer)
272
273 This call returns the handler of a message in the form of a function
274 pointer.
275
276 Sending Messages
277 ----------------
278
279 The following functions allow you to send messages. Our model is that
280 the data starts out in the message buffer, and from there gets
281 transferred “into the network”. The data stays “in the network” for a
282 while, and eventually appears on the target processor. Using that model,
283 each of these send-functions is a device that transfers data into the
284 network. None of these functions wait for the data to be delivered.
285
286 On some machines, the network accepts data rather slowly. We don’t want
287 the process to sit idle, waiting for the network to accept the data. So,
288 we provide several variations on each send function:
289
290 -  sync: a version that is as simple as possible, pushing the data into
291    the network and not returning until the data is “in the network”. As
292    soon as a sync function returns, you can reuse the message buffer.
293
294 -  async: a version that returns almost instantaneously, and then
295    continues working in the background. The background job transfers the
296    data from the message buffer into the network. Since the background
297    job is still using the message buffer when the function returns, you
298    can’t reuse the message buffer immediately. The background job sets a
299    flag when it is done and you can then reuse the message buffer.
300
301 -  send and free: a version that returns almost instantaneously, and
302    then continues working in the background. The background job
303    transfers the data from the message buffer into the network. When the
304    background job finishes, it CmiFrees the message buffer. In this
305    situation, you can’t reuse the message buffer at all. To use a
306    function of this type, you must allocate the message buffer using
307    CmiAlloc.
308
309 -  node: a version that send a message to a node instead of a specific
310    processor. This means that when the message is received, any “free”
311    processor within than node can handle it.
312
313 .. code-block:: c++
314
315   void CmiSyncSend(unsigned int destPE, unsigned int size, void *msg)
316
317 Sends msg of size size bytes to processor destPE. When it returns, you
318 may reuse the message buffer.
319
320 .. code-block:: c++
321
322   void CmiSyncNodeSend(unsigned int destNode, unsigned int size, void *msg)
323
324 Sends msg of size size bytes to node destNode. When it returns, you may
325 reuse the message buffer.
326
327 .. code-block:: c++
328
329   void CmiSyncSendAndFree(unsigned int destPE, unsigned int size, void *msg)
330
331 Sends msg of size size bytes to processor destPE. When it returns, the
332 message buffer has been freed using CmiFree.
333
334 .. code-block:: c++
335
336   void CmiSyncNodeSendAndFree(unsigned int destNode, unsigned int size, void *msg)
337
338 Sends msg of size size bytes to node destNode. When it returns, the
339 message buffer has been freed using CmiFree.
340
341 .. code-block:: c++
342
343   CmiCommHandle CmiAsyncSend(unsigned int destPE, unsigned int size, void *msg)
344
345 Sends msg of size size bytes to processor destPE. It returns a
346 communication handle which can be tested using CmiAsyncMsgSent: when
347 this returns true, you may reuse the message buffer. If the returned
348 communication handle is 0, message buffer can be reused immediately,
349 thus saving a call to CmiAsyncMsgSent.
350
351 .. code-block:: c++
352
353   CmiCommHandle CmiAsyncNodeSend(unsigned int destNode, unsigned int size, void *msg)
354
355 Sends msg of size size bytes to node destNode. It returns a
356 communication handle which can be tested using CmiAsyncMsgSent: when
357 this returns true, you may reuse the message buffer. If the returned
358 communication handle is 0, message buffer can be reused immediately,
359 thus saving a call to CmiAsyncMsgSent.
360
361 .. code-block:: c++
362
363   void CmiSyncVectorSend(int destPE, int len, int sizes[], char *msgComps[])
364
365 Concatenates several pieces of data and sends them to
366 processor destPE. The data consists of len pieces residing in different
367 areas of memory, which are logically concatenated. The msgComps array
368 contains pointers to the pieces; the size of msgComps[i] is taken from
369 sizes[i]. When it returns, sizes, msgComps and the message components
370 specified in msgComps can be immediately reused.
371
372 .. code-block:: c++
373
374   void CmiSyncVectorSendAndFree(int destPE, int len, int sizes[], char *msgComps[])
375
376 Concatenates several pieces of data and sends them to
377 processor destPE. The data consists of len pieces residing in different
378 areas of memory, which are logically concatenated. The msgComps array
379 contains pointers to the pieces; the size of msgComps[i] is taken from
380 sizes[i]. The message components specified in msgComps are CmiFreed by
381 this function therefore, they should be dynamically allocated using
382 CmiAlloc. However, the sizes and msgComps array themselves are not
383 freed.
384
385 .. code-block:: c++
386
387   CmiCommHandle CmiAsyncVectorSend(int destPE, int len, int sizes[], char *msgComps[])
388
389 Concatenates several pieces of data and sends them to
390 processor destPE. The data consists of len pieces residing in different
391 areas of memory, which are logically concatenated. The msgComps array
392 contains pointers to the pieces; the size of msgComps[i] is taken from
393 sizes[i]. The individual pieces of data as well as the arrays sizes and
394 msgComps should not be overwritten or freed before the communication is
395 complete. This function returns a communication handle which can be
396 tested using CmiAsyncMsgSent: when this returns true, the input
397 parameters can be reused. If the returned communication handle is 0,
398 message buffer can be reused immediately, thus saving a call to
399 CmiAsyncMsgSent.
400
401 .. code-block:: c++
402
403   int CmiAsyncMsgSent(CmiCommHandle handle)
404
405 Returns true if the communication specified by the given CmiCommHandle
406 has proceeded to the point where the message buffer can be reused.
407
408 .. code-block:: c++
409
410   void CmiReleaseCommHandle(CmiCommHandle handle)
411
412 Releases the communication handle handle and associated resources. It
413 does not free the message buffer.
414
415 .. code-block:: c++
416
417   void CmiMultipleSend(unsigned int destPE, int len, int sizes[], char *msgComps[])
418
419 This function allows the user to send multiple messages that may be
420 destined for the SAME PE in one go. This is more efficient than sending
421 each message to the destination node separately. This function assumes
422 that the handlers that are to receive this message have already been
423 set. If this is not done, the behavior of the function is undefined.
424
425 In the function, The destPE parameter identifies the destination
426 processor. The len argument identifies the *number* of messages that are
427 to be sent in one go. The sizes[] array is an array of sizes of each of
428 these messages. The msgComps[] array is the array of the messages. The
429 indexing in each array is from 0 to len - 1. (**Note:** Before calling
430 this function, the program needs to initialize the system to be able to
431 provide this service. This is done by calling the function
432 CmiInitMultipleSendRoutine. Unless this function is called, the system
433 will not be able to provide the service to the user.)
434
435 Broadcasting Messages
436 ---------------------
437 .. code-block:: c++
438
439   void CmiSyncBroadcast(unsigned int size, void *msg)
440
441 Sends msg of length size bytes to all processors excluding the processor
442 on which the caller resides.
443
444 .. code-block:: c++
445
446   void CmiSyncNodeBroadcast(unsigned int size, void *msg)
447
448 Sends msg of length size bytes to all nodes excluding the node on which
449 the caller resides.
450
451 .. code-block:: c++
452
453   void CmiSyncBroadcastAndFree(unsigned int size, void *msg)
454
455 Sends msg of length size bytes to all processors excluding the processor
456 on which the caller resides. Uses CmiFree to deallocate the message
457 buffer for msg when the broadcast completes. Therefore msg must point to
458 a buffer allocated with CmiAlloc.
459
460 .. code-block:: c++
461
462   void CmiSyncNodeBroadcastAndFree(unsigned int size, void *msg)
463
464 Sends msg of length size bytes to all nodes excluding the node on which
465 the caller resides. Uses CmiFree to deallocate the message buffer for
466 msg when the broadcast completes. Therefore msg must point to a buffer
467 allocated with CmiAlloc.
468
469 .. code-block:: c++
470
471   void CmiSyncBroadcastAll(unsigned int size, void *msg)
472
473 Sends msg of length size bytes to all processors including the processor
474 on which the caller resides. This function does not free the message
475 buffer for msg.
476
477 .. code-block:: c++
478
479   void CmiSyncNodeBroadcastAll(unsigned int size, void *msg)
480
481 Sends msg of length size bytes to all nodes including the node on which
482 the caller resides. This function does not free the message buffer for
483 msg.
484
485 .. code-block:: c++
486
487   void CmiSyncBroadcastAllAndFree(unsigned int size, void *msg)
488
489 Sends msg of length size bytes to all processors including the processor
490 on which the caller resides. This function frees the message buffer for
491 msg before returning, so msg must point to a dynamically allocated
492 buffer.
493
494 .. code-block:: c++
495
496   void CmiSyncNodeBroadcastAllAndFree(unsigned int size, void *msg)
497
498 Sends msg of length size bytes to all nodes including the node on which
499 the caller resides. This function frees the message buffer for msg
500 before returning, so msg must point to a dynamically allocated buffer.
501
502 .. code-block:: c++
503
504   CmiCommHandle CmiAsyncBroadcast(unsigned int size, void *msg)
505
506 Initiates asynchronous broadcast of message msg of length size bytes to
507 all processors excluding the processor on which the caller resides. It
508 returns a communication handle which could be used to check the status
509 of this send using CmiAsyncMsgSent. If the returned communication handle
510 is 0, message buffer can be reused immediately, thus saving a call to
511 CmiAsyncMsgSent. msg should not be overwritten or freed before the
512 communication is complete.
513
514 .. code-block:: c++
515
516   CmiCommHandle CmiAsyncNodeBroadcast(unsigned int size, void *msg)
517
518 Initiates asynchronous broadcast of message msg of length size bytes to
519 all nodes excluding the node on which the caller resides. It returns a
520 communication handle which could be used to check the status of this
521 send using CmiAsyncMsgSent. If the returned communication handle is 0,
522 message buffer can be reused immediately, thus saving a call to
523 CmiAsyncMsgSent. msg should not be overwritten or freed before the
524 communication is complete.
525
526 .. code-block:: c++
527
528   CmiCommHandle CmiAsyncBroadcastAll(unsigned int size, void *msg)
529
530 Initiates asynchronous broadcast of message msg of length size bytes to
531 all processors including the processor on which the caller resides. It
532 returns a communication handle which could be used to check the status
533 of this send using CmiAsyncMsgSent. If the returned communication handle
534 is 0, message buffer can be reused immediately, thus saving a call to
535 CmiAsyncMsgSent. msg should not be overwritten or freed before the
536 communication is complete.
537
538 .. code-block:: c++
539
540   CmiCommHandle CmiAsyncNodeBroadcastAll(unsigned int size, void *msg)
541
542 Initiates asynchronous broadcast of message msg of length size bytes to
543 all nodes including the node on which the caller resides. It returns a
544 communication handle which could be used to check the status of this
545 send using CmiAsyncMsgSent. If the returned communication handle is 0,
546 message buffer can be reused immediately, thus saving a call to
547 CmiAsyncMsgSent. msg should not be overwritten or freed before the
548 communication is complete.
549
550 .. _sec:multicast:
551
552 Multicasting Messages
553 ---------------------
554
555 .. code-block:: c++
556
557   typedef ... CmiGroup;
558
559 A CmiGroup represents a set of processors. It is an opaque type. Group
560 IDs are useful for the multicast functions below.
561
562 .. code-block:: c++
563
564   CmiGroup CmiEstablishGroup(int npes, int *pes);
565
566 Converts an array of processor numbers into a group ID. Group IDs are
567 useful for the multicast functions below. Caution: this call uses up
568 some resources. In particular, establishing a group uses some network
569 bandwidth (one broadcast’s worth) and a small amount of memory on all
570 processors.
571
572 .. code-block:: c++
573
574   void CmiSyncMulticast(CmiGroup grp, unsigned int size, void *msg)
575
576 Sends msg of length size bytes to all members of the specified group.
577 Group IDs are created using CmiEstablishGroup.
578
579 .. code-block:: c++
580
581   void CmiSyncMulticastAndFree(CmiGroup grp, unsigned int size, void *msg)
582
583 Sends msg of length size bytes to all members of the specified group.
584 Uses CmiFree to deallocate the message buffer for msg when the broadcast
585 completes. Therefore msg must point to a buffer allocated with CmiAlloc.
586 Group IDs are created using CmiEstablishGroup.
587
588 .. code-block:: c++
589
590   CmiCommHandle CmiAsyncMulticast(CmiGroup grp, unsigned int size, void *msg)
591
592 (Note: Not yet implemented.) Initiates asynchronous broadcast of message
593 msg of length size bytes to all members of the specified group. It
594 returns a communication handle which could be used to check the status
595 of this send using CmiAsyncMsgSent. If the returned communication handle
596 is 0, message buffer can be reused immediately, thus saving a call to
597 CmiAsyncMsgSent. msg should not be overwritten or freed before the
598 communication is complete. Group IDs are created using
599 CmiEstablishGroup.
600
601 .. code-block:: c++
602
603   void CmiSyncListSend(int npes, int *pes, unsigned int size, void *msg)
604
605 Sends msg of length size bytes to npes processors in the array pes.
606
607 .. code-block:: c++
608
609   void CmiSyncListSendAndFree(int npes, int *pes, unsigned int size, void *msg)
610
611 Sends msg of length size bytes to npes processors in the array pes. Uses
612 CmiFree to deallocate the message buffer for msg when the multicast
613 completes. Therefore, msg must point to a buffer allocated with
614 CmiAlloc.
615
616 .. code-block:: c++
617
618   CmiCommHandle CmiAsyncListSend(int npes, int *pes, unsigned int size, void *msg)
619
620 Initiates asynchronous multicast of message msg of length size bytes to
621 npes processors in the array pes. It returns a communication handle
622 which could be used to check the status of this send using
623 CmiAsyncMsgSent. If the returned communication handle is 0, message
624 buffer can be reused immediately, thus saving a call to CmiAsyncMsgSent.
625 msg should not be overwritten or freed before the communication is
626 complete.
627
628 .. _reduce:
629
630 Reducing Messaging
631 ------------------
632
633 Reductions are operations for which a message (or user data structure)
634 is contributed by each participant processor. All these contributions
635 are merged according to a merge-function provided by the user. A
636 Converse handler is then invoked with the resulting message. Reductions
637 can be on the entire set of processors, or on a subset of the whole.
638 Currently reductions are only implemented on processors sets. No
639 equivalent exists for SMP nodes.
640
641 There are eight functions used to deposit a message into the system,
642 summarized in Table :numref:`table:reductions`. Half
643 of them receive as contribution a Converse message (with a Converse
644 header at its beginning). This message must have already been set for
645 delivery to the desired handler. The other half (ending with “Struct”)
646 receives a pointer to a data structure allocated by the user. This
647 second version may allow the user to write a simpler merging function.
648 For instance, the data structure could be a tree that can be easily
649 expanded by adding more nodes.
650
651 .. _table:reductions:
652 .. table:: Reductions functions in Converse
653
654    =========== =============== ================== =================== ====================
655    \           **global**      **global with ID** **processor set**   **CmiGroup**
656    =========== =============== ================== =================== ====================
657    **message** CmiReduce       CmiReduceID        CmiListReduce       CmiGroupReduce
658    **data**    CmiReduceStruct CmiReduceStructID  CmiListReduceStruct CmiGroupReduceStruct
659    =========== =============== ================== =================== ====================
660
661 The signatures for the functions in
662 Table :numref:`table:reductions` are:
663
664 .. code-block:: c++
665
666   void CmiReduce(void *msg, int size, CmiReduceMergeFn mergeFn);
667
668   void CmiReduceStruct(void *data, CmiReducePupFn pupFn,
669   CmiReduceMergeFn mergeFn, CmiHandler dest, CmiReduceDeleteFn deleteFn);
670
671   void CmiReduceID(void *msg, int size, CmiReduceMergeFn mergeFn,
672   CmiReductionID id);
673
674   void CmiReduceStructID(void *data, CmiReducePupFn pupFn, CmiReduceMergeFn mergeFn,
675   CmiHandler dest, CmiReduceDeleteFn deleteFn, CmiReductionID id);
676
677   void CmiListReduce(int npes, int *pes, void *msg, int size,
678   CmiReduceMergeFn mergeFn, CmiReductionID id);
679
680   void CmiListReduceStruct(int npes, int *pes, void *data, CmiReducePupFn
681   pupFn, CmiReduceMergeFn mergeFn, CmiHandler dest, CmiReduceDeleteFn
682   deleteFn, CmiReductionID id);
683
684   void CmiGroupReduce(CmiGroup grp, void *msg, int size,
685   CmiReduceMergeFn mergeFn, CmiReductionID id);
686
687   void CmiGroupReduceStruct(CmiGroup grp, void *data, CmiReducePupFn pupFn,
688   CmiReduceMergeFn mergeFn, CmiHandler dest, CmiReduceDeleteFn deleteFn,
689   CmiReductionID id);
690
691 In all the above, msg is the Converse message deposited by the local
692 processor, size is the size of the message msg, and data is a pointer to
693 the user-allocated data structure deposited by the local processor. dest
694 is the CmiHandler where the final message shall be delivered. It is
695 explicitly passed in “Struct” functions only, since for the message
696 versions it is taken from the header of msg. Moreover there are several
697 other function pointers passed in by the user:
698
699 .. code-block:: c++
700
701   void * (*mergeFn)(int *size, void *local, void **remote, int count)
702
703 Prototype for a CmiReduceMergeFn function pointer argument. This
704 function is used in all the CmiReduce forms to merge the local
705 message/data structure deposited on a processor with all the messages
706 incoming from the children processors of the reduction spanning tree.
707 The input parameters are in the order: the size of the local data for
708 message reductions (always zero for struct reductions); the local data
709 itself (the exact same pointer passed in as first parameter of CmiReduce
710 and similar); a pointer to an array of incoming messages; the number of
711 elements in the second parameter. The function returns a pointer to a
712 freshly allocated message (or data structure for the Struct forms)
713 corresponding to the merge of all the messages. When performing message
714 reductions, this function is also responsible to updating the integer
715 pointed by size to the new size of the returned message. All the
716 messages in the remote array are deleted by the system; the data pointed
717 by the first parameter should be deleted by this function. If the data
718 can be merged “in-place” by modifying or augmenting local, the function
719 can return the same pointer to local which can be considered freshly
720 allocated. Each element in remote is the complete incoming message
721 (including the converse header) for message reductions, and the data as
722 it has been packed by the pup function (without any additional header)
723 for struct reductions.
724
725 .. code-block:: c++
726
727   void (*pupFn)(pup_er p, void *data)
728
729 Prototype for a CmiReducePupFn function pointer argument.
730 This function will use the PUP framework to
731 pup the data passed in into a message for sending across the network.
732 The data can be either the same data passed in as first parameter of any
733 “Struct” function, or the return of the merge function. It will be
734 called for sizing and packing. (Note: It will not be called for
735 unpacking.)
736
737 .. code-block:: c++
738
739   void (*deleteFn)(void *ptr)
740
741 Prototype for a CmiReduceDeleteFn function pointer argument.
742 This function is used to delete either the data
743 structure passed in as first parameter of any “Struct” function, or the
744 return of the merge function. It can be as simple as “free” or as
745 complicated as needed to delete complex structures. If this function is
746 NULL, the data structure will not be deleted, and the program can
747 continue to use it. Note: even if this function is NULL, the input data
748 structure may still be modified by the merge function.
749
750 CmiReduce and CmiReduceStruct are the simplest reduction function, and
751 they reduce the deposited message/data across all the processors in the
752 system. Each processor must to call this function exactly once. Multiple
753 reductions can be invoked without waiting for previous ones to finish,
754 but the user is responsible to call CmiReduce/CmiReduceStruct in the
755 same order on every processor. (**Note:** CmiReduce and CmiReduceStruct
756 are not interchangeable. Either every processor calls CmiReduce or every
757 processor calls CmiReduceStruct).
758
759 In situations where it is not possible to guarantee the order of
760 reductions, the user may use CmiReduceID or CmiReduceStructID. These
761 functions have an additional parameter of type CmiReductionID which will
762 uniquely identify the reduction, and match them correctly. (**Note:** No
763 two reductions can be active at the same time with the same
764 CmiReductionID. It is up to the user to guarantee this.)
765
766 A CmiReductionID can be obtained by the user in three ways, using one of
767 the following functions:
768
769 .. code-block:: c++
770
771   CmiReductionID CmiGetGlobalReduction()
772
773 This function must be called on
774 every processor, and in the same order if called multiple times. This
775 would generally be inside initialization code, that can set aside some
776 CmiReductionIDs for later use.
777
778 .. code-block:: c++
779
780   CmiReductionID CmiGetDynamicReduction()
781
782 This function may be called only
783 on processor zero. It returns a unique ID, and it is up to the user to
784 distribute this ID to any processor that needs it.
785
786 .. code-block:: c++
787
788   void CmiGetDynamicReductionRemote(int handlerIdx, int pe, int dataSize, void *data)
789
790 This function may be called on any processor. The produced
791 CmiReductionID is returned on the specified pe by sending a message to
792 the specified handlerIdx. If pe is -1, then all processors will receive
793 the notification message. data can be any data structure that the user
794 wants to receive on the specified handler (for example to differentiate
795 between requests). dataSize is the size in bytes of data. If dataSize is
796 zero, data is ignored. The message received by handlerIdx consists of
797 the standard Converse header, followed by the requested CmiReductionID
798 (represented as a 4 bytes integer the user can cast to a CmiReductionID,
799 a 4 byte integer containing dataSize, and the data itself.
800
801 The other four functions (CmiListReduce, CmiListReduceStruct,
802 CmiGroupReduce, CmiGroupReduceStruct) are used for reductions over
803 subsets of processors. They all require a CmiReductionID that the user
804 must obtain in one of the ways described above. The user is also
805 responsible that no two reductions use the same CmiReductionID
806 simultaneously. The first two functions receive the subset description
807 as processor list (pes) of size npes. The last two receive the subset
808 description as a previously established CmiGroup
809 (see :numref:`sec:multicast`).
810
811 .. _schedqueue:
812
813 Scheduling Messages
814 -------------------
815
816 The scheduler queue is a powerful priority queue. The following
817 functions can be used to place messages into the scheduler queue. These
818 messages are treated very much like newly-arrived messages: when they
819 reach the front of the queue, they trigger handler functions, just like
820 messages transmitted with CMI functions. Note that unlike the CMI send
821 functions, these cannot move messages across processors.
822
823 Every message inserted into the queue has a priority associated with it.
824 Converse priorities are arbitrary-precision numbers between 0 and 1.
825 Priorities closer to 0 get processed first, priorities closer to 1 get
826 processed last. Arbitrary-precision priorities are very useful in AI
827 search-tree applications. Suppose we have a heuristic suggesting that
828 tree node N1 should be searched before tree node N2. We therefore
829 designate that node N1 and its descendants will use high priorities, and
830 that node N2 and its descendants will use lower priorities. We have
831 effectively split the range of possible priorities in two. If several
832 such heuristics fire in sequence, we can easily split the priority range
833 in two enough times that no significant bits remain, and the search
834 begins to fail for lack of meaningful priorities to assign. The solution
835 is to use arbitrary-precision priorities, aka bitvector priorities.
836
837 These arbitrary-precision numbers are represented as bit-strings: for
838 example, the bit-string “0011000101” represents the binary number
839 (.0011000101). The format of the bit-string is as follows: the
840 bit-string is represented as an array of unsigned integers. The most
841 significant bit of the first integer contains the first bit of the
842 bitvector. The remaining bits of the first integer contain the next 31
843 bits of the bitvector. Subsequent integers contain 32 bits each. If the
844 size of the bitvector is not a multiple of 32, then the last integer
845 contains 0 bits for padding in the least-significant bits of the
846 integer.
847
848 Some people only want regular integers as priorities. For simplicity’s
849 sake, we provide an easy way to convert integer priorities to Converse’s
850 built-in representation.
851
852 In addition to priorities, you may choose to enqueue a message “LIFO” or
853 “FIFO”. Enqueueing a message “FIFO” simply pushes it behind all the
854 other messages of the same priority. Enqueueing a message “LIFO” pushes
855 it in front of other messages of the same priority.
856
857 Messages sent using the CMI functions take precedence over everything in
858 the scheduler queue, regardless of priority.
859
860 A recent addition to Converse scheduling mechanisms is the introduction
861 of node-level scheduling designed to support low-overhead programming
862 for the SMP clusters. These functions have “Node” in their names. All
863 processors within the node has access to the node-level scheduler’s
864 queue, and thus a message enqueued in a node-level queue may be handled
865 by any processor within that node. When deciding about which message to
866 process next, i.e. from processor’s own queue or from the node-level
867 queue, a quick priority check is performed internally, thus a processor
868 views scheduler’s queue as a single prioritized queue that includes
869 messages directed at that processor and messages from the node-level
870 queue sorted according to priorities.
871
872 .. code-block:: c++
873
874   void CsdEnqueueGeneral(void *Message, int strategy, int priobits, int *prioptr)
875
876 This call enqueues a message to the processor’s scheduler’s queue, to be
877 sorted according to its priority and the queueing ``strategy``. The
878 meaning of the priobits and prioptr fields depend on the value of
879 strategy, which are explained below.
880
881 .. code-block:: c++
882
883   void CsdNodeEnqueueGeneral(void *Message, int strategy, int priobits, int *prioptr)
884
885 This call enqueues a message to the node-level scheduler’s queue, to be
886 sorted according to its priority and the queueing strategy. The meaning
887 of the priobits and prioptr fields depend on the value of strategy,
888 which can be any of the following:
889
890 -  CQS_QUEUEING_BFIFO: the priobits and prioptr point to a bit-string
891    representing an arbitrary-precision priority. The message is pushed
892    behind all other message of this priority.
893
894 -  CQS_QUEUEING_BLIFO: the priobits and prioptr point to a bit-string
895    representing an arbitrary-precision priority. The message is pushed
896    in front all other message of this priority.
897
898 -  CQS_QUEUEING_IFIFO: the prioptr is a pointer to a signed integer. The
899    integer is converted to a bit-string priority, normalizing so that
900    the integer zero is converted to the bit-string “1000...” (the
901    “middle” priority). To be more specific, the conversion is performed
902    by adding 0x80000000 to the integer, and then treating the resulting
903    32-bit quantity as a 32-bit bitvector priority. The message is pushed
904    behind all other messages of this priority.
905
906 -  CQS_QUEUEING_ILIFO: the prioptr is a pointer to a signed integer. The
907    integer is converted to a bit-string priority, normalizing so that
908    the integer zero is converted to the bit-string “1000...” (the
909    “middle” priority). To be more specific, the conversion is performed
910    by adding 0x80000000 to the integer, and then treating the resulting
911    32-bit quantity as a 32-bit bitvector priority. The message is pushed
912    in front of all other messages of this priority.
913
914 -  CQS_QUEUEING_FIFO: the prioptr and priobits are ignored. The message
915    is enqueued with the middle priority “1000...”, and is pushed behind
916    all other messages with this priority.
917
918 -  CQS_QUEUEING_LIFO: the prioptr and priobits are ignored. The message
919    is enqueued with the middle priority “1000...”, and is pushed in
920    front of all other messages with this priority.
921
922 Caution: the priority itself is *not copied* by the scheduler.
923 Therefore, if you pass a pointer to a priority into the scheduler, you
924 must not overwrite or free that priority until after the message has
925 emerged from the scheduler’s queue. It is normal to actually store the
926 priority *in the message itself*, though it is up to the user to
927 actually arrange storage for the priority.
928
929 .. code-block:: c++
930
931   void CsdEnqueue(void *Message)
932
933 This macro is a shorthand for
934
935 .. code-block:: c++
936
937    CsdEnqueueGeneral(Message, CQS_QUEUEING_FIFO,0, NULL)
938
939 provided here for backward compatibility.
940
941 .. code-block:: c++
942
943   void CsdNodeEnqueue(void *Message)
944
945 This macro is a shorthand for
946
947 .. code-block:: c++
948
949    CsdNodeEnqueueGeneral(Message, CQS_QUEUEING_FIFO,0, NULL)
950
951 provided here for backward compatibility.
952
953 .. code-block:: c++
954
955   void CsdEnqueueFifo(void *Message)
956
957 This macro is a shorthand for
958
959 .. code-block:: c++
960
961    CsdEnqueueGeneral(Message, CQS_QUEUEING_FIFO,0, NULL)
962
963 provided here for backward compatibility.
964
965 .. code-block:: c++
966
967   void CsdNodeEnqueueFifo(void *Message)
968
969 This macro is a shorthand for
970
971 .. code-block:: c++
972
973    CsdNodeEnqueueGeneral(Message, CQS_QUEUEING_FIFO,0, NULL)
974
975 provided here for backward compatibility.
976
977 .. code-block:: c++
978
979   void CsdEnqueueLifo(void *Message)
980
981 This macro is a shorthand for
982
983 .. code-block:: c++
984
985    CsdEnqueueGeneral(Message, CQS_QUEUEING_LIFO,0, NULL)
986
987 provided here for backward compatibility.
988
989 .. code-block:: c++
990
991   void CsdNodeEnqueueLifo(void *Message)
992
993 This macro is a shorthand for
994
995 .. code-block:: c++
996
997    CsdNodeEnqueueGeneral(Message, CQS_QUEUEING_LIFO,0, NULL)
998
999 provided here for backward compatibility.
1000
1001 .. code-block:: c++
1002
1003   int CsdEmpty()
1004
1005 This function returns non-zero integer when the scheduler’s
1006 processor-level queue is empty, zero otherwise.
1007
1008 .. code-block:: c++
1009
1010   int CsdNodeEmpty()
1011
1012 This function returns non-zero integer when the scheduler’s node-level
1013 queue is empty, zero otherwise.
1014
1015 .. _polling:
1016
1017 Polling for Messages
1018 --------------------
1019
1020 As we stated earlier, Converse messages trigger handler functions when
1021 they arrive. In fact, for this to work, the processor must occasionally
1022 poll for messages. When the user starts Converse, he can put it into one
1023 of several modes. In the normal mode, the message polling happens
1024 automatically. However *user-calls-scheduler* mode is designed to let
1025 the user poll manually. To do this, the user must use one of two polling
1026 functions: CmiDeliverMsgs, or CsdScheduler. CsdScheduler is more
1027 general, it will notice any Converse event. CmiDeliverMsgs is a
1028 lower-level function that ignores all events except for recently-arrived
1029 messages. (In particular, it ignores messages in the scheduler queue).
1030 You can save a tiny amount of overhead by using the lower-level
1031 function. We recommend the use of CsdScheduler for all applications
1032 except those that are using only the lowest level of Converse, the CMI.
1033 A third polling function, CmiDeliverSpecificMsg, is used when you know
1034 the exact event you want to wait for: it does not allow any other event
1035 to occur.
1036
1037 In each iteration, a scheduler first looks for any message that has
1038 arrived from another processor, and delivers it. If there isn’t any, it
1039 selects a message from the locally enqueued messages, and delivers it.
1040
1041 .. code-block:: c++
1042
1043   void CsdScheduleForever(void)
1044
1045 Extract and deliver messages until the
1046 scheduler is stopped. Raises the idle handling converse signals. This is
1047 the scheduler to use in most Converse programs.
1048
1049 .. code-block:: c++
1050
1051   int CsdScheduleCount(int n)
1052
1053 Extract and deliver messages until :math:`n`
1054 messages have been delivered, then return 0. If the scheduler is stopped
1055 early, return :math:`n` minus the number of messages delivered so far.
1056 Raises the idle handling converse signals.
1057
1058 .. code-block:: c++
1059
1060   void CsdSchedulePoll(void)
1061
1062 Extract and deliver messages until no more
1063 messages are available, then return. This is useful for running
1064 non-networking code when the networking code has nothing to do.
1065
1066 .. code-block:: c++
1067
1068   void CsdScheduler(int n)
1069
1070 If :math:`n` is zero, call CsdSchedulePoll. If :math:`n` is negative,
1071 call CsdScheduleForever. If :math:`n` is positive, call
1072 CsdScheduleCount(\ :math:`n`).
1073
1074 .. code-block:: c++
1075
1076   int CmiDeliverMsgs(int MaxMsgs)
1077
1078 Retrieves messages from the network message queue and invokes
1079 corresponding handler functions for arrived messages. This function
1080 returns after either the network message queue becomes empty or after
1081 MaxMsgs messages have been retrieved and their handlers called. It
1082 returns the difference between total messages delivered and MaxMsgs. The
1083 handler is given a pointer to the message as its parameter.
1084
1085 .. code-block:: c++
1086
1087   void CmiDeliverSpecificMsg(int HandlerId)
1088
1089 Retrieves messages from the network queue and delivers the first message
1090 with its handler field equal to HandlerId. This functions leaves alone
1091 all other messages. It returns after the invoked handler function
1092 returns.
1093
1094 .. code-block:: c++
1095
1096   void CsdExitScheduler(void)
1097
1098 This call causes CsdScheduler to stop processing messages when control
1099 has returned back to it. The scheduler then returns to its calling
1100 routine.
1101
1102 The Timer
1103 ---------
1104
1105 .. code-block:: c++
1106
1107   double CmiTimer(void)
1108
1109 Returns current value of the timer in seconds. This is typically the
1110 time spent since the ``ConverseInit`` call. The precision of this timer is
1111 the best available on the particular machine, and usually has at least
1112 microsecond accuracy.
1113
1114 Processor Ids
1115 -------------
1116
1117 .. code-block:: c++
1118
1119   int CmiNumPe(void)
1120
1121 Returns the total number of processors on which the parallel program is
1122 being run.
1123
1124 .. code-block:: c++
1125
1126   int CmiMyPe(void)
1127
1128 Returns the logical processor identifier of processor on which the
1129 caller resides. A processor Id is between ``0`` and ``CmiNumPe()-1``.
1130
1131 Also see the calls in Section :numref:`utility`.
1132
1133 .. _globalvars:
1134
1135 Global Variables and Utility functions
1136 --------------------------------------
1137
1138 Different vendors are not consistent about how they treat global and
1139 static variables. Most vendors write C compilers in which global
1140 variables are shared among all the processors in the node. A few vendors
1141 write C compilers where each processor has its own copy of the global
1142 variables. In theory, it would also be possible to design the compiler
1143 so that each thread has its own copy of the global variables.
1144
1145 The lack of consistency across vendors, makes it very hard to write a
1146 portable program. The fact that most vendors make the globals shared is
1147 inconvenient as well, usually, you don’t want your globals to be shared.
1148 For these reasons, we added “pseudoglobals” to Converse. These act much
1149 like C global and static variables, except that you have explicit
1150 control over the degree of sharing.
1151
1152 In this section we use the terms Node, PE, and User-level thread as they
1153 are used in Charm++, to refer to an OS process, a worker/communication
1154 thread, and a user-level thread, respectively. In the SMP mode of
1155 Charm++ all three of these are separate entities, whereas in non-SMP
1156 mode Node and PE have the same scope.
1157
1158 Converse PseudoGlobals
1159 ~~~~~~~~~~~~~~~~~~~~~~
1160
1161 Three classes of pseudoglobal variables are supported: node-shared,
1162 processor-private, and thread-private variables.
1163
1164 Node-shared variables (Csv)
1165    are specific to a node. They are shared among all the PEs within the
1166    node.
1167
1168 PE-private variables (Cpv)
1169    are specific to a PE. They are shared by all the objects and Converse
1170    user-level threads on a PE.
1171
1172 Thread-private variables (Ctv)
1173    are specific to a Converse user-level thread. They are truly private.
1174
1175 There are five macros for each class. These macros are for declaration,
1176 static declaration, extern declaration, initialization, and access. The
1177 declaration, static and extern specifications have the same meaning as
1178 in C. In order to support portability, however, the global variables
1179 must be installed properly, by using the initialization macros. For
1180 example, if the underlying machine is a simulator for the machine model
1181 supported by Converse, then the thread-private variables must be turned
1182 into arrays of variables. Initialize and Access macros hide these
1183 details from the user. It is possible to use global variables without
1184 these macros, as supported by the underlying machine, but at the expense
1185 of portability.
1186
1187 Macros for node-shared variables:
1188
1189 .. code-block:: c++
1190
1191   CsvDeclare(type,variable)
1192
1193   CsvStaticDeclare(type,variable)
1194
1195   CsvExtern(type,variable)
1196
1197   CsvInitialize(type,variable)
1198
1199   CsvAccess(variable)
1200
1201 Macros for PE-private variables:
1202
1203 .. code-block:: c++
1204
1205   CpvDeclare(type,variable)
1206
1207   CpvStaticDeclare(type,variable)
1208
1209   CpvExtern(type,variable)
1210
1211   CpvInitialize(type,variable)
1212
1213   CpvAccess(variable)
1214
1215 Macros for thread-private variables:
1216
1217 .. code-block:: c++
1218
1219   CtvDeclare(type,variable)
1220
1221   CtvStaticDeclare(type,variable)
1222
1223   CtvExtern(type,variable)
1224
1225   CtvInitialize(type,variable)
1226
1227   CtvAccess(variable)
1228
1229 A sample code to illustrate the usage of the macros is provided in
1230 the example below. There are a few rules that the user
1231 must pay attention to: The ``type`` and ``variable`` fields of the
1232 macros must be a single word. Therefore, structures or pointer types can
1233 be used by defining new types with the ``typedef``. In the sample code,
1234 for example, a ``struct point`` type is redefined with a ``typedef`` as
1235 ``Point`` in order to use it in the macros. Similarly, the access macros
1236 contain only the name of the global variable. Any indexing or member
1237 access must be outside of the macro as shown in the sample code
1238 (function ``func1``). Finally, all the global variables must be
1239 installed before they are used. One way to do this systematically is to
1240 provide a module-init function for each file (in the sample code -
1241 ``ModuleInit()``. The module-init functions of each file, then, can be
1242 called at the beginning of execution to complete the installations of
1243 all global variables.
1244
1245 .. code-block:: c++
1246
1247    File: Module1.c
1248
1249        typedef struct point
1250        {
1251             float x,y;
1252        } Point;
1253
1254
1255        CpvDeclare(int, a);
1256        CpvDeclare(Point, p);
1257
1258        void ModuleInit()
1259        {
1260             CpvInitialize(int, a)
1261             CpvInitialize(Point, p);
1262
1263             CpvAccess(a) = 0;
1264        }
1265
1266        int func1()
1267        {
1268             CpvAccess(p).x = 0;
1269             CpvAccess(p).y = CpvAccess(p).x + 1;
1270        }
1271
1272 .. _utility:
1273
1274 Utility Functions
1275 ~~~~~~~~~~~~~~~~~
1276
1277 To further simplify programming with global variables on shared memory
1278 machines, Converse provides the following functions and/or macros.
1279 (**Note:** These functions are defined on machines other than
1280 shared-memory machines also, and have the effect of only one processor
1281 per node and only one thread per processor.)
1282
1283 .. code-block:: c++
1284
1285   int CmiMyNode()
1286
1287 Returns the node number to which the calling processor belongs.
1288
1289 .. code-block:: c++
1290
1291   int CmiNumNodes()
1292
1293 Returns number of nodes in the system. Note that this is not the same as
1294 ``CmiNumPes()``.
1295
1296 .. code-block:: c++
1297
1298   int CmiMyRank()
1299
1300 Returns the rank of the calling processor within a shared memory node.
1301
1302 .. code-block:: c++
1303
1304   int CmiNodeFirst(int node)
1305
1306 Returns the processor number of the lowest ranked processor on node
1307 ``node``
1308
1309 .. code-block:: c++
1310
1311   int CmiNodeSize(int node)
1312
1313 Returns the number of processors that belong to the node ``node``.
1314
1315 .. code-block:: c++
1316
1317   int CmiNodeOf(int pe)
1318
1319 Returns the node number to which processor ``pe`` belongs. Indeed,
1320 ``CmiMyNode()`` is a utility macro that is aliased to
1321 ``CmiNodeOf(CmiMyPe())``.
1322
1323 .. code-block:: c++
1324
1325   int CmiRankOf(int pe)
1326
1327 Returns the rank of processor ``pe`` in the node to which it belongs.
1328
1329 .. _nodelocks:
1330
1331 Node-level Locks and other Synchronization Mechanisms
1332 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1333
1334 .. code-block:: c++
1335
1336   void CmiNodeBarrier()
1337
1338 Provide barrier synchronization at the node level, i.e. all the
1339 processors belonging to the node participate in this barrier.
1340
1341 .. code-block:: c++
1342
1343   typedef McDependentType CmiNodeLock
1344
1345 This is the type for all the node-level locks in Converse.
1346
1347 .. code-block:: c++
1348
1349   CmiNodeLock CmiCreateLock(void)
1350
1351 Creates, initializes and returns a new lock. Initially the lock is
1352 unlocked.
1353
1354 .. code-block:: c++
1355
1356   void CmiLock(CmiNodeLock lock)
1357
1358 Locks ``lock``. If the ``lock`` has been locked by other processor,
1359 waits for ``lock`` to be unlocked.
1360
1361 .. code-block:: c++
1362
1363   void CmiUnlock(CmiNodeLock lock)
1364
1365 Unlocks ``lock``. Processors waiting for the ``lock`` can then compete
1366 for acquiring ``lock``.
1367
1368 .. code-block:: c++
1369
1370   int CmiTryLock(CmiNodeLock lock)
1371
1372 Tries to lock ``lock``. If it succeeds in locking, it returns 0. If any
1373 other processor has already acquired the lock, it returns 1.
1374
1375 .. code-block:: c++
1376
1377   voi CmiDestroyLock(CmiNodeLock lock)
1378
1379 Frees any memory associated with ``lock``. It is an error to perform any
1380 operations with ``lock`` after a call to this function.
1381
1382 Input/Output
1383 ------------
1384
1385 .. code-block:: c++
1386
1387   void CmiPrintf(char *format, arg1, arg2, ...)
1388
1389 This function does an atomic ``printf()`` on ``stdout``. On machine with
1390 host, this is implemented on top of the messaging layer using
1391 asynchronous sends.
1392
1393 .. code-block:: c++
1394
1395   int CmiScanf(char *format, void *arg1, void *arg2, ...)
1396
1397 This function performs an atomic ``scanf`` from ``stdin``. The
1398 processor, on which the caller resides, blocks for input. On machines
1399 with host, this is implemented on top of the messaging layer using
1400 asynchronous send and blocking receive.
1401
1402 .. code-block:: c++
1403
1404   void CmiError(char *format, arg1, arg2, ...)
1405
1406 This function does an atomic ``printf()`` on ``stderr``. On machines
1407 with host, this is implemented on top of the messaging layer using
1408 asynchronous sends.
1409
1410 Spanning Tree Calls
1411 -------------------
1412
1413 Sometimes, it is convenient to view the processors/nodes of the machine
1414 as a tree. For this purpose, Converse defines a tree over
1415 processors/nodes. We provide functions to obtain the parent and children
1416 of each processor/node. On those machines where the communication
1417 topology is relevant, we arrange the tree to optimize communication
1418 performance. The root of the spanning tree (processor based or
1419 node-based) is always 0, thus the CmiSpanTreeRoot call has been
1420 eliminated.
1421
1422 .. code-block:: c++
1423
1424   int CmiSpanTreeParent(int procNum)
1425
1426 This function returns the processor number of the parent of procNum in
1427 the spanning tree.
1428
1429 .. code-block:: c++
1430
1431   int CmiNumSpanTreeChildren(int procNum)
1432
1433 Returns the number of children of procNum in the spanning tree.
1434
1435 .. code-block:: c++
1436
1437   void CmiSpanTreeChildren(int procNum, int *children)
1438
1439 This function fills the array children with processor numbers of
1440 children of procNum in the spanning tree.
1441
1442 .. code-block:: c++
1443
1444   int CmiNodeSpanTreeParent(int nodeNum)
1445
1446 This function returns the node number of the parent of nodeNum in the
1447 spanning tree.
1448
1449 .. code-block:: c++
1450
1451   int CmiNumNodeSpanTreeChildren(int nodeNum)
1452
1453 Returns the number of children of nodeNum in the spanning tree.
1454
1455 .. code-block:: c++
1456
1457   void CmiNodeSpanTreeChildren(int nodeNum, int *children)
1458
1459 This function fills the array children with node numbers of children of
1460 nodeNum in the spanning tree.
1461
1462 Isomalloc
1463 ---------
1464
1465 It is occasionally useful to allocate memory at a globally unique
1466 virtual address. This is trivial on a shared memory machine (where every
1467 address is globally unique); but more difficult on a distributed memory
1468 machine (where each node has its own separate data at address
1469 0x80000000). Isomalloc provides a uniform interface for allocating
1470 globally unique virtual addresses.
1471
1472 Isomalloc can thus be thought of as a software distributed shared memory
1473 implementation; except data movement between processors is explicit (by
1474 making a subroutine call), not on demand (by taking a page fault).
1475
1476 Isomalloc is useful when moving highly interlinked data structures from
1477 one processor to another, because internal pointers will still point to
1478 the correct locations, even on a new processor. This is especially
1479 useful when the format of the data structure is complex or unknown, as
1480 with thread stacks.
1481
1482 .. code-block:: c++
1483
1484   void *CmiIsomalloc(int size)
1485
1486 Allocate size bytes at a unique virtual address. Returns a pointer to
1487 the allocated region.
1488
1489 CmiIsomalloc makes allocations with page granularity (typically several
1490 kilobytes); so it is not recommended for small allocations.
1491
1492 .. code-block:: c++
1493
1494   void CmiIsomallocFree(void *doomedBlock)
1495
1496 Release the given block, which must have been previously returned by
1497 CmiIsomalloc. Also releases the used virtual address range, which the
1498 system may subsequently reuse.
1499
1500 After a CmiIsomallocFree, references to that block will likely result in
1501 a segmentation violation. It is illegal to call CmiIsomallocFree more
1502 than once on the same block.
1503
1504 .. code-block:: c++
1505
1506   void CmiIsomallocPup(pup_er p,void **block)
1507
1508 Pack/Unpack the given block. This routine can be used to move blocks
1509 across processors, save blocks to disk, or checkpoint blocks.
1510
1511 After unpacking, the pointer is guaranteed to have the same value that
1512 it did before packing.
1513
1514 Note- Use of this function to pup individual blocks is not supported any
1515 longer. All the blocks allocated via CmiIsomalloc are pupped by the RTS
1516 as one single unit.
1517
1518 .. code-block:: c++
1519
1520   int CmiIsomallocLength(void *block);
1521
1522 Return the length, in bytes, of this isomalloc’d block.
1523
1524 .. code-block:: c++
1525
1526   int CmiIsomallocInRange(void *address)
1527
1528 Return 1 if the given address may have been previously allocated to this
1529 processor using Isomalloc; 0 otherwise.
1530 ``CmiIsomallocInRange(malloc(size))`` is guaranteed to be zero;
1531 ``CmiIsomallocInRange(CmiIsomalloc(size))`` is guaranteed to be one.
1532
1533 Threads
1534 =======
1535
1536 The calls in this chapter can be used to put together runtime systems
1537 for languages that support threads. This threads package, like most
1538 thread packages, provides basic functionality for creating threads,
1539 destroying threads, yielding, suspending, and awakening a suspended
1540 thread. In addition, it provides facilities whereby you can write your
1541 own thread schedulers.
1542
1543 Basic Thread Calls
1544 ------------------
1545
1546 .. code-block:: c++
1547
1548   typedef struct CthThreadStruct *CthThread;
1549
1550 This is an opaque type defined in ``converse.h``. It represents a
1551 first-class thread object. No information is publicized about the
1552 contents of a CthThreadStruct.
1553
1554 .. code-block:: c++
1555
1556   typedef void (CthVoidFn)(void *);
1557
1558 This is a type defined in ``converse.h``. It represents a function that
1559 returns nothing.
1560
1561 .. code-block:: c++
1562
1563   typedef CthThread (CthThFn)(void);
1564
1565 This is a type defined in ``converse.h``. It represents a function that
1566 returns a CthThread.
1567
1568 .. code-block:: c++
1569
1570   CthThread CthSelf()
1571
1572 Returns the currently-executing thread. Note: even the initial flow of
1573 control that inherently existed when the program began executing
1574 ``main`` counts as a thread. You may retrieve that thread object using
1575 ``CthSelf`` and use it like any other.
1576
1577 .. code-block:: c++
1578
1579   CthThread CthCreate(CthVoidFn fn, void *arg, int size)
1580
1581 Creates a new thread object. The thread is not given control yet. To
1582 make the thread execute, you must push it into the scheduler queue,
1583 using CthAwaken below. When (and if) the thread eventually receives
1584 control, it will begin executing the specified function ``fn`` with the
1585 specified argument. The ``size`` parameter specifies the stack size in
1586 bytes, 0 means use the default size. Caution: almost all threads are
1587 created with CthCreate, but not all. In particular, the one initial
1588 thread of control that came into existence when your program was first
1589 ``exec``\ ’d was not created with ``CthCreate``, but it can be retrieved
1590 (say, by calling ``CthSelf`` in ``main``), and it can be used like any
1591 other ``CthThread``.
1592
1593 .. code-block:: c++
1594
1595   CthThread CthCreateMigratable(CthVoidFn fn, void *arg, int size)
1596
1597 Create a thread that can later be moved to other processors. Otherwise
1598 identical to CthCreate.
1599
1600 This is only a hint to the runtime system; some threads implementations
1601 cannot migrate threads, others always create migratable threads. In
1602 these cases, CthCreateMigratable is equivalent to CthCreate.
1603
1604 .. code-block:: c++
1605
1606   CthThread CthPup(pup_er p,CthThread t)
1607
1608 Pack/Unpack a thread. This can be used to save a thread to disk, migrate
1609 a thread between processors, or checkpoint the state of a thread.
1610
1611 Only a suspended thread can be Pup’d. Only a thread created with
1612 CthCreateMigratable can be Pup’d.
1613
1614 .. code-block:: c++
1615
1616   void CthFree(CthThread t)
1617
1618 Frees thread ``t``. You may ONLY free the currently-executing thread
1619 (yes, this sounds strange, it’s historical). Naturally, the free will
1620 actually be postponed until the thread suspends. To terminate itself, a
1621 thread calls ``CthFree(CthSelf())``, then gives up control to another
1622 thread.
1623
1624 .. code-block:: c++
1625
1626   void CthSuspend()
1627
1628 Causes the current thread to stop executing. The suspended thread will
1629 not start executing again until somebody pushes it into the scheduler
1630 queue again, using CthAwaken below. Control transfers to the next task
1631 in the scheduler queue.
1632
1633 .. code-block:: c++
1634
1635   void CthAwaken(CthThread t)
1636
1637 Pushes a thread into the scheduler queue. Caution: a thread must only be
1638 in the queue once. Pushing it in twice is a crashable error.
1639
1640 .. code-block:: c++
1641
1642   void CthAwakenPrio(CthThread t, int strategy, int priobits, int *prio)
1643
1644 Pushes a thread into the scheduler queue with priority specified by
1645 ``priobits`` and ``prio`` and queueing strategy ``strategy``. Caution: a
1646 thread must only be in the queue once. Pushing it in twice is a
1647 crashable error. ``prio`` is not copied internally, and is used when the
1648 scheduler dequeues the message, so it should not be reused until then.
1649
1650 .. code-block:: c++
1651
1652   void CthYield()
1653
1654 This function is part of the scheduler-interface. It simply executes
1655 ``{ CthAwaken(CthSelf()); CthSuspend(); }``. This combination gives up
1656 control temporarily, but ensures that control will eventually return.
1657
1658 .. code-block:: c++
1659
1660   void CthYieldPrio(int strategy, int priobits, int *prio)
1661
1662 This function is part of the scheduler-interface. It simply executes
1663 ``{CthAwakenPrio(CthSelf(),strategy,priobits,prio);CthSuspend();}``
1664 This combination gives up control temporarily, but ensures that control
1665 will eventually return.
1666
1667 .. code-block:: c++
1668
1669   CthThread CthGetNext(CthThread t)
1670
1671 Each thread contains space for the user to store a “next” field (the
1672 functions listed here pay no attention to the contents of this field).
1673 This field is typically used by the implementors of mutexes, condition
1674 variables, and other synchronization abstractions to link threads
1675 together into queues. This function returns the contents of the next
1676 field.
1677
1678 .. code-block:: c++
1679
1680   void CthSetNext(CthThread t, CthThread next)
1681
1682 Each thread contains space for the user to store a “next” field (the
1683 functions listed here pay no attention to the contents of this field).
1684 This field is typically used by the implementors of mutexes, condition
1685 variables, and other synchronization abstractions to link threads
1686 together into queues. This function sets the contents of the next field.
1687
1688 Thread Scheduling and Blocking Restrictions
1689 -------------------------------------------
1690
1691 Converse threads use a scheduler queue, like any other threads package.
1692 We chose to use the same queue as the one used for Converse messages
1693 (see Section :numref:`schedqueue`). Because of this, thread
1694 context-switching will not work unless there is a thread polling for
1695 messages. A rule of thumb, with Converse, it is best to have a thread
1696 polling for messages at all times. In Converse’s normal mode (see
1697 Section :numref:`initial`), this happens automatically. However, in
1698 user-calls-scheduler mode, you must be aware of it.
1699
1700 There is a second caution associated with this design. There is a thread
1701 polling for messages (even in normal mode, it’s just hidden in normal
1702 mode). The continuation of your computation depends on that thread — you
1703 must not block it. In particular, you must not call blocking operations
1704 in these places:
1705
1706 -  In the code of a Converse handler (see
1707    Sections :numref:`handler1` and :numref:`handler2`).
1708
1709 -  In the code of the Converse start-function (see
1710    section :numref:`initial`).
1711
1712 These restrictions are usually easy to avoid. For example, if you wanted
1713 to use a blocking operation inside a Converse handler, you would
1714 restructure the code so that the handler just creates a new thread and
1715 returns. The newly-created thread would then do the work that the
1716 handler originally did.
1717
1718 Thread Scheduling Hooks
1719 -----------------------
1720
1721 Normally, when you CthAwaken a thread, it goes into the primary
1722 ready-queue: namely, the main Converse queue described in
1723 Section :numref:`schedqueue`. However, it is possible to hook a
1724 thread to make it go into a different ready-queue. That queue doesn’t
1725 have to be priority-queue: it could be FIFO, or LIFO, or in fact it
1726 could handle its threads in any complicated order you desire. This is a
1727 powerful way to implement your own scheduling policies for threads.
1728
1729 To achieve this, you must first implement a new kind of ready-queue. You
1730 must implement a function that inserts threads into this queue. The
1731 function must have this prototype:
1732
1733 .. code-block:: c++
1734
1735   void awakenfn(CthThread t, int strategy, int priobits, int *prio);
1736
1737 When a thread suspends, it must choose a new thread to transfer control
1738 to. You must implement a function that makes the decision: which thread
1739 should the current thread transfer to. This function must have this
1740 prototype:
1741
1742 .. code-block:: c++
1743
1744   CthThread choosefn();
1745
1746 Typically, the choosefn would choose a thread from your ready-queue.
1747 Alternately, it might choose to always transfer control to a central
1748 scheduling thread.
1749
1750 You then configure individual threads to actually use this new
1751 ready-queue. This is done using CthSetStrategy:
1752
1753 .. code-block:: c++
1754
1755   void CthSetStrategy(CthThread t, CthAwkFn awakenfn, CthThFn choosefn)
1756
1757 Causes the thread to use the specified ``awakefn`` whenever you
1758 CthAwaken it, and the specified ``choosefn`` whenever you CthSuspend it.
1759
1760 CthSetStrategy alters the behavior of CthSuspend and CthAwaken.
1761 Normally, when a thread is awakened with CthAwaken, it gets inserted
1762 into the main ready-queue. Setting the thread’s ``awakenfn`` will cause
1763 the thread to be inserted into your ready-queue instead. Similarly, when
1764 a thread suspends using CthSuspend, it normally transfers control to
1765 some thread in the main ready-queue. Setting the thread’s ``choosefn``
1766 will cause it to transfer control to a thread chosen by your
1767 ``choosefn`` instead.
1768
1769 You may reset a thread to its normal behavior using
1770 CthSetStrategyDefault:
1771
1772 .. code-block:: c++
1773
1774   void CthSetStrategyDefault(CthThread t)
1775
1776 Restores the value of ``awakefn`` and ``choosefn`` to their default
1777 values. This implies that the next time you CthAwaken the specified
1778 thread, it will be inserted into the normal ready-queue.
1779
1780 Keep in mind that this only resolves the issue of how threads get into
1781 your ready-queue, and how those threads suspend. To actually make
1782 everything “work out” requires additional planning: you have to make
1783 sure that control gets transferred to everywhere it needs to go.
1784
1785 Scheduling threads may need to use this function as well:
1786
1787 .. code-block:: c++
1788
1789   void CthResume(CthThread t)
1790
1791 Immediately transfers control to thread ``t``. This routine is primarily
1792 intended for people who are implementing schedulers, not for end-users.
1793 End-users should probably call ``CthSuspend`` or ``CthAwaken`` (see
1794 below). Likewise, programmers implementing locks, barriers, and other
1795 synchronization devices should also probably rely on ``CthSuspend`` and
1796 ``CthAwaken``.
1797
1798 A final caution about the ``choosefn``: it may only return a thread that
1799 wants the CPU, eg, a thread that has been awakened using the
1800 ``awakefn``. If no such thread exists, if the ``choosefn`` cannot return
1801 an awakened thread, then it must not return at all: instead, it must
1802 wait until, by means of some pending IO event, a thread becomes awakened
1803 (pending events could be asynchronous disk reads, networked message
1804 receptions, signal handlers, etc). For this reason, many schedulers
1805 perform the task of polling the IO devices as a side effect. If handling
1806 the IO event causes a thread to be awakened, then the choosefn may
1807 return that thread. If no pending events exist, then all threads will
1808 remain permanently blocked, the program is therefore done, and the
1809 ``choosefn`` should call ``exit``.
1810
1811 There is one minor exception to the rule stated above (“the scheduler
1812 may not resume a thread unless it has been declared that the thread
1813 wants the CPU using the ``awakefn``”). If a thread ``t`` is part of the
1814 scheduling module, it is permitted for the scheduling module to resume
1815 ``t`` whenever it so desires: presumably, the scheduling module knows
1816 when its threads want the CPU.
1817
1818 Timers, Periodic Checks, and Conditions
1819 =======================================
1820
1821 This module provides functions that allow users to insert hooks, i.e.
1822 user-supplied functions, that are called by the system at as specific
1823 conditions arise. These conditions differ from UNIX signals in that they
1824 are raised synchronously, via a regular function call; and that a single
1825 condition can call several different functions.
1826
1827 The system-defined conditions are:
1828
1829 CcdPROCESSOR_BEGIN_IDLE
1830    Raised when the scheduler first finds it has no messages to execute.
1831    That is, this condition is raised at the trailing edge of the
1832    processor utilization graph.
1833
1834 CcdPROCESSOR_STILL_IDLE
1835    Raised when the scheduler subsequently finds it still has no messages
1836    to execute. That is, this condition is raised while the processor
1837    utilization graph is flat.
1838
1839 CcdPROCESSOR_BEGIN_BUSY
1840    Raised when a message first arrives on an idle processor. That is,
1841    raised on the rising edge of the processor utilization graph.
1842
1843 CcdPERIODIC
1844    The scheduler attempts to raise this condition every few
1845    milliseconds. The scheduling for this and the other periodic
1846    conditions is nonpreemptive, and hence may be delayed until the
1847    current entry point is finished.
1848
1849 CcdPERIODIC_10ms
1850    Raised every 10ms (at 100Hz).
1851
1852 CcdPERIODIC_100ms
1853    Raised every 100ms (at 10Hz).
1854
1855 CcdPERIODIC_1second
1856    Raised once per second.
1857
1858 CcdPERIODIC_10second
1859    Raised once every 10 seconds.
1860
1861 CcdPERIODIC_1minute
1862    Raised once per minute.
1863
1864 CcdPERIODIC_10minute
1865    Raised once every 10 minutes.
1866
1867 CcdPERIODIC_1hour
1868    Raised once every hour.
1869
1870 CcdPERIODIC_12hour
1871    Raised once every twelve hours.
1872
1873 CcdPERIODIC_1day
1874    Raised once every day.
1875
1876 CcdQUIESCENCE
1877    Raised when the quiescence detection system has determined that the
1878    system is quiescent.
1879
1880 CcdSIGUSR1
1881    Raised when the system receives the UNIX signal SIGUSR1. Be aware
1882    that this condition is thus raised asynchronously, from within a
1883    signal handler, and all the usual signal handler restrictions apply.
1884
1885 CcdSIGUSR2
1886    Raised when the system receives the UNIX signal SIGUSR2.
1887
1888 CcdUSER
1889    The system never raises this or any larger conditions. They can be
1890    used by the user for application-specific use.
1891
1892 CcdUSERMAX
1893    All conditions from CcdUSER to CcdUSERMAX (inclusive) are available.
1894
1895 .. code-block:: c++
1896
1897    int CcdCallOnCondition(int condnum, CcdVoidFn fnp, void* arg)
1898
1899 This call instructs the system to call the function indicated by the
1900 function pointer ``fnp``, with the specified argument ``arg``, when
1901 the condition indicated by ``condnum`` is raised next. Multiple
1902 functions may be registered for the same condition number.
1903 ``CcdVoidFn`` is a function pointer with the signature ``void fnp(void
1904 *userParam, double curWallTime)``
1905
1906 .. code-block:: c++
1907
1908   int CcdCallOnConditionKeep(int condnum, CcdVoidFn fnp, void* arg)
1909
1910 As above, but the association is permanent- the given function will
1911 be called again whenever this condition is raised.
1912 Returns an index that may be used to cancel the association later.
1913
1914 .. code-block:: c++
1915
1916   void CcdCancelCallOnCondition(int condnum, int idx)
1917
1918   void CcdCancelCallOnConditionKeep(int condnum, int idx)
1919
1920 Delete the given index from the list of callbacks for the given condition. The
1921 corresponding function will no longer be called when the condition is
1922 raised. Note that it is illegal to call these two functions to cancel
1923 callbacks from within ccd callbacks.
1924
1925 .. code-block:: c++
1926
1927   void CcdRaiseCondition(int condNum)
1928
1929
1930 When this function is called, it invokes all the functions whose
1931 pointers were registered for the ``condNum`` via a *prior* call to
1932 ``CcdCallOnCondition`` or ``CcdCallOnConditionKeep``.
1933
1934 .. code-block:: c++
1935
1936   void CcdCallFnAfter(CcdVoidFn fnp, void* arg, double msLater)
1937
1938 This call registers a function via a pointer to it, ``fnp``, that will
1939 be called at least ``msLater`` milliseconds later. The registered
1940 function ``fnp`` is actually called the first time the scheduler gets
1941 control after ``deltaT`` milliseconds have elapsed. The default
1942 polling resolution for timed callbacks is 5 ms.
1943
1944 .. code-block:: c++
1945
1946   double CcdSetResolution(double newResolution)
1947
1948 This call sets the polling resolution for completion of timed
1949 callbacks. ``newResolution`` is the updated time in seconds. The
1950 default polling resolution for timed callbacks is 5 ms. The resolution
1951 cannot be any longer than this but it can be set arbitrarily short.
1952 Shorter resolution times can result in a performance decrease due to
1953 more time being spent polling for callbacks but may be preferred in
1954 cases where these need to be triggered quickly and/or are on the
1955 critical path of an application. This function also returns the old
1956 resolution in seconds in case it needs to be reset to a non-default
1957 value.
1958
1959 .. code-block:: c++
1960
1961   double CcdResetResolution()
1962
1963 This call returns the time based callback polling resolution to its
1964 default, 5 milliseconds. It returns the previously set resolution in
1965 seconds.
1966
1967 .. code-block:: c++
1968
1969   double CcdIncreaseResolution(double newResolution)
1970
1971 This is a “safe” version of ``CcdSetResolution`` that only ever sets
1972 the resolution to a shorter time. The same caveats about short polling
1973 times affecting performance still apply, This function returns the
1974 previous (and potentially current, if it was shorter than
1975 ``newResolution``,) resolution in seconds.
1976
1977 .. _converse_client_server:
1978
1979 Converse Client-Server Interface
1980 ================================
1981
1982 This note describes the Converse client-server (CCS) module. This module
1983 enables Converse programs to act as parallel servers, responding to
1984 requests from (non-Converse) programs across the internet.
1985
1986 The CCS module is split into two parts- client and server. The server
1987 side is the interface used by a Converse program; the client side is
1988 used by arbitrary (non-Converse) programs. The following sections
1989 describe both these parts.
1990
1991 A CCS client accesses a running Converse program by talking to a
1992 ``server-host``, which receives the CCS requests and relays them to the
1993 appropriate processor. The ``server-host`` is charmrun for netlrts-
1994 versions, and is the first processor for all other versions.
1995
1996 CCS: Starting a Server
1997 ----------------------
1998
1999 A Converse program is started using
2000
2001 .. code-block:: bash
2002
2003    $ charmrun pgmname +pN charmrun-opts pgm-opts
2004
2005 charmrun also accepts the CCS options:
2006
2007 ``++server``: open a CCS server on any TCP port number
2008
2009 ``++server-port``\ =\ :math:`port`: open the given TCP port as a CCS
2010 server
2011
2012 ``++server-auth``\ =\ :math:`authfile`: accept authenticated queries
2013
2014 As the parallel job starts, it will print a line giving the IP address
2015 and TCP port number of the new CCS server. The format is: “ccs: Server
2016 IP = :math:`ip`, Server port = :math:`port` $”, where :math:`ip` is a
2017 dotted decimal version of the server IP address, and :math:`port` is the
2018 decimal port number.
2019
2020 CCS: Client-Side
2021 ----------------
2022
2023 A CCS client connects to a CCS server, asks a server PE to execute a
2024 pre-registered handler, and receives the response data. The CCS client
2025 may be written in any language (see CCS network protocol, below), but a
2026 C interface (files “ccs-client.c” and “ccs-client.h”) and Java interface
2027 (file “CcsServer.java”) are available in the charm include directory.
2028
2029 The C routines use the skt_abort error-reporting strategy; see
2030 “sockRoutines.h” for details. The C client API is:
2031
2032 .. code-block:: c++
2033
2034   void CcsConnect(CcsServer *svr, char *host, int port); Connect to the
2035
2036 given CCS server. svr points to a pre-allocated CcsServer structure.
2037
2038 .. code-block:: c++
2039
2040   void CcsConnectIp(CcsServer *svr, int ip, int port);
2041
2042 As above, but a numeric IP is specified.
2043
2044 .. code-block:: c++
2045
2046   int CcsNumNodes(CcsServer *svr);
2047
2048   int CcsNumPes(CcsServer *svr);
2049
2050   int CcsNodeFirst(CcsServer *svr, int node);
2051
2052   int CcsNodeSize(CcsServer *svr,int node);
2053
2054 These functions return information about the parallel
2055 machine; they are equivalent to the Converse calls CmiNumNodes,
2056 CmiNumPes, CmiNodeFirst, and CmiNodeSize.
2057
2058 .. code-block:: c++
2059
2060   void CcsSendRequest(CcsServer *svr, char *hdlrID, int pe, unsigned int
2061   size, const char *msg);
2062
2063 Ask the server to execute the handler hdlrID on
2064 the given processor. The handler is passed the given data as a message.
2065 The data may be in any desired format (including binary).
2066
2067 .. code-block:: c++
2068
2069   int CcsSendBroadcastRequest(CcsServer *svr, const char *hdlrID, int
2070   size, const void *msg);
2071
2072 As CcsSendRequest, only that the handler hdlrID
2073 is invoked on all processors.
2074
2075 .. code-block:: c++
2076
2077   int CcsSendMulticastRequest(CcsServer *svr, const char *hdlrID,
2078   int  npes, int *pes, int size, const void *msg);
2079
2080 As CcsSendRequest, only that the handler hdlrID is invoked on the processors
2081 specified in the array pes (of size npes).
2082
2083 .. code-block:: c++
2084
2085   int CcsRecvResponse(CcsServer *svr, unsigned int maxsize,
2086   char *recvBuffer, int timeout);
2087
2088 Receive a response to the previous request
2089 in-place. Timeout gives the number of seconds to wait before returning
2090 0; otherwise the number of bytes received is returned.
2091
2092 .. code-block:: c++
2093
2094   int CcsRecvResponseMsg(CcsServer *svr, unsigned int *retSize,
2095   char **newBuf, int timeout);
2096
2097 As above, but receive a variable-length
2098 response. The returned buffer must be free()’d after use.
2099
2100 .. code-block:: c++
2101
2102   int CcsProbe(CcsServer *svr);
2103
2104 Return 1 if a response is available; otherwise 0.
2105
2106 .. code-block:: c++
2107
2108   void CcsFinalize(CcsServer *svr);
2109
2110 Closes connection and releases server.
2111
2112 The Java routines throw an IOException on network errors. Use javadoc on
2113 CcsServer.java for the interface, which mirrors the C version above.
2114
2115 CCS: Server-Side
2116 ----------------
2117
2118 Once a request arrives on a CCS server socket, the CCS server runtime
2119 looks up the appropriate handler and calls it. If no handler is found,
2120 the runtime prints a diagnostic and ignores the message.
2121
2122 CCS calls its handlers in the usual Converse fashion- the request data
2123 is passed as a newly-allocated message, and the actual user data begins
2124 CmiMsgHeaderSizeBytes into the message. The handler is responsible for
2125 CmiFree’ing the passed-in message.
2126
2127 The interface for the server side of CCS is included in “converse.h”; if
2128 CCS is disabled (in conv-mach.h), all CCS routines become macros
2129 returning 0.
2130
2131 The handler registration interface is:
2132
2133 .. code-block:: c++
2134
2135   void CcsUseHandler(char *id, int hdlr);
2136
2137   int CcsRegisterHandler(char *id, CmiHandler fn);
2138
2139 Associate this handler ID string with this function.
2140 hdlr is a Converse handler index; fn is a function pointer.
2141 The ID string cannot be more than 32 characters, including the
2142 terminating NULL.
2143
2144 After a handler has been registered to CCS, the user can also setup a
2145 merging function. This function will be passed in to CmiReduce to
2146 combine replies to multicast and broadcast requests.
2147
2148 .. code-block:: c++
2149
2150   void CcsSetMergeFn(const char *name, CmiReduceMergeFn newMerge);
2151
2152 Associate the given merge function to the CCS identified by id. This
2153 will be used for CCS request received as broadcast or multicast.
2154
2155 These calls can be used from within a CCS handler:
2156
2157 .. code-block:: c++
2158
2159   int CcsEnabled(void);
2160
2161 Return 1 if CCS routines are available (from
2162 conv-mach.h). This routine does not determine if a CCS server port is
2163 actually open.
2164
2165 .. code-block:: c++
2166
2167   int CcsIsRemoteRequest(void);
2168
2169 Return 1 if this handler was called via
2170 CCS; 0 if it was called as the result of a normal Converse message.
2171
2172 .. code-block:: c++
2173
2174   void CcsCallerId(skt_ip_t *pip, unsigned int *pport);
2175
2176 Return the IP address and TCP port number of the CCS client that invoked this method.
2177 Can only be called from a CCS handler invoked remotely.
2178
2179 .. code-block:: c++
2180
2181   void CcsSendReply(int size, const void *reply);
2182
2183 Send the given data back to the client as a reply. Can only be called from a CCS handler
2184 invoked remotely. In case of broadcast or multicast CCS requests, the
2185 handlers in all processors involved must call this function.
2186
2187 .. code-block:: c++
2188
2189   CcsDelayedReply CcsDelayReply(void);
2190
2191 Allows a CCS reply to be delayed until after the handler has completed.
2192 Returns a token used below.
2193
2194 .. code-block:: c++
2195
2196   void CcsSendDelayedReply(CcsDelayedReply d,int size, const void *reply);
2197
2198 Send a CCS reply for the given request. Unlike CcsSendReply,
2199 can be invoked from any handler on any processor.
2200
2201 CCS: system handlers
2202 --------------------
2203
2204 The CCS runtime system provides several built-in CCS handlers, which are
2205 available in any Converse job:
2206
2207 ``ccs_getinfo`` Takes an empty message, responds with information about the
2208 parallel job. The response is in the form of network byte order
2209 (big-endian) 4-byte integers: first the number of parallel nodes, then
2210 the number of processors on each node. This handler is invoked by the
2211 client routine CcsConnect.
2212
2213 ``ccs_killport`` Allows a client to be notified when a parallel run exits
2214 (for any reason). Takes one network byte order (big-endian) 4-byte
2215 integer: a TCP port number. The runtime writes “die
2216 n” to this port before exiting. There is no response data.
2217
2218 ``perf_monitor`` Takes an empty message, responds (after a delay) with
2219 performance data. When CMK_WEB_MODE is enabled in conv-mach.h, the
2220 runtime system collects performance data. Every 2 seconds, this data is
2221 collected on processor 0 and sent to any clients that have invoked
2222 perf_monitor on processor 0. The data is returned in ASCII format with
2223 the leading string "perf", and for each processor the current load (in
2224 percent) and scheduler message queue length (in messages). Thus a
2225 heavily loaded, two-processor system might reply with the string “perf
2226 98 148230 100 385401”.
2227
2228 CCS: network protocol
2229 ---------------------
2230
2231 This information is provided for completeness and clients written in
2232 non-C, non-Java languages. The client and server APIs above are the
2233 preferred way to use CCS.
2234
2235 A CCS request arrives as a new TCP connection to the CCS server port.
2236 The client speaks first, sending a request header and then the request
2237 data. The server then sends the response header and response data, and
2238 closes the connection. Numbers are sent as network byte order
2239 (big-endian) 4-byte integers- network binary integers.
2240
2241 The request header has three fields: the number of bytes of request
2242 data, the (0-based) destination processor number, and the CCS handler
2243 identifier string. The byte count and processor are network binary
2244 integers (4 bytes each), the CCS handler ID is zero-terminated ASCII
2245 text (32 bytes); for a total request header length of 40 bytes. The
2246 remaining request data is passed directly to the CCS handler.
2247
2248 The response header consists of a single network binary integer- the
2249 length in bytes of the response data to follow. The header is thus 4
2250 bytes long. If there is no response data, this field has value 0.
2251
2252 CCS: Authentication
2253 -------------------
2254
2255 By default, CCS provides no authentication- this means any client
2256 anywhere on the internet can interact with the server. :math:`authfile`,
2257 passed to ’++server-auth’, is a configuration file that enables
2258 authentication and describes the authentication to perform.
2259
2260 The configuration file is line-oriented ASCII text, consisting of
2261 security level / key pairs. The security level is an integer from 0 (the
2262 default) to 255. Any security levels not listed in the file are
2263 disallowed.
2264
2265 The key is the 128-bit secret key used to authenticate CCS clients for
2266 that security level. It is either up to 32 hexadecimal digits of key
2267 data or the string "OTP". "OTP" stands for One Time Pad, which will
2268 generate a random key when the server is started. This key is printed
2269 out at job startup with the format "CCS_OTP_KEY:math:`>` Level :math:`i`
2270 key: :math:`hexdigits`" where :math:`i` is the security level in decimal
2271 and :math:`hexdigits` is 32 hexadecimal digits of key data.
2272
2273 For example, a valid CCS authentication file might consist of the single
2274 line "0 OTP", indicating that the default security level 0 requires a
2275 randomly generated key. All other security levels are disallowed.
2276
2277 Converse One Sided Communication Interface
2278 ==========================================
2279
2280 This chapter deals with one sided communication support in converse. It
2281 is imperative to provide a one-sided communication interface to take
2282 advantage of the hardware RDMA facilities provided by a lot of NIC
2283 cards. Drivers for these hardware provide or promise to soon provide
2284 capabilities to use this feature.
2285
2286 Converse provides an implementation which wraps the functionality
2287 provided by different hardware and presents them as a uniform interface
2288 to the programmer. For machines which do not have a one-sided hardware
2289 at their disposal, these operations are emulated through converse
2290 messages.
2291
2292 Converse provides the following types of operations to support one-sided
2293 communication.
2294
2295 Registering / Unregistering Memory for RDMA
2296 -------------------------------------------
2297
2298 The interface provides functions to register(pin) and unregister(unpin)
2299 memory on the NIC hardware. The emulated version of these operations do
2300 not do anything.
2301
2302 .. code-block:: c++
2303
2304   int CmiRegisterMemory(void *addr, unsigned int size);
2305
2306 This function takes an allocated memory at starting address addr of
2307 length size and registers it with the hardware NIC, thus making this
2308 memory DMAable. This is also called pinning memory on the NIC hardware,
2309 making remote DMA operations on this memory possible. This directly
2310 calls the hardware driver function for registering the memory region and
2311 is usually an expensive operation, so should be used sparingly.
2312
2313 .. code-block:: c++
2314
2315   int CmiUnRegisterMemory(void *addr, unsigned int size);
2316
2317 This function unregisters the memory at starting address addr of length
2318 size, making it no longer DMAable. This operation corresponds to
2319 unpinning memory from the NIC hardware. This is also an expensive
2320 operation and should be sparingly used.
2321
2322 For certain machine layers which support a DMA, we support the function
2323 ``void *CmiDMAAlloc(int size);``
2324
2325 This operation allocates a memory region of length size from the DMAable
2326 region on the NIC hardware. The memory region returned is pinned to the
2327 NIC hardware. This is an alternative to CmiRegisterMemory and is
2328 implemented only for hardwares that support this.
2329
2330 RDMA operations (Get / Put)
2331 ---------------------------
2332
2333 This section presents functions that provide the actual RDMA operations.
2334 For hardware architectures that support these operations these functions
2335 provide a standard interface to the operations, while for NIC
2336 architectures that do not support RDMA operations, we provide an
2337 emulated implementation. There are three types of NIC architectures
2338 based on how much support they provide for RDMA operations:
2339
2340 -  Hardware support for both *Get* and *Put* operations.
2341
2342 -  Hardware support for one of the two operations, mostly for *Put*. For
2343    these the other RDMA operation is emulated by using the operation
2344    that is implemented in hardware and extra messages.
2345
2346 -  No hardware support for any RDMA operation. For these, both the RDMA
2347    operations are emulated through messages.
2348
2349 There are two different sets of RDMA operations
2350
2351 -  The first set of RDMA operations return an opaque handle to the
2352    programmer, which can only be used to verify if the operation is
2353    complete. This suits AMPI better and closely follows the idea of
2354    separating communication from synchronization. So, the user program
2355    needs to keep track of synchronization.
2356
2357 -  The second set of RDMA operations do not return anything, instead
2358    they provide a callback when the operation completes. This suits
2359    nicely the charm++ framework of sending asynchronous messages. The
2360    handler(callback) will be automatically invoked when the operation
2361    completes.
2362
2363 **For machine layer developer:** Internally, every machine layer is free
2364 to create a suitable data structure for this purpose. This is the reason
2365 this has been kept opaque from the programmer.
2366
2367 .. code-block:: c++
2368
2369   void *CmiPut(unsigned int sourceId, unsigned int targetId, void
2370   *Saddr, void *Taadr, unsigned int size);
2371
2372 This function is pretty self explanatory. It puts the memory location at
2373 Saddr on the machine specified by sourceId to Taddr on the machine
2374 specified by targetId. The memory region being RDMA’ed is of length size
2375 bytes.
2376
2377 .. code-block:: c++
2378
2379   void *CmiGet(unsigned int sourceId, unsigned int targetId, void
2380   *Saddr, void *Taadr, unsigned int size);
2381
2382 Similar to CmiPut except the direction of the data transfer is opposite;
2383 from target to source.
2384
2385 .. code-block:: c++
2386
2387   void CmiPutCb(unsigned int sourceId, unsigned int targetId, void
2388   *Saddr, void *Taddr, unsigned int size, CmiRdmaCallbackFn fn, void
2389   *param);
2390
2391 Similar to CmiPut except a callback is called when the operation
2392 completes.
2393
2394 .. code-block:: c++
2395
2396   void CmiGetCb(unsigned int sourceId, unsigned int targetId, void
2397   *Saddr, void *Taddr, unsigned int size, CmiRdmaCallbackFn fn, void
2398   *param);
2399
2400 Similar to CmiGet except a callback is called when the operation
2401 completes.
2402
2403 Completion of RDMA operation
2404 ----------------------------
2405
2406 This section presents functions that are used to check for completion of
2407 an RDMA operation. The one sided communication operations are
2408 asynchronous, thus there needs to be a mechanism to verify for
2409 completion. One mechanism is for the programmer to check for completion.
2410 The other mechanism is through callback functions registered during the
2411 RDMA operations.
2412
2413 .. code-block:: c++
2414
2415   int CmiWaitTest(void *obj);
2416
2417 This function takes this RDMA handle and verifies if the operation
2418 corresponding to this handle has completed.
2419
2420 A typical usage of this function would be in AMPI when there is a call
2421 to AMPIWait. The implementation should call the CmiWaitTest for all
2422 pending RDMA operations in that window.
2423
2424 Random Number Generation
2425 ========================
2426
2427 Converse includes support for random number generation using a 64-bit
2428 Linear Congruential Generator (LCG). The user can choose between using a
2429 supplied default stream shared amongst all chares on the processor, or
2430 creating a private stream. Note that there is a limit on the number of
2431 private streams, which at the time of writing was 15,613.
2432
2433 .. code-block:: c++
2434
2435   struct CrnStream;
2436
2437 This structure contains the current state of a random number stream. The
2438 user is responsible for allocating the memory for this structure.
2439
2440 Default Stream Calls
2441 --------------------
2442
2443 .. code-block:: c++
2444
2445   void CrnSrand(int seed);
2446
2447 Seeds the default random number generator with ``seed``.
2448
2449 .. code-block:: c++
2450
2451   int CrnRand(void);
2452
2453 Returns the next random number in the default stream as an integer.
2454
2455 .. code-block:: c++
2456
2457   int CrnDrand(void);
2458
2459 Returns the next random number in the default stream as a double.
2460
2461 Private Stream Calls
2462 --------------------
2463
2464 .. code-block:: c++
2465
2466   void CrnInitStream(CrnStream *dest, int seed, int type);
2467
2468 Initializes a new stream with its initial state stored in ``dest``. The
2469 user must supply a seed in ``seed``, as well as the ``type`` of the
2470 stream, where the ``type`` can be 0, 1, or 2.
2471
2472 .. code-block:: c++
2473
2474   double CrnDouble(CrnStream *genptr);
2475
2476 Returns the next random number in the stream whose state is given by
2477 ``genptr``; the number is returned as a double.
2478
2479 .. code-block:: c++
2480
2481   double CrnInt(CrnStream *genptr);
2482
2483 Returns the next random number in the stream whose state is given by
2484 ``genptr``; the number is returned as an integer.
2485
2486 .. code-block:: c++
2487
2488   double CrnFloat(CrnStream *genptr);
2489
2490 Returns the next random number in the stream whose state is given by
2491 ``genptr``; the number is returned as a float. (Note: This function is
2492 exactly equivalent to ``(float) CrnDouble(genptr);``.)
2493
2494 Converse Persistent Communication Interface
2495 ===========================================
2496
2497 This chapter deals with persistent communication support in converse. It
2498 is used when point-to-point message communication is called repeatedly
2499 to avoid redundancy in setting up the message each time it is sent. In
2500 the message-driven model like charm, the sender will first notify the
2501 receiver that it will send message to it, the receiver will create
2502 handler to record the message size and malloc the address for the
2503 upcoming message and send that information back to the sender, then if
2504 the machine have one-sided hardware, it can directly put the message
2505 into the address on the receiver.
2506
2507 Converse provides an implementation which wraps the functionality
2508 provided by different hardware and presents them as a uniform interface
2509 to the programmer. For machines which do not have a one-sided hardware
2510 at their disposal, these operations are emulated through converse
2511 messages.
2512
2513 Converse provides the following types of operations to support
2514 persistent communication.
2515
2516 Create / Destroy Persistent Handler
2517 -----------------------------------
2518
2519 The interface provides functions to crate and destroy handler on the
2520 processor for use of persistent communication.
2521
2522 .. code-block:: c++
2523
2524   Persistenthandle CmiCreatePersistent(int destPE, int maxBytes);
2525
2526 This function creates a persistent communication handler with dest PE
2527 and maximum bytes for this persistent communication. Machine layer will
2528 send message to destPE and setup a persistent communication. A buffer of
2529 size maxBytes is allocated in the destination PE.
2530
2531 .. code-block:: c++
2532
2533   PersistentReq CmiCreateReceiverPersistent(int maxBytes);
2534   PersistentHandle CmiRegisterReceivePersistent(PersistentReq req);
2535
2536 Alternatively, a receiver can initiate the setting up of persistent
2537 communication. At receiver side, user calls
2538 CmiCreateReceiverPersistent() which returns a temporary handle type -
2539 PersistentRecvHandle. Send this handle to the sender side and the sender
2540 should call CmiRegisterReceivePersistent() to setup the persistent
2541 communication. The function returns a PersistentHandle which can then be
2542 used for the persistent communication.
2543
2544 .. code-block:: c++
2545
2546   void CmiDestroyPersistent(PersistentHandle h);
2547
2548 This function destroys a persistent communication specified by
2549 PersistentHandle h.
2550
2551 .. code-block:: c++
2552
2553   void CmiDestroyAllPersistent();
2554
2555 This function will destroy all persistent communication on the local
2556 processor.
2557
2558 Persistent Operation
2559 --------------------
2560
2561 This section presents functions that uses persistent handler for
2562 communications.
2563
2564 .. code-block:: c++
2565
2566   void CmiUsePersistentHandle(PersistentHandle *p, int n)
2567
2568 This function will ask Charm machine layer to use an array of
2569 PersistentHandle "p"(array size of n) for all the following
2570 communication. Calling with p=NULL will cancel the persistent
2571 communication. n=1 is for sending message to each Chare, n>1 is for
2572 message in multicast-one PersistentHandle for each PE.