1 // Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com> 2 3 // Use, modification and distribution is subject to the Boost Software 4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 /** @file environment.hpp 8 * 9 * This header provides the @c environment class, which provides 10 * routines to initialize, finalization, and query the status of the 11 * Boost MPI environment. 12 */ 13 #ifndef BOOST_MPI_ENVIRONMENT_HPP 14 #define BOOST_MPI_ENVIRONMENT_HPP 15 16 #include <boost/mpi/config.hpp> 17 #include <boost/noncopyable.hpp> 18 #include <boost/optional.hpp> 19 #include <string> 20 #include <iosfwd> 21 22 namespace boost { namespace mpi { 23 namespace threading { 24 /** @brief specify the supported threading level. 25 * 26 * Based on MPI 2 standard/8.7.3 27 */ 28 enum level { 29 /** Only one thread will execute. 30 */ 31 single = MPI_THREAD_SINGLE, 32 /** Only main thread will do MPI calls. 33 * 34 * The process may be multi-threaded, but only the main 35 * thread will make MPI calls (all MPI calls are ``funneled'' 36 * to the main thread). 37 */ 38 funneled = MPI_THREAD_FUNNELED, 39 /** Only one thread at the time do MPI calls. 40 * 41 * The process may be multi-threaded, and multiple 42 * threads may make MPI calls, but only one at a time: 43 * MPI calls are not made concurrently from two distinct 44 * threads (all MPI calls are ``serialized''). 45 */ 46 serialized = MPI_THREAD_SERIALIZED, 47 /** Multiple thread may do MPI calls. 48 * 49 * Multiple threads may call MPI, with no restrictions. 50 */ 51 multiple = MPI_THREAD_MULTIPLE 52 }; 53 54 /** Formated output for threading level. */ 55 std::ostream& operator<<(std::ostream& out, level l); 56 57 /** Formated input for threading level. */ 58 std::istream& operator>>(std::istream& in, level& l); 59 } // namespace threading 60 /** @brief Initialize, finalize, and query the MPI environment. 61 * 62 * The @c environment class is used to initialize, finalize, and 63 * query the MPI environment. It will typically be used in the @c 64 * main() function of a program, which will create a single instance 65 * of @c environment initialized with the arguments passed to the 66 * program: 67 * 68 * @code 69 * int main(int argc, char* argv[]) 70 * { 71 * mpi::environment env(argc, argv); 72 * } 73 * @endcode 74 * 75 * The instance of @c environment will initialize MPI (by calling @c 76 * MPI_Init) in its constructor and finalize MPI (by calling @c 77 * MPI_Finalize for normal termination or @c MPI_Abort for an 78 * uncaught exception) in its destructor. 79 * 80 * The use of @c environment is not mandatory. Users may choose to 81 * invoke @c MPI_Init and @c MPI_Finalize manually. In this case, no 82 * @c environment object is needed. If one is created, however, it 83 * will do nothing on either construction or destruction. 84 */ 85 class BOOST_MPI_DECL environment : noncopyable { 86 public: 87 #ifdef BOOST_MPI_HAS_NOARG_INITIALIZATION 88 /** Initialize the MPI environment. 89 * 90 * If the MPI environment has not already been initialized, 91 * initializes MPI with a call to @c MPI_Init. Since this 92 * constructor does not take command-line arguments (@c argc and @c 93 * argv), it is only available when the underlying MPI 94 * implementation supports calling @c MPI_Init with @c NULL 95 * arguments, indicated by the macro @c 96 * BOOST_MPI_HAS_NOARG_INITIALIZATION. 97 * 98 * @param abort_on_exception When true, this object will abort the 99 * program if it is destructed due to an uncaught exception. 100 */ 101 explicit environment(bool abort_on_exception = true); 102 /** Initialize the MPI environment. 103 * 104 * If the MPI environment has not already been initialized, 105 * initializes MPI with a call to @c MPI_Init_thread. Since this 106 * constructor does not take command-line arguments (@c argc and @c 107 * argv), it is only available when the underlying MPI 108 * implementation supports calling @c MPI_Init with @c NULL 109 * arguments, indicated by the macro @c 110 * BOOST_MPI_HAS_NOARG_INITIALIZATION. 111 * 112 * @param mt_level the required level of threading support. 113 * 114 * @param abort_on_exception When true, this object will abort the 115 * program if it is destructed due to an uncaught exception. 116 */ 117 explicit environment(threading::level mt_level, bool abort_on_exception = true); 118 #endif 119 120 /** Initialize the MPI environment. 121 * 122 * If the MPI environment has not already been initialized, 123 * initializes MPI with a call to @c MPI_Init. 124 * 125 * @param argc The number of arguments provided in @p argv, as 126 * passed into the program's @c main function. 127 * 128 * @param argv The array of argument strings passed to the program 129 * via @c main. 130 * 131 * @param abort_on_exception When true, this object will abort the 132 * program if it is destructed due to an uncaught exception. 133 */ 134 environment(int& argc, char** &argv, bool abort_on_exception = true); 135 136 /** Initialize the MPI environment. 137 * 138 * If the MPI environment has not already been initialized, 139 * initializes MPI with a call to @c MPI_Init_thread. 140 * 141 * @param argc The number of arguments provided in @p argv, as 142 * passed into the program's @c main function. 143 * 144 * @param argv The array of argument strings passed to the program 145 * via @c main. 146 * 147 * @param mt_level the required level of threading support 148 * 149 * @param abort_on_exception When true, this object will abort the 150 * program if it is destructed due to an uncaught exception. 151 */ 152 environment(int& argc, char** &argv, threading::level mt_level, 153 bool abort_on_exception = true); 154 155 /** Shuts down the MPI environment. 156 * 157 * If this @c environment object was used to initialize the MPI 158 * environment, and the MPI environment has not already been shut 159 * down (finalized), this destructor will shut down the MPI 160 * environment. Under normal circumstances, this only involves 161 * invoking @c MPI_Finalize. However, if destruction is the result 162 * of an uncaught exception and the @c abort_on_exception parameter 163 * of the constructor had the value @c true, this destructor will 164 * invoke @c MPI_Abort with @c MPI_COMM_WORLD to abort the entire 165 * MPI program with a result code of -1. 166 */ 167 ~environment(); 168 169 /** Abort all MPI processes. 170 * 171 * Aborts all MPI processes and returns to the environment. The 172 * precise behavior will be defined by the underlying MPI 173 * implementation. This is equivalent to a call to @c MPI_Abort 174 * with @c MPI_COMM_WORLD. 175 * 176 * @param errcode The error code to return to the environment. 177 * @returns Will not return. 178 */ 179 static void abort(int errcode); 180 181 /** Determine if the MPI environment has already been initialized. 182 * 183 * This routine is equivalent to a call to @c MPI_Initialized. 184 * 185 * @returns @c true if the MPI environment has been initialized. 186 */ 187 static bool initialized(); 188 189 /** Determine if the MPI environment has already been finalized. 190 * 191 * The routine is equivalent to a call to @c MPI_Finalized. 192 * 193 * @returns @c true if the MPI environment has been finalized. 194 */ 195 static bool finalized(); 196 197 /** Retrieves the maximum tag value. 198 * 199 * Returns the maximum value that may be used for the @c tag 200 * parameter of send/receive operations. This value will be 201 * somewhat smaller than the value of @c MPI_TAG_UB, because the 202 * Boost.MPI implementation reserves some tags for collective 203 * operations. 204 * 205 * @returns the maximum tag value. 206 */ 207 static int max_tag(); 208 209 /** The tag value used for collective operations. 210 * 211 * Returns the reserved tag value used by the Boost.MPI 212 * implementation for collective operations. Although users are not 213 * permitted to use this tag to send or receive messages, it may be 214 * useful when monitoring communication patterns. 215 * 216 * @returns the tag value used for collective operations. 217 */ 218 static int collectives_tag(); 219 220 /** Retrieves the rank of the host process, if one exists. 221 * 222 * If there is a host process, this routine returns the rank of 223 * that process. Otherwise, it returns an empty @c 224 * optional<int>. MPI does not define the meaning of a "host" 225 * process: consult the documentation for the MPI 226 * implementation. This routine examines the @c MPI_HOST attribute 227 * of @c MPI_COMM_WORLD. 228 * 229 * @returns The rank of the host process, if one exists. 230 */ 231 static optional<int> host_rank(); 232 233 /** Retrieves the rank of a process that can perform input/output. 234 * 235 * This routine returns the rank of a process that can perform 236 * input/output via the standard C and C++ I/O facilities. If every 237 * process can perform I/O using the standard facilities, this 238 * routine will return @c any_source; if no process can perform 239 * I/O, this routine will return no value (an empty @c 240 * optional). This routine examines the @c MPI_IO attribute of @c 241 * MPI_COMM_WORLD. 242 * 243 * @returns the rank of the process that can perform I/O, @c 244 * any_source if every process can perform I/O, or no value if no 245 * process can perform I/O. 246 */ 247 static optional<int> io_rank(); 248 249 /** Retrieve the name of this processor. 250 * 251 * This routine returns the name of this processor. The actual form 252 * of the name is unspecified, but may be documented by the 253 * underlying MPI implementation. This routine is implemented as a 254 * call to @c MPI_Get_processor_name. 255 * 256 * @returns the name of this processor. 257 */ 258 static std::string processor_name(); 259 260 /** Query the current level of thread support. 261 */ 262 static threading::level thread_level(); 263 264 /** Are we in the main thread? 265 */ 266 static bool is_main_thread(); 267 268 /** @brief MPI version. 269 * 270 * Returns a pair with the version and sub-version number. 271 */ 272 static std::pair<int, int> version(); 273 274 private: 275 /// Whether this environment object called MPI_Init 276 bool i_initialized; 277 278 /// Whether we should abort if the destructor is 279 bool abort_on_exception; 280 281 /// The number of reserved tags. 282 static const int num_reserved_tags = 1; 283 }; 284 285 } } // end namespace boost::mpi 286 287 #endif // BOOST_MPI_ENVIRONMENT_HPP 288