Switch to using size_t instead of int for buffer position, and properly account for MPI using int

This commit is contained in:
Vegard Kippe
2024-07-09 13:48:04 +02:00
parent 758a5f0dfd
commit c10695c5d5
4 changed files with 53 additions and 35 deletions

View File

@@ -45,7 +45,7 @@ template<std::size_t Size>
void Packing<false,std::bitset<Size>>:: void Packing<false,std::bitset<Size>>::
pack(const std::bitset<Size>& data, pack(const std::bitset<Size>& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) Parallel::MPIComm comm)
{ {
Packing<true,unsigned long long>::pack(data.to_ullong(), buffer, position, comm); Packing<true,unsigned long long>::pack(data.to_ullong(), buffer, position, comm);
@@ -55,7 +55,7 @@ template<std::size_t Size>
void Packing<false,std::bitset<Size>>:: void Packing<false,std::bitset<Size>>::
unpack(std::bitset<Size>& data, unpack(std::bitset<Size>& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) Parallel::MPIComm comm)
{ {
unsigned long long d; unsigned long long d;
@@ -76,28 +76,32 @@ packSize(const std::string& data, Parallel::MPIComm comm)
void Packing<false,std::string>:: void Packing<false,std::string>::
pack(const std::string& data, pack(const std::string& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) Parallel::MPIComm comm)
{ {
std::size_t length = data.size(); std::size_t length = data.size();
MPI_Pack(&length, 1, Dune::MPITraits<std::size_t>::getType(), buffer.data(), int int_position;
buffer.size(), &position, comm); MPI_Pack(&length, 1, Dune::MPITraits<std::size_t>::getType(), buffer.data()+position,
MPI_Pack(data.data(), length, MPI_CHAR, buffer.data(), buffer.size(), mpi_buffer_size(buffer.size(), position), &int_position, comm);
&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<false,std::string>:: void Packing<false,std::string>::
unpack(std::string& data, unpack(std::string& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Opm::Parallel::MPIComm comm) Opm::Parallel::MPIComm comm)
{ {
std::size_t length = 0; 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<std::size_t>::getType(), comm); Dune::MPITraits<std::size_t>::getType(), comm);
std::vector<char> cStr(length+1, '\0'); std::vector<char> 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); MPI_CHAR, comm);
position += int_position;
data.clear(); data.clear();
data.append(cStr.data(), length); data.append(cStr.data(), length);
} }
@@ -111,7 +115,7 @@ packSize(const time_point&, Opm::Parallel::MPIComm comm)
void Packing<false,time_point>:: void Packing<false,time_point>::
pack(const time_point& data, pack(const time_point& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) Parallel::MPIComm comm)
{ {
Packing<true,std::time_t>::pack(TimeService::to_time_t(data), Packing<true,std::time_t>::pack(TimeService::to_time_t(data),
@@ -121,7 +125,7 @@ pack(const time_point& data,
void Packing<false,time_point>:: void Packing<false,time_point>::
unpack(time_point& data, unpack(time_point& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) Parallel::MPIComm comm)
{ {
std::time_t res; std::time_t res;

View File

@@ -26,19 +26,26 @@
#include <bitset> #include <bitset>
#include <cstddef> #include <cstddef>
#include <limits>
#include <string> #include <string>
namespace Opm { namespace Opm {
namespace Mpi { namespace Mpi {
namespace detail { namespace detail {
static std::size_t mpi_buffer_size(const std::size_t bufsize, const std::size_t position) {
return static_cast<int>(std::min(bufsize-position,
static_cast<std::size_t>(std::numeric_limits<int>::max())));
}
//! \brief Abstract struct for packing which is (partially) specialized for specific types. //! \brief Abstract struct for packing which is (partially) specialized for specific types.
template <bool pod, class T> template <bool pod, class T>
struct Packing struct Packing
{ {
static std::size_t packSize(const T&, Parallel::MPIComm); static std::size_t packSize(const T&, Parallel::MPIComm);
static void pack(const T&, std::vector<char>&, int&, Parallel::MPIComm); static void pack(const T&, std::vector<char>&, std::size_t&, Parallel::MPIComm);
static void unpack(T&, std::vector<char>&, int&, Parallel::MPIComm); static void unpack(T&, std::vector<char>&, std::size_t&, Parallel::MPIComm);
}; };
//! \brief Packaging for pod data. //! \brief Packaging for pod data.
@@ -59,6 +66,9 @@ struct Packing<true,T>
//! \param comm The communicator to use //! \param comm The communicator to use
static std::size_t packSize(const T*, std::size_t n, Parallel::MPIComm comm) 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<int>::max() );
int size = 0; int size = 0;
MPI_Pack_size(n, Dune::MPITraits<T>::getType(), comm, &size); MPI_Pack_size(n, Dune::MPITraits<T>::getType(), comm, &size);
return size; return size;
@@ -71,7 +81,7 @@ struct Packing<true,T>
//! \param comm The communicator to use //! \param comm The communicator to use
static void pack(const T& data, static void pack(const T& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) Parallel::MPIComm comm)
{ {
pack(&data, 1, buffer, position, comm); pack(&data, 1, buffer, position, comm);
@@ -86,11 +96,13 @@ struct Packing<true,T>
static void pack(const T* data, static void pack(const T* data,
std::size_t n, std::size_t n,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) Parallel::MPIComm comm)
{ {
MPI_Pack(data, n, Dune::MPITraits<T>::getType(), buffer.data(), int int_position = 0;
buffer.size(), &position, comm); MPI_Pack(data, n, Dune::MPITraits<T>::getType(), buffer.data()+position,
mpi_buffer_size(buffer.size(), position), &int_position, comm);
position += int_position;
} }
//! \brief Unpack a POD. //! \brief Unpack a POD.
@@ -100,7 +112,7 @@ struct Packing<true,T>
//! \param comm The communicator to use //! \param comm The communicator to use
static void unpack(T& data, static void unpack(T& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) Parallel::MPIComm comm)
{ {
unpack(&data, 1, buffer, position, comm); unpack(&data, 1, buffer, position, comm);
@@ -115,11 +127,13 @@ struct Packing<true,T>
static void unpack(T* data, static void unpack(T* data,
std::size_t n, std::size_t n,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position, std::size_t& position,
Parallel::MPIComm comm) 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<T>::getType(), comm); Dune::MPITraits<T>::getType(), comm);
position += int_position;
} }
}; };
@@ -133,13 +147,13 @@ struct Packing<false,T>
return 0; return 0;
} }
static void pack(const T&, std::vector<char>&, int&, static void pack(const T&, std::vector<char>&, std::size_t&,
Parallel::MPIComm) Parallel::MPIComm)
{ {
static_assert(!std::is_same_v<T,T>, "Packing not supported for type"); static_assert(!std::is_same_v<T,T>, "Packing not supported for type");
} }
static void unpack(T&, std::vector<char>&, int&, static void unpack(T&, std::vector<char>&, std::size_t&,
Parallel::MPIComm) Parallel::MPIComm)
{ {
static_assert(!std::is_same_v<T,T>, "Packing not supported for type"); static_assert(!std::is_same_v<T,T>, "Packing not supported for type");
@@ -151,8 +165,8 @@ template <std::size_t Size>
struct Packing<false,std::bitset<Size>> struct Packing<false,std::bitset<Size>>
{ {
static std::size_t packSize(const std::bitset<Size>&, Opm::Parallel::MPIComm); static std::size_t packSize(const std::bitset<Size>&, Opm::Parallel::MPIComm);
static void pack(const std::bitset<Size>&, std::vector<char>&, int&, Opm::Parallel::MPIComm); static void pack(const std::bitset<Size>&, std::vector<char>&, std::size_t&, Opm::Parallel::MPIComm);
static void unpack(std::bitset<Size>&, std::vector<char>&, int&, Opm::Parallel::MPIComm); static void unpack(std::bitset<Size>&, std::vector<char>&, std::size_t&, Opm::Parallel::MPIComm);
}; };
#define ADD_PACK_SPECIALIZATION(T) \ #define ADD_PACK_SPECIALIZATION(T) \
@@ -160,8 +174,8 @@ struct Packing<false,std::bitset<Size>>
struct Packing<false,T> \ struct Packing<false,T> \
{ \ { \
static std::size_t packSize(const T&, Parallel::MPIComm); \ static std::size_t packSize(const T&, Parallel::MPIComm); \
static void pack(const T&, std::vector<char>&, int&, Parallel::MPIComm); \ static void pack(const T&, std::vector<char>&, std::size_t&, Parallel::MPIComm); \
static void unpack(T&, std::vector<char>&, int&, Parallel::MPIComm); \ static void unpack(T&, std::vector<char>&, std::size_t&, Parallel::MPIComm); \
}; };
ADD_PACK_SPECIALIZATION(std::string) ADD_PACK_SPECIALIZATION(std::string)
@@ -207,7 +221,7 @@ struct Packer {
template<class T> template<class T>
void pack(const T& data, void pack(const T& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position) const std::size_t& position) const
{ {
detail::Packing<std::is_pod_v<T>,T>::pack(data, buffer, position, m_comm); detail::Packing<std::is_pod_v<T>,T>::pack(data, buffer, position, m_comm);
} }
@@ -222,7 +236,7 @@ struct Packer {
void pack(const T* data, void pack(const T* data,
std::size_t n, std::size_t n,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position) const std::size_t& position) const
{ {
static_assert(std::is_pod_v<T>, "Array packing not supported for non-pod data"); static_assert(std::is_pod_v<T>, "Array packing not supported for non-pod data");
detail::Packing<true,T>::pack(data, n, buffer, position, m_comm); detail::Packing<true,T>::pack(data, n, buffer, position, m_comm);
@@ -236,7 +250,7 @@ struct Packer {
template<class T> template<class T>
void unpack(T& data, void unpack(T& data,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position) const std::size_t& position) const
{ {
detail::Packing<std::is_pod_v<T>,T>::unpack(data, buffer, position, m_comm); detail::Packing<std::is_pod_v<T>,T>::unpack(data, buffer, position, m_comm);
} }
@@ -251,7 +265,7 @@ struct Packer {
void unpack(T* data, void unpack(T* data,
std::size_t n, std::size_t n,
std::vector<char>& buffer, std::vector<char>& buffer,
int& position) const std::size_t& position) const
{ {
static_assert(std::is_pod_v<T>, "Array packing not supported for non-pod data"); static_assert(std::is_pod_v<T>, "Array packing not supported for non-pod data");
detail::Packing<true,T>::unpack(data, n, buffer, position, m_comm); detail::Packing<true,T>::unpack(data, n, buffer, position, m_comm);

View File

@@ -34,14 +34,14 @@ packSize(const boost::gregorian::date& data)
void Packing<false,boost::gregorian::date>:: void Packing<false,boost::gregorian::date>::
pack(const boost::gregorian::date& data, pack(const boost::gregorian::date& data,
std::vector<char>& buffer, int& position) std::vector<char>& buffer, std::size_t& position)
{ {
Packing<false,std::string>::pack(boost::gregorian::to_simple_string(data), buffer, position); Packing<false,std::string>::pack(boost::gregorian::to_simple_string(data), buffer, position);
} }
void Packing<false,boost::gregorian::date>:: void Packing<false,boost::gregorian::date>::
unpack(boost::gregorian::date& data, unpack(boost::gregorian::date& data,
std::vector<char>& buffer, int& position) std::vector<char>& buffer, std::size_t& position)
{ {
std::string date; std::string date;
Packing<false,std::string>::unpack(date, buffer, position); Packing<false,std::string>::unpack(date, buffer, position);

View File

@@ -35,10 +35,10 @@ struct Packing<false,boost::gregorian::date>
static std::size_t packSize(const boost::gregorian::date& data); static std::size_t packSize(const boost::gregorian::date& data);
static void pack(const boost::gregorian::date& data, static void pack(const boost::gregorian::date& data,
std::vector<char>& buffer, int& position); std::vector<char>& buffer, std::size_t& position);
static void unpack(boost::gregorian::date& data, static void unpack(boost::gregorian::date& data,
std::vector<char>& buffer, int& position); std::vector<char>& buffer, std::size_t& position);
}; };
} }