From: mquinson Date: Sat, 15 Jul 2006 17:03:10 +0000 (+0000) Subject: First chapters of the GRAS tutorial X-Git-Tag: v3.3~2781 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/a4c4a618cd7f38611b0a635d4c2b1724760501db First chapters of the GRAS tutorial git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2578 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 235acfecdf..be6ecea3ba 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -404,7 +404,11 @@ INPUT = @srcdir@/index.doc \ @srcdir@/module-xbt.doc \ @srcdir@/module-msg.doc \ @srcdir@/module-gras.doc @srcdir@/module-amok.doc \ - @srcdir@/module-sd.doc \ + @srcdir@/module-sd.doc \ + \ + @srcdir@/gtut-main.doc \ + @srcdir@/gtut-introduction.doc \ + @srcdir@/gtut-tour.doc \ \ ./logcategories.doc \ \ @@ -464,6 +468,7 @@ EXCLUDE_PATTERNS = # the \include command). EXAMPLE_PATH = ./ \ + @top_srcdir@/doc/gtut-files \ @top_srcdir@/src/surf/ \ @top_srcdir@/src/xbt/ \ @top_srcdir@/examples \ diff --git a/doc/Makefile.am b/doc/Makefile.am index 2710660645..fe67e0c0d0 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -32,7 +32,9 @@ html: Doxyfile ./logcategories.doc simgrid_modules.map $(PNGS) $(DOCSOURCES) : # First pass doxygen Doxyfile >/dev/null @top_srcdir@/tools/doxygen/index_create.pl simgrid.tag index-API.doc - @top_srcdir@/tools/doxygen/toc_create.pl @srcdir@/FAQ.doc @srcdir@/index.doc @srcdir@/contrib.doc + @top_srcdir@/tools/doxygen/toc_create.pl \ + @srcdir@/FAQ.doc @srcdir@/index.doc @srcdir@/contrib.doc \ + @srcdir@/gtut-introduction.doc : # Second pass doxygen Doxyfile >/dev/null : # Post-processing diff --git a/doc/gtut-files/1-bones.c b/doc/gtut-files/1-bones.c new file mode 100644 index 0000000000..85ff3e2695 --- /dev/null +++ b/doc/gtut-files/1-bones.c @@ -0,0 +1,19 @@ +#include + +int client(int argc, char *argv[]) { + gras_init(&argc,argv); + + /* Your own code for the client process */ + + gras_exit(); + return 0; +} + +int server(int argc, char *argv[]) { + gras_init(&argc,argv); + + /* Your own code for the server process */ + + gras_exit(); + return 0; +} diff --git a/doc/gtut-files/1-bones.output b/doc/gtut-files/1-bones.output new file mode 100644 index 0000000000..2a079b15e4 --- /dev/null +++ b/doc/gtut-files/1-bones.output @@ -0,0 +1,9 @@ +$ ./test_client +[blaise:client:(27306) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS +$ ./test_server +[blaise:server:(27309) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS +$ ./test_simulator platform.xml test.xml +[Jacquelin:server:(1) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS +[Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS +[0.000000] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all process are over +$ diff --git a/doc/gtut-files/2-simple.c b/doc/gtut-files/2-simple.c new file mode 100644 index 0000000000..07ff8d5b25 --- /dev/null +++ b/doc/gtut-files/2-simple.c @@ -0,0 +1,39 @@ +#include + +int server(int argc, char *argv[]) { + gras_socket_t mysock; /* socket on which I listen */ + gras_socket_t toclient; /* socket used to write to the client */ + + gras_init(&argc,argv); + + gras_msgtype_declare("hello", NULL); + mysock = gras_socket_server(12345); + + gras_msg_wait(60, gras_msgtype_by_name("hello"), &toclient, NULL /* no payload */); + + fprintf(stderr,"Cool, we received the message from %s:%d.\n", + gras_socket_peer_name(toclient), gras_socket_peer_port(toclient)); + + gras_exit(); + return 0; +} +int client(int argc, char *argv[]) { + gras_socket_t mysock; /* socket on which I listen */ + gras_socket_t toserver; /* socket used to write to the server */ + + gras_init(&argc,argv); + + gras_msgtype_declare("hello", NULL); + mysock = gras_socket_server_range(1024, 10000, 0, 0); + + fprintf(stderr,"Client ready; listening on %d\n", gras_socket_my_port(mysock)); + + gras_os_sleep(1.5); /* sleep 1 second and half */ + toserver = gras_socket_client("Jacquelin", 12345); + + gras_msg_send(toserver,gras_msgtype_by_name("hello"), NULL); + fprintf(stderr,"That's it, we sent the data to the server\n"); + + gras_exit(); + return 0; +} diff --git a/doc/gtut-files/2-simple.output b/doc/gtut-files/2-simple.output new file mode 100644 index 0000000000..3e6f5360e3 --- /dev/null +++ b/doc/gtut-files/2-simple.output @@ -0,0 +1,8 @@ +$ ./test_simulator platform.xml test.xml +Client ready; listening on 1024 +That's it, we sent the data to the server +[Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS +Cool, we received the message from Boivin:1024. +[Jacquelin:server:(1) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS +[0.000000] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all process are over +$ diff --git a/doc/gtut-files/Makefile b/doc/gtut-files/Makefile new file mode 100644 index 0000000000..99ba5a9f81 --- /dev/null +++ b/doc/gtut-files/Makefile @@ -0,0 +1,51 @@ +# This works mainly on my box for now +export LD_LIBRARY_PATH=$(GRAS_ROOT)/lib + +all: 1-bones 2-simple + +veryclean: clean + rm *.output + +# Lesson 1: simple bones of project +######################################## + +1-bones: 1-bones.output +1-bones.output: 1-bones_client 1-bones_server 1-bones_simulator + echo '$$ ./test_client' > $@ + ./1-bones_client >> $@ 2>&1 + echo '$$ ./test_server' >> $@ + ./1-bones_server >> $@ 2>&1 + echo '$$ ./test_simulator platform.xml test.xml' >> $@ + ./1-bones_simulator gtut-platform.xml test.xml >> $@ 2>&1 + echo '$$' >> $@ + +1-bones_client 1-bones_server 1-bones_simulator: _1-bones_client.c _1-bones_server.c _1-bones_simulator.c + make -f 1-bones.mk + +_1-bones_client.c _1-bones_server.c _1-bones_simulator.c: 1-bones.c test.xml + ../../tools/gras/gras_stub_generator 1-bones test.xml >/dev/null + +clean:: + if [ -e 1-bones.mk ] ; then make -f 1-bones.mk clean; fi + rm -f _1-bones_client.c _1-bones_server.c _1-bones_simulator.c 1-bones.trace 1-bones.mk + +# Lesson 2: simple message exchange +######################################## + +2-simple: 2-simple.output +2-simple.output: 2-simple_client 2-simple_server 2-simple_simulator + echo '$$ ./test_simulator platform.xml test.xml' > $@ + ./2-simple_simulator gtut-platform.xml test.xml >> $@ 2>&1 + echo '$$' >> $@ + +2-simple_client 2-simple_server 2-simple_simulator: _2-simple_client.c _2-simple_server.c _2-simple_simulator.c + make -f 2-simple.mk + +_2-simple_client.c _2-simple_server.c _2-simple_simulator.c: 2-simple.c test.xml + ../../tools/gras/gras_stub_generator 2-simple test.xml >/dev/null + +clean:: + if [ -e 2-simple.mk ] ; then make -f 2-simple.mk clean; fi + rm -f _2-simple_client.c _2-simple_server.c _2-simple_simulator.c 2-simple.trace 2-simple.mk + +.PHONY: 1-bones 2-simple diff --git a/doc/gtut-files/README b/doc/gtut-files/README new file mode 100644 index 0000000000..df4eff42b5 --- /dev/null +++ b/doc/gtut-files/README @@ -0,0 +1,4 @@ +You shouldn't muck with these files unless you know what you are doing. They +are used for the GRAS tutorial. + +Mt. diff --git a/doc/gtut-files/gtut-platform.xml b/doc/gtut-files/gtut-platform.xml new file mode 100644 index 0000000000..a0952aa521 --- /dev/null +++ b/doc/gtut-files/gtut-platform.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/doc/gtut-files/test.xml b/doc/gtut-files/test.xml new file mode 100644 index 0000000000..fe26214a3a --- /dev/null +++ b/doc/gtut-files/test.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doc/gtut-introduction.doc b/doc/gtut-introduction.doc new file mode 100644 index 0000000000..f7e0f3ba1c --- /dev/null +++ b/doc/gtut-introduction.doc @@ -0,0 +1,336 @@ +/** +@page GRAS_tut_intro Introduction to the GRAS framework + +\htmlinclude .gtut-introduction.doc.toc + +\section GRAS_tut_intro_toc What will you find here + + - The section \ref GRAS_tut_intro_what explains what the GRAS framework and how it + relates to other existing solutions. + - The section \ref GRAS_tut_intro_model presents somehow formaly the programmation + model used in GRAS. + +
+ +\section GRAS_tut_intro_what What is GRAS + +GRAS is a framework to implement and study distributed algorithms. It +provides a simple communication API to allow several processes to +interoperate through the exchange of messages. This is quite classical, and +GRAS differs from the other existing messaging API by several points: + + - \ref GRAS_tut_intro_what_2ways + - \ref GRAS_tut_intro_what_dist + - \ref GRAS_tut_intro_what_grid + - \ref GRAS_tut_intro_what_target + - \ref GRAS_tut_intro_what_simple + +We now detail each of these points. + +\subsection GRAS_tut_intro_what_2ways GRAS allows you to run both in simulation mode and on real platforms + +We wrote two implementations of the interface: the first one is built on top +of the SimGrid simulator, allowing you to run your application in a +controled environment, which reveals precious to debug and study algorithms. +Everyone who tried to run even simple tests on more than 100 real machines +will consider a simulator as a nirvana. + +The experiments can be reproduced in the exact same conditions (which is +somehow hard in real settings), allowing for example to reproduce a bug as +many times as you want while debugging. You can also test your algorithm +under experimental conditions which you couldn't achieve on a real platform +(like a network topology and/or size you do don't have access to). Under +some conditions, SimGrid simulations are also much faster than real +executions, allowing you to run more experiments in less time. + +Once you assessed the quality of your algorithm in the simulator, you can +deploy it on real platforms using the second implementation of the library. +Usually, taking an algorithm out of a simulator implies an almost complete +rewrite. There is no need to modify your program for this in GRAS. You don't +even need to recompile it, but simply to relink your program it against the +right library. + +GRAS applications running on real hardware deliver high performance. +The sequential parts of your code are not mediated by GRAS or slowed down +anyhow. The communications use advanced data exchange and conversion +mecanism ensuring that you are likely to get performance at least comparable +to other communication solutions (FIXME: cite the paper once it gets +accepted). + +GRAS applications are portable on several operating systems (Linux, MacOS X, +Solaris, IRIX, AIX and soon Windows) and several processor architectures +(x86, amd64, ppc, sparc, etc). Moreover, GRAS processes can interoperate +efficiently even when deployed on differing material. You can for example +have a process deployed on ppc/MacOS X interacting transparently with +another one deployed on alpha/Linux. + +The simulation mode of GRAS is called usually SG (for SimGrid) while the in +situ execution mode is called RL (for Real Life). + +\subsection GRAS_tut_intro_what_dist GRAS was designed for distributed computing, not parallel computing + +In GRAS, you build your algorithm as a set of independent processes +interacting through messages. This is the well known MPMD model (multiple +program, multiple data). It contrasts to the SPMD model (simple program, +multiple data) and communications solutions such as MPI or PVM, where you +build an uniq program with conditionnals here and there specifying what each +processes should do (something like "If I'm process number 0, then send data +to the others, else get the data sent to me"). + +None of these models are inherently better than the other, and there is a +plenty of algorithms betterly expressed in the SPMD paradigm. If your +program falls into that category, then GRAS may not be the right tool for +you. We think however that most non-sequential algorithms can be expressed +gracefully in a MPMD way where some are really difficult to express in a +SPMD way. + +There is no parallelism in GRAS, and it is discouraged to introduce threads +in GRAS (althrough it should be possible in some months). This is an explict +choice since threads are so hard to use (see the section \ref +GRAS_tut_intro_what_simple below). The framework itself do use threads to +achieve good performances, but I don't want to impose this to users (FIXME: +actually, GRAS is not multi-threaded yet internally, but I plan to do so +really soon). + +\subsection GRAS_tut_intro_what_grid GRAS was designed for large scale computing + +Another difference to the MPI communication libraries is that GRAS was not +designed for static small-sized platforms such as clusters, but to dynamic +larger-scale platforms such as grids. That is why GRAS do include static +membership solutions such as the MPI channels. Support for fault-tolerance +is also provided through the timeouts on communication primitives and +through an exception mecanism. + +GRAS also comes with a sister library called AMOK containing several usefull +building block for large scale network aware applications. The most +proheminent one allows to assess the network availabilities through active +testing, just like the classical NWS tool in the grid research community. We +are actively working on a network topology discovery mecanism and a +distributed locking solution. Some other modules are planned, such as +reliable broacasting in open environments. + +\subsection GRAS_tut_intro_what_target GRAS targets at applicative overlay rather than end-user application + +The application class targeted by GRAS is constituted of so called overlays. +They do not constitute a complete application by themselves, but can be seen +as a "distributed library", a thing offering offering a service to another +application through a set of physically distributed entities. An example of +such overlay could be a monitoring system allowing you to retrieve the +available bandwidth between two remote hosts. It could be used in a +network-aware parallel matrix multiplication library assigning more work to +well interconnected nodes. I wouldn't advice to build a physical or +biological compututation program on top of GRAS, even if it would be +possible in theory. + +In other words, GRAS is not a grid middleware in the common understanding of +the world, but rather a tool to constitute the building bricks of such a +middleware. GRAS is thus a sort of "underware" ;) + +\subsection GRAS_tut_intro_what_simple GRAS tries to remain simple to use + +A lot of effort was put into the framework so that it remains simple to the +users. For example, you can exchange structured data (any kind of C data +structure) just by passing its address, and the framework will create the +exact same structure on the receiver side. + +There is no threads like the pthread ones in GRAS, and it is not planned to +introduce this in the future. This is an explicit choice since I consider +multi-threading as too complicated for usual users. There is too much +non-determinism, too many race conditions, and too few language-level +constructs to keep yourself from screwing up. This idea is well expressed +by John Ousterhout in Why Threads Are a Bad Idea (for most purposes), +published at USENIX'96. See section \ref GRAS_tut_intro_what_dist for +platform performance consideration. + +For the user code, I plan to allow the co-existance of several "gras +processes" within the same regular unix process. The communication semantic +will still be message-oriented, even if implemented using the shared memory +for efficiency. + +Likewise, there is no interuption mecanism in GRAS which could break the +user code execution flow. When you write a function, you can be absolutely +sure that nothing will happen between each lines of it. This assumption +considerably simplify the code written in GRAS. The main use of of +interruptions in a distributed application is to timeout communications when +they fail. GRAS communication calls allow to setup a timeout value, and +handle it internally (see below). + +The only interruption mecanism used is constituted by exceptions, just like +in C++ or Java (but implemented directly in C). They are propagated from the +point where they are raised to a point where they will be trapped, if any, +or abort the execution when not trapped. You can still be certain that +nothing will happen between two lines of your code, but the second line may +never be executed if the first one raises an exception ;) + +This exception mecanism was introduced because without it, user code has to +be loaded by tons of non-functional code to check whether an operation was +properly performed or whether you have to pass the error condition to your +caller. + +
+ +\section GRAS_tut_intro_model The model provided by GRAS + +From a more formal point of view, GRAS overlays (=applications) can be seen +as a set of state machines mainly interacting with messages. Because of the +distributed setting of overlays, the internal state of each process cannot +be accessed or modified directly by other processes. Even when it would be +possible pratically (like in SG), it is forbidden by the model. This makes +it difficult to gain a complete knowledge on the global system state. This +global system state can still be defined by agregating the states of each +processes, but this remains theoretical and impratical because of the +probable combinatorial explosion. + + - \ref GRAS_tut_intro_model_events + - \ref GRAS_tut_intro_model_commmodel + - \ref GRAS_tut_intro_model_timing_policy + - \ref GRAS_tut_intro_model_exception + - \ref GRAS_tut_intro_model_rpc + +\subsection GRAS_tut_intro_model_events Event types + +Two main types of events may change the internal state of a given process: + + - Incomming messages. Messages are somehow strongly typed: a message + type is described by its name (a string), and the C datatype of its + payload. Any message of the same type will convey the same datatype, but + of course the actual content of the payload may change from message to + message of the same type.\n + \n + Processes may attach callback functions to the arrival of messages + of a given type. They describe the action to achieve to handle the + messages during the transition associated to this event.\n + \n + Incoming messages are not handled as soon as they arrive, but only when + the process declares to be ready to accept incomming events (using \ref + gras_msg_handle or related functions). It ensures that the treatment of a + given message won't run in parallel to any other callback, so that + process globals (its state) can be accessed and modified without + locking.\n + \n + Messages received when the process is not ready to consume them are + queued, and will be processed in order in the subsequent calls to \ref + gras_msg_handle.\n + \n + Processes can also wait explicitely for incoming messages matching some + given criterions (using \ref gras_msg_wait). Any messages received before the + one matching the criterions will be added to the incomming messages' + queue for further use. This may breaks the message delivery order. + Moreover, there is no restriction on when this can be done. So, a + callback to a given message can consume messages of other types. There is + also no restriction on the criterion: you can specify a function in charge + of examinating the messages either incoming or already in the queue and + decide based on their meta-data (sender and message type) or their actual + content whether they match your criterions.\n + \n + It is even possible to program processes so that they only explicitely + wait for messages without using \ref gras_msg_handle to accept messages + and start the callbacks associated to them. GRAS thus supports both the + pure event-based programming model and the more classical message passing + model.\n + + - Internal timers. There is two types of timers: delayed actions and + repetitive actions. The former happen only once when the delay expires + while the second happen regularly each time that a period expires.\n + \n + Like incoming messages, timer treatments are not prehemptive. Ie, the + function attached to a given timer will not start as soon as the period + expires, but only when the process declares to be ready to accept + incoming events. This also done in the \ref gras_msg_handle function, and + expired timers are prioritaire with regard to incoming messages. + +Messages are sent using the \ref gras_msg_send function. You should specify +the receiver, the message type and the actual payload. This operation can +happen at any time of your program. Message sending is not considered as a +process state change, but rather as a reaction to an incoming event. It +changes the state of another process, though. Trying to send messages to +yourself will deadlock (althrough it may change in the future). + +\subsection GRAS_tut_intro_model_commmodel Communication model + +Send operations are as synchronous as possible pratically. They +block the process until the message actually gets delivered to the receiving +process (an acknoledgment is awaited). We thus have an 1-port model in +emission. This limitation allows the framework to signal error condition +to the user code in the section which asked for the transmission, without +having to rely on an interuption mecanism to signal errors asynchronously. +This communication model is not completely synchronous in that sense that +the receiver cannot be sure that the acknoledgment has been delivered +(this is the classical byzantin generals problem). Pratically, the +acknoledgment is so small that there is a good probability that the message +where delivered. If you need more guaranty, you will need to implement +better solutions in the user space. + +Receive operations can be done in parallel, thanks to a specific thread +within the framework. Moreover, the messages not matching the criterion in +explicite receive are queued. The model is thus N-port in reception. + +Previous paragraph describes the model we are targeting, but the current +state of the implementation is a bit different: an acknoledgment is awaited +in send operation only in SG (this is a bug of RL), and there is no specific +thread for handling incoming communications yet. This shouldn't last long +until we solve this. + +\subsection GRAS_tut_intro_model_timing_policy Timing policy + +All communication primitives allow 3 timout policies: one can only poll for +incomming events (using timeout=0), wait endlessly for the communication to +be performed (using timeout<0) or specify a maximal delay to wait for the +communication to proceed (using timeout>0, being a number of seconds). + +Again, this describes the targeted model. The current implementation does +not allow to specify a delay for the outgoing communication. In SG, the +delay is then hardcoded to 60 seconds while outgoing communication wait for +ever to proceed in RL. + +Another timing policy we plan to implement in the future is "adaptative +timeouts", where the timeout is computed automatically by the framework +according to performance of previous communications. This was demonstrated +for example in the NWS tool. + +\subsection GRAS_tut_intro_model_exception Error handling through exceptions + +As explained in section \ref GRAS_tut_intro_what_simple, any function may +raise exceptions breaking their execution. No support is provided by the +framework to ensure that the internal state remains consistent when +exceptions are raised. Changing this would imply that we are able to +checkpoint the internal state to provide a transaction service, which seems +quite difficult to achieve efficiently. + +\subsection GRAS_tut_intro_model_rpc RPC messaging + +In addition to the one-way messages described above, GRAS supports RPC +communication. Using this, a client process asks for the execution of a +callback on a server process. RPC types are close to regular message types: +they are described by a type (a string), a payload type for the request, but +in addition, they also have a payload type for the answer from the server to +the client. + +RPC can be either synchronous (the function blocks until an answer is +received) or asynchronous (you send the request and wait later for the +anwer). They accept the same timing policies than regular messages. + +If the callback raises an exception on the server side, this exception will +be trapped by the framework on the server side, sent back to the client +side, and revived on the client side. So, if the client calls a RPC which +raises an error, it will have to deal with the exception itself. No +provision is given concerning the state consistency on the server side when +an exception arise. The host fields of the exception structure +indicates the name of the host on which it was raised. + +The callback performing the treatment associated to a RPC can perform any +kind of communication itself, including RPC. In the case where A calls a RPC +on B, leading to B calling a RPC on C (ie, A->B->C), if an exception is +raised on C, it will be forwarded back to A. The host field will +indicate C. + +
+ +\section GRAS_tut_intro_next What's next? + +Now that you know what GRAS is and the communication model used, it is time +to move to the \ref GRAS_tut_tour section. There, you will build +incrementally a full-featured GRAS application demonstrating most of the +aspects of the framework. + +*/ diff --git a/doc/gtut-main.doc b/doc/gtut-main.doc new file mode 100644 index 0000000000..acf8959cc9 --- /dev/null +++ b/doc/gtut-main.doc @@ -0,0 +1,26 @@ +/** +@addtogroup GRAS_tut + +This section constitutes a tutorial to the GRAS programming environment. + + - \ref GRAS_tut_intro :\n + This section details what GRAS is, and what are the target application + class. It also formalize somehow the communication model used in GRAS.\n + If you are new to the system and want to start using the tool as quickly + as possible and learn by trying things out instead of reading a lenghty + manual, you might want to start from next section directly. + + - \ref GRAS_tut_tour :\n + This section aims at turning new-comers into GRAS power user. It briefly + explains how to install the framework and setup your own projects. Then, + an example distributed application is builded incrementaly to show the + several aspects of the framework. + + \htmlonly \endhtmlonly + +*/ + diff --git a/doc/gtut-tour.doc b/doc/gtut-tour.doc new file mode 100644 index 0000000000..d7102a5b1f --- /dev/null +++ b/doc/gtut-tour.doc @@ -0,0 +1,359 @@ + +/** +@page GRAS_tut_tour GRAS initiatic tour + + +\section GRAS_tut_tour_what What will you find here + +On this page, you will learn all you need to write your own GRAS +applications, from the installation of the framework to the use of all +features available in GRAS. + + - \ref GRAS_tut_tour_install + - \ref GRAS_tut_tour_setup\n It explains the code layout you should setup to + build a GRAS application as well as the role and content of the several + files needed. + - \ref GRAS_tut_tour_setup_C + - \ref GRAS_tut_tour_setup_plat + - \ref GRAS_tut_tour_setup_deploy + - \ref GRAS_tut_tour_setup_glue + - \ref GRAS_tut_tour_setup_make + - \ref GRAS_tut_tour_setup_start + - \ref GRAS_tut_tour_simpleexchange + - \ref GRAS_tut_tour_simpleexchange_msgtype + - \ref GRAS_tut_tour_simpleexchange_socks + - \ref GRAS_tut_tour_simpleexchange_exchange + - \ref GRAS_tut_tour_simpleexchange_recaping + - \ref GRAS_tut_tour_args + +
+\section GRAS_tut_tour_install Lesson 0: Installing GRAS + +Since GRAS is technically part of the SimGrid project, you have to install +SimGrid to install GRAS. Doing so is explained in the relevant FAQ section +(\ref faq_installation). + +Newcommers should install the stable release from the tarball, since the cvs +snapshots may suffer from (additionnal;) stability issues. Only go for the CVS if you +really need features not present in the stable releases yet. + +
+\section GRAS_tut_tour_setup Lesson 1: Setting up your own project + +Any GRAS project should be constituted of at least 3 files, and possibly +much more. + + - <project>.c: A source file providing the source code of your + processes. + + - <platform>.xml: A platform description file. It describes + the virtual platform you want to run your application onto following the + SurfXML formatting so that the simulator can parse it. This file is only + needed in SG, and you don't need any to run on real platforms (of + course). The simplest is to use one of the pre-existing one. + + - <project>.xml: A deployment file. It describes which of + your processes to start, on which machine and with which arguments. + + - A makefile is often needed, too, even if it's not mandatory. + +If we start a project called test, we have to write 3 files: +test.c, platform.xml and test.xml + +\subsection GRAS_tut_tour_setup_C The C source file + +Let's look at the C source file first. It should contain one main function +for each type of processes in your overlay. Let's assume that you want to +code a simple client/server communication. For this, the source file should +read as: + +\verbatim #include + +int client(int argc, char *argv[]) { + ... +} + +int server(int argc, char *argv[]) { + ... +} +\endverbatim + +Note that each of the processes's main function have the exact same +prototype of the classical main() function in C. + +This is on purpose, each of them can assume this role when running in RL. +But you shouldn't write a main() function yourself since all processes will +run as threads within the same regular process in simulation mode. That is +why the real main function of GRAS programs are generated +automatically. This will be detailled in time (section \ref +GRAS_tut_tour_setup_glue), but for now just note the similarity between the +"main" functions you have to write for each processes and a "real main" +function. + +Then, each process must initialize the GRAS framework at the beginning (with +\ref gras_init) and should finalize it at the end (with \ref gras_exit). + +You should pass to \ref gras_init the argc and argv you +received in your "main" function so that the users of your application can +pass some configuration flags to the framework. + +It is not enough to have one of the processes initializing the framework +since in RL, each of them will run on a different host. If you use some AMOK +modules, you have to initialize them in each process too. + +The source file then reads: \include 1-bones.c + +That's it. You have a working GRAS application with two processes. They +don't do anything useful, but that's a beginning. Let's see how to bring +them to life. + +\subsection GRAS_tut_tour_setup_plat The platform file + +The platform file is used by the simulator to know about the existing hosts +and their interactions. Its exact syntax is at the same time very simple and +a bit beyond the topic of this document. Here is a very simple example +describin two hosts named Jacquelin and Boivin and how they +are interconnected. + +\include gtut-platform.xml + +At this point, you should not try to write your own platform file, but use +one of the existing ones. There is a few of them in the examples/msg +directory of the project. The only information we need from those files are +the names of the existing hosts. It will be mandatory to write the +deployment file. + +\subsection GRAS_tut_tour_setup_deploy The deployment file + +This file explains which of your processes should be started on the +different hosts. It is mainly used in simulation. In real life, you will +have to start your processes manually (see below). We we dream of a system +able to apply a deployment file in real life and TakTuk may be the right +tool for this, but this is still to be done. + +Here is an example of such file, describing that a server process +must be started onto the Jacquelin host and a client +process must be started on the Boivin host. + +\include test.xml + +Actually, you should write such a file also if you only plan to use GRAS in +RL since this file is also used to glue your code to GRAS, as explained in +the next section. + +\subsection GRAS_tut_tour_setup_glue Glueing things together + +As explained above, you shouldn't write any real main function +since its content depends on whether you run in RL ou in SG. Instead, you +use a tool gras_stub_generator to get the proper glue around your +code generated. If you installed SimGrid in a regular place, this program is +now in your path. Its source resides in the tools/gras/ directory of the +archive, if you wonder. + +Here is the calling syntax: +\verbatim gras_stub_generator \endverbatim + +It parses the deployment file (called test.xml in our example), +searching for all the kind of processes you have in your project. It +then generates the following C files: + + - a _<project_name>_<process_kind>.c file for each process kind you + have.\n + They are used to launch your project in real life. They + contain a main() in charge of initializing the GRAS infrastructure and + launching your code afterward. + - a _<project_name>_simulator.c file.\n + This file is suited to the simulation mode. It contains a main() + function initializing the simulator and launching your project within. + - a <project_name>.mk file.\n + This is a makefile to regenerate any files on need. See next section. + +In our example, we will thus obtain _test_server.c, +_test_client.c, _test_simulator.c and test.mk. + +There is a pitfall: no verification is made on your actual source code, so +if you have a typo on the process name in the deployment file, the generated +code will be wrong, and the linker will spit error messages at you. Also +remember that those names are in fact C function names, so they are +case-sensitive. + +\subsection GRAS_tut_tour_setup_make A typical Makefile + +Now, we want to compile all the source files to build the actual binaries. +It can be done manually, but it is much more convenient to use a makefile. +Fortunately, gras_stub_generator generates a makefile for you under the name +<project>.mk. This file is sufficient for now. To compile our test +application, just type: +\verbatim make -f test.mk \endverbatim + +You may want to rename this file to Makefile so that typing make +without argument becomes sufficient. In any case, do not edit this file +without renaming it, or your changes will get overwritten at the next glue +generation. + +If you already have a Makefile (or a Makefile.am for automake users), you +can also add the following chunk at the end of your file: +\verbatim NAME=your_project_name + PROCESSES=list of processes type in your project + + $(foreach proc, $(PROCESSES), _$(NAME)_$(proc).c) _$(NAME)_simulator.c: $(NAME).c $(NAME)_deployment.xml + path/to/gras_stub_generator $(NAME) $(NAME)_deployment.xml >/dev/null +\endverbatim + +A simpler solution in our example would be to add: +\verbatim _test_client.c _test_server.c _test_simulator.c: test.c test.xml + path/to/gras_stub_generator test test.xml >/dev/null +\endverbatim + + + +\subsection GRAS_tut_tour_setup_start Actually running the processes + +There is nothing to know to start your processes in RL. Simply call the +generated binaries, and that's it. To start the simulation, simply call: +\verbatim ./_simulator platform.xml deployment.xml\endverbatim + +Here is an example of execution: \include 1-bones.output + +That's it. You are done with this lesson and can now write, build and +execute GRAS applications as long as they don't do anything ;) Simply read on +to add some flesh on these bones. + +(back to the top of the \ref GRAS_tut_tour) +
+ +\section GRAS_tut_tour_simpleexchange Lesson 2: Exchanging simple messages + +\subsection GRAS_tut_tour_simpleexchange_msgtype Declaring the messages to be exchanged + +We will now see how to exchange messages between hosts. As explained in +section \ref GRAS_tut_intro_model, every GRAS message is (strongly) typed. A +message type is described by its name and the datatype of the data it can +convey. Each process which may exchange a given type of message should +declare it before sending or receiving it. If the description used by the +sender doesn't match the one used by the receiver, you'll get into trouble. +Fortunately, such discrepency will be detected in SG. + +We won't convey any payload in this lesson, so we just have to give the name +of message to declare them: +\dontinclude 2-simple.c +\skip gras_msgtype_declare +\until gras_msgtype_declare + +Remember that all processes should declare the message types they use. + +\subsection GRAS_tut_tour_simpleexchange_socks Identifying peers you want to communicate with + +Then, you need to specify with who you want to communicate. This is done +by opening sockets. GRAS sockets are loosely inspirated by the regular BSD +sockets, but with several simplifications. + +If you want to eventually receive messages, you have to open a so-called +server socket. Actually, any GRAS process should open a server socket +since it will allows to identify it uniquely in the system. A socket is +defined by an host name and a port number (just like with BSD sockets). + +Since server socket are on the current host, opening a socket to receive +messages on the port 12345 is as easy as: +\skip gras_socket_server +\until gras_socket_server + +Hardcoding port numbers that way may lead to difficulties on RL (at least) +since at most one process can listen on a given port. So, if you can, prefer +the \ref gras_socket_server_range, which picks a working port from a range +of value. Of course, if you want your processes to find each others, at +least one port must be hardcoded in the system. Then, any other processes +contact the one listening on that port, which acts as a coordinator. + +Our client should also open a server socket, but the picked port don't +matter, so we use: +\skip gras_socket_server +\until gras_socket_server + +It will select a port between 1024 (ports below 1024 are reserved under +UNIX) and 10000. You can safely ignore the two last arguments for now and +pass 0. + +So, you now know how to create sockets allowing to receive messages. To send +messages, you have to create a so-called client socket. For this, use +\ref gras_socket_client with the hostname and the port of the process you +want to contact as arguments. Our client should simply do: + +\dontinclude 2-simple.c +\skip socket_client +\until socket_client + +The corresponding server socket must be opened before any client socket can +connect to it. It is thus safe to add a little delay before creating the +client socket. But you cannot use the classical sleep() function for this, +or you will delay the simulator in SG, not your processes. Use \ref +gras_os_sleep instead. + +\subsection GRAS_tut_tour_simpleexchange_exchange Actually exchanging messages + +GRAS offers a plenty of ways to communicate. The simple one is to use \ref +gras_msg_send on the sender side, and \ref gras_msg_wait on the receiver side. + +\ref gras_msg_send expects 3 arguments: the socket on which to send the +message, the message type, and a pointer to the actual content of the +message. The simplest way to retrive a message type from its name is to use +\ref gras_msgtype_by_name. Since we don't have any payload, this becomes: + +\dontinclude 2-simple.c +\skip msg_send +\until msg_send + +\ref gras_msg_wait accepts 4 arguments. The first one is the delay you are +disposed to wait for messages, while the the type of message you are +expecting. Then come output arguments. The third argument should be the +address of a gras_socket_t variable which will indicate who wrote the +message you received while the last argument is where to put the payload. + +Since our server is willing to wait up to 60 seconds for a message, the +following will do it: +\dontinclude 2-simple.c +\skip msg_wait +\until msg_wait + +\subsection GRAS_tut_tour_simpleexchange_recaping Recaping everything together + +Here is the complete code of this example. Note the use of the functions +\ref gras_socket_my_port, \ref gras_socket_peer_name and \ref +gras_socket_peer_port to retrieve information about who you are connected to. + +\include 2-simple.c + +Here is the output of the simulator. Note that \ref gras_socket_peer_port +actually returns the port number of the server of the peer. This may +sound a bit strange to BSD experts, but it is actually really useful: you +can store this value, and contact your peer afterward passing this number to +\ref gras_socket_client . +\include 2-simple.output + +Here we are, you now know how to exchange messages between peers. There is +still a large room for improvement, such as adding payload to messages. +Moreover the most problematic issue is that this code does not work in RL +since we hardcoded the server hostname in the client code. Next lesson will +learn you how to pass arguments to your processes to overcome this situation. + +
+\section GRAS_tut_tour_args Lesson 3: Passing arguments to the processes (in SG) + +\section GRAS_tut_tour_todo TODO + +- Lesson 4: Passing arguments to processes in the deployment file +- Lesson 5: Callback ("I got a message from %s") +- Lesson 6: Globals (for a kill message) +- Lesson : Timers +- Lesson 7: Using logs + +- Lesson 8: Exchanging simple data through ping-pong +- Lesson 9: More complex data description (automatic parsing, manual description) and example + +- Lesson 10: Splitting in several files + +- Lesson 11: RPC mecanism and dealing with exceptions + +- Lesson 12: Debuging GRAS programs + +*/ diff --git a/doc/module-gras.doc b/doc/module-gras.doc index 19d6e82f07..9c84bb25d0 100644 --- a/doc/module-gras.doc +++ b/doc/module-gras.doc @@ -59,6 +59,7 @@ /** @defgroup GRAS_run Virtualization */ /** @defgroup GRAS_code Project and code management */ /** @defgroup GRAS_ex Examples */ + /** @defgroup GRAS_tut GRAS Tutorial */ /** @} */ ##################################################################### /** @addtogroup GRAS_comm