File indexing completed on 2025-01-18 09:40:57
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MPI_SCATTERV_HPP
0009 #define BOOST_MPI_SCATTERV_HPP
0010
0011 #include <boost/scoped_array.hpp>
0012 #include <boost/mpi/collectives/scatter.hpp>
0013 #include <boost/mpi/detail/offsets.hpp>
0014 #include <boost/mpi/detail/antiques.hpp>
0015
0016 namespace boost { namespace mpi {
0017
0018 namespace detail {
0019
0020
0021
0022
0023
0024
0025
0026 template<typename T>
0027 void
0028 scatterv_impl(const communicator& comm, const T* in_values, T* out_values, int out_size,
0029 const int* sizes, const int* displs, int root, mpl::true_)
0030 {
0031 assert(!sizes || out_size == sizes[comm.rank()]);
0032 assert(!bool(in_values) || bool(sizes));
0033
0034 scoped_array<int> new_offsets_mem(make_offsets(comm, sizes, displs, root));
0035 if (new_offsets_mem) displs = new_offsets_mem.get();
0036 MPI_Datatype type = get_mpi_datatype<T>(*in_values);
0037 BOOST_MPI_CHECK_RESULT(MPI_Scatterv,
0038 (const_cast<T*>(in_values), const_cast<int*>(sizes),
0039 const_cast<int*>(displs), type,
0040 out_values, out_size, type, root, comm));
0041 }
0042
0043
0044
0045 template<typename T>
0046 void
0047 scatterv_impl(const communicator& comm, T* out_values, int out_size, int root,
0048 mpl::true_ is_mpi_type)
0049 {
0050 scatterv_impl(comm, (T const*)0, out_values, out_size,
0051 (const int*)0, (const int*)0, root, is_mpi_type);
0052 }
0053
0054
0055
0056
0057
0058
0059
0060 template<typename T>
0061 void
0062 scatterv_impl(const communicator& comm, const T* in_values, T* out_values, int out_size,
0063 int const* sizes, int const* displs, int root, mpl::false_)
0064 {
0065 packed_oarchive::buffer_type sendbuf;
0066 bool is_root = comm.rank() == root;
0067 int nproc = comm.size();
0068 std::vector<int> archsizes;
0069 if (is_root) {
0070 assert(out_size == sizes[comm.rank()]);
0071 archsizes.resize(nproc);
0072 std::vector<int> skipped;
0073 if (displs) {
0074 skipped.resize(nproc);
0075 offsets2skipped(sizes, displs, c_data(skipped), nproc);
0076 displs = c_data(skipped);
0077 }
0078 fill_scatter_sendbuf(comm, in_values, sizes, (int const*)0, sendbuf, archsizes);
0079 }
0080 dispatch_scatter_sendbuf(comm, sendbuf, archsizes, (T const*)0, out_values, out_size, root);
0081 }
0082
0083
0084
0085
0086 template<typename T>
0087 void
0088 scatterv_impl(const communicator& comm, T* out_values, int n, int root,
0089 mpl::false_ isnt_mpi_type)
0090 {
0091 assert(root != comm.rank());
0092 scatterv_impl(comm, (T const*)0, out_values, n, (int const*)0, (int const*)0, root, isnt_mpi_type);
0093 }
0094
0095 }
0096
0097 template<typename T>
0098 void
0099 scatterv(const communicator& comm, const T* in_values,
0100 const std::vector<int>& sizes, const std::vector<int>& displs,
0101 T* out_values, int out_size, int root)
0102 {
0103 using detail::c_data;
0104 detail::scatterv_impl(comm, in_values, out_values, out_size, c_data(sizes), c_data(displs),
0105 root, is_mpi_datatype<T>());
0106 }
0107
0108 template<typename T>
0109 void
0110 scatterv(const communicator& comm, const std::vector<T>& in_values,
0111 const std::vector<int>& sizes, const std::vector<int>& displs,
0112 T* out_values, int out_size, int root)
0113 {
0114 using detail::c_data;
0115 ::boost::mpi::scatterv(comm, c_data(in_values), sizes, displs,
0116 out_values, out_size, root);
0117 }
0118
0119 template<typename T>
0120 void scatterv(const communicator& comm, T* out_values, int out_size, int root)
0121 {
0122 BOOST_ASSERT(comm.rank() != root);
0123 detail::scatterv_impl(comm, out_values, out_size, root, is_mpi_datatype<T>());
0124 }
0125
0126
0127
0128
0129 template<typename T>
0130 void
0131 scatterv(const communicator& comm, const T* in_values,
0132 const std::vector<int>& sizes, T* out_values, int root)
0133 {
0134 using detail::c_data;
0135 detail::scatterv_impl(comm, in_values, out_values, sizes[comm.rank()],
0136 c_data(sizes), (int const*)0,
0137 root, is_mpi_datatype<T>());
0138 }
0139
0140 template<typename T>
0141 void
0142 scatterv(const communicator& comm, const std::vector<T>& in_values,
0143 const std::vector<int>& sizes, T* out_values, int root)
0144 {
0145 ::boost::mpi::scatterv(comm, detail::c_data(in_values), sizes, out_values, root);
0146 }
0147
0148 template<typename T>
0149 void
0150 scatterv(const communicator& comm, const T* in_values,
0151 T* out_values, int n, int root)
0152 {
0153 detail::scatterv_impl(comm, in_values, out_values, n, (int const*)0, (int const*)0,
0154 root, is_mpi_datatype<T>());
0155 }
0156
0157 template<typename T>
0158 void
0159 scatterv(const communicator& comm, const std::vector<T>& in_values,
0160 T* out_values, int out_size, int root)
0161 {
0162 ::boost::mpi::scatterv(comm, detail::c_data(in_values), out_values, out_size, root);
0163 }
0164
0165 } }
0166
0167 #endif