Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
New question: What is the difference between MSG, SimDag, and GRAS? Do they serve...
[simgrid.git] / doc / FAQ.doc
index 63235ab..fd1a06c 100644 (file)
@@ -89,25 +89,38 @@ command that resides in the top of the source tree. Then just follow the
 instructions of Section \ref faq_compiling.
 
 We insist on the fact that you really need the latest versions of
-autoconf and automake. Doing this step on exotic architectures/systems
+autoconf, automake and libtool. Doing this step on exotic architectures/systems
 (i.e. anything different from a recent linux distribution) may be
-... uncertain. If you want to use the CVS version on another
-architecture/system, you should do the previous steps on a perfectly
-standard box, then do a <tt>make dist</tt> that will build you a
-perfectly portable SimGrid archive.
+... uncertain. If you need to compile the CVS version on a machine where all these
+dependencies are not met, the easiest is to do <tt>make dist</tt> in the CVS
+dir of another machine where all dependencies are met. It will create an
+archive you may deploy on other sites just as a regular stable release.
 
 In summary, the following commands will checkout the CVS, regenerate the
-configure script and friends, configure SimGrid and build an archive you can
-use on another machine afterward.
+configure script and friends, configure SimGrid and build it.
 
 \verbatim cvs -d :pserver:anonymous@scm.gforge.inria.fr:/cvsroot/simgrid login
 cvs -d :pserver:anonymous@scm.gforge.inria.fr:/cvsroot/simgrid checkout simgrid
 cd simgrid
 ./bootstrap
-./configure --enable-maintainer-mode
-make dist \endverbatim
+./configure --enable-maintainer-mode --prefix=<where to install SimGrid>
+make \endverbatim
 
-\subsection faq_setting Setting up your own code
+Then, if you want to install SimGrid on the current box, just do:
+\verbatim make install \endverbatim
+
+If you want to build an snapshot of the CVS to deploy it on another box (for
+example because the other machine don't have the autotools), do:
+\verbatim make dist \endverbatim
+
+Moreover, you should never call the autotools manually since you must run
+them in a specific order with specific arguments. Most of the times, the
+makefiles will automatically call the tools for you. When it's not possible
+(such as the first time you checkout the CVS), use the ./bootstrap command
+to call them explicitely.
+
+
+\subsection faq_setting_MSG Setting up your own MSG code
 
 Do not build your simulator by modifying the SimGrid examples.  Go
 outside the SimGrid source tree and create your own working directory
@@ -186,6 +199,110 @@ in a terminal : <tt>info make</tt> and read the introduction. The
 previous example should be enough for a first try but you may want to
 perform some more complex compilations...
 
+\subsection faq_setting_GRAS Setting up your own GRAS code
+
+If you use the GRAS interface instead of the MSG one, then previous section
+is not the better source of information. Instead, you should check the GRAS
+tutorial in general, and the \ref GRAS_tut_tour_setup in particular.
+
+\subsection faq_crosscompile Cross-compiling a Windows DLL of SimGrid from linux
+
+At the moment, we do not distribute Windows pre-compiled version of SimGrid
+because the support for this platform is still experimental. We know that
+some parts of the GRAS environment do not work, and we think that the others
+environments (MSG and SD) have good chances to work, but we didn't test
+ourselves. This section explains how we generate the SimGrid DLL so that you
+can build it for yourself. First of all, you need to have a version more
+recent than 3.1 (ie, a CVS version as time of writting).
+
+In order to cross-compile the package to windows from linux, you need to
+install mingw32 (minimalist gnu win32). On Debian, you can do so by
+installing the packages mingw32 (compiler), mingw32-binutils (linker and
+so), mingw32-runtime.
+
+You can use the VPATH support of configure to compile at the same time for
+linux and windows without dupplicating the source nor cleaning the tree
+between each. Just run bootstrap (if you use the CVS) to run the autotools.
+Then, create a linux and a win directories. Then, type:
+\verbatim  cd linux; ../configure --srcdir=.. <usual configure flags>; make; cd ..
+cd win;  ../configure --srcdir=.. --host=i586-mingw32msvc <flags>; make; cd ..
+\endverbatim
+The trick to VPATH builds is to call configure from another directory,
+passing it an extra --srcdir argument to tell it where all the sources are.
+It will understand you want to use VPATH. Then, the trick to cross-compile
+is simply to add a --host argument specifying the target you want to build
+for. The i586-mingw32msvc string is what you have to pass to use the mingw32
+environment as distributed in Debian.
+
+After that, you can run all make targets from both directories, and test
+easily that what you change for one arch does not break the other one. 
+
+It is possible that this VPATH build thing breaks from time to time in the
+CVS since it's quite fragile, but it's granted to work in any released
+version. If you experience problems, drop us a mail. 
+
+Another possible source of issue is that at the moment, building the
+examples request to use the gras_stub_generator tool, which is a compiled
+program, not a script. In cross-compilation, you need to cross-execute with
+wine for example, which is not really pleasant. We are working on this, but
+in the meanwhile, simply don't build the examples in cross-compilation
+(<tt>cd src</tt> before running make).
+    
+Program (cross-)compiled with mingw32 do request an extra DLL at run-time to be
+usable. For example, if you want to test your build with wine, you should do
+the following to put this library where wine looks for DLLs.
+\verbatim 
+cp /usr/share/doc/mingw32-runtime/mingwm10.dll.gz ~/.wine/c/windows/system/
+gunzip ~/.wine/c/windows/system/mingwm10.dll.gz
+\endverbatim
+
+The DLL is builded in src/.libs, and installed in the <i>prefix</i>/bin directory
+when you run make install. 
+
+If you want to use it in a native project on windows, you need to use 
+simgrid.dll and mingwm10.dll. For each DLL, you need to build .def file
+under linux (listing the defined symbols), and convert it into a .lib file
+under windows (specifying this in a way that windows compilers like). To
+generate the def files, run (under linux):
+\verbatim echo "LIBRARY libsimgrid-0.dll" > simgrid.def
+echo EXPORTS >> simgrid.def
+nm libsimgrid-0.dll | grep ' T _' | sed 's/.* T _//' >> simgrid.def
+nm libsimgrid-0.dll | grep ' D _' | sed 's/.* D _//' | sed 's/$/ DATA/' >> simgrid.def
+
+echo "LIBRARY mingwm10.dll" > mingwm10.def
+echo EXPORTS >> mingwm10.def
+nm mingwm10.dll | grep ' T _' | sed 's/.* T _//' >> mingwm10.def
+nm mingwm10.dll | grep ' D _' | sed 's/.* D _//' | sed 's/$/ DATA/' >> mingwm10.def
+\endverbatim
+
+To create the import .lib files, use the <tt>lib</tt> windows tool (from
+MSVC) the following way to produce simgrid.lib and mingwm10.lib
+\verbatim lib /def:simgrid.def
+lib /def:mingwm10.def
+\endverbatim
+
+If you happen to use Borland C Builder, the right command line is the
+following (note that you don't need any file.def to get this working).
+\verbatim implib simgrid.lib libsimgrid-0.dll
+implib mingwm10.lib mingwm10.dll
+\endverbatim
+
+Then, set the following parameters in Visual C++ 2005:
+Linker -> Input -> Additional dependencies = simgrid.lib mingwm10.lib
+
+Just in case you wonder how to generate a DLL from libtool in another
+project, we added -no-undefined to any lib*_la_LDFLAGS variables so that
+libtool accepts to generate a dynamic library under windows. Then, to make
+it true, we pass any dependencies (such as -lws2 under windows or -lpthread
+on need) on the linking line. Passing such deps is a good idea anyway so
+that they get noted in the library itself, avoiding the users to know about
+our dependencies and put them manually on their compilation line. Then we
+added the AC_LIBTOOL_WIN32_DLL macro just before AC_PROG_LIBTOOL in the
+configure.ac. It means that we exported any symbols which need to be.
+Nowadays, functions get automatically exported, so we don't need to load our
+header files with tons of __declspec(dllexport) cruft. We only need to do so
+for data, but there is no public data in SimGrid so we are good.
+
 \section faq_simgrid I'm new to SimGrid. I have some questions. Where should I start?
 
 You are at the right place... Having a look to these
@@ -196,6 +313,30 @@ may give you some insights on what SimGrid can help you to do and what
 are its limitations. Then you definitely should read the \ref
 MSG_examples. There is also a mailing list: <simgrid-user@lists.gforge.inria.fr>.
 
+\subsection faq_interfaces What is the difference between MSG, SimDag, and GRAS? Do they serve the same purpose?
+
+It depend on how you define "purpose", I guess ;)
+
+They all allow you to build a prototype of application which you can run
+within the simulator afterward. They all share the same simulation kernel,
+which is the core of the SimGrid project. They differ by the way you express
+your application.
+
+With SimDag, you express your code as a collection of interdependent
+parallel tasks. So, in this model, applications can be seen as a DAG of
+tasks. 
+
+With both GRAS and MSG, your application is seen as a set of communicating
+processes, exchanging data by the way of messages and performing computation
+on their own.
+
+The difference between both is that MSG is somehow easier to use, but GRAS
+is not limitated to the simulator. Once you're done writing your GRAS code,
+you can run your code both in the simulator or on a real platform. For this,
+there is two implementations of the GRAS interface, one for simulation, one
+for real execution. So, you just have to relink your code to chose one of
+both world.
+
 \subsection faq_generic Building a generic simulator
 
 Please read carefully the \ref MSG_examples. You'll find in \ref
@@ -328,10 +469,10 @@ MSG_task_get_name(), MSG_task_get_compute_duration(),
 MSG_task_get_remaining_computation(), MSG_task_get_data_size(),
 and MSG_task_get_data().
 
-You could use a dictionnary (#xbt_dict_t) of dynars (#xbt_dict_t). If
+You could use a dictionnary (#xbt_dict_t) of dynars (#xbt_dynar_t). If
 you still don't see how to do it, please come back to us...
 
-\subsection faq_MIA_asynchronous I want to do asynchronous communications.
+\subsection faq_MIA_asynchronous I want to do asynchronous communications in MSG
 
 Up until now, there is no asynchronous communications in MSG. However,
 you can create as many process as you want so you should be able to do
@@ -340,7 +481,7 @@ some asynchronous communications at low cost (creating thousands of
 process only to handle communications may be problematic in term of
 performance at some point). I'll add it in the distribution asap.
 
-\subsection faq_MIA_thread_synchronization I need to synchronize my processes
+\subsection faq_MIA_thread_synchronization I need to synchronize my MSG processes
 
 You obviously cannot use pthread_mutexes of pthread_conds. The best
 thing would be to propose similar structures. Unfortunately, we
@@ -363,12 +504,20 @@ even take the currently running tasks into account. In some SURF models,
 communications have an influence on computational power. Should it be taken
 into account too?
 
-So, we decided not to include such a function into MSG and let people do it
-thereselves so that they get the value matching exactly what they mean. One
-possibility is to run active measurement as in next code snippet. It is very
-close from what you would have to do out of the simulator, and thus gives
-you information that you could also get in real settings to not hinder the
-realism of your simulation. 
+First of all, it's near to impossible to predict the load beforehands in the
+simulator since it depends on too much parameters (background load
+variation, bandwidth sharing algorithmic complexity) some of them even being
+not known beforehands (other task starting at the same time). So, getting
+this information is really hard (just like in real life). It's not just that
+we want MSG to be as painful as real life. But as it is in some way
+realistic, we face some of the same problems as we would face in real life.
+
+How would you do it for real? The most common option is to use something
+like NWS that performs active probes. The best solution is probably to do
+the same within MSG, as in next code snippet. It is very close from what you
+would have to do out of the simulator, and thus gives you information that
+you could also get in real settings to not hinder the realism of your
+simulation. 
 
 \verbatim
 double get_host_load() {
@@ -386,6 +535,42 @@ Of course, it may not match your personal definition of "host load". In this
 case, please detail what you mean on the mailing list, and we will extend
 this FAQ section to fit your taste if possible.
 
+\subsection faq_MIA_communication_time How can I get the *real* communication time ?  
+
+Communications are synchronous and thus if you simply get the time
+before and after a communication, you'll only get the transmission
+time and the time spent to really communicate (it will also take into
+account the time spent waiting for the other party to be
+ready). However, getting the *real* communication time is not really
+hard either. The following solution is a good starting point.
+
+\verbatim
+int sender()
+{
+  m_task_t task = MSG_task_create("Task", task_comp_size, task_comm_size, 
+                                  calloc(1,sizeof(double)));
+  *((double*) task->data) = MSG_get_clock();
+  MSG_task_put(task, slaves[i % slaves_count], PORT_22);
+  INFO0("Send completed");
+  return 0;
+}
+int receiver()
+{
+  m_task_t task = NULL;
+  double time1,time2;
+
+  time1 = MSG_get_clock();
+  a = MSG_task_get(&(task), PORT_22);
+  time2 = MSG_get_clock();
+  if(time1<*((double *)task->data))
+     time1 = *((double *) task->data);
+  INFO1("Communication time :  \"%f\" ", time2-time1);
+  free(task->data);
+  MSG_task_destroy(task);
+  return 0;
+}
+\endverbatim
+
 \subsection faq_MIA_batch_scheduler Is there a native support for batch schedulers in SimGrid ?
 
 No, there is no native support for batch schedulers and none is
@@ -601,10 +786,10 @@ PERIODICITY 1.0
 20.0 0.9
 \endverbatim
 
-At time 0, our CPU will deliver 100 Mflop/s. At time 11.0, it will
-deliver only 50 Mflop/s until time 20.0 where it will will start
-delivering 90 Mflop/s. Last at time 21.0 (20.0 plus the periodicity
-1.0), we'll be back to the beginning and it will deliver 100Mflop/s.
+At time 0, our CPU will deliver 100 flop/s. At time 11.0, it will
+deliver only 50 flop/s until time 20.0 where it will will start
+delivering 90 flop/s. Last at time 21.0 (20.0 plus the periodicity
+1.0), we'll be back to the beginning and it will deliver 100 flop/s.
 
 Now let's look at the state file:
 \verbatim
@@ -628,7 +813,7 @@ links. A usual declaration looks like:
 You have at your disposal the following options: bandwidth_file,
 latency_file and state_file. The only difference with CPUs is that
 bandwidth_file and latency_file do not express fraction of available
-power but are expressed directly in Mb/s and seconds.
+power but are expressed directly in bytes per seconds and seconds.
 
 \subsection faq_flexml_bypassing How can I have some C functions do what the platform file does?
 
@@ -801,7 +986,7 @@ machine:
    If none of the above apply, please drop us a mail on the mailing list so
    that we can check it out.
 
-\subsection faq_longjmp longjmp madness
+\subsection faq_longjmp longjmp madness in valgrind
 
 This is when valgrind starts complaining about longjmp things, just like:
 
@@ -838,6 +1023,52 @@ probably, you have a <tt>return;</tt> somewhere within a <tt>TRY{}</tt>
 block. This is <b>evil</b>, and you must not do this. Did you read the section
 about \ref XBT_ex??
 
+\subsection faq_valgrind Valgrind spits tons of errors!
+
+It may happen that valgrind, the memory debugger beloved by any decent C
+programmer, spits tons of warnings like the following :
+\verbatim ==8414== Conditional jump or move depends on uninitialised value(s)
+==8414==    at 0x400882D: (within /lib/ld-2.3.6.so)
+==8414==    by 0x414EDE9: (within /lib/tls/i686/cmov/libc-2.3.6.so)
+==8414==    by 0x400B105: (within /lib/ld-2.3.6.so)
+==8414==    by 0x414F937: _dl_open (in /lib/tls/i686/cmov/libc-2.3.6.so)
+==8414==    by 0x4150F4C: (within /lib/tls/i686/cmov/libc-2.3.6.so)
+==8414==    by 0x400B105: (within /lib/ld-2.3.6.so)
+==8414==    by 0x415102D: __libc_dlopen_mode (in /lib/tls/i686/cmov/libc-2.3.6.so)
+==8414==    by 0x412D6B9: backtrace (in /lib/tls/i686/cmov/libc-2.3.6.so)
+==8414==    by 0x8076446: xbt_dictelm_get_ext (dict_elm.c:714)
+==8414==    by 0x80764C1: xbt_dictelm_get (dict_elm.c:732)
+==8414==    by 0x8079010: xbt_cfg_register (config.c:208)
+==8414==    by 0x806821B: MSG_config (msg_config.c:42)
+\endverbatim
+
+This problem is somewhere in the libc when using the backtraces and there is
+very few things we can do ourselves to fix it. Instead, here is how to tell
+valgrind to ignore the error. Add the following to your ~/.valgrind.supp (or
+create this file on need). Make sure to change the obj line according to
+your personnal mileage (change 2.3.6 to the actual version you are using,
+which you can retrieve with a simple "ls /lib/ld*.so").
+
+\verbatim {
+   name: Backtrace madness
+   Memcheck:Cond
+   obj:/lib/ld-2.3.6.so
+   fun:dl_open_worker
+   fun:_dl_open
+   fun:do_dlopen
+   fun:dlerror_run
+   fun:__libc_dlopen_mode
+}\endverbatim
+
+Then, you have to specify valgrind to use this suppression file by passing
+the <tt>--suppressions=$HOME/.valgrind.supp</tt> option on the command line.
+You can also add the following to your ~/.bashrc so that it gets passed
+automatically. Actually, it passes a bit more options to valgrind, and this
+happen to be my personnal settings. Check the valgrind documentation for
+more information.
+
+\verbatim export VALGRIND_OPTS="--leak-check=yes --leak-resolution=high --num-callers=40 --tool=memcheck --suppressions=$HOME/.valgrind.supp" \endverbatim
+
 \subsection faq_flexml_limit I get the message "surf_parse_lex: Assertion `next&lt;limit' failed."
 
 This is because your platform file is too big for the parser. 
@@ -874,6 +1105,17 @@ These are changes to FleXML itself, not SimGrid. But since we kinda hijacked
 the development of FleXML, I can grant you that any patches would be really
 welcome and quickly integrated.
 
+<b>Update:</b> A new version of FleXML (1.7) was released. Most of the work
+was done by William Dowling, who use it in his own work. The good point is
+that it now use a dynamic buffer, and that the memory usage was greatly
+improved. The downside is that William also changed some things internally,
+and it breaks the hack we devised to bypass the parser, as explained in 
+\ref faq_flexml_bypassing. Indeed, this is not a classical usage of the
+parser, and Will didn't imagine that we may have used (and even documented)
+such a crude usage of FleXML. So, we now have to repare the bypassing
+functionnality to use the lastest FleXML version and fix the memory usage in
+SimGrid.
+
 \subsection faq_gras_transport GRAS spits networking error messages
 
 Gras, on real platforms, naturally use regular sockets to communicate. They
@@ -914,52 +1156,6 @@ reason:
    before the client get a chance to read them (use gras_os_sleep() to delay
    the server), or the server died awfully before the client got the data.
 
-\subsection faq_valgrind Valgrind spits tons of errors!
-
-It may happen that valgrind, the memory debugger beloved by any decent C
-programmer, spits tons of warnings like the following :
-\verbatim ==8414== Conditional jump or move depends on uninitialised value(s)
-==8414==    at 0x400882D: (within /lib/ld-2.3.6.so)
-==8414==    by 0x414EDE9: (within /lib/tls/i686/cmov/libc-2.3.6.so)
-==8414==    by 0x400B105: (within /lib/ld-2.3.6.so)
-==8414==    by 0x414F937: _dl_open (in /lib/tls/i686/cmov/libc-2.3.6.so)
-==8414==    by 0x4150F4C: (within /lib/tls/i686/cmov/libc-2.3.6.so)
-==8414==    by 0x400B105: (within /lib/ld-2.3.6.so)
-==8414==    by 0x415102D: __libc_dlopen_mode (in /lib/tls/i686/cmov/libc-2.3.6.so)
-==8414==    by 0x412D6B9: backtrace (in /lib/tls/i686/cmov/libc-2.3.6.so)
-==8414==    by 0x8076446: xbt_dictelm_get_ext (dict_elm.c:714)
-==8414==    by 0x80764C1: xbt_dictelm_get (dict_elm.c:732)
-==8414==    by 0x8079010: xbt_cfg_register (config.c:208)
-==8414==    by 0x806821B: MSG_config (msg_config.c:42)
-\endverbatim
-
-This problem is somewhere in the libc when using the backtraces and there is
-very few things we can do ourselves to fix it. Instead, here is how to tell
-valgrind to ignore the error. Add the following to your ~/.valgrind.supp (or
-create this file on need). Make sure to change the obj line according to
-your personnal mileage (change 2.3.6 to the actual version you are using,
-which you can retrieve with a simple "ls /lib/ld*.so").
-
-\verbatim {
-   name: Backtrace madness
-   Memcheck:Cond
-   obj:/lib/ld-2.3.6.so
-   fun:dl_open_worker
-   fun:_dl_open
-   fun:do_dlopen
-   fun:dlerror_run
-   fun:__libc_dlopen_mode
-}\endverbatim
-
-Then, you have to specify valgrind to use this suppression file by passing
-the <tt>--suppressions=$HOME/.valgrind.supp</tt> option on the command line.
-You can also add the following to your ~/.bashrc so that it gets passed
-automatically. Actually, it passes a bit more options to valgrind, and this
-happen to be my personnal settings. Check the valgrind documentation for
-more information.
-
-\verbatim export VALGRIND_OPTS="--leak-check=yes --leak-resolution=high --num-callers=40 --tool=memcheck --suppressions=$HOME/.valgrind.supp" \endverbatim
-
 \subsection faq_deadlock There is a deadlock !!!
 
 Unfortunately, we cannot debug every code written in SimGrid.  We
@@ -985,7 +1181,67 @@ valuer greater than 1:
 \endverbatim
 You should try to use the surfxml_update.pl script that can be found
 <a href="http://gforge.inria.fr/plugins/scmcvs/cvsweb.php/contrib/platform_generation/?cvsroot=cvsroot%2Fsimgrid">here</a>.
-  
+
+\subsection faq_surf_network_latency I get weird timings when I play with the latencies.
+
+OK, first of all, remember that units should be Bytes, Flops and
+Seconds. If you don't use such units, some SimGrid constants (e.g. the
+SG_TCP_CTE_GAMMA constant used in most network models) won't have the
+right unit and you'll end up with weird results.
+
+Here is what happens with a single transfer of size L on a link
+(bw,lat) when nothing else happens.
+
+\verbatim
+0-----lat--------------------------------------------------t
+|-----|**** real_bw =min(bw,SG_TCP_CTE_GAMMA/(2*lat)) *****|
+\endverbatim
+
+In more complex situations, this min is the solution of a complex
+max-min linear system.  Have a look 
+<a href="http://lists.gforge.inria.fr/pipermail/simgrid-devel/2006-April/thread.html">here</a>
+and read the two threads "Bug in SURF?" and "Surf bug not
+fixed?". You'll have a few other examples of such computations. You
+can also read "A Network Model for Simulation of Grid Application" by
+Henri Casanova and Loris Marchal to have all the details. The fact
+that the real_bw is smaller than bw is easy to understand. The fact
+that real_bw is smaller than SG_TCP_CTE_GAMMA/(2*lat) is due to the
+window-based congestion mechanism of TCP. With TCP, you can't exploit
+your huge network capacity if you don't have a good round-trip-time
+because of the acks...
+
+Anyway, what you get is t=lat + L/min(bw,SG_TCP_CTE_GAMMA/(2*lat)).
+
+  * if I you set (bw,lat)=(100 000 000, 0.00001), you get t =  1.00001 (you fully
+use your link)
+  * if I you set (bw,lat)=(100 000 000, 0.0001),  you get t =  1.0001 (you're on the
+limit)
+  * if I you set (bw,lat)=(100 000 000, 0.001),   you get t = 10.001  (ouch!)
+
+This bound on the effective bandwidth of a flow is not the only thing
+that may make your result be unexpected. For example, two flows
+competing on a saturated link receive an amount of bandwidth inversely
+proportional to their round trip time.
+
+\subsection faq_bugrepport So I've found a bug in SimGrid. How to report it?
+
+We do our best to make sure to hammer away any bugs of SimGrid, but this is
+still an academic project so please be patient if/when you find bugs in it.
+If you do, the best solution is to drop an email either on the simgrid-user
+or the simgrid-devel mailing list and explain us about the issue.  You can
+also decide to open a formal bug report using the
+<a href="https://gforge.inria.fr/tracker/?atid=165&group_id=12&func=browse">relevant
+interface</a>. You need to login on the server to get the ability to submit
+bugs. 
+
+We will do our best to solve any problem repported, but you need to help us
+finding the issue. Just telling "it segfault" isn't enough. Telling "It
+segfaults when running the attached simulator" doesn't really help either.
+You may find the following article interesting to see how to repport
+informative bug repports:
+http://www.chiark.greenend.org.uk/~sgtatham/bugs.html (it is not SimGrid
+specific at all, but it's full of good advices).
+
 \author Arnaud Legrand (arnaud.legrand::imag.fr)
 \author Martin Quinson (martin.quinson::loria.fr)