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