[section:tutorial Tutorial] A Boost.MPI program consists of many cooperating processes (possibly running on different computers) that communicate among themselves by passing messages. Boost.MPI is a library (as is the lower-level MPI), not a language, so the first step in a Boost.MPI is to create an [classref boost::mpi::environment mpi::environment] object that initializes the MPI environment and enables communication among the processes. The [classref boost::mpi::environment mpi::environment] object is initialized with the program arguments (which it may modify) in your main program. The creation of this object initializes MPI, and its destruction will finalize MPI. In the vast majority of Boost.MPI programs, an instance of [classref boost::mpi::environment mpi::environment] will be declared in `main` at the very beginning of the program. [warning Declaring an [classref boost::mpi::environment mpi::environment] at global scope is undefined behavior. [footnote According to the MPI standard, initialization must take place at user's initiative after once the main function has been called.] ] Communication with MPI always occurs over a *communicator*, which can be created by simply default-constructing an object of type [classref boost::mpi::communicator mpi::communicator]. This communicator can then be queried to determine how many processes are running (the "size" of the communicator) and to give a unique number to each process, from zero to the size of the communicator (i.e., the "rank" of the process): #include #include #include namespace mpi = boost::mpi; int main() { mpi::environment env; mpi::communicator world; std::cout << "I am process " << world.rank() << " of " << world.size() << "." << std::endl; return 0; } If you run this program with 7 processes, for instance, you will receive output such as: [pre I am process 5 of 7. I am process 0 of 7. I am process 1 of 7. I am process 6 of 7. I am process 2 of 7. I am process 4 of 7. I am process 3 of 7. ] Of course, the processes can execute in a different order each time, so the ranks might not be strictly increasing. More interestingly, the text could come out completely garbled, because one process can start writing "I am a process" before another process has finished writing "of 7.". If you should still have an MPI library supporting only MPI 1.1 you will need to pass the command line arguments to the environment constructor as shown in this example: #include #include #include namespace mpi = boost::mpi; int main(int argc, char* argv[]) { mpi::environment env(argc, argv); mpi::communicator world; std::cout << "I am process " << world.rank() << " of " << world.size() << "." << std::endl; return 0; } [include point_to_point.qbk] [include collective.qbk] [include user_data_types.qbk] [include communicator.qbk] [include threading.qbk] [include skeleton_and_content.qbk] [section:performance_optimizations Performance optimizations] [section:serialization_optimizations Serialization optimizations] To obtain optimal performance for small fixed-length data types not containing any pointers it is very important to mark them using the type traits of Boost.MPI and Boost.Serialization. It was already discussed that fixed length types containing no pointers can be using as [classref boost::mpi::is_mpi_datatype `is_mpi_datatype`], e.g.: namespace boost { namespace mpi { template <> struct is_mpi_datatype : mpl::true_ { }; } } or the equivalent macro BOOST_IS_MPI_DATATYPE(gps_position) In addition it can give a substantial performance gain to turn off tracking and versioning for these types, if no pointers to these types are used, by using the traits classes or helper macros of Boost.Serialization: BOOST_CLASS_TRACKING(gps_position,track_never) BOOST_CLASS_IMPLEMENTATION(gps_position,object_serializable) [endsect:serialization_optimizations] [section:homogeneous_machines Homogeneous Machines] More optimizations are possible on homogeneous machines, by avoiding MPI_Pack/MPI_Unpack calls but using direct bitwise copy. This feature is enabled by default by defining the macro [macroref BOOST_MPI_HOMOGENEOUS] in the include file `boost/mpi/config.hpp`. That definition must be consistent when building Boost.MPI and when building the application. In addition all classes need to be marked both as is_mpi_datatype and as is_bitwise_serializable, by using the helper macro of Boost.Serialization: BOOST_IS_BITWISE_SERIALIZABLE(gps_position) Usually it is safe to serialize a class for which is_mpi_datatype is true by using binary copy of the bits. The exception are classes for which some members should be skipped for serialization. [endsect:homogeneous_machines] [endsect:performance_optimizations] [endsect:tutorial]