Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / mpi / doc / tutorial.qbk
1 [section:tutorial Tutorial]
2
3 A Boost.MPI program consists of many cooperating processes (possibly
4 running on different computers) that communicate among themselves by
5 passing messages. Boost.MPI is a library (as is the lower-level MPI),
6 not a language, so the first step in a Boost.MPI is to create an
7 [classref boost::mpi::environment mpi::environment] object
8 that initializes the MPI environment and enables communication among
9 the processes. The [classref boost::mpi::environment
10 mpi::environment] object is initialized with the program arguments
11 (which it may modify) in your main program. The creation of this
12 object initializes MPI, and its destruction will finalize MPI. In the
13 vast majority of Boost.MPI programs, an instance of [classref
14 boost::mpi::environment mpi::environment] will be declared
15 in `main` at the very beginning of the program.
16 [warning
17 Declaring an [classref boost::mpi::environment mpi::environment] at global scope is undefined behavior.
18 [footnote According to the MPI standard, initialization must take place at user's initiative after once the main function has been called.]
19 ]
20
21 Communication with MPI always occurs over a *communicator*,
22 which can be created be simply default-constructing an object of type
23 [classref boost::mpi::communicator mpi::communicator]. This
24 communicator can then be queried to determine how many processes are
25 running (the "size" of the communicator) and to give a unique number
26 to each process, from zero to the size of the communicator (i.e., the
27 "rank" of the process):
28
29   #include <boost/mpi/environment.hpp>
30   #include <boost/mpi/communicator.hpp>
31   #include <iostream>
32   namespace mpi = boost::mpi;
33
34   int main() 
35   {
36     mpi::environment env;
37     mpi::communicator world;
38     std::cout << "I am process " << world.rank() << " of " << world.size()
39               << "." << std::endl;
40     return 0;
41   }
42
43 If you run this program with 7 processes, for instance, you will
44 receive output such as:
45
46 [pre
47 I am process 5 of 7.
48 I am process 0 of 7.
49 I am process 1 of 7.
50 I am process 6 of 7.
51 I am process 2 of 7.
52 I am process 4 of 7.
53 I am process 3 of 7.
54 ]
55
56 Of course, the processes can execute in a different order each time,
57 so the ranks might not be strictly increasing. More interestingly, the
58 text could come out completely garbled, because one process can start
59 writing "I am a process" before another process has finished writing
60 "of 7.".
61
62 If you should still have an MPI library supporting only MPI 1.1 you 
63 will need to pass the command line arguments to the environment
64 constructor as shown in this example:
65
66   #include <boost/mpi/environment.hpp>
67   #include <boost/mpi/communicator.hpp>
68   #include <iostream>
69   namespace mpi = boost::mpi;
70
71   int main(int argc, char* argv[]) 
72   {
73     mpi::environment env(argc, argv);
74     mpi::communicator world;
75     std::cout << "I am process " << world.rank() << " of " << world.size()
76               << "." << std::endl;
77     return 0;
78   }
79
80 [include point_to_point.qbk]
81 [include collective.qbk]
82 [include user_data_types.qbk]
83 [include communicator.qbk]
84 [include threading.qbk]
85 [include skeleton_and_content.qbk]
86
87 [section:performance_optimizations Performance optimizations]
88 [section:serialization_optimizations Serialization optimizations]
89
90 To obtain optimal performance for small fixed-length data types not containing
91 any pointers it is very important to mark them using the type traits of
92 Boost.MPI and Boost.Serialization. 
93
94 It was already discussed that fixed length types containing no pointers can be 
95 using as [classref
96 boost::mpi::is_mpi_datatype `is_mpi_datatype`], e.g.:
97
98   namespace boost { namespace mpi {
99     template <>
100     struct is_mpi_datatype<gps_position> : mpl::true_ { };
101   } }
102
103 or the equivalent macro 
104
105   BOOST_IS_MPI_DATATYPE(gps_position)
106   
107 In addition it can give a substantial performance gain to turn off tracking
108 and versioning for these types, if no pointers to these types are used, by
109 using the traits classes or helper macros of Boost.Serialization:
110
111   BOOST_CLASS_TRACKING(gps_position,track_never)
112   BOOST_CLASS_IMPLEMENTATION(gps_position,object_serializable)
113
114 [endsect:serialization_optimizations]
115   
116 [section:homogeneous_machines Homogeneous Machines]
117
118 More optimizations are possible on homogeneous machines, by avoiding
119 MPI_Pack/MPI_Unpack calls but using direct bitwise copy. This feature is 
120 enabled by default by defining the macro [macroref BOOST_MPI_HOMOGENEOUS] in the include 
121 file  `boost/mpi/config.hpp`.
122 That definition must be consistent when building Boost.MPI and
123 when building the application.
124
125 In addition all classes need to be marked both as is_mpi_datatype and
126 as is_bitwise_serializable, by using the helper macro of Boost.Serialization:
127
128   BOOST_IS_BITWISE_SERIALIZABLE(gps_position)
129
130 Usually it is safe to serialize a class for which is_mpi_datatype is true 
131 by using binary copy of the bits. The exception are classes for which
132 some members should be skipped for serialization.
133
134 [endsect:homogeneous_machines]
135 [endsect:performance_optimizations]
136 [endsect:tutorial]