123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- [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 be 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 <boost/mpi/environment.hpp>
- #include <boost/mpi/communicator.hpp>
- #include <iostream>
- 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 <boost/mpi/environment.hpp>
- #include <boost/mpi/communicator.hpp>
- #include <iostream>
- 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<gps_position> : 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]
|