environment.hpp 10 KB

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