Chris@16: // Copyright (C) 2006 Douglas Gregor Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software Chris@16: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: /** @file environment.hpp Chris@16: * Chris@16: * This header provides the @c environment class, which provides Chris@16: * routines to initialize, finalization, and query the status of the Chris@16: * Boost MPI environment. Chris@16: */ Chris@16: #ifndef BOOST_MPI_ENVIRONMENT_HPP Chris@16: #define BOOST_MPI_ENVIRONMENT_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace mpi { Chris@16: namespace threading { Chris@16: /** @brief specify the supported threading level. Chris@16: * Chris@16: * Based on MPI 2 standard/8.7.3 Chris@16: */ Chris@16: enum level { Chris@16: /** Only one thread will execute. Chris@16: */ Chris@16: single = MPI_THREAD_SINGLE, Chris@16: /** Only main thread will do MPI calls. Chris@16: * Chris@16: * The process may be multi-threaded, but only the main Chris@16: * thread will make MPI calls (all MPI calls are ``funneled'' Chris@16: * to the main thread). Chris@16: */ Chris@16: funneled = MPI_THREAD_FUNNELED, Chris@16: /** Only one thread at the time do MPI calls. Chris@16: * Chris@16: * The process may be multi-threaded, and multiple Chris@16: * threads may make MPI calls, but only one at a time: Chris@16: * MPI calls are not made concurrently from two distinct Chris@16: * threads (all MPI calls are ``serialized''). Chris@16: */ Chris@16: serialized = MPI_THREAD_SERIALIZED, Chris@16: /** Multiple thread may do MPI calls. Chris@16: * Chris@16: * Multiple threads may call MPI, with no restrictions. Chris@16: */ Chris@16: multiple = MPI_THREAD_MULTIPLE Chris@16: }; Chris@16: Chris@16: /** Formated output for threading level. */ Chris@16: std::ostream& operator<<(std::ostream& out, level l); Chris@16: Chris@16: /** Formated input for threading level. */ Chris@16: std::istream& operator>>(std::istream& in, level& l); Chris@16: } // namespace threading Chris@16: /** @brief Initialize, finalize, and query the MPI environment. Chris@16: * Chris@16: * The @c environment class is used to initialize, finalize, and Chris@16: * query the MPI environment. It will typically be used in the @c Chris@16: * main() function of a program, which will create a single instance Chris@16: * of @c environment initialized with the arguments passed to the Chris@16: * program: Chris@16: * Chris@16: * @code Chris@16: * int main(int argc, char* argv[]) Chris@16: * { Chris@16: * mpi::environment env(argc, argv); Chris@16: * } Chris@16: * @endcode Chris@16: * Chris@16: * The instance of @c environment will initialize MPI (by calling @c Chris@16: * MPI_Init) in its constructor and finalize MPI (by calling @c Chris@16: * MPI_Finalize for normal termination or @c MPI_Abort for an Chris@16: * uncaught exception) in its destructor. Chris@16: * Chris@16: * The use of @c environment is not mandatory. Users may choose to Chris@16: * invoke @c MPI_Init and @c MPI_Finalize manually. In this case, no Chris@16: * @c environment object is needed. If one is created, however, it Chris@16: * will do nothing on either construction or destruction. Chris@16: */ Chris@16: class BOOST_MPI_DECL environment : noncopyable { Chris@16: public: Chris@16: #ifdef BOOST_MPI_HAS_NOARG_INITIALIZATION Chris@16: /** Initialize the MPI environment. Chris@16: * Chris@16: * If the MPI environment has not already been initialized, Chris@16: * initializes MPI with a call to @c MPI_Init. Since this Chris@16: * constructor does not take command-line arguments (@c argc and @c Chris@16: * argv), it is only available when the underlying MPI Chris@16: * implementation supports calling @c MPI_Init with @c NULL Chris@16: * arguments, indicated by the macro @c Chris@16: * BOOST_MPI_HAS_NOARG_INITIALIZATION. Chris@16: * Chris@16: * @param abort_on_exception When true, this object will abort the Chris@16: * program if it is destructed due to an uncaught exception. Chris@16: */ Chris@16: explicit environment(bool abort_on_exception = true); Chris@16: /** Initialize the MPI environment. Chris@16: * Chris@16: * If the MPI environment has not already been initialized, Chris@16: * initializes MPI with a call to @c MPI_Init_thread. Since this Chris@16: * constructor does not take command-line arguments (@c argc and @c Chris@16: * argv), it is only available when the underlying MPI Chris@16: * implementation supports calling @c MPI_Init with @c NULL Chris@16: * arguments, indicated by the macro @c Chris@16: * BOOST_MPI_HAS_NOARG_INITIALIZATION. Chris@16: * Chris@16: * @param mt_level the required level of threading support. Chris@16: * Chris@16: * @param abort_on_exception When true, this object will abort the Chris@16: * program if it is destructed due to an uncaught exception. Chris@16: */ Chris@16: explicit environment(threading::level mt_level, bool abort_on_exception = true); Chris@16: #endif Chris@16: Chris@16: /** Initialize the MPI environment. Chris@16: * Chris@16: * If the MPI environment has not already been initialized, Chris@16: * initializes MPI with a call to @c MPI_Init. Chris@16: * Chris@16: * @param argc The number of arguments provided in @p argv, as Chris@16: * passed into the program's @c main function. Chris@16: * Chris@16: * @param argv The array of argument strings passed to the program Chris@16: * via @c main. Chris@16: * Chris@16: * @param abort_on_exception When true, this object will abort the Chris@16: * program if it is destructed due to an uncaught exception. Chris@16: */ Chris@16: environment(int& argc, char** &argv, bool abort_on_exception = true); Chris@16: Chris@16: /** Initialize the MPI environment. Chris@16: * Chris@16: * If the MPI environment has not already been initialized, Chris@16: * initializes MPI with a call to @c MPI_Init_thread. Chris@16: * Chris@16: * @param argc The number of arguments provided in @p argv, as Chris@16: * passed into the program's @c main function. Chris@16: * Chris@16: * @param argv The array of argument strings passed to the program Chris@16: * via @c main. Chris@16: * Chris@16: * @param mt_level the required level of threading support Chris@16: * Chris@16: * @param abort_on_exception When true, this object will abort the Chris@16: * program if it is destructed due to an uncaught exception. Chris@16: */ Chris@16: environment(int& argc, char** &argv, threading::level mt_level, Chris@16: bool abort_on_exception = true); Chris@16: Chris@16: /** Shuts down the MPI environment. Chris@16: * Chris@16: * If this @c environment object was used to initialize the MPI Chris@16: * environment, and the MPI environment has not already been shut Chris@16: * down (finalized), this destructor will shut down the MPI Chris@16: * environment. Under normal circumstances, this only involves Chris@16: * invoking @c MPI_Finalize. However, if destruction is the result Chris@16: * of an uncaught exception and the @c abort_on_exception parameter Chris@16: * of the constructor had the value @c true, this destructor will Chris@16: * invoke @c MPI_Abort with @c MPI_COMM_WORLD to abort the entire Chris@16: * MPI program with a result code of -1. Chris@16: */ Chris@16: ~environment(); Chris@16: Chris@16: /** Abort all MPI processes. Chris@16: * Chris@16: * Aborts all MPI processes and returns to the environment. The Chris@16: * precise behavior will be defined by the underlying MPI Chris@16: * implementation. This is equivalent to a call to @c MPI_Abort Chris@16: * with @c MPI_COMM_WORLD. Chris@16: * Chris@16: * @param errcode The error code to return to the environment. Chris@16: * @returns Will not return. Chris@16: */ Chris@16: static void abort(int errcode); Chris@16: Chris@16: /** Determine if the MPI environment has already been initialized. Chris@16: * Chris@16: * This routine is equivalent to a call to @c MPI_Initialized. Chris@16: * Chris@16: * @returns @c true if the MPI environment has been initialized. Chris@16: */ Chris@16: static bool initialized(); Chris@16: Chris@16: /** Determine if the MPI environment has already been finalized. Chris@16: * Chris@16: * The routine is equivalent to a call to @c MPI_Finalized. Chris@16: * Chris@16: * @returns @c true if the MPI environment has been finalized. Chris@16: */ Chris@16: static bool finalized(); Chris@16: Chris@16: /** Retrieves the maximum tag value. Chris@16: * Chris@16: * Returns the maximum value that may be used for the @c tag Chris@16: * parameter of send/receive operations. This value will be Chris@16: * somewhat smaller than the value of @c MPI_TAG_UB, because the Chris@16: * Boost.MPI implementation reserves some tags for collective Chris@16: * operations. Chris@16: * Chris@16: * @returns the maximum tag value. Chris@16: */ Chris@16: static int max_tag(); Chris@16: Chris@16: /** The tag value used for collective operations. Chris@16: * Chris@16: * Returns the reserved tag value used by the Boost.MPI Chris@16: * implementation for collective operations. Although users are not Chris@16: * permitted to use this tag to send or receive messages, it may be Chris@16: * useful when monitoring communication patterns. Chris@16: * Chris@16: * @returns the tag value used for collective operations. Chris@16: */ Chris@16: static int collectives_tag(); Chris@16: Chris@16: /** Retrieves the rank of the host process, if one exists. Chris@16: * Chris@16: * If there is a host process, this routine returns the rank of Chris@16: * that process. Otherwise, it returns an empty @c Chris@16: * optional. MPI does not define the meaning of a "host" Chris@16: * process: consult the documentation for the MPI Chris@16: * implementation. This routine examines the @c MPI_HOST attribute Chris@16: * of @c MPI_COMM_WORLD. Chris@16: * Chris@16: * @returns The rank of the host process, if one exists. Chris@16: */ Chris@16: static optional host_rank(); Chris@16: Chris@16: /** Retrieves the rank of a process that can perform input/output. Chris@16: * Chris@16: * This routine returns the rank of a process that can perform Chris@16: * input/output via the standard C and C++ I/O facilities. If every Chris@16: * process can perform I/O using the standard facilities, this Chris@16: * routine will return @c any_source; if no process can perform Chris@16: * I/O, this routine will return no value (an empty @c Chris@16: * optional). This routine examines the @c MPI_IO attribute of @c Chris@16: * MPI_COMM_WORLD. Chris@16: * Chris@16: * @returns the rank of the process that can perform I/O, @c Chris@16: * any_source if every process can perform I/O, or no value if no Chris@16: * process can perform I/O. Chris@16: */ Chris@16: static optional io_rank(); Chris@16: Chris@16: /** Retrieve the name of this processor. Chris@16: * Chris@16: * This routine returns the name of this processor. The actual form Chris@16: * of the name is unspecified, but may be documented by the Chris@16: * underlying MPI implementation. This routine is implemented as a Chris@16: * call to @c MPI_Get_processor_name. Chris@16: * Chris@16: * @returns the name of this processor. Chris@16: */ Chris@16: static std::string processor_name(); Chris@16: Chris@16: /** Query the current level of thread support. Chris@16: */ Chris@16: static threading::level thread_level(); Chris@16: Chris@16: /** Are we in the main thread? Chris@16: */ Chris@16: static bool is_main_thread(); Chris@16: Chris@16: private: Chris@16: /// Whether this environment object called MPI_Init Chris@16: bool i_initialized; Chris@16: Chris@16: /// Whether we should abort if the destructor is Chris@16: bool abort_on_exception; Chris@16: Chris@16: /// The number of reserved tags. Chris@16: static const int num_reserved_tags = 1; Chris@16: }; Chris@16: Chris@16: } } // end namespace boost::mpi Chris@16: Chris@16: #endif // BOOST_MPI_ENVIRONMENT_HPP