Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:56

0001 // Copyright (C) 2011 JĂșlio Hoffimann.
0002 
0003 // Use, modification and distribution is subject to the Boost Software
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 // Message Passing Interface 1.1 -- Section 4.5. Gatherv
0008 #ifndef BOOST_MPI_GATHERV_HPP
0009 #define BOOST_MPI_GATHERV_HPP
0010 
0011 #include <vector>
0012 
0013 #include <boost/mpi/exception.hpp>
0014 #include <boost/mpi/datatype.hpp>
0015 #include <boost/mpi/packed_oarchive.hpp>
0016 #include <boost/mpi/packed_iarchive.hpp>
0017 #include <boost/mpi/detail/point_to_point.hpp>
0018 #include <boost/mpi/communicator.hpp>
0019 #include <boost/mpi/environment.hpp>
0020 #include <boost/mpi/detail/offsets.hpp>
0021 #include <boost/assert.hpp>
0022 #include <boost/scoped_array.hpp>
0023 
0024 namespace boost { namespace mpi {
0025 
0026 namespace detail {
0027   // We're gathering at the root for a type that has an associated MPI
0028   // datatype, so we'll use MPI_Gatherv to do all of the work.
0029   template<typename T>
0030   void
0031   gatherv_impl(const communicator& comm, const T* in_values, int in_size, 
0032                T* out_values, const int* sizes, const int* displs, int root, mpl::true_)
0033   {
0034     MPI_Datatype type = get_mpi_datatype<T>(*in_values);
0035     BOOST_MPI_CHECK_RESULT(MPI_Gatherv,
0036                            (const_cast<T*>(in_values), in_size, type,
0037                             out_values, const_cast<int*>(sizes), const_cast<int*>(displs),
0038                             type, root, comm));
0039   }
0040 
0041   // We're gathering from a non-root for a type that has an associated MPI
0042   // datatype, so we'll use MPI_Gatherv to do all of the work.
0043   template<typename T>
0044   void
0045   gatherv_impl(const communicator& comm, const T* in_values, int in_size, int root, 
0046               mpl::true_)
0047   {
0048     MPI_Datatype type = get_mpi_datatype<T>(*in_values);
0049     BOOST_MPI_CHECK_RESULT(MPI_Gatherv,
0050                            (const_cast<T*>(in_values), in_size, type,
0051                             0, 0, 0, type, root, comm));
0052   }
0053 
0054   // We're gathering at the root for a type that does not have an
0055   // associated MPI datatype, so we'll need to serialize
0056   // it. Unfortunately, this means that we cannot use MPI_Gatherv, so
0057   // we'll just have all of the non-root nodes send individual
0058   // messages to the root.
0059   template<typename T>
0060   void
0061   gatherv_impl(const communicator& comm, const T* in_values, int in_size, 
0062                T* out_values, const int* sizes, const int* displs, int root, mpl::false_)
0063   {
0064     // convert displacement to offsets to skip
0065     scoped_array<int> skipped(make_skipped_slots(comm, sizes, displs, root));
0066     gather_impl(comm, in_values, in_size, out_values, sizes, skipped.get(), root, mpl::false_());
0067   }
0068 
0069   // We're gathering at a non-root for a type that does not have an
0070   // associated MPI datatype, so we'll need to serialize
0071   // it.
0072   template<typename T>
0073   void
0074   gatherv_impl(const communicator& comm, const T* in_values, int in_size, int root, 
0075               mpl::false_)
0076   {
0077     gather_impl(comm, in_values, in_size, (T*)0,(int const*)0,(int const*)0, root,
0078                 mpl::false_());
0079   }
0080 } // end namespace detail
0081 
0082 template<typename T>
0083 void
0084 gatherv(const communicator& comm, const T* in_values, int in_size,
0085         T* out_values, const std::vector<int>& sizes, const std::vector<int>& displs,
0086         int root)
0087 {
0088   if (comm.rank() == root)
0089     detail::gatherv_impl(comm, in_values, in_size,
0090                          out_values, detail::c_data(sizes), detail::c_data(displs),
0091                          root, is_mpi_datatype<T>());
0092   else
0093     detail::gatherv_impl(comm, in_values, in_size, root, is_mpi_datatype<T>());
0094 }
0095 
0096 template<typename T>
0097 void
0098 gatherv(const communicator& comm, const std::vector<T>& in_values,
0099         T* out_values, const std::vector<int>& sizes, const std::vector<int>& displs,
0100         int root)
0101 {
0102   ::boost::mpi::gatherv(comm, detail::c_data(in_values), in_values.size(), out_values, sizes, displs, root);
0103 }
0104 
0105 template<typename T>
0106 void gatherv(const communicator& comm, const T* in_values, int in_size, int root)
0107 {
0108   BOOST_ASSERT(comm.rank() != root);
0109   detail::gatherv_impl(comm, in_values, in_size, root, is_mpi_datatype<T>());
0110 }
0111 
0112 template<typename T>
0113 void gatherv(const communicator& comm, const std::vector<T>& in_values, int root)
0114 {
0115   BOOST_ASSERT(comm.rank() != root);
0116   detail::gatherv_impl(comm, detail::c_data(in_values), in_values.size(), root, is_mpi_datatype<T>());
0117 }
0118 
0119 ///////////////////////
0120 // common use versions
0121 ///////////////////////
0122 template<typename T>
0123 void
0124 gatherv(const communicator& comm, const T* in_values, int in_size,
0125         T* out_values, const std::vector<int>& sizes, int root)
0126 {
0127   int nprocs = comm.size();
0128 
0129   std::vector<int> displs( nprocs );
0130   for (int rank = 0, aux = 0; rank < nprocs; ++rank) {
0131     displs[rank] = aux;
0132     aux += sizes[rank];
0133   }
0134   ::boost::mpi::gatherv(comm, in_values, in_size, out_values, sizes, displs, root);
0135 }
0136 
0137 template<typename T>
0138 void
0139 gatherv(const communicator& comm, const std::vector<T>& in_values,
0140         T* out_values, const std::vector<int>& sizes, int root)
0141 {
0142   ::boost::mpi::gatherv(comm, detail::c_data(in_values), in_values.size(), out_values, sizes, root);
0143 }
0144 
0145 } } // end namespace boost::mpi
0146 
0147 #endif // BOOST_MPI_GATHERV_HPP