diff options
Diffstat (limited to 'libs/mpi/src/environment.cpp')
-rw-r--r-- | libs/mpi/src/environment.cpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/libs/mpi/src/environment.cpp b/libs/mpi/src/environment.cpp new file mode 100644 index 000000000..4da844724 --- /dev/null +++ b/libs/mpi/src/environment.cpp @@ -0,0 +1,125 @@ +// Copyright (C) 2005-2006 Douglas Gregor <doug.gregor@gmail.com> + +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Message Passing Interface 1.1 -- 7.1.1. Environmental Inquiries +#include <boost/mpi/environment.hpp> +#include <boost/mpi/exception.hpp> +#include <boost/mpi/detail/mpi_datatype_cache.hpp> +#include <cassert> +#include <exception> +#include <stdexcept> + +namespace boost { namespace mpi { + +#ifdef BOOST_MPI_HAS_NOARG_INITIALIZATION +environment::environment(bool abort_on_exception) + : i_initialized(false), + abort_on_exception(abort_on_exception) +{ + if (!initialized()) { + BOOST_MPI_CHECK_RESULT(MPI_Init, (0, 0)); + i_initialized = true; + } + + MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN); +} +#endif + +environment::environment(int& argc, char** &argv, bool abort_on_exception) + : i_initialized(false), + abort_on_exception(abort_on_exception) +{ + if (!initialized()) { + BOOST_MPI_CHECK_RESULT(MPI_Init, (&argc, &argv)); + i_initialized = true; + } + + MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN); +} + +environment::~environment() +{ + if (i_initialized) { + if (std::uncaught_exception() && abort_on_exception) { + abort(-1); + } else if (!finalized()) { + detail::mpi_datatype_cache().clear(); + BOOST_MPI_CHECK_RESULT(MPI_Finalize, ()); + } + } +} + +void environment::abort(int errcode) +{ + BOOST_MPI_CHECK_RESULT(MPI_Abort, (MPI_COMM_WORLD, errcode)); +} + +bool environment::initialized() +{ + int flag; + BOOST_MPI_CHECK_RESULT(MPI_Initialized, (&flag)); + return flag != 0; +} + +bool environment::finalized() +{ + int flag; + BOOST_MPI_CHECK_RESULT(MPI_Finalized, (&flag)); + return flag != 0; +} + +int environment::max_tag() +{ + int* max_tag_value; + int found = 0; + + BOOST_MPI_CHECK_RESULT(MPI_Attr_get, + (MPI_COMM_WORLD, MPI_TAG_UB, &max_tag_value, &found)); + assert(found != 0); + return *max_tag_value - num_reserved_tags; +} + +int environment::collectives_tag() +{ + return max_tag() + 1; +} + +optional<int> environment::host_rank() +{ + int* host; + int found = 0; + + BOOST_MPI_CHECK_RESULT(MPI_Attr_get, + (MPI_COMM_WORLD, MPI_HOST, &host, &found)); + if (!found || *host == MPI_PROC_NULL) + return optional<int>(); + else + return *host; +} + +optional<int> environment::io_rank() +{ + int* io; + int found = 0; + + BOOST_MPI_CHECK_RESULT(MPI_Attr_get, + (MPI_COMM_WORLD, MPI_IO, &io, &found)); + if (!found || *io == MPI_PROC_NULL) + return optional<int>(); + else + return *io; +} + +std::string environment::processor_name() +{ + char name[MPI_MAX_PROCESSOR_NAME]; + int len; + + BOOST_MPI_CHECK_RESULT(MPI_Get_processor_name, (name, &len)); + return std::string(name, len); +} + +} } // end namespace boost::mpi |