@@ -128,9 +128,88 @@ TEST(MPI, TupleMPIDatatypes) {
128
128
129
129
using type5 = std::tuple<int , double , char , custom_cplx, bool >;
130
130
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 ); }
132
132
mpi::broadcast (tup5, world, root);
133
133
EXPECT_EQ (tup5, std::make_tuple (100 , 3.1314 , ' r' , custom_cplx{1.0 , 2.0 }, false ));
134
134
}
135
135
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
+
136
215
MPI_TEST_MAIN;
0 commit comments