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>
17 namespace boost { namespace mpi {
19 std::istream& operator>>(std::istream& in, level& l)
26 } else if (tk == "funneled") {
28 } else if (tk == "serialized") {
30 } else if (tk == "multiple") {
33 in.setstate(std::ios::badbit);
39 std::ostream& operator<<(std::ostream& out, level l)
55 out << "<level error>[" << int(l) << ']';
56 out.setstate(std::ios::badbit);
62 } // namespace threading
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)
70 BOOST_MPI_CHECK_RESULT(MPI_Init, (0, 0));
74 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
77 environment::environment(threading::level mt_level, bool abort_on_exception)
78 : i_initialized(false),
79 abort_on_exception(abort_on_exception)
81 // It is not clear that we can pass null in MPI_Init_thread.
82 int dummy_thread_level = 0;
84 BOOST_MPI_CHECK_RESULT(MPI_Init_thread,
85 (0, 0, int(mt_level), &dummy_thread_level ));
89 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
93 environment::environment(int& argc, char** &argv, bool abort_on_exception)
94 : i_initialized(false),
95 abort_on_exception(abort_on_exception)
98 BOOST_MPI_CHECK_RESULT(MPI_Init, (&argc, &argv));
102 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
105 environment::environment(int& argc, char** &argv, threading::level mt_level,
106 bool abort_on_exception)
107 : i_initialized(false),
108 abort_on_exception(abort_on_exception)
110 // It is not clear that we can pass null in MPI_Init_thread.
111 int dummy_thread_level = 0;
112 if (!initialized()) {
113 BOOST_MPI_CHECK_RESULT(MPI_Init_thread,
114 (&argc, &argv, int(mt_level), &dummy_thread_level));
115 i_initialized = true;
118 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
121 environment::~environment()
124 if (std::uncaught_exception() && abort_on_exception) {
126 } else if (!finalized()) {
127 detail::mpi_datatype_cache().clear();
128 BOOST_MPI_CHECK_RESULT(MPI_Finalize, ());
133 void environment::abort(int errcode)
135 BOOST_MPI_CHECK_RESULT(MPI_Abort, (MPI_COMM_WORLD, errcode));
138 bool environment::initialized()
141 BOOST_MPI_CHECK_RESULT(MPI_Initialized, (&flag));
145 bool environment::finalized()
148 BOOST_MPI_CHECK_RESULT(MPI_Finalized, (&flag));
152 int environment::max_tag()
157 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
158 (MPI_COMM_WORLD, MPI_TAG_UB, &max_tag_value, &found));
160 return *max_tag_value - num_reserved_tags;
163 int environment::collectives_tag()
165 return max_tag() + 1;
168 optional<int> environment::host_rank()
173 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
174 (MPI_COMM_WORLD, MPI_HOST, &host, &found));
175 if (!found || *host == MPI_PROC_NULL)
176 return optional<int>();
181 optional<int> environment::io_rank()
186 BOOST_MPI_CHECK_RESULT(MPI_Attr_get,
187 (MPI_COMM_WORLD, MPI_IO, &io, &found));
188 if (!found || *io == MPI_PROC_NULL)
189 return optional<int>();
194 std::string environment::processor_name()
196 char name[MPI_MAX_PROCESSOR_NAME];
199 BOOST_MPI_CHECK_RESULT(MPI_Get_processor_name, (name, &len));
200 return std::string(name, len);
203 threading::level environment::thread_level()
207 BOOST_MPI_CHECK_RESULT(MPI_Query_thread, (&level));
208 return static_cast<threading::level>(level);
211 bool environment::is_main_thread()
215 BOOST_MPI_CHECK_RESULT(MPI_Is_thread_main, (&isit));
216 return static_cast<bool>(isit);
219 } } // end namespace boost::mpi