-/**
-@page GRAS_tut_intro Introduction to the GRAS framework
+/** @defgroup GRAS_tut_intro What is GRAS
+ @ingroup GRAS_tut
\htmlinclude .gtut-introduction.doc.toc
- The section \ref GRAS_tut_intro_model presents somehow formaly the programmation
model used in GRAS.
+\section GRAS_tut_intro_further Further readings
+
+After this page, you may find these one interesting:
+\ref GRAS_howto_design. If you're new to GRAS, you may want to read the
+initiatic tour first, begining with \ref GRAS_tut_tour_install or
+\ref GRAS_tut_tour_setup.
+
<hr>
\section GRAS_tut_intro_what What is GRAS
- \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
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
(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
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).
+accepted).
GRAS applications are portable on several operating systems (Linux, MacOS X,
Solaris, IRIX, AIX and soon Windows) and several processor architectures
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
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.
+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
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
+constructs to keep yourself from screwing up. This idea is well expressed
by John Ousterhout in <i>Why Threads Are a Bad Idea (for most purposes)</i>,
published at USENIX'96. See section \ref GRAS_tut_intro_what_dist for
platform performance consideration.
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).
+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 ;)
+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
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
+ the process declares to be ready to accept incoming 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
\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'
+ one matching the criterions will be added to the incoming 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
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
-
+
- <b>Internal timers</b>. 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
\subsection GRAS_tut_intro_model_commmodel Communication model
-Send operations are <b>as synchronous as possible pratically</b>. They
-block the process until the message actually gets delivered to the receiving
-process (an acknoledgment is awaited). We thus have an <b>1-port model in
-emission</b>. This limitation allows the framework to signal error condition
+Send operations are <b>as synchronous as possible pratically</b>. They block
+the process until the message actually gets delivered to the receiving
+process. An acknoledgment is awaited in SG, and we consider the fact that RL
+does not the same as a bug to be fixed one day. We thus have an <b>1-port model
+in emission</b>. 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 <b>N-port in reception</b>.
-
-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.
+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.
+
+As in SimGrid v3.3, receive operations are done in a separated thread, but they
+are done sequentially by this thread. The model is thus <b>1-port in
+reception</b>, but something like 2-port in general. Moreover, the messages not
+matching the criterion in explicite receive (see for example \ref
+gras_msg_wait) are queued for further use. Thanks to this specific
+thread, the emission and reception are completely decorelated. Ie, the
+main thread can perfectly send a message while the listener is
+receiving something. We thus have a classical <b>1-port model</b>.
+
+Here is a graphical representation of a scenario involving two processes A and
+B. Both are naturally composed of two threads: the one running user code, and
+the listener in charge of listening incoming messages from the network. Both
+processes also have a queue for the communication between the two threads, even
+if only the queue of process B is depicted in the graph.
+
+The experimental scenario is as follows: <ul>
+
+<li>Process A sends a first message (depicted in red) with gras_msg_send(), do
+ some more computation, and then send another message (depicted in
+ yellow). Then, this process handles any incoming message with
+ gras_msg_handle(). Since no message is already queued in process A at this
+ point, this is a blocking call until the third message (depicted in
+ magenta) arrives from the other process.</li>
+
+<li>On its side, the process B explicitely wait for the second message with
+ gras_msg_wait(), do some computation with it, and then call
+ gras_msg_handle() to handle any incoming message. This will pop the red
+ message from the queue, and start the callback attached to that kind of
+ messages. This callback sends back a new message (depicted in magenta) back
+ to process A.</li>
+</ul>
+
+<img src="gras_comm.png">
+
+This figure is a bit dense, and there is several point to detail here:<ul>
+
+<li>The timings associated to a given data exchange are detailed for the first
+message. The time (1) corresponds to the network latency. That is the time to
+reach the machine on which B is running from the machine running on A. The time
+(2) is mainly given by the network bandwidth. This is the time for all bytes of
+the messages to travel from one machine to the other. Please note that the
+models used by SimGrid are a bit more complicated to keep realistic, as
+explained in <a href="http://www.loria.fr/~quinson/blog/2010/06/28/Tutorial_at_HPCS/">the
+slides of the HPCS'10</a>, but this not that important here. The time (3) is mainly
+found in the SG version and not in RL (and that's a bug). This is the time to
+make sure that message were received on machine B. In real life, some buffering
+at system and network level may give the illusion to machine A that the message
+were already received before it's actually delivered to the listener of machine
+B (this would reduce the time (3)). To circumvent this, machine B should send a
+little acknoledgment message when it's done, but this is not implemented yet.</li>
+
+<li>As you can see on the figure, sending is blocking until the message is
+received by the listener on the other side, but the main thread of the receiver
+side is not involved in this operation. Sender will get released from its send
+even if the main thread of receiver is occuped elsewhere.</li>
+
+<li>Incomming messages not matching the expectations of a gras_msg_wait() (such
+as the red one) are queued for further use. The next message receiving
+operation will explore this queue in order, and if empty, block on the
+network. The order of unexpected messages and subsequent ones is thus preserved
+from the receiver point of view.</li>
+
+<li>gras_msg_wait() and gras_msg_handle() accept timeouts as argument to
+specify how long you are willing to wait at most for incoming messages. These
+were ignored here to not complexify the example any further. It is worth
+mentionning that the send operation cannot be timeouted. The existance of the
+listener should make it useless.</li>
+
+</ul>
\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
+incoming 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).