summaryrefslogtreecommitdiff
path: root/boost/mpi
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
committerChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
commit08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch)
tree7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/mpi
parentbb4dd8289b351fae6b55e303f189127a394a1edd (diff)
downloadboost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/mpi')
-rw-r--r--boost/mpi/collectives.hpp30
-rw-r--r--boost/mpi/collectives/all_reduce.hpp31
-rw-r--r--boost/mpi/collectives/gather.hpp7
-rw-r--r--boost/mpi/collectives/reduce.hpp19
-rw-r--r--boost/mpi/communicator.hpp3
-rw-r--r--boost/mpi/config.hpp13
-rw-r--r--boost/mpi/detail/binary_buffer_iprimitive.hpp4
-rw-r--r--boost/mpi/detail/forward_skeleton_iarchive.hpp1
-rw-r--r--boost/mpi/detail/ignore_iprimitive.hpp2
-rw-r--r--boost/mpi/detail/ignore_oprimitive.hpp2
-rw-r--r--boost/mpi/detail/mpi_datatype_primitive.hpp27
-rw-r--r--boost/mpi/detail/packed_iprimitive.hpp4
-rw-r--r--boost/mpi/detail/packed_oprimitive.hpp3
-rw-r--r--boost/mpi/environment.hpp82
-rw-r--r--boost/mpi/inplace.hpp63
-rw-r--r--boost/mpi/nonblocking.hpp6
-rw-r--r--boost/mpi/packed_iarchive.hpp57
-rw-r--r--boost/mpi/packed_oarchive.hpp47
-rw-r--r--boost/mpi/python/config.hpp6
19 files changed, 338 insertions, 69 deletions
diff --git a/boost/mpi/collectives.hpp b/boost/mpi/collectives.hpp
index 76d6bda3ae..e74fd72bb0 100644
--- a/boost/mpi/collectives.hpp
+++ b/boost/mpi/collectives.hpp
@@ -19,10 +19,10 @@
#define BOOST_MPI_COLLECTIVES_HPP
#include <boost/mpi/communicator.hpp>
+#include <boost/mpi/inplace.hpp>
#include <vector>
namespace boost { namespace mpi {
-
/**
* @brief Gather the values stored at every process into vectors of
* values from each process.
@@ -94,12 +94,15 @@ all_gather(const communicator& comm, const T* in_values, int n, T* out_values);
*
* @param comm The communicator over which the reduction will
* occur.
- *
- * @param in_value The local value to be combined with the local
+ * @param value The local value to be combined with the local
* values of every other process. For reducing arrays, @c in_values
* is a pointer to the local values to be reduced and @c n is the
* number of values to reduce. See @c reduce for more information.
*
+ * If wrapped in a @c inplace_t object, combine the usage of both
+ * input and $c out_value and the local value will be overwritten
+ * (a convenience function @c inplace is provided for the wrapping).
+ *
* @param out_value Will receive the result of the reduction
* operation. If this parameter is omitted, the outgoing value will
* instead be returned.
@@ -116,26 +119,39 @@ all_gather(const communicator& comm, const T* in_values, int n, T* out_values);
* gives the implementation additional lattitude to optimize the
* reduction operation.
*
+ * @param n Indicated the size of the buffers of array type.
* @returns If no @p out_value parameter is supplied, returns the
* result of the reduction operation.
*/
template<typename T, typename Op>
void
-all_reduce(const communicator& comm, const T& in_value, T& out_value, Op op);
-
+all_reduce(const communicator& comm, const T* value, int n, T* out_value,
+ Op op);
+/**
+ * \overload
+ */
+template<typename T, typename Op>
+void
+all_reduce(const communicator& comm, const T& value, T& out_value, Op op);
/**
* \overload
*/
template<typename T, typename Op>
-T all_reduce(const communicator& comm, const T& in_value, Op op);
+T all_reduce(const communicator& comm, const T& value, Op op);
/**
* \overload
*/
template<typename T, typename Op>
void
-all_reduce(const communicator& comm, const T* in_values, int n, T* out_values,
+all_reduce(const communicator& comm, inplace_t<T*> value, int n,
Op op);
+/**
+ * \overload
+ */
+template<typename T, typename Op>
+void
+all_reduce(const communicator& comm, inplace_t<T> value, Op op);
/**
* @brief Send data from every process to every other process.
diff --git a/boost/mpi/collectives/all_reduce.hpp b/boost/mpi/collectives/all_reduce.hpp
index 26b8fc9cd1..06e116a65e 100644
--- a/boost/mpi/collectives/all_reduce.hpp
+++ b/boost/mpi/collectives/all_reduce.hpp
@@ -12,12 +12,15 @@
#ifndef BOOST_MPI_ALL_REDUCE_HPP
#define BOOST_MPI_ALL_REDUCE_HPP
+#include <vector>
+
+#include <boost/mpi/inplace.hpp>
+
// All-reduce falls back to reduce() + broadcast() in some cases.
#include <boost/mpi/collectives/broadcast.hpp>
#include <boost/mpi/collectives/reduce.hpp>
namespace boost { namespace mpi {
-
namespace detail {
/**********************************************************************
* Simple reduction with MPI_Allreduce *
@@ -67,7 +70,17 @@ namespace detail {
T* out_values, Op op, mpl::false_ /*is_mpi_op*/,
mpl::false_ /*is_mpi_datatype*/)
{
- reduce(comm, in_values, n, out_values, op, 0);
+ if (in_values == MPI_IN_PLACE) {
+ // if in_values matches the in place tag, then the output
+ // buffer actually contains the input data.
+ // But we can just go back to the out of place
+ // implementation in this case.
+ // it's not clear how/if we can avoid the copy.
+ std::vector<T> tmp_in( out_values, out_values + n);
+ reduce(comm, &(tmp_in[0]), n, out_values, op, 0);
+ } else {
+ reduce(comm, in_values, n, out_values, op, 0);
+ }
broadcast(comm, out_values, n, 0);
}
} // end namespace detail
@@ -83,6 +96,20 @@ all_reduce(const communicator& comm, const T* in_values, int n, T* out_values,
template<typename T, typename Op>
inline void
+all_reduce(const communicator& comm, inplace_t<T*> inout_values, int n, Op op)
+{
+ all_reduce(comm, static_cast<const T*>(MPI_IN_PLACE), n, inout_values.buffer, op);
+}
+
+template<typename T, typename Op>
+inline void
+all_reduce(const communicator& comm, inplace_t<T> inout_values, Op op)
+{
+ all_reduce(comm, static_cast<const T*>(MPI_IN_PLACE), 1, &(inout_values.buffer), op);
+}
+
+template<typename T, typename Op>
+inline void
all_reduce(const communicator& comm, const T& in_value, T& out_value, Op op)
{
detail::all_reduce_impl(comm, &in_value, 1, &out_value, op,
diff --git a/boost/mpi/collectives/gather.hpp b/boost/mpi/collectives/gather.hpp
index 4f39392a84..70dfd65313 100644
--- a/boost/mpi/collectives/gather.hpp
+++ b/boost/mpi/collectives/gather.hpp
@@ -131,7 +131,12 @@ void
gather(const communicator& comm, const T* in_values, int n,
std::vector<T>& out_values, int root)
{
- ::boost::mpi::gather(comm, in_values, n, &out_values[0], root);
+ if (comm.rank() == root) {
+ out_values.resize(comm.size() * n);
+ ::boost::mpi::gather(comm, in_values, n, &out_values[0], root);
+ }
+ else
+ ::boost::mpi::gather(comm, in_values, n, root);
}
template<typename T>
diff --git a/boost/mpi/collectives/reduce.hpp b/boost/mpi/collectives/reduce.hpp
index f1dee8230e..8fc2fe6eb6 100644
--- a/boost/mpi/collectives/reduce.hpp
+++ b/boost/mpi/collectives/reduce.hpp
@@ -330,6 +330,25 @@ reduce(const communicator& comm, const T* in_values, int n, Op op, int root)
is_mpi_op<Op, T>(), is_mpi_datatype<T>());
}
+template<typename T, typename Op>
+void
+reduce(const communicator & comm, std::vector<T> const & in_values, Op op,
+ int root)
+{
+ reduce(comm, &in_values.front(), in_values.size(), op, root);
+}
+
+template<typename T, typename Op>
+void
+reduce(const communicator & comm, std::vector<T> const & in_values,
+ std::vector<T> & out_values, Op op, int root)
+{
+ out_values.resize(in_values.size());
+ reduce(comm, &in_values.front(), in_values.size(), &out_values.front(), op,
+ root);
+}
+
+
template<typename T, typename Op>
void
reduce(const communicator& comm, const T& in_value, T& out_value, Op op,
diff --git a/boost/mpi/communicator.hpp b/boost/mpi/communicator.hpp
index e450e2a54b..65de3a47f2 100644
--- a/boost/mpi/communicator.hpp
+++ b/boost/mpi/communicator.hpp
@@ -13,6 +13,7 @@
#ifndef BOOST_MPI_COMMUNICATOR_HPP
#define BOOST_MPI_COMMUNICATOR_HPP
+#include <boost/assert.hpp>
#include <boost/mpi/config.hpp>
#include <boost/mpi/exception.hpp>
#include <boost/optional.hpp>
@@ -869,6 +870,8 @@ class BOOST_MPI_DECL communicator
{
void operator()(MPI_Comm* comm) const
{
+ BOOST_ASSERT( comm != 0 );
+ BOOST_ASSERT(*comm != MPI_COMM_NULL);
int finalized;
BOOST_MPI_CHECK_RESULT(MPI_Finalized, (&finalized));
if (!finalized)
diff --git a/boost/mpi/config.hpp b/boost/mpi/config.hpp
index cf08e2cdbe..acbdc78daa 100644
--- a/boost/mpi/config.hpp
+++ b/boost/mpi/config.hpp
@@ -27,7 +27,7 @@
// If this is an MPI-2 implementation, define configuration macros for
// the features we are interested in.
-#if defined(MPI_VERSION) && MPI_VERSION == 2
+#if defined(MPI_VERSION) && MPI_VERSION >= 2
/** @brief Determine if the MPI implementation has support for memory
* allocation.
*
@@ -48,6 +48,11 @@
* environment class will provide a default constructor. This macro is
* always defined for MPI-2 implementations. */
# define BOOST_MPI_HAS_NOARG_INITIALIZATION
+#else
+// If this is an MPI-1.x implementation, no arg initialization for
+// mpi environement could still be available, but not mandatory.
+// Undef this if no arg init is available:
+//# define BOOST_MPI_HAS_NOARG_INITIALIZATION
#endif
#if defined(MPIAPI)
@@ -80,12 +85,12 @@
* *
*****************************************************************************/
-#if defined(BOOST_HAS_DECLSPEC) && (defined(BOOST_MPI_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_MPI_STATIC_LINK)
+#if (defined(BOOST_MPI_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_MPI_STATIC_LINK)
# if defined(BOOST_MPI_SOURCE)
-# define BOOST_MPI_DECL __declspec(dllexport)
+# define BOOST_MPI_DECL BOOST_SYMBOL_EXPORT
# define BOOST_MPI_BUILD_DLL
# else
-# define BOOST_MPI_DECL __declspec(dllimport)
+# define BOOST_MPI_DECL BOOST_SYMBOL_IMPORT
# endif
#endif
diff --git a/boost/mpi/detail/binary_buffer_iprimitive.hpp b/boost/mpi/detail/binary_buffer_iprimitive.hpp
index 2bc028fc22..f499d0d5a8 100644
--- a/boost/mpi/detail/binary_buffer_iprimitive.hpp
+++ b/boost/mpi/detail/binary_buffer_iprimitive.hpp
@@ -21,6 +21,7 @@
#include <vector>
#include <boost/mpi/allocator.hpp>
#include <cstring> // for memcpy
+#include <cassert>
namespace boost { namespace mpi {
@@ -107,7 +108,8 @@ private:
void load_impl(void * p, int l)
{
assert(position+l<=static_cast<int>(buffer_.size()));
- std::memcpy(p,&buffer_[position],l);
+ if (l)
+ std::memcpy(p,&buffer_[position],l);
position += l;
}
diff --git a/boost/mpi/detail/forward_skeleton_iarchive.hpp b/boost/mpi/detail/forward_skeleton_iarchive.hpp
index 4d0ef7e9b8..6e1181981d 100644
--- a/boost/mpi/detail/forward_skeleton_iarchive.hpp
+++ b/boost/mpi/detail/forward_skeleton_iarchive.hpp
@@ -61,6 +61,7 @@ BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::version_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_reference_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::object_id_type)
+BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::object_reference_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::tracking_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_name_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(serialization::collection_size_type)
diff --git a/boost/mpi/detail/ignore_iprimitive.hpp b/boost/mpi/detail/ignore_iprimitive.hpp
index 724d711560..eb3d2b78fb 100644
--- a/boost/mpi/detail/ignore_iprimitive.hpp
+++ b/boost/mpi/detail/ignore_iprimitive.hpp
@@ -44,7 +44,7 @@ public:
/// don't do anything when loading primitive types
template<class T>
- void load(T & t)
+ void load(T &)
{
}
};
diff --git a/boost/mpi/detail/ignore_oprimitive.hpp b/boost/mpi/detail/ignore_oprimitive.hpp
index 9070ea7f65..23375cad7b 100644
--- a/boost/mpi/detail/ignore_oprimitive.hpp
+++ b/boost/mpi/detail/ignore_oprimitive.hpp
@@ -52,7 +52,7 @@ public:
/// don't do anything when saving primitive types
template<class T>
- void save(const T & t)
+ void save(const T &)
{
}
};
diff --git a/boost/mpi/detail/mpi_datatype_primitive.hpp b/boost/mpi/detail/mpi_datatype_primitive.hpp
index 3c22245d87..0a6078548f 100644
--- a/boost/mpi/detail/mpi_datatype_primitive.hpp
+++ b/boost/mpi/detail/mpi_datatype_primitive.hpp
@@ -49,7 +49,11 @@ public:
: is_committed(false),
origin()
{
+#if defined(MPI_VERSION) && MPI_VERSION >= 2
+ BOOST_MPI_CHECK_RESULT(MPI_Get_address,(const_cast<void*>(orig), &origin));
+#else
BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(orig), &origin));
+#endif
}
void save_binary(void const *address, std::size_t count)
@@ -72,7 +76,8 @@ public:
{
if (!is_committed)
{
- BOOST_MPI_CHECK_RESULT(MPI_Type_struct,
+#if defined(MPI_VERSION) && MPI_VERSION >= 2
+ BOOST_MPI_CHECK_RESULT(MPI_Type_create_struct,
(
addresses.size(),
boost::serialization::detail::get_data(lengths),
@@ -80,9 +85,18 @@ public:
boost::serialization::detail::get_data(types),
&datatype_
));
-
+#else
+ BOOST_MPI_CHECK_RESULT(MPI_Type_struct,
+ (
+ addresses.size(),
+ boost::serialization::detail::get_data(lengths),
+ boost::serialization::detail::get_data(addresses),
+ boost::serialization::detail::get_data(types),
+ &datatype_
+ ));
+#endif
BOOST_MPI_CHECK_RESULT(MPI_Type_commit,(&datatype_));
-
+
is_committed = true;
}
@@ -105,8 +119,11 @@ private:
// store address, type and length
MPI_Aint a;
- BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(p), &a));
-
+#if defined(MPI_VERSION) && MPI_VERSION >= 2
+ BOOST_MPI_CHECK_RESULT(MPI_Get_address,(const_cast<void*>(p), &a));
+#else
+ BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(p), &a));
+#endif
addresses.push_back(a-origin);
types.push_back(t);
lengths.push_back(l);
diff --git a/boost/mpi/detail/packed_iprimitive.hpp b/boost/mpi/detail/packed_iprimitive.hpp
index 6e981c7f2b..bb471a7c66 100644
--- a/boost/mpi/detail/packed_iprimitive.hpp
+++ b/boost/mpi/detail/packed_iprimitive.hpp
@@ -94,7 +94,9 @@ public:
load(l);
s.resize(l);
// note breaking a rule here - could be a problem on some platform
- load_impl(const_cast<CharType *>(s.data()),get_mpi_datatype(CharType()),l);
+ if (l)
+ load_impl(const_cast<CharType *>(s.data()),
+ get_mpi_datatype(CharType()),l);
}
private:
diff --git a/boost/mpi/detail/packed_oprimitive.hpp b/boost/mpi/detail/packed_oprimitive.hpp
index 1f59df8977..5ac6835e15 100644
--- a/boost/mpi/detail/packed_oprimitive.hpp
+++ b/boost/mpi/detail/packed_oprimitive.hpp
@@ -81,7 +81,8 @@ public:
{
unsigned int l = static_cast<unsigned int>(s.size());
save(l);
- save_impl(s.data(),get_mpi_datatype(CharType()),s.size());
+ if (l)
+ save_impl(s.data(),get_mpi_datatype(CharType()),s.size());
}
private:
diff --git a/boost/mpi/environment.hpp b/boost/mpi/environment.hpp
index 378a3b6041..92af129f38 100644
--- a/boost/mpi/environment.hpp
+++ b/boost/mpi/environment.hpp
@@ -17,9 +17,46 @@
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <string>
+#include <iosfwd>
namespace boost { namespace mpi {
+namespace threading {
+/** @brief specify the supported threading level.
+ *
+ * Based on MPI 2 standard/8.7.3
+ */
+enum level {
+ /** Only one thread will execute.
+ */
+ single = MPI_THREAD_SINGLE,
+ /** Only main thread will do MPI calls.
+ *
+ * The process may be multi-threaded, but only the main
+ * thread will make MPI calls (all MPI calls are ``funneled''
+ * to the main thread).
+ */
+ funneled = MPI_THREAD_FUNNELED,
+ /** Only one thread at the time do MPI calls.
+ *
+ * The process may be multi-threaded, and multiple
+ * threads may make MPI calls, but only one at a time:
+ * MPI calls are not made concurrently from two distinct
+ * threads (all MPI calls are ``serialized'').
+ */
+ serialized = MPI_THREAD_SERIALIZED,
+ /** Multiple thread may do MPI calls.
+ *
+ * Multiple threads may call MPI, with no restrictions.
+ */
+ multiple = MPI_THREAD_MULTIPLE
+};
+
+/** Formated output for threading level. */
+std::ostream& operator<<(std::ostream& out, level l);
+/** Formated input for threading level. */
+std::istream& operator>>(std::istream& in, level& l);
+} // namespace threading
/** @brief Initialize, finalize, and query the MPI environment.
*
* The @c environment class is used to initialize, finalize, and
@@ -62,6 +99,22 @@ public:
* program if it is destructed due to an uncaught exception.
*/
explicit environment(bool abort_on_exception = true);
+ /** Initialize the MPI environment.
+ *
+ * If the MPI environment has not already been initialized,
+ * initializes MPI with a call to @c MPI_Init_thread. Since this
+ * constructor does not take command-line arguments (@c argc and @c
+ * argv), it is only available when the underlying MPI
+ * implementation supports calling @c MPI_Init with @c NULL
+ * arguments, indicated by the macro @c
+ * BOOST_MPI_HAS_NOARG_INITIALIZATION.
+ *
+ * @param mt_level the required level of threading support.
+ *
+ * @param abort_on_exception When true, this object will abort the
+ * program if it is destructed due to an uncaught exception.
+ */
+ explicit environment(threading::level mt_level, bool abort_on_exception = true);
#endif
/** Initialize the MPI environment.
@@ -80,6 +133,25 @@ public:
*/
environment(int& argc, char** &argv, bool abort_on_exception = true);
+ /** Initialize the MPI environment.
+ *
+ * If the MPI environment has not already been initialized,
+ * initializes MPI with a call to @c MPI_Init_thread.
+ *
+ * @param argc The number of arguments provided in @p argv, as
+ * passed into the program's @c main function.
+ *
+ * @param argv The array of argument strings passed to the program
+ * via @c main.
+ *
+ * @param mt_level the required level of threading support
+ *
+ * @param abort_on_exception When true, this object will abort the
+ * program if it is destructed due to an uncaught exception.
+ */
+ environment(int& argc, char** &argv, threading::level mt_level,
+ bool abort_on_exception = true);
+
/** Shuts down the MPI environment.
*
* If this @c environment object was used to initialize the MPI
@@ -185,13 +257,21 @@ public:
*/
static std::string processor_name();
+ /** Query the current level of thread support.
+ */
+ static threading::level thread_level();
+
+ /** Are we in the main thread?
+ */
+ static bool is_main_thread();
+
private:
/// Whether this environment object called MPI_Init
bool i_initialized;
/// Whether we should abort if the destructor is
bool abort_on_exception;
-
+
/// The number of reserved tags.
static const int num_reserved_tags = 1;
};
diff --git a/boost/mpi/inplace.hpp b/boost/mpi/inplace.hpp
new file mode 100644
index 0000000000..d84d07db59
--- /dev/null
+++ b/boost/mpi/inplace.hpp
@@ -0,0 +1,63 @@
+// Copyright (C) 2005-2006 Alain Miniussi <alain.miniussi -at- oca.eu>.
+
+// 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 -- Section 4. MPI Collectives
+
+/** @file inplace.hpp
+ *
+ * This header provides helpers to indicate to MPI collective operation
+ * that a buffer can be use both as an input and output.
+ */
+#ifndef BOOST_MPI_INPLACE_HPP
+#define BOOST_MPI_INPLACE_HPP
+
+#include <boost/mpi/communicator.hpp>
+#include <vector>
+
+namespace boost { namespace mpi {
+
+/**
+ * @brief Wrapper type to explicitly indicate that a input data
+ * can be overriden with an output value.
+ */
+template <typename T>
+struct inplace_t {
+ inplace_t(T& inout) : buffer(inout) {}
+ T& buffer;
+};
+
+template <typename T>
+struct inplace_t<T*> {
+ inplace_t(T* inout) : buffer(inout) {}
+ T* buffer;
+};
+
+
+/**
+ * @brief Wrapp a input data to indicate that it can be overriden
+ * with an ouput value.
+ * @param inout the contributing input value, it will be overriden
+ * with the output value where one is expected. If it is a pointer,
+ * the number of elements will be provided separatly.
+ * @returns The wrapped value or pointer.
+ */
+template<typename T>
+inplace_t<T>
+inplace(T& inout) {
+ return inplace_t<T>(inout);
+}
+/**
+ * \overload
+ */
+template<typename T>
+inplace_t<T*>
+inplace(T* inout) {
+ return inplace_t<T*>(inout);
+}
+} } // end namespace boost::mpi
+
+#endif // BOOST_MPI_INPLACE_HPP
+
diff --git a/boost/mpi/nonblocking.hpp b/boost/mpi/nonblocking.hpp
index ba024c7df4..a2d2e34313 100644
--- a/boost/mpi/nonblocking.hpp
+++ b/boost/mpi/nonblocking.hpp
@@ -59,8 +59,10 @@ wait_any(ForwardIterator first, ForwardIterator last)
ForwardIterator current = first;
while (true) {
// Check if we have found a completed request. If so, return it.
- if (optional<status> result = current->test())
- return std::make_pair(*result, current);
+ if (current->m_requests[0] != MPI_REQUEST_NULL &&
+ current->m_requests[1] != MPI_REQUEST_NULL)
+ if (optional<status> result = current->test())
+ return std::make_pair(*result, current);
// Check if this request (and all others before it) are "trivial"
// requests, e.g., they can be represented with a single
diff --git a/boost/mpi/packed_iarchive.hpp b/boost/mpi/packed_iarchive.hpp
index c33e7f9979..23d6468c55 100644
--- a/boost/mpi/packed_iarchive.hpp
+++ b/boost/mpi/packed_iarchive.hpp
@@ -21,7 +21,7 @@
#include <boost/mpi/datatype.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
-#include <boost/archive/shared_ptr_helper.hpp>
+#include <boost/archive/basic_archive.hpp>
#include <boost/mpi/detail/packed_iprimitive.hpp>
#include <boost/mpi/detail/binary_buffer_iprimitive.hpp>
#include <boost/serialization/string.hpp>
@@ -37,57 +37,55 @@ namespace boost { namespace mpi {
typedef packed_iprimitive iprimitive;
#endif
-/** @brief An archive that packs binary data into an MPI buffer.
+
+/** @brief An archive that unpacks binary data from an MPI buffer.
*
- * The @c packed_iarchive class is an Archiver (as in the
- * Boost.Serialization library) that packs binary data into a buffer
- * for transmission via MPI. It can operate on any Serializable data
- * type and will use the @c MPI_Pack function of the underlying MPI
- * implementation to perform serialization.
+ * The @c packed_oarchive class is an Archiver (as in the
+ * Boost.Serialization library) that unpacks binary data from a
+ * buffer received via MPI. It can operate on any Serializable data
+ * type and will use the @c MPI_Unpack function of the underlying MPI
+ * implementation to perform deserialization.
*/
+
class BOOST_MPI_DECL packed_iarchive
: public iprimitive
, public archive::detail::common_iarchive<packed_iarchive>
- , public archive::detail::shared_ptr_helper
{
public:
/**
- * Construct a @c packed_iarchive for transmission over the given
+ * Construct a @c packed_iarchive to receive data over the given
* MPI communicator and with an initial buffer.
*
* @param comm The communicator over which this archive will be
- * sent.
+ * received.
*
- * @param b A user-defined buffer that will be filled with the
- * binary representation of serialized objects.
+ * @param b A user-defined buffer that contains the binary
+ * representation of serialized objects.
*
* @param flags Control the serialization of the data types. Refer
* to the Boost.Serialization documentation before changing the
* default flags.
- *
- * @param position Set the offset into buffer @p b at which
- * deserialization will begin.
*/
+
packed_iarchive(MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header, int position = 0)
: iprimitive(b,comm,position),
archive::detail::common_iarchive<packed_iarchive>(flags)
{}
/**
- * Construct a @c packed_iarchive for transmission over the given
+ * Construct a @c packed_iarchive to receive data over the given
* MPI communicator.
*
* @param comm The communicator over which this archive will be
- * sent.
- *
- * @param s The size of the buffer to be received.
+ * received.
*
* @param flags Control the serialization of the data types. Refer
* to the Boost.Serialization documentation before changing the
* default flags.
*/
+
packed_iarchive
- ( MPI_Comm const & comm , std::size_t s=0,
+ ( MPI_Comm const & comm , std::size_t s=0,
unsigned int flags = boost::archive::no_header)
: iprimitive(internal_buffer_,comm)
, archive::detail::common_iarchive<packed_iarchive>(flags)
@@ -118,9 +116,25 @@ public:
load_override(x, version, use_optimized());
}
- // input archives need to ignore the optional information
+ // input archives need to ignore the optional information
void load_override(archive::class_id_optional_type & /*t*/, int){}
+ void load_override(archive::class_id_type & t, int version){
+ int_least16_t x=0;
+ * this->This() >> x;
+ t = boost::archive::class_id_type(x);
+ }
+
+ void load_override(archive::version_type & t, int version){
+ int_least8_t x=0;
+ * this->This() >> x;
+ t = boost::archive::version_type(x);
+ }
+
+ void load_override(archive::class_id_reference_type & t, int version){
+ load_override(static_cast<archive::class_id_type &>(t), version);
+ }
+
void load_override(archive::class_name_type & t, int)
{
std::string cn;
@@ -139,7 +153,6 @@ private:
} } // end namespace boost::mpi
-BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(boost::mpi::packed_iarchive)
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_iarchive)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_iarchive)
diff --git a/boost/mpi/packed_oarchive.hpp b/boost/mpi/packed_oarchive.hpp
index fb87e460c5..887aeac6e3 100644
--- a/boost/mpi/packed_oarchive.hpp
+++ b/boost/mpi/packed_oarchive.hpp
@@ -19,9 +19,9 @@
#define BOOST_MPI_PACKED_OARCHIVE_HPP
#include <boost/mpi/datatype.hpp>
+#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
-#include <boost/archive/shared_ptr_helper.hpp>
#include <boost/mpi/detail/packed_oprimitive.hpp>
#include <boost/mpi/detail/binary_buffer_oprimitive.hpp>
#include <boost/serialization/string.hpp>
@@ -36,34 +36,36 @@ namespace boost { namespace mpi {
typedef packed_oprimitive oprimitive;
#endif
-/** @brief An archive that unpacks binary data from an MPI buffer.
+/** @brief An archive that packs binary data into an MPI buffer.
*
- * The @c packed_oarchive class is an Archiver (as in the
- * Boost.Serialization library) that unpacks binary data from a
- * buffer received via MPI. It can operate on any Serializable data
- * type and will use the @c MPI_Unpack function of the underlying MPI
- * implementation to perform deserialization.
+ * The @c packed_iarchive class is an Archiver (as in the
+ * Boost.Serialization library) that packs binary data into a buffer
+ * for transmission via MPI. It can operate on any Serializable data
+ * type and will use the @c MPI_Pack function of the underlying MPI
+ * implementation to perform serialization.
*/
-
+
class BOOST_MPI_DECL packed_oarchive
: public oprimitive
, public archive::detail::common_oarchive<packed_oarchive>
- , public archive::detail::shared_ptr_helper
{
public:
/**
- * Construct a @c packed_oarchive to receive data over the given
+ * Construct a @c packed_oarchive for transmission over the given
* MPI communicator and with an initial buffer.
*
* @param comm The communicator over which this archive will be
- * received.
+ * sent.
*
- * @param b A user-defined buffer that contains the binary
- * representation of serialized objects.
+ * @param b A user-defined buffer that will be filled with the
+ * binary representation of serialized objects.
*
* @param flags Control the serialization of the data types. Refer
* to the Boost.Serialization documentation before changing the
* default flags.
+ *
+ * @param position Set the offset into buffer @p b at which
+ * deserialization will begin.
*/
packed_oarchive( MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header)
: oprimitive(b,comm),
@@ -71,11 +73,13 @@ public:
{}
/**
- * Construct a @c packed_oarchive to receive data over the given
+ * Construct a @c packed_oarchive for transmission over the given
* MPI communicator.
*
* @param comm The communicator over which this archive will be
- * received.
+ * sent.
+ *
+ * @param s The size of the buffer to be received.
*
* @param flags Control the serialization of the data types. Refer
* to the Boost.Serialization documentation before changing the
@@ -93,7 +97,7 @@ public:
archive::detail::common_oarchive<packed_oarchive>::save_override(x,version);
}
- // Save it directly using the primnivites
+ // Save it directly using the primitives
template<class T>
void save_override(T const& x, int /*version*/, mpl::true_)
{
@@ -108,7 +112,7 @@ public:
save_override(x, version, use_optimized());
}
- // input archives need to ignore the optional information
+ // input archives need to ignore the optional information
void save_override(const archive::class_id_optional_type & /*t*/, int){}
// explicitly convert to char * to avoid compile ambiguities
@@ -117,6 +121,15 @@ public:
* this->This() << s;
}
+ void save_override(archive::class_id_type & t, int version){
+ const boost::int_least16_t x = t;
+ * this->This() << x;
+ }
+
+ void save_override(archive::version_type & t, int version){
+ const boost::int_least8_t x = t;
+ * this->This() << x;
+ }
private:
/// An internal buffer to be used when the user does not supply his
/// own buffer.
diff --git a/boost/mpi/python/config.hpp b/boost/mpi/python/config.hpp
index 8bd0cdaf30..6126d955b2 100644
--- a/boost/mpi/python/config.hpp
+++ b/boost/mpi/python/config.hpp
@@ -20,12 +20,12 @@
* *
*****************************************************************************/
-#if defined(BOOST_HAS_DECLSPEC) && (defined(BOOST_MPI_PYTHON_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_MPI_PYTHON_STATIC_LINK)
+#if (defined(BOOST_MPI_PYTHON_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_MPI_PYTHON_STATIC_LINK)
# if defined(BOOST_MPI_PYTHON_SOURCE)
-# define BOOST_MPI_PYTHON_DECL __declspec(dllexport)
+# define BOOST_MPI_PYTHON_DECL BOOST_SYMBOL_EXPORT
# define BOOST_MPI_PYTHON_BUILD_DLL
# else
-# define BOOST_MPI_PYTHON_DECL __declspec(dllimport)
+# define BOOST_MPI_PYTHON_DECL BOOST_SYMBOL_IMPORT
# endif
#endif