]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/mpi/src/environment.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / mpi / src / environment.cpp
1 // Copyright (C) 2005-2006 Douglas Gregor <doug.gregor@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 // Message Passing Interface 1.1 -- 7.1.1. Environmental Inquiries
8 #include <boost/mpi/environment.hpp>
9 #include <boost/mpi/exception.hpp>
10 #include <boost/mpi/detail/mpi_datatype_cache.hpp>
11 #include <cassert>
12 #include <string>
13 #include <exception>
14 #include <stdexcept>
15 #include <ostream>
16
17 namespace boost { namespace mpi {
18 namespace threading {
19 std::istream& operator>>(std::istream& in, level& l)
20 {
21 std::string tk;
22 in >> tk;
23 if (!in.bad()) {
24 if (tk == "single") {
25 l = single;
26 } else if (tk == "funneled") {
27 l = funneled;
28 } else if (tk == "serialized") {
29 l = serialized;
30 } else if (tk == "multiple") {
31 l = multiple;
32 } else {
33 in.setstate(std::ios::badbit);
34 }
35 }
36 return in;
37 }
38
39 std::ostream& operator<<(std::ostream& out, level l)
40 {
41 switch(l) {
42 case single:
43 out << "single";
44 break;
45 case funneled:
46 out << "funneled";
47 break;
48 case serialized:
49 out << "serialized";
50 break;
51 case multiple:
52 out << "multiple";
53 break;
54 default:
55 out << "<level error>[" << int(l) << ']';
56 out.setstate(std::ios::badbit);
57 break;
58 }
59 return out;
60 }
61
62 } // namespace threading
63
64 #ifdef BOOST_MPI_HAS_NOARG_INITIALIZATION
65 environment::environment(bool abort_on_exception)
66 : i_initialized(false),
67 abort_on_exception(abort_on_exception)
68 {
69 if (!initialized()) {
70 BOOST_MPI_CHECK_RESULT(MPI_Init, (0, 0));
71 i_initialized = true;
72 }
73
74 #if (2 <= MPI_VERSION)
75 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
76 #else
77 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
78 #endif
79 }
80
81 environment::environment(threading::level mt_level, bool abort_on_exception)
82 : i_initialized(false),
83 abort_on_exception(abort_on_exception)
84 {
85 // It is not clear that we can pass null in MPI_Init_thread.
86 int dummy_thread_level = 0;
87 if (!initialized()) {
88 BOOST_MPI_CHECK_RESULT(MPI_Init_thread,
89 (0, 0, int(mt_level), &dummy_thread_level ));
90 i_initialized = true;
91 }
92
93 #if (2 <= MPI_VERSION)
94 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
95 #else
96 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
97 #endif
98 }
99 #endif
100
101 environment::environment(int& argc, char** &argv, bool abort_on_exception)
102 : i_initialized(false),
103 abort_on_exception(abort_on_exception)
104 {
105 if (!initialized()) {
106 BOOST_MPI_CHECK_RESULT(MPI_Init, (&argc, &argv));
107 i_initialized = true;
108 }
109
110 #if (2 <= MPI_VERSION)
111 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
112 #else
113 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
114 #endif
115 }
116
117 environment::environment(int& argc, char** &argv, threading::level mt_level,
118 bool abort_on_exception)
119 : i_initialized(false),
120 abort_on_exception(abort_on_exception)
121 {
122 // It is not clear that we can pass null in MPI_Init_thread.
123 int dummy_thread_level = 0;
124 if (!initialized()) {
125 BOOST_MPI_CHECK_RESULT(MPI_Init_thread,
126 (&argc, &argv, int(mt_level), &dummy_thread_level));
127 i_initialized = true;
128 }
129
130 #if (2 <= MPI_VERSION)
131 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
132 #else
133 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
134 #endif
135 }
136
137 environment::~environment()
138 {
139 if (i_initialized) {
140 if (std::uncaught_exception() && abort_on_exception) {
141 abort(-1);
142 } else if (!finalized()) {
143 detail::mpi_datatype_cache().clear();
144 BOOST_MPI_CHECK_RESULT(MPI_Finalize, ());
145 }
146 }
147 }
148
149 void environment::abort(int errcode)
150 {
151 BOOST_MPI_CHECK_RESULT(MPI_Abort, (MPI_COMM_WORLD, errcode));
152 }
153
154 bool environment::initialized()
155 {
156 int flag;
157 BOOST_MPI_CHECK_RESULT(MPI_Initialized, (&flag));
158 return flag != 0;
159 }
160
161 bool environment::finalized()
162 {
163 int flag;
164 BOOST_MPI_CHECK_RESULT(MPI_Finalized, (&flag));
165 return flag != 0;
166 }
167
168 int environment::max_tag()
169 {
170 int* max_tag_value;
171 int found = 0;
172
173 #if (2 <= MPI_VERSION)
174 BOOST_MPI_CHECK_RESULT(MPI_Comm_get_attr,
175 (MPI_COMM_WORLD, MPI_TAG_UB, &max_tag_value, &found));
176 #else
177 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
178 (MPI_COMM_WORLD, MPI_TAG_UB, &max_tag_value, &found));
179 #endif
180 assert(found != 0);
181 return *max_tag_value - num_reserved_tags;
182 }
183
184 int environment::collectives_tag()
185 {
186 return max_tag() + 1;
187 }
188
189 optional<int> environment::host_rank()
190 {
191 int* host;
192 int found = 0;
193
194 #if (2 <= MPI_VERSION)
195 BOOST_MPI_CHECK_RESULT(MPI_Comm_get_attr,
196 (MPI_COMM_WORLD, MPI_HOST, &host, &found));
197 #else
198 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
199 (MPI_COMM_WORLD, MPI_HOST, &host, &found));
200 #endif
201 if (!found || *host == MPI_PROC_NULL)
202 return optional<int>();
203 else
204 return *host;
205 }
206
207 optional<int> environment::io_rank()
208 {
209 int* io;
210 int found = 0;
211
212 #if (2 <= MPI_VERSION)
213 BOOST_MPI_CHECK_RESULT(MPI_Comm_get_attr,
214 (MPI_COMM_WORLD, MPI_IO, &io, &found));
215 #else
216 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
217 (MPI_COMM_WORLD, MPI_IO, &io, &found));
218 #endif
219 if (!found || *io == MPI_PROC_NULL)
220 return optional<int>();
221 else
222 return *io;
223 }
224
225 std::string environment::processor_name()
226 {
227 char name[MPI_MAX_PROCESSOR_NAME];
228 int len;
229
230 BOOST_MPI_CHECK_RESULT(MPI_Get_processor_name, (name, &len));
231 return std::string(name, len);
232 }
233
234 threading::level environment::thread_level()
235 {
236 int level;
237
238 BOOST_MPI_CHECK_RESULT(MPI_Query_thread, (&level));
239 return static_cast<threading::level>(level);
240 }
241
242 bool environment::is_main_thread()
243 {
244 int isit;
245
246 BOOST_MPI_CHECK_RESULT(MPI_Is_thread_main, (&isit));
247 return static_cast<bool>(isit);
248 }
249
250 } } // end namespace boost::mpi