Skip to content

Commit 7cf0126

Browse files
committed
Add tests for serializable MPI datatypes
1 parent faaeb1b commit 7cf0126

File tree

1 file changed

+80
-1
lines changed

1 file changed

+80
-1
lines changed

test/c++/mpi_custom.cpp

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,88 @@ TEST(MPI, TupleMPIDatatypes) {
128128

129129
using type5 = std::tuple<int, double, char, custom_cplx, bool>;
130130
type5 tup5;
131-
if (rank == root) { tup5 = std::make_tuple(100, 3.1314, 'r', custom_cplx{1.0, 2.0}, false); }
131+
if (rank == root) { tup5 = std::make_tuple(100, 3.1314, 'r', custom_cplx{.real = 1.0, .imag = 2.0}, false); }
132132
mpi::broadcast(tup5, world, root);
133133
EXPECT_EQ(tup5, std::make_tuple(100, 3.1314, 'r', custom_cplx{1.0, 2.0}, false));
134134
}
135135

136+
// a simple struct representing a complex number that is serializable
137+
struct serializable_cplx {
138+
double real{}, imag{};
139+
140+
// add two serializable_cplx objects
141+
serializable_cplx operator+(serializable_cplx z) const {
142+
z.real += real;
143+
z.imag += imag;
144+
return z;
145+
}
146+
147+
// default equal-to operator
148+
bool operator==(const serializable_cplx &) const = default;
149+
150+
// serialize the object
151+
void serialize(auto &ar) const { ar & real & imag; }
152+
void deserialize(auto &ar) { ar & real & imag; }
153+
};
154+
155+
// a simple struct that contains a serializable type and is serializable itself
156+
struct serializable_container {
157+
serializable_cplx z1;
158+
serializable_cplx z2;
159+
160+
// add two serializable_container objects
161+
serializable_container operator+(serializable_container z) const {
162+
z.z1 = z.z1 + z1;
163+
z.z2 = z.z2 + z2;
164+
return z;
165+
}
166+
167+
// default equal-to operator
168+
bool operator==(const serializable_container &) const = default;
169+
170+
// serialize the object
171+
void serialize(auto &ar) const { ar & z1 & z2; }
172+
void deserialize(auto &ar) { ar & z1 & z2; }
173+
};
174+
175+
// check Serializable concept
176+
static_assert(mpi::Serializable<serializable_cplx>);
177+
static_assert(mpi::Serializable<serializable_container>);
178+
179+
TEST(MPI, SerializableMPIDatatypes) {
180+
mpi::communicator world;
181+
int rank = world.rank();
182+
int root = 0;
183+
184+
// check broadcast
185+
auto z_exp = serializable_cplx{.real = 1.0, .imag = 2.0};
186+
auto z = (rank == root ? z_exp : serializable_cplx{});
187+
mpi::broadcast(z, world, root);
188+
EXPECT_EQ(z, z_exp);
189+
190+
// check all_reduce
191+
auto z_red = mpi::all_reduce(z, world, mpi::map_add<serializable_cplx>());
192+
EXPECT_DOUBLE_EQ(z_exp.real * world.size(), z_red.real);
193+
EXPECT_DOUBLE_EQ(z.imag * world.size(), z_red.imag);
194+
}
195+
196+
TEST(MPI, SerializableOfSerializableMPIDatatypes) {
197+
mpi::communicator world;
198+
int rank = world.rank();
199+
int root = 0;
200+
201+
// check broadcast
202+
auto c_exp = serializable_container{.z1 = {.real = 1.0, .imag = 2.0}, .z2 = {.real = 3.0, .imag = 4.0}};
203+
auto c = (rank == root ? c_exp : serializable_container{});
204+
mpi::broadcast(c, world, root);
205+
EXPECT_EQ(c, c_exp);
206+
207+
// check all_reduce
208+
auto c_red = mpi::all_reduce(c, world, mpi::map_add<serializable_container>());
209+
EXPECT_DOUBLE_EQ(c_exp.z1.real * world.size(), c_red.z1.real);
210+
EXPECT_DOUBLE_EQ(c_exp.z1.imag * world.size(), c_red.z1.imag);
211+
EXPECT_DOUBLE_EQ(c_exp.z2.real * world.size(), c_red.z2.real);
212+
EXPECT_DOUBLE_EQ(c_exp.z2.imag * world.size(), c_red.z2.imag);
213+
}
214+
136215
MPI_TEST_MAIN;

0 commit comments

Comments
 (0)