• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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