From c10695c5d5756ce8fbda3bc7f49cbd577a9a47c4 Mon Sep 17 00:00:00 2001 From: Vegard Kippe Date: Tue, 9 Jul 2024 13:48:04 +0200 Subject: [PATCH] Switch to using size_t instead of int for buffer position, and properly account for MPI using int --- opm/simulators/utils/MPIPacker.cpp | 28 +++++----- opm/simulators/utils/MPIPacker.hpp | 52 ++++++++++++------- opm/simulators/utils/SerializationPackers.cpp | 4 +- opm/simulators/utils/SerializationPackers.hpp | 4 +- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/opm/simulators/utils/MPIPacker.cpp b/opm/simulators/utils/MPIPacker.cpp index 5d0d08ce1..601f53f37 100644 --- a/opm/simulators/utils/MPIPacker.cpp +++ b/opm/simulators/utils/MPIPacker.cpp @@ -45,7 +45,7 @@ template void Packing>:: pack(const std::bitset& data, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { Packing::pack(data.to_ullong(), buffer, position, comm); @@ -55,7 +55,7 @@ template void Packing>:: unpack(std::bitset& data, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { unsigned long long d; @@ -76,28 +76,32 @@ packSize(const std::string& data, Parallel::MPIComm comm) void Packing:: pack(const std::string& data, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { std::size_t length = data.size(); - MPI_Pack(&length, 1, Dune::MPITraits::getType(), buffer.data(), - buffer.size(), &position, comm); - MPI_Pack(data.data(), length, MPI_CHAR, buffer.data(), buffer.size(), - &position, comm); + int int_position; + MPI_Pack(&length, 1, Dune::MPITraits::getType(), buffer.data()+position, + mpi_buffer_size(buffer.size(), position), &int_position, comm); + MPI_Pack(data.data(), length, MPI_CHAR, buffer.data()+position, mpi_buffer_size(buffer.size(), position), + &int_position, comm); + position += int_position; } void Packing:: unpack(std::string& data, std::vector& buffer, - int& position, + std::size_t& position, Opm::Parallel::MPIComm comm) { std::size_t length = 0; - MPI_Unpack(buffer.data(), buffer.size(), &position, &length, 1, + int int_position; + MPI_Unpack(buffer.data()+position, mpi_buffer_size(buffer.size(), position), &int_position, &length, 1, Dune::MPITraits::getType(), comm); std::vector cStr(length+1, '\0'); - MPI_Unpack(buffer.data(), buffer.size(), &position, cStr.data(), length, + MPI_Unpack(buffer.data()+position, mpi_buffer_size(buffer.size(), position), &int_position, cStr.data(), length, MPI_CHAR, comm); + position += int_position; data.clear(); data.append(cStr.data(), length); } @@ -111,7 +115,7 @@ packSize(const time_point&, Opm::Parallel::MPIComm comm) void Packing:: pack(const time_point& data, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { Packing::pack(TimeService::to_time_t(data), @@ -121,7 +125,7 @@ pack(const time_point& data, void Packing:: unpack(time_point& data, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { std::time_t res; diff --git a/opm/simulators/utils/MPIPacker.hpp b/opm/simulators/utils/MPIPacker.hpp index 9d5173e8c..056fc1255 100644 --- a/opm/simulators/utils/MPIPacker.hpp +++ b/opm/simulators/utils/MPIPacker.hpp @@ -26,19 +26,26 @@ #include #include +#include #include + namespace Opm { namespace Mpi { namespace detail { +static std::size_t mpi_buffer_size(const std::size_t bufsize, const std::size_t position) { + return static_cast(std::min(bufsize-position, + static_cast(std::numeric_limits::max()))); +} + //! \brief Abstract struct for packing which is (partially) specialized for specific types. template struct Packing { static std::size_t packSize(const T&, Parallel::MPIComm); - static void pack(const T&, std::vector&, int&, Parallel::MPIComm); - static void unpack(T&, std::vector&, int&, Parallel::MPIComm); + static void pack(const T&, std::vector&, std::size_t&, Parallel::MPIComm); + static void unpack(T&, std::vector&, std::size_t&, Parallel::MPIComm); }; //! \brief Packaging for pod data. @@ -59,6 +66,9 @@ struct Packing //! \param comm The communicator to use static std::size_t packSize(const T*, std::size_t n, Parallel::MPIComm comm) { + // For now we do not handle the situation where a a single call to packSize/pack/unpack + // is likely to require an MPI_Pack_size value larger than intmax + assert ( n*sizeof(T) <= std::numeric_limits::max() ); int size = 0; MPI_Pack_size(n, Dune::MPITraits::getType(), comm, &size); return size; @@ -71,7 +81,7 @@ struct Packing //! \param comm The communicator to use static void pack(const T& data, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { pack(&data, 1, buffer, position, comm); @@ -86,11 +96,13 @@ struct Packing static void pack(const T* data, std::size_t n, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { - MPI_Pack(data, n, Dune::MPITraits::getType(), buffer.data(), - buffer.size(), &position, comm); + int int_position = 0; + MPI_Pack(data, n, Dune::MPITraits::getType(), buffer.data()+position, + mpi_buffer_size(buffer.size(), position), &int_position, comm); + position += int_position; } //! \brief Unpack a POD. @@ -100,7 +112,7 @@ struct Packing //! \param comm The communicator to use static void unpack(T& data, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { unpack(&data, 1, buffer, position, comm); @@ -115,11 +127,13 @@ struct Packing static void unpack(T* data, std::size_t n, std::vector& buffer, - int& position, + std::size_t& position, Parallel::MPIComm comm) { - MPI_Unpack(buffer.data(), buffer.size(), &position, data, n, + int int_position = 0; + MPI_Unpack(buffer.data()+position, mpi_buffer_size(buffer.size(), position), &int_position, data, n, Dune::MPITraits::getType(), comm); + position += int_position; } }; @@ -133,13 +147,13 @@ struct Packing return 0; } - static void pack(const T&, std::vector&, int&, + static void pack(const T&, std::vector&, std::size_t&, Parallel::MPIComm) { static_assert(!std::is_same_v, "Packing not supported for type"); } - static void unpack(T&, std::vector&, int&, + static void unpack(T&, std::vector&, std::size_t&, Parallel::MPIComm) { static_assert(!std::is_same_v, "Packing not supported for type"); @@ -151,8 +165,8 @@ template struct Packing> { static std::size_t packSize(const std::bitset&, Opm::Parallel::MPIComm); - static void pack(const std::bitset&, std::vector&, int&, Opm::Parallel::MPIComm); - static void unpack(std::bitset&, std::vector&, int&, Opm::Parallel::MPIComm); + static void pack(const std::bitset&, std::vector&, std::size_t&, Opm::Parallel::MPIComm); + static void unpack(std::bitset&, std::vector&, std::size_t&, Opm::Parallel::MPIComm); }; #define ADD_PACK_SPECIALIZATION(T) \ @@ -160,8 +174,8 @@ struct Packing> struct Packing \ { \ static std::size_t packSize(const T&, Parallel::MPIComm); \ - static void pack(const T&, std::vector&, int&, Parallel::MPIComm); \ - static void unpack(T&, std::vector&, int&, Parallel::MPIComm); \ + static void pack(const T&, std::vector&, std::size_t&, Parallel::MPIComm); \ + static void unpack(T&, std::vector&, std::size_t&, Parallel::MPIComm); \ }; ADD_PACK_SPECIALIZATION(std::string) @@ -207,7 +221,7 @@ struct Packer { template void pack(const T& data, std::vector& buffer, - int& position) const + std::size_t& position) const { detail::Packing,T>::pack(data, buffer, position, m_comm); } @@ -222,7 +236,7 @@ struct Packer { void pack(const T* data, std::size_t n, std::vector& buffer, - int& position) const + std::size_t& position) const { static_assert(std::is_pod_v, "Array packing not supported for non-pod data"); detail::Packing::pack(data, n, buffer, position, m_comm); @@ -236,7 +250,7 @@ struct Packer { template void unpack(T& data, std::vector& buffer, - int& position) const + std::size_t& position) const { detail::Packing,T>::unpack(data, buffer, position, m_comm); } @@ -251,7 +265,7 @@ struct Packer { void unpack(T* data, std::size_t n, std::vector& buffer, - int& position) const + std::size_t& position) const { static_assert(std::is_pod_v, "Array packing not supported for non-pod data"); detail::Packing::unpack(data, n, buffer, position, m_comm); diff --git a/opm/simulators/utils/SerializationPackers.cpp b/opm/simulators/utils/SerializationPackers.cpp index 6d7d927db..4c5879351 100644 --- a/opm/simulators/utils/SerializationPackers.cpp +++ b/opm/simulators/utils/SerializationPackers.cpp @@ -34,14 +34,14 @@ packSize(const boost::gregorian::date& data) void Packing:: pack(const boost::gregorian::date& data, - std::vector& buffer, int& position) + std::vector& buffer, std::size_t& position) { Packing::pack(boost::gregorian::to_simple_string(data), buffer, position); } void Packing:: unpack(boost::gregorian::date& data, - std::vector& buffer, int& position) + std::vector& buffer, std::size_t& position) { std::string date; Packing::unpack(date, buffer, position); diff --git a/opm/simulators/utils/SerializationPackers.hpp b/opm/simulators/utils/SerializationPackers.hpp index d30bb50df..9b3a17cd2 100644 --- a/opm/simulators/utils/SerializationPackers.hpp +++ b/opm/simulators/utils/SerializationPackers.hpp @@ -35,10 +35,10 @@ struct Packing static std::size_t packSize(const boost::gregorian::date& data); static void pack(const boost::gregorian::date& data, - std::vector& buffer, int& position); + std::vector& buffer, std::size_t& position); static void unpack(boost::gregorian::date& data, - std::vector& buffer, int& position); + std::vector& buffer, std::size_t& position); }; }