diff --git a/opm/simulators/utils/MPIPacker.cpp b/opm/simulators/utils/MPIPacker.cpp index cf25f7a4c..430a10b26 100644 --- a/opm/simulators/utils/MPIPacker.cpp +++ b/opm/simulators/utils/MPIPacker.cpp @@ -70,7 +70,7 @@ packSize(const std::string& data, Parallel::MPIComm comm) MPI_Pack_size(1, Dune::MPITraits::getType(), comm, &size); int totalSize = size; MPI_Pack_size(data.size(), MPI_CHAR, comm, &size); - return static_cast(totalSize + size); + return totalSize + size; } void Packing:: diff --git a/opm/simulators/utils/MPIPacker.hpp b/opm/simulators/utils/MPIPacker.hpp index 8263d1645..cd4406280 100644 --- a/opm/simulators/utils/MPIPacker.hpp +++ b/opm/simulators/utils/MPIPacker.hpp @@ -35,7 +35,9 @@ namespace Mpi { namespace detail { static std::size_t mpi_buffer_size(const std::size_t bufsize, const std::size_t position) { - assert (bufsize >= position); + if (bufsize < position) + throw std::invalid_argument("Buffer size should never be less than position!"); + return static_cast(std::min(bufsize-position, static_cast(std::numeric_limits::max()))); } @@ -69,11 +71,10 @@ struct Packing { // 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() ); + if (n*sizeof(T) > std::numeric_limits::max()) + throw std::invalid_argument("packSize will be larger than max integer - this is not supported."); int size = 0; MPI_Pack_size(n, Dune::MPITraits::getType(), comm, &size); - assert (size >= 0); - assert (size < std::numeric_limits::max() ); return static_cast(size); } diff --git a/opm/simulators/utils/MPISerializer.hpp b/opm/simulators/utils/MPISerializer.hpp index 49729e4cd..1a12f07dd 100644 --- a/opm/simulators/utils/MPISerializer.hpp +++ b/opm/simulators/utils/MPISerializer.hpp @@ -52,15 +52,7 @@ public: try { this->pack(data); m_comm.broadcast(&m_packSize, 1, root); - const int maxChunkSize = std::numeric_limits::max(); - std::size_t remainingSize = m_packSize; - std::size_t pos = 0; - while (remainingSize > maxChunkSize) { - m_comm.broadcast(m_buffer.data()+pos, maxChunkSize, root); - pos += maxChunkSize; - remainingSize -= maxChunkSize; - } - m_comm.broadcast(m_buffer.data()+pos, static_cast(remainingSize), root); + broadcast_chunked(root); } catch (...) { m_packSize = std::numeric_limits::max(); m_comm.broadcast(&m_packSize, 1, root); @@ -72,15 +64,7 @@ public: throw std::runtime_error("Error detected in parallel serialization"); } m_buffer.resize(m_packSize); - const int maxChunkSize = std::numeric_limits::max(); - std::size_t remainingSize = m_packSize; - std::size_t pos = 0; - while (remainingSize > maxChunkSize) { - m_comm.broadcast(m_buffer.data()+pos, maxChunkSize, root); - pos += maxChunkSize; - remainingSize -= maxChunkSize; - } - m_comm.broadcast(m_buffer.data()+pos, static_cast(remainingSize), root); + broadcast_chunked(root); this->unpack(data); } } @@ -95,15 +79,7 @@ public: try { this->pack(std::forward(args)...); m_comm.broadcast(&m_packSize, 1, root); - const int maxChunkSize = std::numeric_limits::max(); - std::size_t remainingSize = m_packSize; - std::size_t pos = 0; - while (remainingSize > maxChunkSize) { - m_comm.broadcast(m_buffer.data()+pos, maxChunkSize, root); - pos += maxChunkSize; - remainingSize -= maxChunkSize; - } - m_comm.broadcast(m_buffer.data()+pos, static_cast(remainingSize), root); + broadcast_chunked(root); } catch (...) { m_packSize = std::numeric_limits::max(); m_comm.broadcast(&m_packSize, 1, root); @@ -115,15 +91,7 @@ public: throw std::runtime_error("Error detected in parallel serialization"); } m_buffer.resize(m_packSize); - const int maxChunkSize = std::numeric_limits::max(); - std::size_t remainingSize = m_packSize; - std::size_t pos = 0; - while (remainingSize > maxChunkSize) { - m_comm.broadcast(m_buffer.data()+pos, maxChunkSize, root); - pos += maxChunkSize; - remainingSize -= maxChunkSize; - } - m_comm.broadcast(m_buffer.data()+pos, static_cast(remainingSize), root); + broadcast_chunked(root); this->unpack(std::forward(args)...); } } @@ -149,6 +117,18 @@ public: } private: + void broadcast_chunked(int root) { + const int maxChunkSize = std::numeric_limits::max(); + std::size_t remainingSize = m_packSize; + std::size_t pos = 0; + while (remainingSize > maxChunkSize) { + m_comm.broadcast(m_buffer.data()+pos, maxChunkSize, root); + pos += maxChunkSize; + remainingSize -= maxChunkSize; + } + m_comm.broadcast(m_buffer.data()+pos, static_cast(remainingSize), root); + } + const Mpi::Packer m_packer; //!< Packer instance Parallel::Communication m_comm; //!< Communicator to use };