Skip to content

Commit

Permalink
core: Cleanup memcpy_archive test
Browse files Browse the repository at this point in the history
  • Loading branch information
fweik committed Nov 4, 2019
1 parent 344d8de commit 9aec365
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 66 deletions.
71 changes: 16 additions & 55 deletions src/core/ghosts.cpp
Expand Up @@ -38,6 +38,7 @@
#include <utils/Span.hpp>
#include <utils/serialization/memcpy_archive.hpp>

#include <boost/range/algorithm/copy.hpp>
#include <boost/serialization/vector.hpp>

#include <algorithm>
Expand All @@ -50,10 +51,6 @@
/** Tag for ghosts communications. */
#define REQ_GHOST_SEND 100

template <>
struct Utils::is_statically_serializable<ParticleProperties> : std::true_type {
};

/**
* Class that stores marshalled data for ghost communications.
* To store and retrieve data, use the adapter classes below.
Expand Down Expand Up @@ -83,42 +80,6 @@ class CommBuf {
std::vector<int> bondbuf; //< Buffer for bond lists
};

/**
* Adapter to CommBuf that allows putting in and getting back bond data.
* Note, this class inserts the data handed to operator<< at the end
* of the underlying buffer. It does resize the buffer.
*/
struct BondArchiver {
private:
/* underlying buffer type */
using buffer_type = std::vector<int>;
buffer_type &bondbuf;

/* iterator into the underlying buffer */
using const_iterator = buffer_type::const_iterator;
const_iterator bond_retrieve;

// Need to save these because send buffer will invalidate cb.bondbuffer.
const const_iterator initial_begin;
const size_t initial_size;

public:
explicit BondArchiver(buffer_type &bondbuf)
: bondbuf(bondbuf), bond_retrieve(bondbuf.cbegin()),
initial_begin(bondbuf.cbegin()), initial_size(bondbuf.size()) {}

~BondArchiver() { assert(bond_retrieve == initial_begin + initial_size); }

template <typename T> inline void operator<<(const Utils::Span<T> data) {
bondbuf.insert(bondbuf.end(), data.cbegin(), data.cend());
}

template <typename T> inline void operator>>(Utils::Span<T> data) {
std::copy_n(bond_retrieve, data.size(), data.begin());
bond_retrieve += data.size();
}
};

/** whether the ghosts should have velocity information, e.g. for DPD or RATTLE.
* You need this whenever you need the relative velocity of two particles.
* NO CHANGES OF THIS VALUE OUTSIDE OF \ref on_ghost_flags_change !!!!
Expand All @@ -145,28 +106,27 @@ static size_t calc_transmit_size(unsigned data_parts) {
size += Utils::MemcpyOArchive::packing_size<ParticleProperties>();
}
if (data_parts & GHOSTTRANS_BONDS) {
size += sizeof(int);
size += Utils::MemcpyOArchive::packing_size<int>();
}
if (data_parts & GHOSTTRANS_POSITION)
size += sizeof(ParticlePosition);
size += Utils::MemcpyOArchive::packing_size<ParticlePosition>();
if (data_parts & GHOSTTRANS_MOMENTUM)
size += sizeof(ParticleMomentum);
size += Utils::MemcpyOArchive::packing_size<ParticleMomentum>();
if (data_parts & GHOSTTRANS_FORCE)
size += sizeof(ParticleForce);
size += Utils::MemcpyOArchive::packing_size<ParticleForce>();

return size;
}

static size_t calc_transmit_size(GhostCommunication &ghost_comm,
unsigned int data_parts) {
unsigned int data_parts) {
if (data_parts & GHOSTTRANS_PARTNUM)
return sizeof(int) * ghost_comm.part_lists.size();
else {
auto const n_part = boost::accumulate(
ghost_comm.part_lists, 0ul,
[](size_t sum, auto part_list) { return sum + part_list->n; });
return n_part * calc_transmit_size(data_parts);
}

auto const n_part = boost::accumulate(
ghost_comm.part_lists, 0ul,
[](size_t sum, auto part_list) { return sum + part_list->n; });
return n_part * calc_transmit_size(data_parts);
}

static void prepare_send_buffer(CommBuf &send_buffer,
Expand All @@ -177,7 +137,7 @@ static void prepare_send_buffer(CommBuf &send_buffer,
send_buffer.bonds().clear();

auto archiver = Utils::MemcpyOArchive{Utils::make_span(send_buffer)};
auto bond_archiver = BondArchiver{send_buffer.bonds()};
auto bond_buffer = std::back_inserter(send_buffer.bonds());

/* put in data */
for (auto part_list : ghost_comm.part_lists) {
Expand All @@ -203,7 +163,7 @@ static void prepare_send_buffer(CommBuf &send_buffer,
}
if (data_parts & GHOSTTRANS_BONDS) {
archiver << part.bl.n;
bond_archiver << Utils::make_const_span(part.bl);
boost::copy(part.bl, bond_buffer);
}
}
}
Expand Down Expand Up @@ -251,7 +211,7 @@ static void put_recv_buffer(CommBuf &recv_buffer,
unsigned int data_parts) {
/* put back data */
auto archiver = Utils::MemcpyIArchive{Utils::make_span(recv_buffer)};
auto bond_archiver = BondArchiver{recv_buffer.bonds()};
auto bond_buffer = recv_buffer.bonds().begin();

for (auto part_list : ghost_comm.part_lists) {
if (data_parts & GHOSTTRANS_PARTNUM) {
Expand Down Expand Up @@ -279,7 +239,8 @@ static void put_recv_buffer(CommBuf &recv_buffer,
decltype(part.bl.n) n_bonds;
archiver >> n_bonds;
part.bl.resize(n_bonds);
bond_archiver >> Utils::make_span(part.bl);
std::copy_n(bond_buffer, n_bonds, part.bl.begin());
bond_buffer += n_bonds;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/utils/include/utils/serialization/memcpy_archive.hpp
Expand Up @@ -143,8 +143,8 @@ template <class Derived> class BasicMemcpyArchive {
* Can only process types that have a static serialization size,
* e.g. that serialize to the same number of bytes independent of
* the state of the object. This can either be automatically detected
* for types that are trivially copyable, or by explicitly assuring
* this by specializing @c is_statically_serializable to std::true_type.
* for types that are trivially copyable, or by explicitly assured
* by specializing @c is_statically_serializable to std::true_type.
*/
class MemcpyIArchive : public detail::BasicMemcpyArchive<MemcpyIArchive> {
private:
Expand Down
17 changes: 8 additions & 9 deletions src/utils/tests/memcpy_archive_test.cpp
Expand Up @@ -28,9 +28,8 @@

#include <boost/optional.hpp>
#include <boost/serialization/optional.hpp>
#include <boost/variant.hpp>

#include <vector>
#include <array>

struct NonTrivial {
boost::optional<Utils::Vector3d> ov;
Expand All @@ -46,10 +45,6 @@ template <> struct is_statically_serializable<NonTrivial> : std::true_type {};
template <class T>
struct is_statically_serializable<boost::optional<T>>
: is_statically_serializable<T> {};

template <class... T>
struct is_statically_serializable<boost::variant<T...>>
: Utils::conjunction<is_statically_serializable<T>...> {};
} // namespace Utils

BOOST_AUTO_TEST_CASE(packing_size_test) {
Expand All @@ -62,13 +57,17 @@ BOOST_AUTO_TEST_CASE(packing_size_test) {
}

BOOST_AUTO_TEST_CASE(type_traits) {
static_assert(Utils::is_statically_serializable<int>::value, "");
static_assert(Utils::detail::use_memcpy<int>::value, "");
static_assert(not Utils::detail::use_serialize<int>::value, "");

static_assert(Utils::is_statically_serializable<OpVec>::value, "");
static_assert(not Utils::detail::use_memcpy<OpVec>::value, "");
static_assert(Utils::detail::use_serialize<OpVec>::value, "");
}

BOOST_AUTO_TEST_CASE(skiping_and_position) {
std::vector<char> buf(10);
std::array<char, 10> buf;

auto ar = Utils::MemcpyOArchive(Utils::make_span(buf));

Expand All @@ -78,7 +77,7 @@ BOOST_AUTO_TEST_CASE(skiping_and_position) {
}

BOOST_AUTO_TEST_CASE(memcpy_processing) {
std::vector<char> buf(10);
std::array<char, 10> buf;

auto const test_number = 5;
auto oa = Utils::MemcpyOArchive(Utils::make_span(buf));
Expand All @@ -95,7 +94,7 @@ BOOST_AUTO_TEST_CASE(memcpy_processing) {
}

BOOST_AUTO_TEST_CASE(serializaton_processing) {
std::vector<char> buf(2 * Utils::MemcpyOArchive::packing_size<OpVec>());
std::array<char, 2 * sizeof(OpVec)> buf;

const OpVec active = Utils::Vector3d{1., 2., 3.};
const OpVec inactive = boost::none;
Expand Down

0 comments on commit 9aec365

Please sign in to comment.