mirror of https://github.com/QMCPACK/qmcpack.git
160 lines
3.3 KiB
C++
160 lines
3.3 KiB
C++
// -*-indent-tabs-mode:t;c-basic-offset:4;tab-width:4;autowrap:nil;-*-
|
|
// Copyright 2018-2022 Alfredo A. Correa
|
|
|
|
#include <mpi3/communicator.hpp>
|
|
#include <mpi3/main.hpp>
|
|
#include <mpi3/process.hpp>
|
|
|
|
#include<boost/serialization/vector.hpp>
|
|
|
|
// nontrivial nonpod class
|
|
struct B { // NOLINT(readability-identifier-naming)
|
|
std::string name_ = "unnamed"; // NOLINT(misc-non-private-member-variables-in-classes)
|
|
std::size_t n_ = 0; // NOLINT(misc-non-private-member-variables-in-classes)
|
|
double* data = nullptr; // NOLINT(misc-non-private-member-variables-in-classes)
|
|
|
|
B() = default;
|
|
explicit B(std::size_t n) : n_{n}, data{new double[n]} { std::fill_n(data, n, 0.0); }
|
|
B(B const& other) : name_{other.name_}, n_{other.n_}, data{new double[other.n_]} {}
|
|
B(B&&) = delete;
|
|
|
|
B& operator=(B&&) = default;
|
|
B& operator=(B const& other) {
|
|
if(this == &other) {
|
|
return *this;
|
|
}
|
|
name_ = other.name_;
|
|
n_ = other.n_;
|
|
delete[] data;
|
|
data = new double[other.n_]; // NOLINT(cppcoreguidelines-owning-memory)
|
|
std::copy_n(other.data, other.n_, data);
|
|
return *this;
|
|
}
|
|
|
|
~B() { delete[] data; }
|
|
};
|
|
|
|
// nonintrusive serialization
|
|
template<class Archive>
|
|
void save(Archive& ar, B const& b, unsigned int const /*version*/) {
|
|
ar << b.name_ << b.n_ << boost::serialization::make_array(b.data, b.n_);
|
|
}
|
|
template<class Archive>
|
|
void load(Archive& ar, B& b, unsigned int const /*version*/) {
|
|
ar >> b.name_ >> b.n_;
|
|
delete[] b.data; // NOLINT(cppcoreguidelines-owning-memory)
|
|
b.data = new double[b.n_]; // NOLINT(cppcoreguidelines-owning-memory)
|
|
ar >> boost::serialization::make_array(b.data, b.n_);
|
|
}
|
|
BOOST_SERIALIZATION_SPLIT_FREE(B) // cppcheck-suppress unknownMacro
|
|
|
|
namespace mpi3 = boost::mpi3;
|
|
|
|
int mpi3::main(int /*argc*/, char** /*argv*/, mpi3::communicator world) try {
|
|
|
|
assert(world.size() > 1);
|
|
|
|
switch(world.rank()) {
|
|
case 0: {
|
|
int a = 5;
|
|
world[1] << a;
|
|
break;
|
|
}
|
|
case 1: {
|
|
int a = -1;
|
|
world[0] >> a; // specific source (any tag)
|
|
assert(a == 5);
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (world.rank()) {
|
|
case 0: {
|
|
int a = 7;
|
|
world[1] << a;
|
|
break;
|
|
}
|
|
case 1: {
|
|
int a = -1;
|
|
world >> a; // any source (any tag)
|
|
assert(a == 7);
|
|
break;
|
|
}
|
|
}
|
|
|
|
int b = world.rank();
|
|
world[1] & b; // broadcast (from rank 1)
|
|
assert(b == 1);
|
|
|
|
// if(world.root()) {
|
|
// B b1(4);
|
|
// b1.data[2] = 4.5;
|
|
// world[1] << b1;
|
|
// } else {
|
|
// B b2;
|
|
// world[0] >> b2;
|
|
// assert(b2.data[2] == 4.5);
|
|
// }
|
|
|
|
{
|
|
switch(world.rank()) {
|
|
case 0: {
|
|
int a = 7;
|
|
world[1] << a;
|
|
break;
|
|
}
|
|
case 1: {
|
|
int a = -1;
|
|
world >> a; // any source (any tag)
|
|
assert(a == 7);
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch(world.rank()) {
|
|
case 0: {
|
|
world[1] << true;
|
|
break;
|
|
}
|
|
case 1: {
|
|
bool bo = false;
|
|
world >> bo;
|
|
assert(bo == true);
|
|
break;
|
|
}
|
|
}
|
|
|
|
{
|
|
std::vector<double> v = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0};
|
|
|
|
switch(world.rank()) {
|
|
case 0: {
|
|
world[1] << v;
|
|
break;
|
|
}
|
|
case 1: {
|
|
std::vector<double> w;
|
|
world >> w;
|
|
assert(v == w);
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
std::vector<bool> const v_send = {false, true, false};
|
|
switch(world.rank()) {
|
|
case 0: {
|
|
world[1] << v_send;
|
|
break;
|
|
}
|
|
case 1: {
|
|
std::vector<bool> v_recv;
|
|
world >> v_recv;
|
|
assert(v_recv == v_send);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
} catch(...) { return 1; }
|