1 // Copyright (C) 2005-2006 Douglas Gregor <doug.gregor@gmail.com>
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)
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 <boost/core/uncaught_exceptions.hpp>
18 namespace boost { namespace mpi {
20 std::istream& operator>>(std::istream& in, level& l)
27 } else if (tk == "funneled") {
29 } else if (tk == "serialized") {
31 } else if (tk == "multiple") {
34 in.setstate(std::ios::badbit);
40 std::ostream& operator<<(std::ostream& out, level l)
56 out << "<level error>[" << int(l) << ']';
57 out.setstate(std::ios::badbit);
63 } // namespace threading
65 #ifdef BOOST_MPI_HAS_NOARG_INITIALIZATION
66 environment::environment(bool abrt)
67 : i_initialized(false),
68 abort_on_exception(abrt)
71 BOOST_MPI_CHECK_RESULT(MPI_Init, (0, 0));
75 #if (2 <= MPI_VERSION)
76 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
78 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
82 environment::environment(threading::level mt_level, bool abrt)
83 : i_initialized(false),
84 abort_on_exception(abrt)
86 // It is not clear that we can pass null in MPI_Init_thread.
87 int dummy_thread_level = 0;
89 BOOST_MPI_CHECK_RESULT(MPI_Init_thread,
90 (0, 0, int(mt_level), &dummy_thread_level ));
94 #if (2 <= MPI_VERSION)
95 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
97 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
102 environment::environment(int& argc, char** &argv, bool abrt)
103 : i_initialized(false),
104 abort_on_exception(abrt)
106 if (!initialized()) {
107 BOOST_MPI_CHECK_RESULT(MPI_Init, (&argc, &argv));
108 i_initialized = true;
111 #if (2 <= MPI_VERSION)
112 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
114 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
118 environment::environment(int& argc, char** &argv, threading::level mt_level,
120 : i_initialized(false),
121 abort_on_exception(abrt)
123 // It is not clear that we can pass null in MPI_Init_thread.
124 int dummy_thread_level = 0;
125 if (!initialized()) {
126 BOOST_MPI_CHECK_RESULT(MPI_Init_thread,
127 (&argc, &argv, int(mt_level), &dummy_thread_level));
128 i_initialized = true;
131 #if (2 <= MPI_VERSION)
132 MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
134 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
138 environment::~environment()
141 if (boost::core::uncaught_exceptions() > 0 && abort_on_exception) {
143 } else if (!finalized()) {
144 detail::mpi_datatype_cache().clear();
145 BOOST_MPI_CHECK_RESULT(MPI_Finalize, ());
150 void environment::abort(int errcode)
152 BOOST_MPI_CHECK_RESULT(MPI_Abort, (MPI_COMM_WORLD, errcode));
155 bool environment::initialized()
158 BOOST_MPI_CHECK_RESULT(MPI_Initialized, (&flag));
162 bool environment::finalized()
165 BOOST_MPI_CHECK_RESULT(MPI_Finalized, (&flag));
169 int environment::max_tag()
174 #if (2 <= MPI_VERSION)
175 BOOST_MPI_CHECK_RESULT(MPI_Comm_get_attr,
176 (MPI_COMM_WORLD, MPI_TAG_UB, &max_tag_value, &found));
178 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
179 (MPI_COMM_WORLD, MPI_TAG_UB, &max_tag_value, &found));
182 return *max_tag_value - num_reserved_tags;
185 int environment::collectives_tag()
187 return max_tag() + 1;
190 optional<int> environment::host_rank()
195 #if (2 <= MPI_VERSION)
196 BOOST_MPI_CHECK_RESULT(MPI_Comm_get_attr,
197 (MPI_COMM_WORLD, MPI_HOST, &host, &found));
199 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
200 (MPI_COMM_WORLD, MPI_HOST, &host, &found));
202 if (!found || *host == MPI_PROC_NULL)
203 return optional<int>();
208 optional<int> environment::io_rank()
213 #if (2 <= MPI_VERSION)
214 BOOST_MPI_CHECK_RESULT(MPI_Comm_get_attr,
215 (MPI_COMM_WORLD, MPI_IO, &io, &found));
217 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
218 (MPI_COMM_WORLD, MPI_IO, &io, &found));
220 if (!found || *io == MPI_PROC_NULL)
221 return optional<int>();
226 std::string environment::processor_name()
228 char name[MPI_MAX_PROCESSOR_NAME];
231 BOOST_MPI_CHECK_RESULT(MPI_Get_processor_name, (name, &len));
232 return std::string(name, len);
235 threading::level environment::thread_level()
239 BOOST_MPI_CHECK_RESULT(MPI_Query_thread, (&level));
240 return static_cast<threading::level>(level);
243 bool environment::is_main_thread()
247 BOOST_MPI_CHECK_RESULT(MPI_Is_thread_main, (&isit));
248 return static_cast<bool>(isit);
251 std::pair<int, int> environment::version()
254 BOOST_MPI_CHECK_RESULT(MPI_Get_version, (&major, &minor));
255 return std::make_pair(major, minor);
258 } } // end namespace boost::mpi