preCICE v3.1.1
Loading...
Searching...
No Matches
PointToPointCommunicationTest.cpp
Go to the documentation of this file.
1#ifndef PRECICE_NO_MPI
2
3#include <Eigen/Core>
4#include <algorithm>
5#include <map>
6#include <memory>
7#include <vector>
13#include "mesh/Mesh.hpp"
16#include "testing/Testing.hpp"
17#include "utils/IntraComm.hpp"
18
19namespace precice {
20namespace mesh {
21class Vertex;
22} // namespace mesh
23namespace utils {
24class Parallel;
25} // namespace utils
26} // namespace precice
27
31
32using std::vector;
33
34using namespace precice;
35using namespace m2n;
36
38
39void process(vector<double> &data)
40{
41 for (auto &elem : data) {
42 elem += IntraComm::getRank() + 1;
43 }
44}
45
47{
48 BOOST_TEST(context.hasSize(2));
49
50 mesh::PtrMesh mesh(new mesh::Mesh("Mesh", 2, testing::nextMeshID()));
51
53
54 vector<double> data;
55 vector<double> expectedData;
56
57 if (context.isNamed("A")) {
58 if (context.isPrimary()) {
59 mesh->setGlobalNumberOfVertices(10);
60
61 mesh->setVertexDistribution({{0, {0, 1, 3, 5, 7}}, {1, {1, 2, 4, 5, 6}}});
62
63 data = {10, 20, 40, 60, 80};
64 expectedData = {10 + 2, 4 * 20 + 3, 40 + 2, 4 * 60 + 3, 80 + 2};
65 } else { // A Secondary rank
66 data = {20, 30, 50, 60, 70};
67 expectedData = {4 * 20 + 3, 30 + 1, 50 + 2, 4 * 60 + 3, 70 + 1};
68 }
69 } else {
70 BOOST_TEST(context.isNamed("B"));
71 if (context.isPrimary()) {
72 mesh->setGlobalNumberOfVertices(10);
73
74 mesh->setVertexDistribution({{0, {1, 2, 5, 6}}, {1, {0, 1, 3, 4, 5, 7}}});
75
76 data.assign(4, -1);
77 expectedData = {2 * 20, 30, 2 * 60, 70};
78
79 } else {
80 data.assign(6, -1);
81 expectedData = {10, 2 * 20, 40, 50, 2 * 60, 80};
82 }
83 }
84
85 if (context.isNamed("A")) {
86 c.requestConnection("B", "A");
87
88 c.send(data);
89 c.receive(data);
90
91 BOOST_TEST(testing::equals(data, expectedData));
92 } else {
93 c.acceptConnection("B", "A");
94
95 c.receive(data);
96 BOOST_TEST(testing::equals(data, expectedData));
97 process(data);
98 c.send(data);
99 }
100}
101
104{
105 BOOST_TEST(context.hasSize(2));
106 mesh::PtrMesh mesh(new mesh::Mesh("Mesh", 2, testing::nextMeshID()));
107
109
110 vector<double> data;
111 vector<double> expectedData;
112
113 if (context.isNamed("A")) {
114 if (context.isPrimary()) {
115 mesh->setGlobalNumberOfVertices(10);
116
117 mesh->setVertexDistribution({{0, {0, 1, 3, 5, 7}}, {1, {1, 2, 4, 5, 6}}});
118
119 data = {10, 20, 40, 60, 80};
120 expectedData = {10 + 2, 4 * 20 + 3, 2 * 40 + 3, 4 * 60 + 3, 80 + 2};
121 } else {
122 data = {20, 30, 50, 60, 70};
123 expectedData = {4 * 20 + 3, 0, 50 + 2, 4 * 60 + 3, 70 + 1};
124 }
125 } else {
126 BOOST_TEST(context.isNamed("B"));
127 if (context.isPrimary()) {
128 mesh->setGlobalNumberOfVertices(10);
129
130 mesh->setVertexDistribution({{0, {1, 3, 5, 6}}, {1, {0, 1, 3, 4, 5, 7}}});
131
132 data.assign(4, -1);
133 expectedData = {2 * 20, 40, 2 * 60, 70};
134
135 } else {
136 data.assign(6, -1);
137 expectedData = {10, 2 * 20, 40, 50, 2 * 60, 80};
138 }
139 }
140
141 if (context.isNamed("A")) {
142 c.requestConnection("B", "A");
143
144 c.send(data);
145 c.receive(data);
146 BOOST_TEST(testing::equals(data, expectedData));
147 } else {
148 c.acceptConnection("B", "A");
149
150 c.receive(data);
151 BOOST_TEST(testing::equals(data, expectedData));
152 process(data);
153 c.send(data);
154 }
155}
156
158{
159
160 BOOST_TEST(context.hasSize(2));
161
162 int dimensions = 2;
163 mesh::PtrMesh mesh(new mesh::Mesh("Mesh", dimensions, testing::nextMeshID()));
164
165 if (context.isNamed("A")) {
166 if (context.isPrimary()) {
167
168 mesh->setConnectedRanks({0});
169 } else {
170
171 mesh->setConnectedRanks({1});
172 }
173 } else {
174 BOOST_TEST(context.isNamed("B"));
175 if (context.isPrimary()) {
176
177 mesh->setConnectedRanks({0});
178 } else {
179
180 mesh->setConnectedRanks({1});
181 }
182 }
183
185
186 std::vector<int> receiveData;
187
188 if (context.isNamed("A")) {
189 if (context.isPrimary()) {
190
191 c.requestPreConnection("Solid", "Fluid");
192 int sendData = 5;
193 c.broadcastSend(sendData);
194
195 } else {
196
197 c.requestPreConnection("Solid", "Fluid");
198 int sendData = 10;
199 c.broadcastSend(sendData);
200 }
201 } else {
202 c.acceptPreConnection("Solid", "Fluid");
203 c.broadcastReceiveAll(receiveData);
204
205 if (context.isPrimary()) {
206 BOOST_TEST(receiveData.at(0) == 5);
207 } else {
208 BOOST_TEST(receiveData.at(0) == 10);
209 }
210 }
211}
212
214{
215
216 BOOST_TEST(context.hasSize(2));
217
218 int dimensions = 2;
219 mesh::PtrMesh mesh(new mesh::Mesh("Mesh", dimensions, testing::nextMeshID()));
220
221 if (context.isNamed("A")) {
222 if (context.isPrimary()) {
223
224 mesh->setConnectedRanks({1});
225 } else {
226
227 mesh->setConnectedRanks({0});
228 }
229 } else {
230 BOOST_TEST(context.isNamed("B"));
231 if (context.isPrimary()) {
232
233 mesh->setConnectedRanks({1});
234 } else {
235
236 mesh->setConnectedRanks({0});
237 }
238 }
239
241
242 std::vector<int> receiveData;
243
244 if (context.isNamed("A")) {
245 if (context.isPrimary()) {
246
247 c.requestPreConnection("Solid", "Fluid");
248 int sendData = 5;
249 c.broadcastSend(sendData);
250
251 } else {
252
253 c.requestPreConnection("Solid", "Fluid");
254 int sendData = 10;
255 c.broadcastSend(sendData);
256 }
257 } else {
258 c.acceptPreConnection("Solid", "Fluid");
259 c.broadcastReceiveAll(receiveData);
260
261 if (context.isPrimary()) {
262 BOOST_TEST(receiveData.at(0) == 10);
263 } else {
264 BOOST_TEST(receiveData.at(0) == 5);
265 }
266 }
267}
268
270{
271 BOOST_TEST(context.hasSize(2));
272
273 int dimensions = 2;
274 mesh::PtrMesh mesh(new mesh::Mesh("Mesh", dimensions, testing::nextMeshID()));
275
276 if (context.isNamed("A")) {
277 if (context.isPrimary()) {
278
279 mesh->setConnectedRanks({0});
280
281 } else {
282 }
283 } else {
284 BOOST_TEST(context.isNamed("B"));
285 if (context.isPrimary()) {
286 mesh->setConnectedRanks({0});
287
288 } else {
289 }
290 }
291
293
294 std::vector<int> receiveData;
295
296 if (context.isNamed("A")) {
297 c.requestPreConnection("Solid", "Fluid");
298 int sendData = 5;
299 c.broadcastSend(sendData);
300 } else {
301 c.acceptPreConnection("Solid", "Fluid");
302 c.broadcastReceiveAll(receiveData);
303
304 if (context.isPrimary()) {
305 BOOST_TEST(receiveData.at(0) == 5);
306
307 } else {
308 BOOST_TEST(receiveData.size() == 0);
309 }
310 }
311}
312
314{
315 BOOST_TEST(context.hasSize(2));
316
317 int dimensions = 2;
318 mesh::PtrMesh mesh(new mesh::Mesh("Mesh", dimensions, testing::nextMeshID()));
319
320 if (context.isNamed("A")) {
321 if (context.isPrimary()) {
322 Eigen::VectorXd position(dimensions);
323 position << 5.5, 0.0;
324 mesh::Vertex &v1 = mesh->createVertex(position);
325 position << 1.0, 2.0;
326 mesh::Vertex &v2 = mesh->createVertex(position);
327 mesh->createEdge(v1, v2);
328
329 mesh->setConnectedRanks({0});
330
331 } else {
332 Eigen::VectorXd position(dimensions);
333 position << 1.5, 0.0;
334 mesh::Vertex &v1 = mesh->createVertex(position);
335 position << 1.5, 2.0;
336 mesh::Vertex &v2 = mesh->createVertex(position);
337 mesh->createEdge(v1, v2);
338
339 mesh->setConnectedRanks({1});
340 }
341 } else {
342 BOOST_TEST(context.isNamed("B"));
343 if (context.isPrimary()) {
344 mesh->setConnectedRanks({0});
345
346 } else {
347 mesh->setConnectedRanks({1});
348 }
349 }
350
352
353 if (context.isNamed("A")) {
354
355 c.requestPreConnection("Solid", "Fluid");
357 } else {
358
359 c.acceptPreConnection("Solid", "Fluid");
361
362 if (context.isPrimary()) {
363 // This rank should receive the mesh from rank 0 (fluid primary)
364 BOOST_TEST(mesh->nVertices() == 2);
365 BOOST_TEST(mesh->vertex(0).coord(0) == 5.50);
366 BOOST_TEST(mesh->vertex(0).coord(1) == 0.0);
367 BOOST_TEST(mesh->vertex(1).coord(0) == 1.0);
368 BOOST_TEST(mesh->vertex(1).coord(1) == 2.0);
369 } else {
370 // This rank should receive the mesh from rank 1 (fluid secondary)
371 BOOST_TEST(mesh->nVertices() == 2);
372 BOOST_TEST(mesh->vertex(0).coord(0) == 1.50);
373 BOOST_TEST(mesh->vertex(0).coord(1) == 0.0);
374 BOOST_TEST(mesh->vertex(1).coord(0) == 1.50);
375 BOOST_TEST(mesh->vertex(1).coord(1) == 2.0);
376 }
377 }
378}
379
381{
382 BOOST_TEST(context.hasSize(2));
383
384 int dimensions = 2;
385 mesh::PtrMesh mesh(new mesh::Mesh("Mesh", dimensions, testing::nextMeshID()));
386 const auto expectedId = mesh->getID();
387 std::map<int, std::vector<int>> localCommunicationMap;
388
389 if (context.isNamed("A")) {
390 if (context.isPrimary()) {
391
392 // The numbers are chosen in this way to make it easy to test weather
393 // correct values are communicated or not!
394 mesh->setConnectedRanks({0});
395 localCommunicationMap[0].push_back(102);
396 localCommunicationMap[0].push_back(1022);
397 localCommunicationMap[0].push_back(10222);
398 localCommunicationMap[1].push_back(103);
399 localCommunicationMap[1].push_back(1033);
400 localCommunicationMap[1].push_back(10333);
401
402 } else {
403
404 // The numbers are chosen in this way to make it easy to test weather
405 // correct values are communicated or not!
406 mesh->setConnectedRanks({1});
407 localCommunicationMap[0].push_back(112);
408 localCommunicationMap[0].push_back(1122);
409 localCommunicationMap[0].push_back(11222);
410 localCommunicationMap[1].push_back(113);
411 localCommunicationMap[1].push_back(1133);
412 localCommunicationMap[1].push_back(11333);
413 }
414 } else {
415 BOOST_TEST(context.isNamed("B"));
416 if (context.isPrimary()) {
417
418 mesh->setConnectedRanks({0});
419
420 } else {
421
422 mesh->setConnectedRanks({1});
423 }
424 }
425
427
428 if (context.isNamed("A")) {
429
430 c.requestPreConnection("Solid", "Fluid");
431 c.scatterAllCommunicationMap(localCommunicationMap);
432 BOOST_TEST(mesh->getID() == expectedId);
433
434 } else {
435 c.acceptPreConnection("Solid", "Fluid");
436 c.gatherAllCommunicationMap(localCommunicationMap);
437 BOOST_TEST(mesh->getID() == expectedId);
438 }
439
440 if (context.isNamed("B")) {
441 if (context.isPrimary()) {
442 // The numbers are chosen in this way to make it easy to test weather
443 // correct values are communicated or not!
444 BOOST_TEST(localCommunicationMap.size() == 1);
445 BOOST_TEST(localCommunicationMap.at(0).size() == 3);
446 BOOST_TEST(localCommunicationMap.at(0).at(0) == 102);
447 BOOST_TEST(localCommunicationMap.at(0).at(1) == 1022);
448 BOOST_TEST(localCommunicationMap.at(0).at(2) == 10222);
449
450 } else {
451 // The numbers are chosen in this way to make it easy to test weather
452 // correct values are communicated or not!
453 BOOST_TEST(localCommunicationMap.size() == 1);
454 BOOST_TEST(localCommunicationMap.at(1).size() == 3);
455 BOOST_TEST(localCommunicationMap.at(1).at(0) == 113);
456 BOOST_TEST(localCommunicationMap.at(1).at(1) == 1133);
457 BOOST_TEST(localCommunicationMap.at(1).at(2) == 11333);
458 }
459 }
460}
461
463
465{
466 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
468 runP2PComTest1(context, cf);
469}
470
472{
473 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
475 runP2PComTest2(context, cf);
476}
477
478BOOST_AUTO_TEST_CASE(TestSameConnection)
479{
480 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
482 runSameConnectionTest(context, cf);
483}
484
485BOOST_AUTO_TEST_CASE(TestCrossConnection)
486{
487 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
489 runCrossConnectionTest(context, cf);
490}
491
492BOOST_AUTO_TEST_CASE(EmptyConnectionTest)
493{
494 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
496 runEmptyConnectionTest(context, cf);
497}
498
499BOOST_AUTO_TEST_CASE(P2PMeshBroadcastTest)
500{
501 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
503 runP2PMeshBroadcastTest(context, cf);
504}
505
506BOOST_AUTO_TEST_CASE(P2PComLocalCommunicationMapTest)
507{
508 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
511}
512
513BOOST_AUTO_TEST_SUITE_END() // Sockets
514
515BOOST_AUTO_TEST_SUITE(MPIPorts, *boost::unit_test::label("MPI_Ports"))
516
517BOOST_AUTO_TEST_CASE(P2PComTest1)
518{
519 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
521 runP2PComTest1(context, cf);
522}
523
524BOOST_AUTO_TEST_CASE(P2PComTest2)
525{
526 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
528 runP2PComTest2(context, cf);
529}
530
531BOOST_AUTO_TEST_CASE(TestSameConnection)
532{
533 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
535 runSameConnectionTest(context, cf);
536}
537
538BOOST_AUTO_TEST_CASE(TestCrossConnection)
539{
540 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
542 runCrossConnectionTest(context, cf);
543}
544
545BOOST_AUTO_TEST_CASE(EmptyConnectionTest)
546{
547 PRECICE_TEST("A"_on(2_ranks).setupIntraComm(), "B"_on(2_ranks).setupIntraComm(), Require::Events);
549 runEmptyConnectionTest(context, cf);
550}
551
552BOOST_AUTO_TEST_SUITE_END() // MPIPorts
553
555
556#endif // not PRECICE_NO_MPI
BOOST_AUTO_TEST_SUITE(PreProcess)
BOOST_AUTO_TEST_SUITE_END()
void runSameConnectionTest(const TestContext &context, com::PtrCommunicationFactory cf)
void runP2PComTest2(const TestContext &context, com::PtrCommunicationFactory cf)
a very similar test, but with a vertex that has been completely filtered out
void runCrossConnectionTest(const TestContext &context, com::PtrCommunicationFactory cf)
void process(vector< double > &data)
void runP2PComLocalCommunicationMapTest(const TestContext &context, com::PtrCommunicationFactory cf)
void runEmptyConnectionTest(const TestContext &context, com::PtrCommunicationFactory cf)
void runP2PMeshBroadcastTest(const TestContext &context, com::PtrCommunicationFactory cf)
void runP2PComTest1(const TestContext &context, com::PtrCommunicationFactory cf)
BOOST_AUTO_TEST_CASE(P2PComTest1)
#define PRECICE_TEST(...)
Definition Testing.hpp:27
T at(T... args)
Point-to-point communication implementation of DistributedCommunication.
void scatterAllCommunicationMap(CommunicationMap &localCommunicationMap) override
Scatters a communication map over connected ranks on remote participant.
void broadcastSendMesh() override
Broadcasts a mesh to connected ranks on remote participant.
void gatherAllCommunicationMap(CommunicationMap &localCommunicationMap) override
Gathers a communication maps from connected ranks on remote participant.
void broadcastSend(int itemToSend) override
Broadcasts an int to connected ranks on remote participant.
void acceptPreConnection(std::string const &acceptorName, std::string const &requesterName) override
Accepts connection from participant, which has to call requestPreConnection(). Only initial connectio...
void receive(precice::span< double > itemsToReceive, int valueDimension=1) override
Receives a subset of local double values corresponding to local indices deduced from the current and ...
void broadcastReceiveAll(std::vector< int > &itemToReceive) override
Receives an int per connected rank on remote participant @para[out] itemToReceive received ints from ...
void requestPreConnection(std::string const &acceptorName, std::string const &requesterName) override
Requests connection from participant, which has to call acceptConnection(). Only initial connection i...
void acceptConnection(std::string const &acceptorName, std::string const &requesterName) override
Accepts connection from participant, which has to call requestConnection().
void requestConnection(std::string const &acceptorName, std::string const &requesterName) override
Requests connection from participant, which has to call acceptConnection().
void broadcastReceiveAllMesh() override
Receive mesh partitions per connected rank on remote participant.
void send(precice::span< double const > itemsToSend, int valueDimension=1) override
Sends a subset of local double values corresponding to local indices deduced from the current and rem...
Container and creator for meshes.
Definition Mesh.hpp:39
Vertex of a mesh.
Definition Vertex.hpp:16
bool isNamed(const std::string &name) const
Check whether this context has a given name.
bool hasSize(int size) const
Check whether this context has a given size.
Utility class for managing intra-participant communication operations.
Definition IntraComm.hpp:19
static Rank getRank()
Current rank.
Definition IntraComm.cpp:42
Utility class for managing MPI operations.
Definition Parallel.hpp:24
boost::test_tools::predicate_result equals(const std::vector< float > &VectorA, const std::vector< float > &VectorB, float tolerance)
equals to be used in tests. Compares two std::vectors using a given tolerance. Prints both operands o...
Definition Testing.cpp:65
Main namespace of the precice library.
T size(T... args)