doc: clean up syntax highlighting
[charm.git] / doc / pose / manual.rst
1 ======================================================
2 Parallel Object-Oriented Simulation Environment (POSE)
3 ======================================================
4
5 .. contents::
6    :depth: 3
7
8 Introduction
9 ============
10
11 POSE (Parallel Object-oriented Simulation Environment) is a tool for
12 parallel discrete event simulation (PDES) based on Charm++. You should
13 have a background in object-oriented programming (preferably C++) and
14 know the basic principles behind discrete event simulation. Familiarity
15 with simple parallel programming in Charm++ is also a plus.
16
17 POSE uses the approach of message-driven execution of Charm++, but adds
18 the element of discrete timestamps to control when, in simulated time, a
19 message is executed.
20
21 Users may choose synchronization strategies (conservative or several
22 optimistic variants) on a per class basis, depending on the desired
23 behavior of the object. However, POSE is intended to perform best with a
24 special type of *adaptive* synchronization strategy which changes it’s
25 behavior on a per object basis. Thus, other synchronization strategies
26 may not be properly maintained. There are two significant versions of
27 the adaptive strategy, *adapt4*, a simple, stable version, and *adept*, the
28 development version.
29
30 Developing a model in POSE
31 --------------------------
32
33 Modeling a system in POSE is similar to how you would model in C++ or
34 any OOP language. Objects are entities that hold data, and have a fixed
35 set of operations that can be performed on them (methods).
36
37 Charm++ provides the parallelism we desire, but the model does not
38 differ dramatically from C++. The primary difference is that objects may
39 exist on a set of processors, and so invoking methods on them requires
40 communication via messages. These parallel objects are called *chares*.
41
42 POSE adds to Charm++ by putting timestamps on method invocations
43 (events), and executing events in timestamp order to preserve the
44 validity of the global state.
45
46 Developing a model in POSE involves identifying the entities we wish to
47 model, determining their interactions with other entities and
48 determining how they change over time.
49
50 PDES in POSE
51 ------------
52
53 A simulation in POSE consists of a set of Charm++ chares performing
54 timestamped events in parallel. In POSE, these chares are called *posers*.
55 POSE is designed to work with many such entities per processor. The more
56 a system can be broken down into its parallel components when designing
57 the simulation model, the more potential parallelism in the final
58 application.
59
60 A poser class is defined with a synchronization strategy associated with
61 it. We encourage the use of the adaptive strategies, as mentioned
62 earlier. Adaptive strategies are optimistic, and will potentially
63 execute events out of order, but have rollback and cancellation messages
64 as well as checkpointing abilities to deal with this behind the scenes.
65
66 Execution is driven by events. An event arrives for a poser and is
67 sorted into a queue by timestamp. The poser has a local time called
68 object virtual time (OVT) which represents its progress through the
69 simulation. When an event arrives with a timestamp :math:`t>`\ OVT, the
70 OVT is advanced to :math:`t`. If the event has timestamp
71 :math:`t<`\ OVT, it may be that other events with greater timestamps
72 were executed. If this is the case, a rollback will occur. If not, the
73 event is simply executed along with the others in the queue.
74
75 Time can also pass on a poser within the course of executing an event.
76 An *elapse* function is used to advance the OVT.
77
78 POSE maintains a global clock, the global virtual time (GVT), that
79 represents the progress of the entire simulation.
80
81 Currently, POSE has no way to directly specify event dependencies, so if
82 they exist, the programmer must handle errors in ordering carefully.
83 POSE provides a delayed error message print and abort function that is
84 only performed if there is no chance of rolling back the dependency
85 error. Another mechanism provided by POSE is a method of tagging events
86 with *sequence numbers*. This allows the user to determine the execution
87 order of events which have the same timestamp.
88
89 Compiling, Running and Debugging a Sample POSE program
90 ======================================================
91
92 Sample code is available in the Charm++ source distribution. Assuming a
93 netlrts-linux build of Charm++, look in
94 ``charm/netlrts-linux/examples/pose``. The SimBenchmark directory
95 contains a synthetic benchmark simulation and is fairly straightforward
96 to understand.
97
98 Compiling
99 ---------
100
101 To build a POSE simulation, run ``etrans.pl`` on each POSE module to get
102 the new source files. etrans.pl is a source to source translator. Given
103 a module name it will translate the ``module.h``, ``module.ci``, and
104 ``module.C`` files into ``module_sim.h``, ``module_sim.ci``, and
105 ``module_sim.C`` files. The translation operation adds wrapper classes
106 for POSE objects and handles the interface with strategies and other
107 poser options.
108
109 To facilitate code organization, the ``module.C`` file can be broken up
110 into multiple files and those files can appended to the etrans.pl
111 command line after the module name. These additional .C files will be
112 translated and their output appended to the ``module_sim.C`` file.
113
114 The ``-s`` switch can be passed to use the sequential simulator feature
115 of POSE on your simulation, but you must also build a sequential version
116 when you compile (see below).
117
118 Once the code has been translated, it is a Charm++ program that can be
119 compiled with ``charmc``. Please refer to the CHARM++/CONVERSE
120 Installation and Usage Manual for details on the charmc command. You
121 should build the new source files produced by etrans.pl along with the
122 main program and any other source needed with ``charmc``, linking with
123 ``-module pose`` (or ``-module seqpose`` for a sequential version) and
124 ``-language charm++``. The SimBenchmark example has a Makefile that
125 shows this process.
126
127 Running
128 -------
129
130 To run the program in parallel, a ``charmrun`` executable was created by
131 ``charmc``. The flag ``+p`` is used to specify a number of processors to
132 run the program on. For example:
133
134 .. code-block:: bash
135
136    $ ./charmrun pgm +p4
137
138 This runs the executable ``pgm`` on 4 processors. For more information
139 on how to use ``charmrun`` and set up your environment for parallel
140 runs, see the CHARM++/CONVERSE Installation and Usage Manual.
141
142 Debugging
143 ---------
144
145 Because POSE is translated to Charm++, debugging is a little more
146 challenging than normal. Multi-processor debugging can be achieved with
147 the ``charmrun ++debug`` option, and debugging is performed on the
148 ``module_sim.C`` source files. The user thus has to track down problems
149 in the original POSE source code. A long-term goal of the POSE
150 developers is to eliminate the translation phase and rely on the
151 interface translator of Charm++ to provide similar functionality.
152
153 Sequential Mode
154 ---------------
155
156 As mentioned above, the same source code can be used to generate a
157 purely sequential POSE executable by using the ``-s`` flag to
158 ``etrans.pl`` and linking with ``-module seqpose``. This turns off all
159 aspects of synchronization, checkpointing and GVT calculation that are
160 needed for optimistic parallel execution. Thus you should experience
161 better one-processor times for executables built for sequential
162 execution than those built for parallel execution. This is convenient
163 for examining how a program scales in comparison to sequential time. It
164 is also helpful for simulations that are small and fast, or in
165 situations where multiple processors are not available.
166
167 Programming in POSE
168 ===================
169
170 This section details syntax and usage of POSE constructs with code
171 samples.
172
173 POSE Modules
174 ------------
175
176 A POSE module is similar to a Charm++ module. It is comprised of an
177 interface file with suffix ``.ci``, a header ``.h`` file, and the
178 implementation in ``.C`` files. Several posers can be described in one
179 module, and the module can include regular chares as well. The module is
180 translated into Charm++ before the simulation can be compiled. This
181 translation is performed by a Perl script called ``etrans.pl`` which is
182 included with POSE. It generates files suffixed ``_sim.ci``, ``_sim.h``,
183 and ``_sim.C``.
184
185 Event Message and Poser Interface Description
186 ---------------------------------------------
187
188 Messages, be they event messages or otherwise, are described in the
189 ``.ci`` file exactly the way they are in Charm++. Event messages cannot
190 make use of Charm++’s parameter marshalling, and thus you must declare
191 them in the ``.h`` file. Charm++ ``varsize`` event messages are
192 currently not implemented in POSE.
193
194 All event messages inherit from a POSE type ``eventMsg`` which includes
195 data for timestamps and miscellaneous POSE statistics.
196
197 A message is declared in the ``.ci`` file as follows:
198
199 .. code-block:: none
200
201   message myMessage;
202
203
204 Posers are described similar to chares, with a few exceptions. First,
205 the ``poser`` keyword is used to denote that the class is a POSE
206 simulation object class. Second, event methods are tagged with the
207 keyword ``event`` in square brackets. Finally, three components are
208 specified which indicate how objects of the poser class are to be
209 simulated. The *sim* component controls the wrapper class and event
210 queue used by the object. The *strat* component controls the
211 synchronization strategy the object should use (*i.e.* adaptive or
212 basic optimistic). The *rep* component specifies the global state
213 representation, which controls how the global state is kept accurate
214 depending on the synchronization strategy being used (*i.e.*
215 checkpointing or no checkpointing). Currently, there is only one
216 wrapper type, ``sim``. This 3-tuple syntax is likely to become
217 obsolete, replaced simply by synchronization strategy only. Keeping
218 the global state accurate is largely a function of the synchronization
219 strategy used.
220
221 .. code-block:: none
222
223   poser mySim : sim strat rep {
224     entry mySim(myMessage *);``
225     entry [event] void myEventMethod(eventMsg *);
226     ...
227   };
228
229 A typical ``.ci`` file poser specification might look like this:
230
231 .. code-block:: none
232
233   poser Worker : sim adapt4 chpt {
234     entry Worker(WorkerCreationMsg *);
235     entry [event] void doWork(WorkMsg *);
236     ...
237   };
238
239 Note that the constructors and event methods of a poser must take an
240 event message as parameter. If there is no data (and thereby no
241 message defined) that needs to be passed to the method, then the
242 parameter should be of type ``eventMsg *``. This ensures that POSE
243 will be able to timestamp the event.
244
245 Declaring Event Messages and Posers
246 -----------------------------------
247
248 Currently, event messages are declared with no reference to what they
249 might inherit from (unlike in Charm++). The translator takes care of
250 this. In addition, they must define ``operator=``.
251
252 .. code-block:: c++
253
254   class myMessage {
255     public:
256     int someData;
257     myMessage& operator=(const myMessage& obj) {
258       eventMsg::operator=(obj);
259       someData = obj.someData;
260       return *this;
261     }
262   };
263
264 Similarly, posers do not refer to a base class when they are declared.
265 Posers are required to have a void constructor declared that simply
266 initializes the data to sensible values. A destructor must be provided
267 as well. In addition, a ``pup`` and ``operator=`` must be provided.
268 The ``pup`` method should call the ``pup`` method of the global state
269 representation class being used.
270
271 .. code-block:: c++
272
273   class mySim {
274     int anInt; float aFloat; char aString[20];
275      public:
276     mySim();
277     mySim(myMessage *m);
278     ~mySim();
279     void pup(PUP::er &p);
280     mySim& operator=(const mySim& obj);
281     void myEventMethod(eventMsg *m);
282     void myEventMethod_anti(eventMsg *m);
283     void myEventMethod_commit(eventMsg *m);
284     ...
285   };
286
287 Further, for each event method, a commit method should be declared,
288 and if the synchronization strategy being used is optimistic or
289 involves any sort of rollback, an anti-method should also be provided.
290 The syntax of these declarations is shown above. Their usage and
291 implementation will be described next.
292
293 Implementing Posers
294 -------------------
295
296 The void constructor for a poser should be defined however the user sees
297 fit. It could be given an empty body and should still work for POSE.
298 Poser entry constructors (those described in the ``.ci`` file) should
299 follow the template below:
300
301 .. code-block:: c++
302
303   mySim::mySim(myMessage *m)
304   {
305     // initializations from $m$
306     ...
307     delete m;
308     ...
309   };
310
311
312 Note that while the incoming message :math:`m` may be deleted here in
313 the constructor, event messages received on event methods should
314 **not** be deleted. The PDES fossil collection will take care of
315 those.
316
317 An event method should have the following form:
318
319 .. code-block:: c++
320
321   void mySim::myEventMethod(eventMsg *m) {
322     // body of method
323   };
324
325
326 Again, :math:`m` is never deleted in the body of the event. A side
327 effect of optimistic synchronization and rollback is that we would
328 like the effects of event execution to be dependent only upon the
329 state encapsulated in the corresponding poser. Thus, accessing
330 arbitrary states outside of the simulation, such as by calling
331 ``rand``, is forbidden. We are planning to fix this problem by adding
332 a ``POSE_rand()`` operation which will generate a random number the
333 first time the event is executed, and will checkpoint the number for
334 use in subsequent re-executions should a rollback occur.
335
336 Creation of Poser Objects
337 -------------------------
338
339 Posers are created within a module using the following syntax:
340
341 .. code-block:: c++
342
343   int hdl = 13; // handle should be unique
344   myMessage *m = new myMessage;
345   m->someData = 34;
346   POSE_create(mySim(m), hdl, 0);
347
348 This creates a ``mySim`` object that comes into existence at
349 simulation time zero, and can be referred to by the handle 13.
350
351 Creating a poser from outside the module (*i.e.* from ``main``) is
352 somewhat more complex:
353
354 .. code-block:: c++
355
356   int hdl = 13;
357   myMessage *m = new myMessage;
358   m->someData = 34;
359   m->Timestamp(0);
360   (*(CProxy_mySim *) & POSE_Objects)[hdl].insert(m);
361
362 This is similar to what the module code ultimately gets translated to
363 and should be replaced by a macro with similar syntax soon.
364
365 Event Method Invocations
366 ------------------------
367
368 Event method invocations vary significantly from entry method
369 invocations in Charm++, and various forms should be used depending on
370 where the event method is being invoked. In addition, event messages
371 sent to an event method should be allocated specifically for an event
372 invocation, and cannot be recycled or deleted.
373
374 There are three ways to send events within a POSE module. The first and
375 most commonly used way involves specifying and offset in simulation time
376 from the current time. The syntax follows:
377
378 .. code-block:: c++
379
380   aMsg = new eventMsg;
381   POSE_invoke(myEventMethod(aMsg), mySim, hdl, 0);
382
383 Here, we’ve created an ``eventMsg`` and sent it to ``myEventMethod``,
384 an event entry point on ``mySim``. ``mySim`` was created at handle
385 ``hdl``, and we want the event to take place now, i.e. at the current
386 simulation time, so the offset is zero.
387
388 The second way to send an event is reserved for use by non-poser objects
389 within the module. It should not be used by posers. This version allows
390 you to specify an absolute simulation time at which the event happens
391 (as opposed to an offset to the current time). Since non-poser objects
392 are not a part of the simulation, they do not have a current time, or
393 OVT, by which to specify an offset. The syntax is nearly identical to
394 that above, only the last parameter is an absolute time.
395
396 .. code-block:: c++
397
398   aMsg = new eventMsg;
399   POSE_invoke_at(myEventMethod(aMsg), mySim, hdl, 56);
400
401
402 Posers should not use this approach because of the risk of specifying
403 an absolute time that is earlier than the current time on the object
404 sending the event.
405
406 Using this method, event methods can be injected into the system from
407 outside any module, but this is not recommended.
408
409 The third approach is useful when an object send events to itself. It is
410 simply a slightly shorter syntax for the same thing as ``POSE_invoke``:
411
412 .. code-block:: c++
413
414   aMsg = new eventMsg;
415   POSE_local_invoke(myEventMethod(aMsg), offset);
416
417 Elapsing Simulation Time
418 ------------------------
419
420 We’ve seen in the previous section how it is possible to advance
421 simulation time by generating events with non-zero offsets of current
422 time. When such events are received on an object, if the object is
423 behind, it advances its local simulation time (object virtual time or
424 OVT) to the timestamp of the event.
425
426 It is also possible to elapse time on an object while the object is
427 executing an event. This is accomplished thus:
428
429 .. code-block:: c++
430
431  elapse(42);
432
433
434 The example above would simulate the passage of forty-two time units
435 by adding as much to the object’s current OVT.
436
437 Interacting with a POSE Module and the POSE System
438 --------------------------------------------------
439
440 POSE modules consist of ``<modname>.ci``, ``<modname>.h`` and
441 ``<modname>.C`` files that are translated via ``etrans.pl`` into
442 ``<modname>_sim.ci``, ``<modname>_sim.h`` and ``<modname>_sim.C`` files.
443 To interface these with a main program module, say :math:`Pgm` in files
444 ``pgm.ci``, ``pgm.h`` and ``pgm.C``, the ``pgm.ci`` file must declare
445 the POSE module as extern in the ``mainmodule Pgm`` block. For example:
446
447 .. code-block:: c++
448
449   mainmodule Pgm {
450     extern module <modname>;
451     readonly CkChareID mainhandle;
452
453     mainchare main {
454       entry main();
455     };
456   };
457
458 The ``pgm.C`` file should include ``pose.h`` and ``<modname>_sim.h``
459 along with its own headers, declarations and whatever else it needs.
460
461 Somewhere in the ``main`` function, ``POSE_init()`` should be called.
462 This initializes all of POSE’s internal data structures. The parameters
463 to ``POSE_init()`` specify a termination method. POSE programs can be
464 terminated in two ways: with inactivity detection or with an end time.
465 Inactivity detection terminates after a few iterations of the GVT if no
466 events are being executed and virtual time is not advancing. When an end
467 time is specified, and the GVT passes it, the simulation exits. If no
468 parameters are provided to ``POSE_init()``, then the simulation will use
469 inactivity detection. If a time is provided as the parameter, this time
470 will be used as the end time.
471
472 Now POSE is ready for posers. All posers can be created at this point,
473 each with a unique handle. The programmer is responsible for choosing
474 and keeping track of the handles created for posers. Once all posers are
475 created, the simulation can be started:
476
477 .. code-block:: c++
478
479   POSE_start();
480
481
482 Configuring POSE
483 ================
484
485 POSE can be configured in two different ways. Fundamental behaviors are
486 controlled by altering values in the ``pose_config.h`` file in the POSE
487 installation, and rebuilding POSE. Many of these configuration options
488 can (and should) be controlled by command line options. These will be
489 designated here by an asterisk (:math:`*`). See
490 section :numref:`sec:posecommand` for the command line options.
491
492 -  | ``POSE_STATS_ON *``
493    | :math:`\circ` Turn on timing and statistics gathering for internal
494      POSE operations. Produces a small slowdown in program.
495
496 -  | ``POSE_DOP_ON *``
497    | :math:`\circ` Turn on timing and statistics gathering for degree of
498      parallelism calculations. Generates log files that can be loaded by
499      ploticus scripts to produce graphs plotting active entities over
500      time. Slows down program dramatically.
501
502 -  | ``POSE_COMM_ON``
503    | :math:`\circ` Turn on streaming communication optimization for
504      small message packing.
505
506 -  | ``COMM_TIMEOUT``
507    | :math:`\circ` Used by streaming communication library. Time to wait
508      (in ?) before sending buffered messages.
509
510 -  | ``COMM_MAXMSG``
511    | :math:`\circ` Used by streaming communication library. Number of
512      messages to buffer before packing and sending as one.
513
514 -  | ``LB_ON *``
515    | :math:`\circ` Turn on POSE load balancing.
516
517 -  | ``STORE_RATE *``
518    | :math:`\circ` Default checkpointing rate: 1 for every
519      ``STORE_RATE`` events.
520
521 -  | ``SPEC_WINDOW *``
522    | :math:`\circ` Speculative window size: this is how far (in virtual
523      time units) ahead of GVT posers are allowed to go.
524
525 -  | ``MIN_LEASH *`` and ``MAX_LEASH *``
526    | :math:`\circ` Bounds on the speculative window, these are adjusted
527      by adaptive synchronization strategies.
528
529 -  | ``LEASH_FLEX *``
530    | :math:`\circ` Granularity of flexibility when speculative window is
531      shrunk or expanded.
532
533 -  | ``MAX_POOL_SIZE``
534    | :math:`\circ` Memory used by event messages is recycled. This
535      controls how many messages of a particular size will be kept on
536      hand.
537
538 -  | ``MAX_RECYCLABLE``
539    | :math:`\circ` This is the largest size of message that will be
540      recycled.
541
542 -  | ``LB_SKIP *``
543    | :math:`\circ` This controls the frequency of load balance
544      invocation. 1 in every ``LB_SKIP`` executions of the GVT algorithm
545      will invoke load balancing.
546
547 -  | ``LB_THRESHOLD *``
548    | :math:`\circ` What the heck does this number mean? I can’t
549      remember. I’ll have to look through the code... later. Meanwhile, I
550      think this indicates some sort of threshold a single processor has
551      to cross before we even bother with analyzing the load.
552
553 -  | ``LB_DIFF *``
554    | :math:`\circ` Once the load has been analyzed, we compute the
555      difference between the max and min PE loads. Only if this
556      difference exceeds ``LB_DIFF`` do we bother migrating posers.
557
558 Several of the above flags and constants will be eliminated as the
559 adaptive strategy is expanded. What remains will eventually become
560 run-time options.
561
562 .. _sec:posecommand:
563
564 POSE Command Line Options
565 -------------------------
566
567 Command line options are handled like Charm++ command line parameters.
568 For namespace purity all POSE command line options have a \_pose suffix.
569 They can be inspected by appending a ``-h`` to an execution of a POSE
570 program. Command line options override any defaults set in the
571 ``pose_config.h`` file
572
573 -  | ``+stats_pose``
574    | :math:`\circ` Turn on timing and statistics gathering for internal
575      POSE operations. Produces a small slowdown in program.
576
577 -  | ``+dop_pose``
578    | :math:`\circ` Turn on timing and statistics gathering for degree of
579      parallelism calculations. Generates log files that can be loaded by
580      ploticus scripts to produce graphs plotting active entities over
581      time. Slows down program dramatically.
582
583 -  | ``+lb_on_pose``
584    | :math:`\circ` Turn on POSE load balancing.
585
586 -  | ``+store_rate_pose N``
587    | :math:`\circ` Default checkpointing rate: 1 for every
588      ``STORE_RATE`` events.
589
590 -  | ``+spec_window_pose N``
591    | :math:`\circ` Speculative window size: this is how far (in virtual
592      time units) ahead of GVT posers are allowed to go.
593
594 -  | ``+min_leash_pose N`` and ``+min_leash_pose N``
595    | :math:`\circ` Bounds on the speculative window, these are adjusted
596      by adaptive synchronization strategies.
597
598 -  | ``+leash_flex_pose N``
599    | :math:`\circ` Granularity of flexibility when speculative window is
600      shrunk or expanded.
601
602 -  | ``+lb_skip_pose N``
603    | :math:`\circ` This controls the frequency of load balance
604      invocation. 1 in every ``LB_SKIP`` executions of the GVT algorithm
605      will invoke load balancing.
606
607 -  | ``+lb_threshold_pose N``
608    | :math:`\circ` Minimum threshold for load balancing, default is 4000
609
610 -  | ``+lb_diff_pose N``
611    | :math:`\circ` Once the load has been analyzed, we compute the
612      difference between the max and min PE loads. Only if this
613      difference exceeds ``LB_DIFF`` do we bother migrating posers.
614
615 -  | ``+checkpoint_gvt_pose N``
616    | :math:`\circ` Checkpoint to disk approximately every N GVT ticks (N
617      is an integer). The default is 0, which indicates no checkpointing.
618
619 -  | ``+checkpoint_time_pose N``
620    | :math:`\circ` Checkpoint to disk every N seconds (N is an integer).
621      The default is 0, which indicates no checkpointing. If both this
622      parameter and +checkpoint_gvt_pose are greater than 0, a warning
623      will be given, the value of this parameter will be set to 0, and
624      POSE will checkpoint based on GVT ticks.
625
626 As a technical point, pose command line parsing is done inside the
627 ``POSE_init()`` call. Therefore, the most consistent behavior for
628 interleaving pose command line options with user application options
629 will be achieved by calling ``POSE_init()`` before handling user
630 application command line arguments.
631
632 Communication Optimizations
633 ===========================
634
635 Load Balancing
636 ==============
637
638 Glossary of POSE-specific Terms
639 ===============================
640
641 -  | ``void POSE_init()``
642    | :math:`\circ` Initializes various items in POSE; creates the load
643      balancer if load balancing is turned on; initializes the statistics
644      gathering facility if statistics are turned on.
645    | :math:`\circ` Must be called in user’s main program prior to
646      creation of any simulation objects or reference to any other POSE
647      construct.
648
649 -  | ``void POSE_start()``
650    | :math:`\circ` Sets busy wait to default if none specified; starts
651      quiescence detection; starts simulation timer.
652    | :math:`\circ` Must be called in user’s main program when simulation
653      should start.
654
655 -  | ``void POSE_registerCallBack(CkCallback cb)``
656    | :math:`\circ` Registers callback function with POSE - when program
657      ends or quiesces, function is called.
658    | :math:`\circ` CkCallback is created with the index of the callback
659      function and a proxy to the object that function is to be called
660      on. For example, to register the function ``wrapUp`` in the main
661      module as a callback:
662
663    .. code-block:: c++
664
665         CProxy_main M(mainhandle);
666         POSE_registerCallBack(CkCallback(CkIndex_main::wrapUp(), M));
667
668 -  | ``void POSE_stop()``
669    | :math:`\circ` Commits remaining events; prints final time and
670      statistics (if on); calls callback function.
671    | :math:`\circ` Called internally when quiescence is detected or
672      program reaches ``POSE_endtime``.
673
674 -  | ``void POSE_exit()``
675    | :math:`\circ` Similar to ``CkExit()``.
676
677 -  | ``void POSE_set_busy_wait(int n)``
678    | :math:`\circ` Used to control granularity of events; when calling
679      ``POSE_busy_wait``, program busywaits for time to compute
680      :math:`fib(n)`.
681
682 -  | ``void POSE_busy_wait()``
683    | :math:`\circ` Busywait for time to compute :math:`fib(n)` where n
684      is either 1 or set by ``POSE_set_busy_wait``.
685
686 -  | ``POSE_useET(t)``
687    | :math:`\circ` Set program to terminate when global virtual time
688      (GVT) reaches :math:`t`.
689
690 -  | ``POSE_useID()``
691    | :math:`\circ` Set program to terminate when no events are available
692      in the simulation.
693
694 -  | ``void POSE_create(constructorName(eventMsg *m), int handle, int atTime)``
695    | :math:`\circ` Creates a poser object given its constructor, an
696      event message :math:`m` of the appropriate type, any integer as the
697      handle (by which the object will be referred from then on), and a
698      time (in simulation timesteps) at which it should be created.
699    | :math:`\circ` The handle can be thought of as a chare array element
700      index in Charm++.
701
702 -  | ``void POSE_invoke_at(methodName(eventMsg *m), className, int handle, int atTime)``
703    | :math:`\circ` Send a *methodName* event with message :math:`m` to
704      an object of type *className* designated by handle :math:`handle`
705      at time specified by :math:`atTime`.
706    | :math:`\circ` This can be used by non-poser objects in the POSE
707      module to inject events into the system being simulated. It should
708      not be used by a poser object to generate an event.
709
710 -  | ``void POSE_invoke(methodName(eventMsg *m), className, int handle, int timeOffset)``
711    | :math:`\circ` Send a *methodName* event with message :math:`m` to
712      an object of type *className* designated by handle :math:`handle`
713      at current OVT + :math:`timeOffset`.
714    | :math:`\circ` This is used by poser objects to send events from one
715      poser to another.
716
717 -  | ``void POSE_local_invoke(methodName(eventMsg *m), int timeOffset)``
718    | :math:`\circ` Send a *methodName* event with message :math:`m` to
719      this object at current OVT + :math:`timeOffset`.
720    | :math:`\circ` This is used by poser objects to send events to
721      themselves.
722
723 -  | ``void CommitPrintf(char *s, args...)``
724    | :math:`\circ` Buffered print statement; prints when event is
725      committed (i.e. will not be rolled back).
726    | :math:`\circ` Currently, must be called on the wrapper class
727      (parent) to work properly, but a fix for this is in the works.
728
729 -  | ``void CommitError(char *s, args...)``
730    | :math:`\circ` Buffered error statement; prints and aborts program
731      when event is committed.
732    | :math:`\circ` Currently, must be called on the wrapper class
733      (parent) to work properly, but a fix for this is in the works.
734
735 -  | ``void elapse(int n)``
736    | :math:`\circ` Elapse :math:`n` simulation time units.
737
738 -  | ``poser``
739    | :math:`\circ` Keyword (used in place of chare) to denote a poser
740      object in the ``.ci`` file of a POSE module.
741
742 -  | ``event``
743    | :math:`\circ` Keyword used in square brackets in the ``.ci`` file
744      of a POSE module to denote that the entry method is an event
745      method.
746
747 -  | ``eventMsg``
748    | :math:`\circ` Base class for all event messages; provides
749      timestamp, priority and many other properties.
750
751 -  | ``sim``
752    | :math:`\circ` Base class of all wrapper classes.
753
754 -  | ``strat``
755    | :math:`\circ` Base class of all strategy classes.
756
757 -  | ``con``
758    | :math:`\circ` Simple conservative strategy class.
759
760 -  | ``opt, opt2, opt3, spec, adapt, adapt2``
761    | :math:`\circ` Optimistic strategy classes.
762
763 -  | ``rep``
764    | :math:`\circ` Base class for all representation classes.
765
766 -  | ``chpt``
767    | :math:`\circ` Simple checkpointing representation class.
768
769 -  | ``OVT()``
770    | :math:`\circ` Returns the object virtual time (OVT) of the poser in
771      which it is called
772
773 -  | ``void MySim::terminus()``
774    | :math:`\circ` When simulation has terminated and program is about
775      to exit, this method is called on all posers. Implemented as an
776      empty method in the base ``rep`` class, the programmer may choose
777      to override this with whatever actions may need to be performed per
778      object at the end of the simulation.