diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
commit | b8cf34c691623e4ec329053cbbf68522a855882d (patch) | |
tree | 34da08632a99677f6b79ecb65e5b655a5b69a67f /boost/mpi/collectives/all_gatherv.hpp | |
parent | 3fdc3e5ee96dca5b11d1694975a65200787eab86 (diff) | |
download | boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.gz boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.bz2 boost-b8cf34c691623e4ec329053cbbf68522a855882d.zip |
Imported Upstream version 1.67.0upstream/1.67.0
Diffstat (limited to 'boost/mpi/collectives/all_gatherv.hpp')
-rw-r--r-- | boost/mpi/collectives/all_gatherv.hpp | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/boost/mpi/collectives/all_gatherv.hpp b/boost/mpi/collectives/all_gatherv.hpp new file mode 100644 index 0000000000..064412f5d7 --- /dev/null +++ b/boost/mpi/collectives/all_gatherv.hpp @@ -0,0 +1,140 @@ +// Copyright (C) 2005, 2006 Douglas Gregor. + +// 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.5. Gatherv +#ifndef BOOST_MPI_ALLGATHERV_HPP +#define BOOST_MPI_ALLGATHERV_HPP + +#include <cassert> +#include <cstddef> +#include <numeric> +#include <vector> + +#include <boost/mpi/exception.hpp> +#include <boost/mpi/datatype.hpp> +#include <boost/mpi/packed_oarchive.hpp> +#include <boost/mpi/packed_iarchive.hpp> +#include <boost/mpi/detail/point_to_point.hpp> +#include <boost/mpi/communicator.hpp> +#include <boost/mpi/environment.hpp> +#include <boost/mpi/detail/offsets.hpp> +#include <boost/mpi/detail/antiques.hpp> +#include <boost/assert.hpp> +#include <boost/scoped_array.hpp> + +namespace boost { namespace mpi { + +namespace detail { +// We're all-gathering for a type that has an associated MPI +// datatype, so we'll use MPI_Gather to do all of the work. +template<typename T> +void +all_gatherv_impl(const communicator& comm, const T* in_values, + T* out_values, int const* sizes, int const* displs, mpl::true_) +{ + // Make displacements if not provided + scoped_array<int> new_offsets_mem(make_offsets(comm, sizes, displs, -1)); + if (new_offsets_mem) displs = new_offsets_mem.get(); + MPI_Datatype type = get_mpi_datatype<T>(*in_values); + BOOST_MPI_CHECK_RESULT(MPI_Allgatherv, + (const_cast<T*>(in_values), sizes[comm.rank()], type, + out_values, + const_cast<int*>(sizes), + const_cast<int*>(displs), + type, + comm)); +} + +// We're all-gathering for a type that does not have an +// associated MPI datatype, so we'll need to serialize +// it. +template<typename T> +void +all_gatherv_impl(const communicator& comm, const T* in_values, + T* out_values, int const* sizes, int const* displs, + mpl::false_ isnt_mpi_type) +{ + // convert displacement to offsets to skip + scoped_array<int> skipped(make_skipped_slots(comm, sizes, displs)); + all_gather_impl(comm, in_values, sizes[comm.rank()], out_values, + sizes, skipped.get(), isnt_mpi_type); +} +} // end namespace detail + +template<typename T> +void +all_gatherv(const communicator& comm, const T& in_value, T* out_values, + const std::vector<int>& sizes) +{ + using detail::c_data; + assert(sizes.size() == comm.size()); + assert(sizes[comm.rank()] == 1); + detail::all_gatherv_impl(comm, &in_value, out_values, c_data(sizes), 0, is_mpi_datatype<T>()); +} + +template<typename T> +void +all_gatherv(const communicator& comm, const T* in_values, T* out_values, + const std::vector<int>& sizes) +{ + using detail::c_data; + assert(int(sizes.size()) == comm.size()); + detail::all_gatherv_impl(comm, in_values, out_values, c_data(sizes), 0, is_mpi_datatype<T>()); +} + +template<typename T> +void +all_gatherv(const communicator& comm, std::vector<T> const& in_values, std::vector<T>& out_values, + const std::vector<int>& sizes) +{ + using detail::c_data; + assert(int(sizes.size()) == comm.size()); + assert(int(in_values.size()) == sizes[comm.rank()]); + out_values.resize(std::accumulate(sizes.begin(), sizes.end(), 0)); + ::boost::mpi::all_gatherv(comm, c_data(in_values), c_data(out_values), sizes); +} + + +template<typename T> +void +all_gatherv(const communicator& comm, const T& in_value, T* out_values, + const std::vector<int>& sizes, const std::vector<int>& displs) +{ + using detail::c_data; + assert(sizes.size() == comm.size()); + assert(displs.size() == comm.size()); + detail::all_gatherv_impl(comm, &in_value, 1, out_values, + c_data(sizes), c_data(displs), is_mpi_datatype<T>()); +} + +template<typename T> +void +all_gatherv(const communicator& comm, const T* in_values, T* out_values, + const std::vector<int>& sizes, const std::vector<int>& displs) +{ + using detail::c_data; + assert(sizes.size() == comm.size()); + assert(displs.size() == comm.size()); + detail::all_gatherv_impl(comm, in_values, out_values, + c_data(sizes), c_data(displs), is_mpi_datatype<T>()); +} + +template<typename T> +void +all_gatherv(const communicator& comm, std::vector<T> const& in_values, std::vector<T>& out_values, + const std::vector<int>& sizes, const std::vector<int>& displs) +{ + using detail::c_data; + assert(sizes.size() == comm.size()); + assert(displs.size() == comm.size()); + assert(in_values.size() == sizes[comm.rank()]); + out_values.resize(std::accumulate(sizes.begin(), sizes.end(), 0)); + ::boost::mpi::all_gatherv(comm, c_data(in_values), c_data(out_values), sizes, displs); +} + +} } // end namespace boost::mpi + +#endif // BOOST_MPI_ALL_GATHERV_HPP |