Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
efd7935b6b774cb5bbb1e372a2f4907f84f923f0
[simgrid.git] / doc / gtut-tour.doc
1
2 /** 
3 @page GRAS_tut_tour GRAS initiatic tour
4
5 On this page, you will learn all you need to write your own GRAS
6 applications, from the installation of the framework to the use of all
7 features available in GRAS.
8
9 \htmlinclude .gtut-tour.doc.toc
10    
11 <hr>
12 \section GRAS_tut_tour_install Lesson 0: Installing GRAS
13
14 Since GRAS is technically part of the SimGrid project, you have to install
15 SimGrid to install GRAS. Doing so is explained in the relevant FAQ section
16 (\ref faq_installation). 
17
18 Newcommers should install the stable release from the tarball, since the cvs
19 snapshots may suffer from (additionnal;) stability issues. Only go for the CVS if you
20 really need features not present in the stable releases yet.
21
22 <hr>
23 \section GRAS_tut_tour_setup Lesson 1: Setting up your own project
24
25 Any GRAS project should be constituted of at least 3 files, and possibly
26 much more.
27
28   - <tt>&lt;project&gt;.c</tt>: A source file providing the source code of your
29     processes.
30     
31   - <tt>&lt;platform&gt;.xml</tt>: A platform description file. It describes
32     the virtual platform you want to run your application onto following the
33     SurfXML formatting so that the simulator can parse it. This file is only
34     needed in SG, and you don't need any to run on real platforms (of
35     course). The simplest is to use one of the pre-existing one.
36     
37   - <tt>&lt;project&gt;.xml</tt>: A deployment file. It describes which of
38     your processes to start, on which machine and with which arguments.
39     
40   - A makefile is often needed, too, even if it's not mandatory.
41
42 If we start a project called <tt>test</tt>, we have to write 3 files:
43 <tt>test.c</tt>, <tt>platform.xml</tt> and <tt>test.xml</tt>
44
45 \subsection GRAS_tut_tour_setup_C The C source file
46
47 Let's look at the C source file first. It should contain one main function
48 for each type of processes in your overlay. Let's assume that you want to
49 code a simple client/server communication. For this, the source file should
50 read as:
51
52 \verbatim #include <gras.h>
53
54 int client(int argc, char *argv[]) {
55   ...
56 }
57
58 int server(int argc, char *argv[]) {
59   ...
60 }
61 \endverbatim
62
63 Note that each of the processes's main function have the exact same
64 prototype of the classical <tt>main()</tt> function in C. 
65
66 This is on purpose, each of them can assume this role when running in RL.
67 But you shouldn't write a main() function yourself since all processes will
68 run as threads within the same regular process in simulation mode. That is
69 why the real <tt>main</tt> function of GRAS programs are generated
70 automatically. This will be detailled in time (section \ref
71 GRAS_tut_tour_setup_glue), but for now just note the similarity between the
72 "main" functions you have to write for each processes and a "real main"
73 function.
74
75 Then, each process must initialize the GRAS framework at the beginning (with
76 \ref gras_init) and should finalize it at the end (with \ref gras_exit). 
77
78 You should pass to \ref gras_init the <tt>argc</tt> and <tt>argv</tt> you
79 received in your "main" function so that the users of your application can
80 pass some configuration flags to the framework.
81
82 It is not enough to have one of the processes initializing the framework
83 since in RL, each of them will run on a different host. If you use some AMOK
84 modules, you have to initialize them in each process too.
85
86 The source file then reads: \include 1-bones.c
87
88 That's it. You have a working GRAS application with two processes. They
89 don't do anything useful, but that's a beginning. Let's see how to bring
90 them to life.
91
92 \subsection GRAS_tut_tour_setup_plat The platform file
93
94 The platform file is used by the simulator to know about the existing hosts
95 and their interactions. Its exact syntax is at the same time very simple and
96 a bit beyond the topic of this document. Here is a very simple example
97 describin two hosts named <i>Jacquelin</i> and <i>Boivin</i> and how they
98 are interconnected.
99
100 \include gtut-platform.xml
101
102 At this point, you should not try to write your own platform file, but use
103 one of the existing ones. There is a few of them in the examples/msg
104 directory of the project. The only information we need from those files are
105 the names of the existing hosts. It will be mandatory to write the
106 deployment file.
107
108 \subsection GRAS_tut_tour_setup_deploy The deployment file
109
110 This file explains which of your processes should be started on the
111 different hosts. It is mainly used in simulation. In real life, you will
112 have to start your processes manually (see below). We we dream of a system
113 able to apply a deployment file in real life and TakTuk may be the right
114 tool for this, but this is still to be done.
115
116 Here is an example of such file, describing that a <tt>server</tt> process
117 must be started onto the <tt>Jacquelin</tt> host and a <tt>client</tt>
118 process must be started on the <tt>Boivin</tt> host.
119
120 \include test.xml
121
122 Actually, you should write such a file also if you only plan to use GRAS in
123 RL since this file is also used to glue your code to GRAS, as explained in
124 the next section.
125
126 \subsection GRAS_tut_tour_setup_glue Glueing things together
127
128 As explained above, you shouldn't write any real <tt>main</tt> function
129 since its content depends on whether you run in RL ou in SG. Instead, you
130 use a tool <tt>gras_stub_generator</tt> to get the proper glue around your
131 code generated. If you installed SimGrid in a regular place, this program is
132 now in your path. Its source resides in the tools/gras/ directory of the
133 archive, if you wonder.
134
135 Here is the calling syntax:     
136 \verbatim gras_stub_generator <project_name> <deployment_file.xml>\endverbatim
137
138 It parses the deployment file (called <tt>test.xml</tt> in our example),
139 searching for all the kind of processes you have in your project. It
140 then generates the following C files:
141
142  - a <tt>_&lt;project_name&gt;_&lt;process_kind&gt;.c</tt> file for each process kind you
143    have.\n
144    They are used to launch your project in real life. They
145    contain a main() in charge of initializing the GRAS infrastructure and
146    launching your code afterward.
147  - a <tt>_&lt;project_name&gt;_simulator.c</tt> file.\n
148    This file is suited to the simulation mode. It contains a main()
149    function initializing the simulator and launching your project within.
150  - a <tt>&lt;project_name&gt;.mk</tt> file.\n
151    This is a makefile to regenerate any files on need. See next section.
152
153 In our example, we will thus obtain <tt>_test_server.c</tt>,
154 <tt>_test_client.c</tt>, <tt>_test_simulator.c</tt> and <tt>test.mk</tt>.
155
156 There is a pitfall: no verification is made on your actual source code, so
157 if you have a typo on the process name in the deployment file, the generated
158 code will be wrong, and the linker will spit error messages at you. Also
159 remember that those names are in fact C function names, so they are
160 case-sensitive.
161
162 \subsection GRAS_tut_tour_setup_make A typical Makefile
163
164 Now, we want to compile all the source files to build the actual binaries.
165 It can be done manually, but it is much more convenient to use a makefile.
166 Fortunately, gras_stub_generator generates a makefile for you under the name
167 <tt>&lt;project&gt;.mk</tt>. This file is sufficient for now. To compile our test
168 application, just type:
169 \verbatim make -f test.mk \endverbatim
170
171 You may want to rename this file to Makefile so that typing <tt>make</tt>
172 without argument becomes sufficient. In any case, do not edit this file
173 without renaming it, or your changes will get overwritten at the next glue
174 generation.
175
176 If you already have a Makefile (or a Makefile.am for automake users), you
177 can also add the following chunk at the end of your file:
178 \verbatim NAME=your_project_name
179  PROCESSES=list of processes type in your project
180
181  $(foreach proc, $(PROCESSES), _$(NAME)_$(proc).c) _$(NAME)_simulator.c: $(NAME).c $(NAME)_deployment.xml
182         path/to/gras_stub_generator $(NAME) $(NAME)_deployment.xml >/dev/null
183 \endverbatim
184
185 A simpler solution in our example would be to add:
186 \verbatim _test_client.c _test_server.c _test_simulator.c: test.c test.xml
187         path/to/gras_stub_generator test test.xml >/dev/null
188 \endverbatim
189
190
191
192 \subsection GRAS_tut_tour_setup_start Actually running the processes
193
194 There is nothing to know to start your processes in RL. Simply call the
195 generated binaries, and that's it. To start the simulation, simply call:
196 \verbatim ./<project>_simulator platform.xml deployment.xml\endverbatim
197
198 Here is an example of execution: \include 1-bones.output
199
200 That's it. You are done with this lesson and can now write, build and
201 execute GRAS applications as long as they don't do anything ;) Simply read on
202 to add some flesh on these bones.
203
204 (back to the top of the \ref GRAS_tut_tour)
205 <hr>
206
207 \section GRAS_tut_tour_simpleexchange Lesson 2: Exchanging simple messages
208
209 \subsection GRAS_tut_tour_simpleexchange_msgtype Declaring the messages to be exchanged
210
211 We will now see how to exchange messages between hosts. As explained in
212 section \ref GRAS_tut_intro_model, every GRAS message is (strongly) typed. A
213 message type is described by its name and the datatype of the data it can
214 convey. Each process which may exchange a given type of message should
215 declare it before sending or receiving it. If the description used by the
216 sender doesn't match the one used by the receiver, you'll get into trouble.
217 Fortunately, such discrepency will be detected in SG.
218
219 We won't convey any payload in this lesson, so we just have to give the name
220 of message to declare them:
221 \dontinclude 2-simple.c
222 \skip gras_msgtype_declare
223 \until gras_msgtype_declare
224
225 Remember that all processes should declare the message types they use.
226
227 \subsection GRAS_tut_tour_simpleexchange_socks Identifying peers you want to communicate with
228
229 Then, you need to specify with who you want to communicate. This is done
230 by opening sockets. GRAS sockets are loosely inspirated by the regular BSD
231 sockets, but with several simplifications.
232
233 If you want to eventually receive messages, you have to open a so-called
234 <i>server socket</i>. Actually, any GRAS process should open a server socket
235 since it will allows to identify it uniquely in the system. A socket is
236 defined by an host name and a port number (just like with BSD sockets).
237
238 Since server socket are on the current host, opening a socket to receive
239 messages on the port 12345 is as easy as:
240 \skip gras_socket_server
241 \until gras_socket_server
242
243 Hardcoding port numbers that way may lead to difficulties on RL (at least)
244 since at most one process can listen on a given port. So, if you can, prefer
245 the \ref gras_socket_server_range, which picks a working port from a range
246 of value. Of course, if you want your processes to find each others, at
247 least one port must be hardcoded in the system. Then, any other processes
248 contact the one listening on that port, which acts as a coordinator.
249
250 Our client should also open a server socket, but the picked port don't
251 matter, so we use:
252 \skip gras_socket_server
253 \until gras_socket_server
254
255 It will select a port between 1024 (ports below 1024 are reserved under
256 UNIX) and 10000. You can safely ignore the two last arguments for now and
257 pass 0.
258
259 So, you now know how to create sockets allowing to receive messages. To send
260 messages, you have to create a so-called <i>client socket</i>. For this, use
261 \ref gras_socket_client with the hostname and the port of the process you
262 want to contact as arguments. Our client should simply do:
263
264 \dontinclude 2-simple.c
265 \skip socket_client
266 \until socket_client
267
268 The corresponding server socket must be opened before any client socket can
269 connect to it. It is thus safe to add a little delay before creating the
270 client socket. But you cannot use the classical sleep() function for this,
271 or you will delay the simulator in SG, not your processes. Use \ref
272 gras_os_sleep instead.
273
274 \subsection GRAS_tut_tour_simpleexchange_exchange Actually exchanging messages
275
276 GRAS offers a plenty of ways to communicate. The simple one is to use \ref
277 gras_msg_send on the sender side, and \ref gras_msg_wait on the receiver side.
278
279 \ref gras_msg_send expects 3 arguments: the socket on which to send the
280 message, the message type, and a pointer to the actual content of the
281 message. The simplest way to retrive a message type from its name is to use
282 \ref gras_msgtype_by_name. Since we don't have any payload, this becomes:
283
284 \dontinclude 2-simple.c
285 \skip msg_send
286 \until msg_send
287
288 \ref gras_msg_wait accepts 4 arguments. The first one is the delay you are
289 disposed to wait for messages, while the the type of message you are
290 expecting. Then come output arguments. The third argument should be the
291 address of a gras_socket_t variable which will indicate who wrote the
292 message you received while the last argument is where to put the payload.
293
294 Since our server is willing to wait up to 60 seconds for a message, the
295 following will do it:
296 \dontinclude 2-simple.c
297 \skip msg_wait
298 \until msg_wait
299
300 \subsection GRAS_tut_tour_simpleexchange_recaping Recaping everything together
301
302 Here is the complete code of this example. Note the use of the functions
303 \ref gras_socket_my_port, \ref gras_socket_peer_name and \ref
304 gras_socket_peer_port to retrieve information about who you are connected to.
305
306 \include 2-simple.c
307
308 Here is the output of the simulator. Note that \ref gras_socket_peer_port
309 actually returns the port number of the <i>server</i> of the peer. This may
310 sound a bit strange to BSD experts, but it is actually really useful: you
311 can store this value, and contact your peer afterward passing this number to
312 \ref gras_socket_client .
313 \include 2-simple.output
314
315 Here we are, you now know how to exchange messages between peers. There is
316 still a large room for improvement, such as adding payload to messages.
317
318
319 (back to the top of the \ref GRAS_tut_tour)
320 <hr>
321 \section GRAS_tut_tour_args Lesson 3: Passing arguments to the processes (in SG)
322
323 The most problematic issue with the code of previous lesson is that it does
324 not work in RL since we hardcoded the server hostname in the client code. We
325 will thus learn you how to pass arguments to your processes to overcome this
326 situation.
327
328 \subsection GRAS_tut_tour_args_use Using command line arguments from user code
329
330 In RL, the situation is quite simple: we just have to use the command line
331 arguments as we would do in a usual C program. In the server, only change
332 concern the opennong of the master socket:
333 \dontinclude 3-args.c
334 \skip gras_socket_server
335 \until gras_socket_server
336
337 In the client, we only need to change the way we open the client socket:
338 \skip gras_socket_client
339 \until gras_socket_client
340
341 The rest of the program remains inchanged. 
342
343 \subsection GRAS_tut_tour_args_sg Passing command line arguments in deployment files
344
345 At this point, the problem is to pass arguments to the processes in SG.
346 Fortunately, it is quite simple. You just have to edit your deployment file
347 so that it reads: \include 3-args.xml
348 The syntax should be self-explanatory at this point.
349
350 \subsection GRAS_tut_tour_args_recap Recaping everything together
351
352 The whole program now reads:
353 \include 3-args.c
354
355 And here is the output:
356 \include 3-args.output
357
358 (back to the top of the \ref GRAS_tut_tour)
359 <hr>
360
361 \section GRAS_tut_tour_callbacks Lesson 4: Attaching callbacks to messages
362
363 Our program is well and good, but if we had to write a longer message,
364 explicitely waiting for messages of a given type would not be really
365 practical. To add some more dynamism, what we want to do is to attach
366 callbacks to the several messages types, and tell GRAS that we are ready to
367 deal with new messages. That's what we will do now.
368
369 \subsection GRAS_tut_tour_callbacks_declare Declaring callbacks
370
371 First of all, we define the callback we want to attach to the arrival of the
372 "hello" message on the server. Its signature is fixed: it accepts two
373 arguments of relative types <tt>gras_msg_cb_ctx_t ctx</tt> and <tt>void
374 *</tt>. The first one is a working context we should pass to GRAS when
375 speaking about the message we are handling while the second is the payload.
376 The callbackreturns an integer indicating whether we managed to deal with
377 the message. I admit that this semantic is a bit troublesome, it should be 0
378 if we managed to deal properly with the message to mimic "main()" semantic.
379 That's historical, but I may change this in the future (no worry, I'll add
380 backward compatibility solutions). Here is the actual code of our callback:
381
382 \dontinclude 4-callback.c
383 \skip gras_msg_cb_ctx_t 
384 \until end_of_callback
385
386 \subsection GRAS_tut_tour_callbacks_attach Attaching callbacks
387
388 Then, we have to change the server code to use this callback instead of
389 gras_msg_wait. This simply done by a construct like the following:
390
391 \skip cb_register
392 \until cb_register
393
394 \subsection GRAS_tut_tour_callbacks_handle Handling incoming messages
395
396 Once the callback is declared and attached, the server simply has to call
397 \ref gras_msg_handle to tell GRAS it's ready to handle for incoming
398 messages. The only argument is the maximum delay we are disposed to wait for
399 a message. If the delay is negative, the process will block until a message
400 arrives. With delay=0, the process just polls for already arrived messages,
401 but do not wait at all if none arrived yet. If the delay is greater than 0,
402 the process will wait for at most that amount of seconds. If a message
403 arrives in the meanwhile, it won't even wait that long. 
404
405 Sometimes, you want to handle all messages arriving in a given period
406 without really knowing how much messages will come (this is often the case
407 during the initialization phase of an algorithm). In that case, use \ref
408 gras_msg_handleall . It has the same prototype than \ref gras_msg_handle,
409 but waits exactly the passed delay, dealing with all the messages arriving
410 in the meanwhile.
411
412 We have no such needs in our example, so the code simply reads:
413 \skip handle
414 \until handle
415
416 \subsection GRAS_tut_tour_callback_recap Recaping everything together
417
418 The whole program now reads:
419 \include 4-callback.c
420
421 And here is the output (unchanged wrt previous version):
422 \include 4-callback.output
423
424 Our little example turns slowly to a quite advanced GRAS program. It entails
425 most of the mecanism most program will use.
426
427 (back to the top of the \ref GRAS_tut_tour)
428 <hr>
429
430
431 \section GRAS_tut_tour_todo TODO
432
433 - Lesson 5: Globals (for a kill message)
434 - Lesson 6: Timers
435 - Lesson 7: Using logs
436
437 - Lesson 8: Exchanging simple data through ping-pong
438 - Lesson 9: More complex data description (automatic parsing, manual description) and example
439
440 - Lesson 10: Splitting in several files
441
442 - Lesson 11: RPC mecanism and dealing with exceptions
443
444 - Lesson 12: Debuging GRAS programs
445
446 - Lesson   : Doing proper modules
447
448 */