1[section:tutorial Tutorial] 2 3A Boost.MPI program consists of many cooperating processes (possibly 4running on different computers) that communicate among themselves by 5passing messages. Boost.MPI is a library (as is the lower-level MPI), 6not a language, so the first step in a Boost.MPI is to create an 7[classref boost::mpi::environment mpi::environment] object 8that initializes the MPI environment and enables communication among 9the processes. The [classref boost::mpi::environment 10mpi::environment] object is initialized with the program arguments 11(which it may modify) in your main program. The creation of this 12object initializes MPI, and its destruction will finalize MPI. In the 13vast majority of Boost.MPI programs, an instance of [classref 14boost::mpi::environment mpi::environment] will be declared 15in `main` at the very beginning of the program. 16[warning 17Declaring 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 21Communication with MPI always occurs over a *communicator*, 22which can be created by simply default-constructing an object of type 23[classref boost::mpi::communicator mpi::communicator]. This 24communicator can then be queried to determine how many processes are 25running (the "size" of the communicator) and to give a unique number 26to 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 43If you run this program with 7 processes, for instance, you will 44receive output such as: 45 46[pre 47I am process 5 of 7. 48I am process 0 of 7. 49I am process 1 of 7. 50I am process 6 of 7. 51I am process 2 of 7. 52I am process 4 of 7. 53I am process 3 of 7. 54] 55 56Of course, the processes can execute in a different order each time, 57so the ranks might not be strictly increasing. More interestingly, the 58text could come out completely garbled, because one process can start 59writing "I am a process" before another process has finished writing 60"of 7.". 61 62If you should still have an MPI library supporting only MPI 1.1 you 63will need to pass the command line arguments to the environment 64constructor 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 90To obtain optimal performance for small fixed-length data types not containing 91any pointers it is very important to mark them using the type traits of 92Boost.MPI and Boost.Serialization. 93 94It was already discussed that fixed length types containing no pointers can be 95using as [classref 96boost::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 103or the equivalent macro 104 105 BOOST_IS_MPI_DATATYPE(gps_position) 106 107In addition it can give a substantial performance gain to turn off tracking 108and versioning for these types, if no pointers to these types are used, by 109using 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 118More optimizations are possible on homogeneous machines, by avoiding 119MPI_Pack/MPI_Unpack calls but using direct bitwise copy. This feature is 120enabled by default by defining the macro [macroref BOOST_MPI_HOMOGENEOUS] in the include 121file `boost/mpi/config.hpp`. 122That definition must be consistent when building Boost.MPI and 123when building the application. 124 125In addition all classes need to be marked both as is_mpi_datatype and 126as is_bitwise_serializable, by using the helper macro of Boost.Serialization: 127 128 BOOST_IS_BITWISE_SERIALIZABLE(gps_position) 129 130Usually it is safe to serialize a class for which is_mpi_datatype is true 131by using binary copy of the bits. The exception are classes for which 132some members should be skipped for serialization. 133 134[endsect:homogeneous_machines] 135[endsect:performance_optimizations] 136[endsect:tutorial] 137