Updating inaccurate termination info.
[charm.git] / doc / pose / program.tex
1 \section{Programming in \pose{}}
2
3 This section details syntax and usage of \pose{} constructs with code samples.
4
5 \subsection{\pose{} Modules}
6
7 A \pose{} module is similar to a Charm++ module.  It is comprised of
8 an interface file with suffix {\tt .ci}, a header {\tt .h} file, and
9 the implementation in {\tt .C} files.  Several posers can be described
10 in one module, and the module can include regular chares as well.  The
11 module is translated into \charmpp{} before the simulation can be
12 compiled.  This translation is performed by a Perl script called {\tt
13 etrans.pl} which is included with \pose{}.  It generates files
14 suffixed {\tt \_sim.ci}, {\tt \_sim.h}, and {\tt \_sim.C}.
15
16 \subsection{Event Message and Poser Interface Description}
17
18 Messages, be they event messages or otherwise, are described in the
19 {\tt .ci} file exactly the way they are in \charmpp{}. Event messages
20 cannot make use of \charmpp{}'s parameter marshalling, and thus you
21 must declare them in the {\tt .h} file.  \charmpp{} {\tt varsize}
22 event messages are currently not implemented in \pose{}.
23
24 All event messages inherit from a \pose{} type {\tt eventMsg} which
25 includes data for timestamps and miscellaneous \pose{} statistics.
26
27 ~\\
28 \noindent{\tt {\bf message} {\it myMessage};}\\
29
30 Posers are described similar to chares, with a few exceptions.  First,
31 the {\tt poser} keyword is used to denote that the class is a \pose{}
32 simulation object class.  Second, event methods are tagged with the
33 keyword {\tt event} in square brackets. Finally, three components are
34 specified which indicate how objects of the poser class are to be
35 simulated.  The {\it sim} component controls the wrapper class and
36 event queue used by the object.  The {\it strat} component controls
37 the synchronization strategy the object should use ({\it i.e.}
38 adaptive or basic optimistic).  The {\it rep} component specifies the
39 global state representation, which controls how the global state is
40 kept accurate depending on the synchronization strategy being used
41 ({\it i.e.} checkpointing or no checkpointing).  Currently, there is
42 only one wrapper type, {\tt sim}.  This 3-tuple syntax is likely to
43 become obsolete, replaced simply by synchronization strategy only.
44 Keeping the global state accurate is largely a function of the
45 synchronization strategy used.  
46
47 ~\\
48 \noindent{\tt {\bf poser} {\it mySim} : {\it sim strat rep} \{\\
49 \indent {\bf entry} {\it mySim}({\it myMessage} *);\\
50 \indent {\bf entry} [{\bf event}] void {\it myEventMethod}({\bf eventMsg} *);\\
51 \indent ...\\
52 \noindent \};}\\
53
54 A typical {\tt .ci} file poser specification might look like this:
55
56 ~\\
57 \noindent{\tt poser Worker : sim adapt4 chpt \{\\
58 \indent entry Worker(WorkerCreationMsg *);\\
59 \indent entry [event] void doWork(WorkMsg *);\\
60 \indent ...\\
61 \noindent \};}\\
62
63 Note that the constructors and event methods of a poser must take an
64 event message as parameter.  If there is no data (and thereby no
65 message defined) that needs to be passed to the method, then the
66 parameter should be of type {\tt eventMsg *}.  This ensures that
67 \pose{} will be able to timestamp the event.
68
69 \subsection{Declaring Event Messages and Posers}
70
71 Currently, event messages are declared with no reference to what they
72 might inherit from (unlike in Charm++).  The translator takes care of
73 this. In addition, they must define {\tt operator=}.
74
75 ~\\
76 \noindent{\tt class {\it myMessage} \{\\
77 \indent  public:\\
78 \indent   int someData;\\
79 \indent   {\it myMessage}\& operator=(const {\it myMessage}\& obj) \{\\
80 \indent\indent     {\bf eventMsg}::operator=(obj);\\
81 \indent\indent     someData = obj.someData;\\
82 \indent\indent     return *this;\\
83 \indent   \}\\
84 \noindent \};}\\
85
86 Similarly, posers do not refer to a base class when they are
87 declared.  Posers are required to have a void constructor declared
88 that simply initializes the data to sensible values.  A destructor
89 must be provided as well.  In addition, a {\tt pup} and {\tt
90 operator=} must be provided.  The {\tt pup} method should call the
91 {\tt pup} method of the global state representation class being used.
92
93 ~\\
94 \noindent{\tt class {\it mySim} \{\\
95 \indent int anInt; float aFloat; char aString[20];\\
96 ~public:\\
97 \indent {\it mySim}();\\
98 \indent {\it mySim}({\it myMessage} *m);\\
99 \indent \verb|~|{\it mySim}();\\
100 \indent void pup(PUP::er \&p);\\
101 \indent {\it mySim}\& operator=(const {\it mySim}\& obj);\\
102 \indent void {\it myEventMethod}({\bf eventMsg} *m);\\
103 \indent void {\it myEventMethod}{\bf \_anti}({\bf eventMsg} *m);\\
104 \indent void {\it myEventMethod}{\bf \_commit}({\bf eventMsg} *m);\\
105 \indent ...\\
106 \noindent \};}\\
107
108 Further, for each event method, a commit method should be declared,
109 and if the synchronization strategy being used is optimistic or
110 involves any sort of rollback, an anti-method should also be provided.
111 The syntax of these declarations is shown above.  Their usage and
112 implementation will be described next.
113
114 \subsection{Implementing Posers}
115
116 The void constructor for a poser should be defined however the user
117 sees fit.  It could be given an empty body and should still work for
118 \pose{}.  Poser entry constructors (those described in the {\tt .ci}
119 file) should follow the template below:
120
121 ~\\
122 \noindent{\tt {\it mySim}::{\it mySim}({\it myMessage} *m)\\
123 \noindent\{\\
124 \indent // initializations from $m$\\
125 \indent ...\\
126 \indent delete m;\\
127 \indent ...\\
128 \noindent \};}\\
129
130 Note that while the incoming message $m$ may be deleted here in the
131 constructor, event messages received on event methods should {\bf not} be
132 deleted.  The PDES fossil collection will take care of those.
133
134 An event method should have the following form:
135
136 ~\\
137 \noindent{\tt void {\it mySim}::{\it myEventMethod}(eventMsg *m) \{\\
138 \indent // body of method \\
139 \noindent \};}\\
140
141 Again, $m$ is never deleted in the body of the event.  A side effect
142 of optimistic synchronization and rollback is that we would like the
143 effects of event execution to be dependent only upon the state
144 encapsulated in the corresponding poser.  Thus, accessing arbitrary
145 states outside of the simulation, such as by calling {\tt rand}, is
146 forbidden.  We are planning to fix this problem by adding a {\tt
147   POSE\_rand()} operation which will generate a random number the first
148 time the event is executed, and will checkpoint the number for use in
149 subsequent re-executions should a rollback occur.
150
151 \subsection{Creation of Poser Objects}
152
153 Posers are created within a module using the following syntax:
154
155 ~\\
156 \noindent {\tt int hdl = 13;  // handle should be unique\\
157 \noindent {\it myMessage} *m = new {\it myMessage};\\
158 \noindent m->someData = 34;\\
159 \noindent {\bf POSE\_create}({\it mySim}(m), hdl, 0);}\\
160
161 This creates a {\tt mySim} object that comes into existence at
162 simulation time zero, and can be referred to by the handle 13.  
163
164 Creating a poser from outside the module ({\it i.e.} from {\tt main})
165 is somewhat more complex:
166
167 ~\\
168 \noindent {\tt int hdl = 13;\\
169 \noindent {\it myMessage} *m = new {\it myMessage};\\
170 \noindent m->someData = 34;\\
171 \noindent m->{\bf Timestamp}(0);\\
172 \noindent (*(CProxy\_{\it mySim} *) \& {\bf POSE\_Objects})[hdl].insert(m);}\\
173
174 This is similar to what the module code ultimately gets translated to
175 and should be replaced by a macro with similar syntax soon.
176
177 \subsection{Event Method Invocations}
178
179 Event method invocations vary significantly from entry method
180 invocations in Charm++, and various forms should be used depending on
181 where the event method is being invoked.  In addition, event messages
182 sent to an event method should be allocated specifically for an event
183 invocation, and cannot be recycled or deleted.
184
185 There are three ways to send events within a \pose{} module.  The first
186 and most commonly used way involves specifying and offset in
187 simulation time from the current time.  The syntax follows:
188
189 ~\\
190 \noindent {\tt aMsg = new {\bf eventMsg};\\
191 \noindent {\bf POSE\_invoke}({\it myEventMethod}(aMsg), {\it
192 mySim}, hdl, 0);}\\
193
194 Here, we've created an {\tt eventMsg} and sent it to {\tt
195 myEventMethod}, an event entry point on {\tt mySim}.  {\tt mySim} was
196 created at handle {\tt hdl}, and we want the event to take place now,
197 i.e. at the current simulation time, so the offset is zero.  
198
199 The second way to send an event is reserved for use by non-poser
200 objects within the module.  It should not be used by posers.  This
201 version allows you to specify an absolute simulation time at which the
202 event happens (as opposed to an offset to the current time).  Since
203 non-poser objects are not a part of the simulation, they do not have a
204 current time, or OVT, by which to specify an offset.  The syntax is
205 nearly identical to that above, only the last parameter is an absolute
206 time.
207
208 ~\\
209 \noindent {\tt aMsg = new {\bf eventMsg};\\
210 \noindent {\bf POSE\_invoke\_at}({\it myEventMethod}(aMsg), {\it
211 mySim}, hdl, 56);}\\
212
213 Posers should not use this approach because of the risk of specifying
214 an absolute time that is earlier than the current time on the object
215 sending the event.  
216
217 Using this method, event methods can be injected into the system from
218 outside any module, but this is not recommended.
219
220 The third approach is useful when an object send events to itself.  It
221 is simply a slightly shorter syntax for the same thing as {\tt
222 POSE\_invoke}: 
223
224 ~\\
225 \noindent {\tt aMsg = new {\bf eventMsg};\\
226 \noindent {\bf POSE\_local\_invoke}({\it myEventMethod}(aMsg), offset);}\\
227
228 \subsection{Elapsing Simulation Time}
229
230 We've seen in the previous section how it is possible to advance
231 simulation time by generating events with non-zero offsets of current
232 time.  When such events are received on an object, if the object is
233 behind, it advances its local simulation time (object virtual time or
234 OVT) to the timestamp of the event.
235
236 It is also possible to elapse time on an object while the object is
237 executing an event.  This is accomplished thus:
238
239 ~\\
240 \noindent {\tt {\bf elapse}(42);}\\
241
242 The example above would simulate the passage of forty-two time units
243 by adding as much to the object's current OVT.
244
245 \subsection{Interacting with a \pose{} Module and the \pose{} System}
246
247 \pose{} modules consist of {\tt <$modname$>.ci}, {\tt <$modname$>.h}
248 and {\tt <$modname$>.C} files that are translated via {\tt etrans.pl}
249 into {\tt <$modname$>\_sim.ci}, {\tt <$modname$>\_sim.h} and {\tt
250 <$modname$>\_sim.C} files.  To interface these with a main program
251 module, say $Pgm$ in files {\tt pgm.ci}, {\tt pgm.h} and {\tt pgm.C},
252 the {\tt pgm.ci} file must declare the \pose{} module as extern in the
253 {\tt mainmodule Pgm} block. For example:
254
255 ~\\
256 \noindent{\tt mainmodule Pgm \{\\
257 \indent  extern module <$modname$>;\\
258 \indent  readonly CkChareID mainhandle;\\
259    \\
260 \indent  mainchare main \{\\
261 \indent\indent    entry main();\\
262 \indent  \};\\
263 \noindent \};}\\
264
265 The {\tt pgm.C} file should include {\tt pose.h} and {\tt<$modname$>\_sim.h}
266 along with its own headers, declarations and whatever else it needs.
267
268 Somewhere in the {\tt main} function, {\tt POSE\_init()} should be
269 called.  This initializes all of \pose{}'s internal data structures.
270 The parameters to {\tt POSE\_init()} specify a termination method.  \pose{} programs can
271 be terminated in two ways: with inactivity detection or with an end
272 time.  Inactivity detection terminates after a few iterations of the
273 GVT if no events are being executed and virtual time is
274 not advancing.  When an end time is specified, and the GVT passes it,
275 the simulation exits. If no parameters are provided to {\tt POSE\_init()}, then the 
276 simulation will use inactivity detection. If a time is provided as the parameter, this time
277 will be used as the end time.
278
279
280 Now \pose{} is ready for posers.  All posers can be created at this
281 point, each with a unique handle.  The programmer is responsible for
282 choosing and keeping track of the handles created for posers.  Once
283 all posers are created, the simulation can be started:
284
285 ~\\
286 \noindent{\tt POSE\_start();}\\