Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
rework the SMPI documentation
[simgrid.git] / doc / doxygen / module-smpi.doc
1 /** 
2 @defgroup SMPI_API      SMPI: Simulate real MPI applications
3 @brief Programming environment for the simulation of MPI applications
4
5 @tableofcontents
6
7 [TOC]
8
9 This programming environment enables the study of MPI application by
10 emulating them on top of the SimGrid simulator. This is particularly
11 interesting to study existing MPI applications within the comfort of
12 the simulator. The motivation for this work is detailed in the
13 reference article (available at http://hal.inria.fr/inria-00527150).
14
15
16 Our goal is to enable the study of **unmodified MPI applications**,
17 and even if some constructs and features are still missing, we
18 consider SMPI to be stable and usable in production.  For **further
19 scalability**, you may modify your code to speed up your studies or
20 save memory space.  Improved **simulation accuracy** requires some
21 specific care from you.
22
23  - @ref SMPI_use
24    - @ref SMPI_use_compile
25    - @ref SMPI_use_exec
26    - @ref SMPI_use_colls
27      - @ref SMPI_use_colls_algos
28      - @ref SMPI_use_colls_tracing
29  - @ref SMPI_what
30    - @ref SMPI_what_coverage
31    - @ref SMPI_what_globals
32  - @ref SMPI_adapting
33    - @ref SMPI_adapting_size
34    - @ref SMPI_adapting_speed
35  - @ref SMPI_accuracy
36
37
38 @section SMPI_use Using SMPI
39
40 If you're absolutely new to MPI, you should first take our online
41 [SMPI CourseWare](https://simgrid.github.io/SMPI_CourseWare/), and/or
42 take a MPI course in your favorite university.  If you already know
43 MPI, SMPI should sound very familiar to you: Use smpicc instead of
44 mpicc, and smpirun instead of mpirun, and you're almost set.  Once you
45 get a virtual platform description (see @ref platform), you're good to
46 go.
47
48 @subsection SMPI_use_compile Compiling your code
49
50 For that, simply use <tt>smpicc</tt> as a compiler just
51 like you use mpicc with other MPI implementations. This script
52 replaces your usual compiler (gcc, clang, whatever) and adds the right
53 compilation flags along the way.
54
55 This may badly interact with some building infrastructure. Your
56 <tt>./configure</tt> may fail, reporting that the compiler is not
57 functional. If this happens, define the <tt>SMPI_PRETEND_CC</tt>
58 environment variable before running the configuration. Do not define
59 it when using SMPI!
60
61 @verbatim
62 SMPI_PRETEND_CC=1 ./configure # here come the configure parameters
63 make
64 @endverbatim
65
66 @subsection SMPI_use_exec Executing your code on the simulator
67
68 Use the <tt>smpirun</tt> script as follows for that:
69
70 @verbatim
71 smpirun -hostfile my_hostfile.txt -platform my_platform.xml ./program -blah
72 @endverbatim
73
74  - <tt>my_hostfile.txt</tt> is a classical MPI hostfile (that is, this
75    file lists the machines on which the processes must be dispatched, one
76    per line)
77  - <tt>my_platform.xml</tt> is a classical SimGrid platform file. Of
78    course, the hosts of the hostfile must exist in the provided
79    platform.
80  - <tt>./program</tt> is the MPI program to simulate, that you
81    compiled with <tt>smpicc</tt>
82  - <tt>-blah</tt> is a command-line parameter passed to this program.
83
84 <tt>smpirun</tt> accepts other parameters, such as <tt>-np</tt> if you
85 don't want to use all the hosts defined in the hostfile, <tt>-map</tt>
86 to display on which host each rank gets mapped of <tt>-trace</tt> to
87 activate the tracing during the simulation. You can get the full list
88 by running
89
90 @verbatim
91 smpirun -help
92 @endverbatim
93
94 @subsection SMPI_use_colls Simulating collective operations
95
96 MPI collective operations are crucial to the performance of MPI
97 applications and must be carefully optimized according to many
98 parameters. Every existing implementation provides several algorithms
99 for each collective operation, and selects by default the best suited
100 one, depending on the sizes sent, the number of nodes, the
101 communicator, or the communication library being used.  These
102 decisions are based on empirical results and theoretical complexity
103 estimation, and are very different between MPI implementations. In
104 most cases, the users can also manually tune the algorithm used for
105 each collective operation.
106
107 SMPI can simulate the behavior of several MPI implementations:
108 OpenMPI, MPICH,
109 <a href="http://star-mpi.sourceforge.net/">STAR-MPI</a>, and
110 MVAPICH2. For that, it provides 115 collective algorithms and several
111 selector algorithms, that were collected directly in the source code
112 of the targeted MPI implementations.
113
114 You can switch the automatic selector through the
115 \c smpi/coll_selector configuration item. Possible values:
116
117  - <b>ompi</b>: default selection logic of OpenMPI (version 1.7)
118  - <b>mpich</b>: default selection logic of MPICH (version 3.0.4)
119  - <b>mvapich2</b>: selection logic of MVAPICH2 (version 1.9) tuned
120    on the Stampede cluster   
121  - <b>impi</b>: preliminary version of an Intel MPI selector (version
122    4.1.3, also tuned for the Stampede cluster). Due the closed source
123    nature of Intel MPI, some of the algorithms described in the
124    documentation are not available, and are replaced by mvapich ones.   
125  - <b>default</b>: legacy algorithms used in the earlier days of
126    SimGrid. Do not use for serious perform performance studies.
127
128
129 @subsubsection SMPI_use_colls_algos Available algorithms
130
131 You can also pick the algorithm used for each collective with the
132 corresponding configuration item. For example, to use the pairwise
133 alltoall algorithm, one should add \c --cfg=smpi/alltoall:pair to the
134 line. This will override the selector (if any) for this algorithm.
135 It means that the selected algorithm will be used 
136
137 Warning: Some collective may require specific conditions to be
138 executed correctly (for instance having a communicator with a power of
139 two number of nodes only), which are currently not enforced by
140 Simgrid. Some crashes can be expected while trying these algorithms
141 with unusual sizes/parameters
142
143 #### MPI_Alltoall
144
145 Most of these are best described in <a href="http://www.cs.arizona.edu/~dkl/research/papers/ics06.pdf">STAR-MPI</a>
146
147  - default: naive one, by default
148  - ompi: use openmpi selector for the alltoall operations
149  - mpich: use mpich selector for the alltoall operations
150  - mvapich2: use mvapich2 selector for the alltoall operations
151  - impi: use intel mpi selector for the alltoall operations
152  - automatic (experimental): use an automatic self-benchmarking algorithm 
153  - 2dmesh: organizes the nodes as a two dimensional mesh, and perform allgather 
154    along the dimensions
155  - 3dmesh: adds a third dimension to the previous algorithm
156  - rdb: recursive doubling : extends the mesh to a nth dimension, each one 
157    containing two nodes
158  - pair: pairwise exchange, only works for power of 2 procs, size-1 steps,
159    each process sends and receives from the same process at each step
160  - pair_light_barrier: same, with small barriers between steps to avoid
161    contention
162  - pair_mpi_barrier: same, with MPI_Barrier used
163  - pair_one_barrier: only one barrier at the beginning
164  - ring: size-1 steps, at each step a process send to process (n+i)%size, and receives from (n-i)%size
165  - ring_light_barrier: same, with small barriers between some phases to avoid contention
166  - ring_mpi_barrier: same, with MPI_Barrier used
167  - ring_one_barrier: only one barrier at the beginning
168  - basic_linear: posts all receives and all sends,
169 starts the communications, and waits for all communication to finish
170  - mvapich2_scatter_dest: isend/irecv with scattered destinations, posting only a few messages at the same time
171
172 #### MPI_Alltoallv
173
174  - default: naive one, by default
175  - ompi: use openmpi selector for the alltoallv operations
176  - mpich: use mpich selector for the alltoallv operations
177  - mvapich2: use mvapich2 selector for the alltoallv operations
178  - impi: use intel mpi selector for the alltoallv operations
179  - automatic (experimental): use an automatic self-benchmarking algorithm 
180  - bruck: same as alltoall
181  - pair: same as alltoall
182  - pair_light_barrier: same as alltoall
183  - pair_mpi_barrier: same as alltoall
184  - pair_one_barrier: same as alltoall
185  - ring: same as alltoall
186  - ring_light_barrier: same as alltoall
187  - ring_mpi_barrier: same as alltoall
188  - ring_one_barrier: same as alltoall
189  - ompi_basic_linear: same as alltoall
190
191 #### MPI_Gather
192
193  - default: naive one, by default
194  - ompi: use openmpi selector for the gather operations
195  - mpich: use mpich selector for the gather operations
196  - mvapich2: use mvapich2 selector for the gather operations
197  - impi: use intel mpi selector for the gather operations
198  - automatic (experimental): use an automatic self-benchmarking algorithm 
199 which will iterate over all implemented versions and output the best
200  - ompi_basic_linear: basic linear algorithm from openmpi, each process sends to the root
201  - ompi_binomial: binomial tree algorithm
202  - ompi_linear_sync: same as basic linear, but with a synchronization at the
203  beginning and message cut into two segments.
204  - mvapich2_two_level: SMP-aware version from MVAPICH. Gather first intra-node (defaults to mpich's gather), and then exchange with only one process/node. Use mvapich2 selector to change these to tuned algorithms for Stampede cluster.
205
206 #### MPI_Barrier
207
208  - default: naive one, by default
209  - ompi: use openmpi selector for the barrier operations
210  - mpich: use mpich selector for the barrier operations
211  - mvapich2: use mvapich2 selector for the barrier operations
212  - impi: use intel mpi selector for the barrier operations
213  - automatic (experimental): use an automatic self-benchmarking algorithm 
214  - ompi_basic_linear: all processes send to root
215  - ompi_two_procs: special case for two processes
216  - ompi_bruck: nsteps = sqrt(size), at each step, exchange data with rank-2^k and rank+2^k
217  - ompi_recursivedoubling: recursive doubling algorithm
218  - ompi_tree: recursive doubling type algorithm, with tree structure
219  - ompi_doublering: double ring algorithm
220  - mvapich2_pair: pairwise algorithm
221
222 #### MPI_Scatter
223
224  - default: naive one, by default
225  - ompi: use openmpi selector for the scatter operations
226  - mpich: use mpich selector for the scatter operations
227  - mvapich2: use mvapich2 selector for the scatter operations
228  - impi: use intel mpi selector for the scatter operations
229  - automatic (experimental): use an automatic self-benchmarking algorithm 
230  - ompi_basic_linear: basic linear scatter 
231  - ompi_binomial: binomial tree scatter
232  - mvapich2_two_level_direct: SMP aware algorithm, with an intra-node stage (default set to mpich selector), and then a basic linear inter node stage. Use mvapich2 selector to change these to tuned algorithms for Stampede cluster. 
233  - mvapich2_two_level_binomial: SMP aware algorithm, with an intra-node stage (default set to mpich selector), and then a binomial phase. Use mvapich2 selector to change these to tuned algorithms for Stampede cluster.
234
235 #### MPI_Reduce
236
237  - default: naive one, by default
238  - ompi: use openmpi selector for the reduce operations
239  - mpich: use mpich selector for the reduce operations
240  - mvapich2: use mvapich2 selector for the reduce operations
241  - impi: use intel mpi selector for the reduce operations
242  - automatic (experimental): use an automatic self-benchmarking algorithm 
243  - arrival_pattern_aware: root exchanges with the first process to arrive
244  - binomial: uses a binomial tree
245  - flat_tree: uses a flat tree
246  - NTSL: Non-topology-specific pipelined linear-bcast function 
247    0->1, 1->2 ,2->3, ....., ->last node: in a pipeline fashion, with segments
248  of 8192 bytes
249  - scatter_gather: scatter then gather
250  - ompi_chain: openmpi reduce algorithms are built on the same basis, but the
251  topology is generated differently for each flavor
252 chain = chain with spacing of size/2, and segment size of 64KB 
253  - ompi_pipeline: same with pipeline (chain with spacing of 1), segment size 
254 depends on the communicator size and the message size
255  - ompi_binary: same with binary tree, segment size of 32KB
256  - ompi_in_order_binary: same with binary tree, enforcing order on the 
257 operations
258  - ompi_binomial: same with binomial algo (redundant with default binomial 
259 one in most cases)
260  - ompi_basic_linear: basic algorithm, each process sends to root
261  - mvapich2_knomial: k-nomial algorithm. Default factor is 4 (mvapich2 selector adapts it through tuning)
262  - mvapich2_two_level: SMP-aware reduce, with default set to mpich both for intra and inter communicators. Use mvapich2 selector to change these to tuned algorithms for Stampede cluster.
263  - rab: <a href="https://fs.hlrs.de/projects/par/mpi//myreduce.html">Rabenseifner</a>'s reduce algorithm 
264
265 #### MPI_Allreduce
266
267  - default: naive one, by default
268  - ompi: use openmpi selector for the allreduce operations
269  - mpich: use mpich selector for the allreduce operations
270  - mvapich2: use mvapich2 selector for the allreduce operations
271  - impi: use intel mpi selector for the allreduce operations
272  - automatic (experimental): use an automatic self-benchmarking algorithm 
273  - lr: logical ring reduce-scatter then logical ring allgather
274  - rab1: variations of the  <a href="https://fs.hlrs.de/projects/par/mpi//myreduce.html">Rabenseifner</a> algorithm: reduce_scatter then allgather
275  - rab2: variations of the  <a href="https://fs.hlrs.de/projects/par/mpi//myreduce.html">Rabenseifner</a> algorithm: alltoall then allgather
276  - rab_rsag: variation of the  <a href="https://fs.hlrs.de/projects/par/mpi//myreduce.html">Rabenseifner</a> algorithm: recursive doubling 
277 reduce_scatter then recursive doubling allgather 
278  - rdb: recursive doubling
279  - smp_binomial: binomial tree with smp: binomial intra 
280 SMP reduce, inter reduce, inter broadcast then intra broadcast
281  - smp_binomial_pipeline: same with segment size = 4096 bytes
282  - smp_rdb: intra: binomial allreduce, inter: Recursive 
283 doubling allreduce, intra: binomial broadcast
284  - smp_rsag: intra: binomial allreduce, inter: reduce-scatter, 
285 inter:allgather, intra: binomial broadcast
286  - smp_rsag_lr: intra: binomial allreduce, inter: logical ring 
287 reduce-scatter, logical ring inter:allgather, intra: binomial broadcast
288  - smp_rsag_rab: intra: binomial allreduce, inter: rab
289 reduce-scatter, rab inter:allgather, intra: binomial broadcast
290  - redbcast: reduce then broadcast, using default or tuned algorithms if specified
291  - ompi_ring_segmented: ring algorithm used by OpenMPI
292  - mvapich2_rs: rdb for small messages, reduce-scatter then allgather else
293  - mvapich2_two_level: SMP-aware algorithm, with mpich as intra algoritm, and rdb as inter (Change this behavior by using mvapich2 selector to use tuned values)
294  - rab: default <a href="https://fs.hlrs.de/projects/par/mpi//myreduce.html">Rabenseifner</a> implementation
295
296 #### MPI_Reduce_scatter
297
298  - default: naive one, by default
299  - ompi: use openmpi selector for the reduce_scatter operations
300  - mpich: use mpich selector for the reduce_scatter operations
301  - mvapich2: use mvapich2 selector for the reduce_scatter operations
302  - impi: use intel mpi selector for the reduce_scatter operations
303  - automatic (experimental): use an automatic self-benchmarking algorithm 
304  - ompi_basic_recursivehalving: recursive halving version from OpenMPI
305  - ompi_ring: ring version from OpenMPI
306  - mpich_pair: pairwise exchange version from MPICH
307  - mpich_rdb: recursive doubling version from MPICH
308  - mpich_noncomm: only works for power of 2 procs, recursive doubling for noncommutative ops
309
310
311 #### MPI_Allgather
312
313  - default: naive one, by default
314  - ompi: use openmpi selector for the allgather operations
315  - mpich: use mpich selector for the allgather operations
316  - mvapich2: use mvapich2 selector for the allgather operations
317  - impi: use intel mpi selector for the allgather operations
318  - automatic (experimental): use an automatic self-benchmarking algorithm 
319  - 2dmesh: see alltoall
320  - 3dmesh: see alltoall
321  - bruck: Described by Bruck et.al. in <a href="http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=642949">
322 Efficient algorithms for all-to-all communications in multiport message-passing systems</a> 
323  - GB: Gather - Broadcast (uses tuned version if specified)
324  - loosely_lr: Logical Ring with grouping by core (hardcoded, default 
325 processes/node: 4)
326  - NTSLR: Non Topology Specific Logical Ring
327  - NTSLR_NB: Non Topology Specific Logical Ring, Non Blocking operations
328  - pair: see alltoall
329  - rdb: see alltoall
330  - rhv: only power of 2 number of processes
331  - ring: see alltoall
332  - SMP_NTS: gather to root of each SMP, then every root of each SMP node 
333 post INTER-SMP Sendrecv, then do INTRA-SMP Bcast for each receiving message, 
334 using logical ring algorithm (hardcoded, default processes/SMP: 8)
335  - smp_simple: gather to root of each SMP, then every root of each SMP node 
336 post INTER-SMP Sendrecv, then do INTRA-SMP Bcast for each receiving message, 
337 using simple algorithm (hardcoded, default processes/SMP: 8)
338  - spreading_simple: from node i, order of communications is i -> i + 1, i ->
339  i + 2, ..., i -> (i + p -1) % P
340  - ompi_neighborexchange: Neighbor Exchange algorithm for allgather. 
341 Described by Chen et.al. in  <a href="http://ieeexplore.ieee.org/xpl/articleDetails.jsp?tp=&arnumber=1592302">Performance Evaluation of Allgather Algorithms on Terascale Linux Cluster with Fast Ethernet</a>
342  - mvapich2_smp: SMP aware algorithm, performing intra-node gather, inter-node allgather with one process/node, and bcast intra-node
343
344
345 ####_Allgatherv
346
347  - default: naive one, by default
348  - ompi: use openmpi selector for the allgatherv operations
349  - mpich: use mpich selector for the allgatherv operations
350  - mvapich2: use mvapich2 selector for the allgatherv operations
351  - impi: use intel mpi selector for the allgatherv operations
352  - automatic (experimental): use an automatic self-benchmarking algorithm 
353  - GB: Gatherv - Broadcast (uses tuned version if specified, but only for 
354 Bcast, gatherv is not tuned)
355  - pair: see alltoall
356  - ring: see alltoall
357  - ompi_neighborexchange: see allgather
358  - ompi_bruck: see allgather
359  - mpich_rdb: recursive doubling algorithm from MPICH
360  - mpich_ring: ring algorithm from MPICh - performs differently from the  one from STAR-MPI
361
362 #### MPI_Bcast
363
364  - default: naive one, by default
365  - ompi: use openmpi selector for the bcast operations
366  - mpich: use mpich selector for the bcast operations
367  - mvapich2: use mvapich2 selector for the bcast operations
368  - impi: use intel mpi selector for the bcast operations
369  - automatic (experimental): use an automatic self-benchmarking algorithm 
370  - arrival_pattern_aware: root exchanges with the first process to arrive
371  - arrival_pattern_aware_wait: same with slight variation
372  - binomial_tree: binomial tree exchange
373  - flattree: flat tree exchange
374  - flattree_pipeline: flat tree exchange, message split into 8192 bytes pieces
375  - NTSB: Non-topology-specific pipelined binary tree with 8192 bytes pieces
376  - NTSL: Non-topology-specific pipelined linear with 8192 bytes pieces
377  - NTSL_Isend: Non-topology-specific pipelined linear with 8192 bytes pieces, asynchronous communications
378  - scatter_LR_allgather: scatter followed by logical ring allgather
379  - scatter_rdb_allgather: scatter followed by recursive doubling allgather
380  - arrival_scatter: arrival pattern aware scatter-allgather
381  - SMP_binary: binary tree algorithm with 8 cores/SMP
382  - SMP_binomial: binomial tree algorithm with 8 cores/SMP
383  - SMP_linear: linear algorithm with 8 cores/SMP
384  - ompi_split_bintree: binary tree algorithm from OpenMPI, with message split in 8192 bytes pieces
385  - ompi_pipeline: pipeline algorithm from OpenMPI, with message split in 128KB pieces
386  - mvapich2_inter_node: Inter node default mvapich worker 
387  - mvapich2_intra_node: Intra node default mvapich worker
388  - mvapich2_knomial_intra_node:  k-nomial intra node default mvapich worker. default factor is 4.
389
390 #### Automatic evaluation 
391
392 (Warning: This is experimental and may be removed or crash easily)
393
394 An automatic version is available for each collective (or even as a selector). This specific 
395 version will loop over all other implemented algorithm for this particular collective, and apply 
396 them while benchmarking the time taken for each process. It will then output the quickest for 
397 each process, and the global quickest. This is still unstable, and a few algorithms which need 
398 specific number of nodes may crash.
399
400 #### Adding an algorithm
401
402 To add a new algorithm, one should check in the src/smpi/colls folder how other algorithms 
403 are coded. Using plain MPI code inside Simgrid can't be done, so algorithms have to be 
404 changed to use smpi version of the calls instead (MPI_Send will become smpi_mpi_send). Some functions may have different signatures than their MPI counterpart, please check the other algorithms or contact us using <a href="http://lists.gforge.inria.fr/mailman/listinfo/simgrid-devel">SimGrid developers mailing list</a>.
405
406 Example: adding a "pair" version of the Alltoall collective.
407
408  - Implement it in a file called alltoall-pair.c in the src/smpi/colls folder. This file should include colls_private.h.
409
410  - The name of the new algorithm function should be smpi_coll_tuned_alltoall_pair, with the same signature as MPI_Alltoall.
411
412  - Once the adaptation to SMPI code is done, add a reference to the file ("src/smpi/colls/alltoall-pair.c") in the SMPI_SRC part of the DefinePackages.cmake file inside buildtools/cmake, to allow the file to be built and distributed.
413
414  - To register the new version of the algorithm, simply add a line to the corresponding macro in src/smpi/colls/cools.h ( add a "COLL_APPLY(action, COLL_ALLTOALL_SIG, pair)" to the COLL_ALLTOALLS macro ). The algorithm should now be compiled and be selected when using --cfg=smpi/alltoall:pair at runtime.
415
416  - To add a test for the algorithm inside Simgrid's test suite, juste add the new algorithm name in the ALLTOALL_COLL list found inside teshsuite/smpi/CMakeLists.txt . When running ctest, a test for the new algorithm should be generated and executed. If it does not pass, please check your code or contact us.
417
418  - Please submit your patch for inclusion in SMPI, for example through a pull request on GitHub or directly per email.
419
420 @subsubsection SMPI_use_colls_tracing Tracing of internal communications
421
422 By default, the collective operations are traced as a unique operation
423 because tracing all point-to-point communications composing them could
424 result in overloaded, hard to interpret traces. If you want to debug
425 and compare collective algorithms, you should set the
426 \c tracing/smpi/internals configuration item to 1 instead of 0.
427
428 Here are examples of two alltoall collective algorithms runs on 16 nodes, 
429 the first one with a ring algorithm, the second with a pairwise one:
430
431 @htmlonly
432 <a href="smpi_simgrid_alltoall_ring_16.png" border=0><img src="smpi_simgrid_alltoall_ring_16.png" width="30%" border=0 align="center"></a>
433 <a href="smpi_simgrid_alltoall_pair_16.png" border=0><img src="smpi_simgrid_alltoall_pair_16.png" width="30%" border=0 align="center"></a>
434 <br/>
435 @endhtmlonly
436
437 @section SMPI_what What can run within SMPI?
438
439 You can run unmodified MPI applications (both C and Fortran) within
440 SMPI, provided that you only use MPI calls that we implemented. Global
441 variables should be handled correctly on Linux systems.
442
443 @subsection SMPI_what_coverage MPI coverage of SMPI
444
445 Our coverage of the interface is very decent, but still incomplete;
446 Given the size of the MPI standard, we may well never manage to 
447 implement absolutely all existing primitives. Currently, we have a
448 very sparse support for one-sided communications, and almost none for
449 I/O primitives. But our coverage is still very decent: we pass a very
450 large amount of the MPICH coverage tests.
451
452 The full list of not yet implemented functions is documented in the
453 file @ref include/smpi/smpi.h, between two lines containing the
454 <tt>FIXME</tt> marker. If you really need a missing feature, please
455 get in touch with us: we can guide you though the SimGrid code to help
456 you implementing it, and we'd glad to integrate it in the main project
457 afterward if you contribute them back.
458
459 @subsection SMPI_what_globals Global variables
460
461 Concerning the globals, the problem comes from the fact that usually,
462 MPI processes run as real UNIX processes while they are all folded
463 into threads of a unique system process in SMPI. Global variables are
464 usually private to each MPI process while they become shared between
465 the processes in SMPI. This point is rather problematic, and currently
466 forces to modify your application to privatize the global variables.
467
468 We tried several techniques to work this around. We used to have a
469 script that privatized automatically the globals through static
470 analysis of the source code, but it was not robust enough to be used
471 in production. This issue, as well as several potential solutions, is
472 discussed in this article: "Automatic Handling of Global Variables for
473 Multi-threaded MPI Programs",
474 available at http://charm.cs.illinois.edu/newPapers/11-23/paper.pdf
475 (note that this article does not deal with SMPI but with a concurrent
476 solution called AMPI that suffers of the same issue). 
477
478 SimGrid can duplicate and dynamically switch the .data and .bss
479 segments of the ELF process when switching the MPI ranks, allowing
480 each ranks to have its own copy of the global variables. This feature
481 is expected to work correctly on Linux and BSD, so smpirun activates
482 it by default. %As no copy is involved, performance should not be
483 altered (but memory occupation will be higher).
484
485 If you want to turn it off, pass \c -no-privatize to smpirun. This may
486 be necessary if your application uses dynamic libraries as the global
487 variables of these libraries will not be privatized. You can fix this
488 by linking statically with these libraries (but NOT with libsimgrid,
489 as we need SimGrid's own global variables).
490
491 @section SMPI_adapting Adapting your MPI code for further scalability
492
493 As detailed in the reference article (available at
494 http://hal.inria.fr/inria-00527150), you may want to adapt your code
495 to improve the simulation performance. But these tricks may seriously
496 hinder the result quality (or even prevent the app to run) if used
497 wrongly. We assume that if you want to simulate an HPC application,
498 you know what you are doing. Don't prove us wrong!
499
500 @subsection SMPI_adapting_size Reducing your memory footprint
501
502 If you get short on memory (the whole app is executed on a single node when
503 simulated), you should have a look at the SMPI_SHARED_MALLOC and
504 SMPI_SHARED_FREE macros. It allows to share memory areas between processes: The
505 purpose of these macro is that the same line malloc on each process will point
506 to the exact same memory area. So if you have a malloc of 2M and you have 16
507 processes, this macro will change your memory consumption from 2M*16 to 2M
508 only. Only one block for all processes.
509
510 If your program is ok with a block containing garbage value because all
511 processes write and read to the same place without any kind of coordination,
512 then this macro can dramatically shrink your memory consumption. For example,
513 that will be very beneficial to a matrix multiplication code, as all blocks will
514 be stored on the same area. Of course, the resulting computations will useless,
515 but you can still study the application behavior this way. 
516
517 Naturally, this won't work if your code is data-dependent. For example, a Jacobi
518 iterative computation depends on the result computed by the code to detect
519 convergence conditions, so turning them into garbage by sharing the same memory
520 area between processes does not seem very wise. You cannot use the
521 SMPI_SHARED_MALLOC macro in this case, sorry.
522
523 This feature is demoed by the example file
524 <tt>examples/smpi/NAS/DT-folding/dt.c</tt>
525
526 @subsection SMPI_adapting_speed Toward faster simulations
527
528 If your application is too slow, try using SMPI_SAMPLE_LOCAL,
529 SMPI_SAMPLE_GLOBAL and friends to indicate which computation loops can
530 be sampled. Some of the loop iterations will be executed to measure
531 their duration, and this duration will be used for the subsequent
532 iterations. These samples are done per processor with
533 SMPI_SAMPLE_LOCAL, and shared between all processors with
534 SMPI_SAMPLE_GLOBAL. Of course, none of this will work if the execution
535 time of your loop iteration are not stable.
536
537 This feature is demoed by the example file 
538 <tt>examples/smpi/NAS/EP-sampling/ep.c</tt>
539
540 @section SMPI_accuracy Ensuring accurate simulations
541
542 TBD
543
544 */
545
546
547 /** @example include/smpi/smpi.h */