Arcane  4.2.3.0
Developer documentation
Loading...
Searching...
No Matches
TestMpi.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7#include <gtest/gtest.h>
8
9#include "arccore/message_passing_mpi/StandaloneMpiMessagePassingMng.h"
10#include "arccore/base/Ref.h"
11#include "arccore/base/BFloat16.h"
12#include "arccore/base/Float16.h"
13#include "arccore/common/Array.h"
14#include "arccore/trace/ITraceMng.h"
16#include "arccore/message_passing/Communicator.h"
17#include "arccore/serialize/ISerializer.h"
18
19#include "TestMain.h"
20
21#include <iostream>
22
23using namespace Arccore;
24using namespace Arccore::MessagePassing;
25using namespace Arccore::MessagePassing::Mpi;
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30TEST(MessagePassingMpi, Simple)
31{
32 Ref<IMessagePassingMng> pm(global_message_passing_mng);
33 ITraceMng* tm = pm->traceMng();
34 tm->info() << "Rank=" << pm->commRank() << "\n";
35 if (pm->commSize() == 2) {
36 UniqueArray<Int32> send_buf = { 1, 7, -4 };
37 if (pm->commRank() == 0)
38 mpSend(pm.get(), send_buf, 1);
39 else {
40 UniqueArray<Int32> receive_buf(3);
41 mpReceive(pm.get(), receive_buf, 0);
42 ASSERT_EQ(receive_buf.size(), 3);
43 ASSERT_EQ(receive_buf[0], 1);
44 ASSERT_EQ(receive_buf[1], 7);
45 ASSERT_EQ(receive_buf[2], -4);
46 }
47 }
48 Communicator c(pm->communicator());
49 ASSERT_TRUE(c.isValid());
50 MPI_Comm comm = c;
51 std::cout << "Communicator=" << comm << "\n";
52}
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57TEST(MessagePassingMpi, SerializeGather)
58{
59 // Tests only the call. Tests with actual values
60 // are done in Arcane.
61 Ref<IMessagePassingMng> pm(global_message_passing_mng);
62 ASSERT_EQ(pm->commSize(), 3);
63 Int32 my_rank = pm->commRank();
64 Ref<ISerializer> send_serializer(createSerializer());
66
67 send_buf[0] = UniqueArray<Int32>{ 1, 12, 4, -3 };
68 send_buf[1] = UniqueArray<Int32>{ 27, 0 };
69 send_buf[2] = UniqueArray<Int32>{ -5, 32, 8, -1, 8932 };
70
71 send_serializer->setMode(ISerializer::ModeReserve);
72 send_serializer->reserveArray(send_buf[my_rank]);
73 send_serializer->allocateBuffer();
74 send_serializer->setMode(ISerializer::ModePut);
75 send_serializer->putArray(send_buf[my_rank]);
76
77 Ref<ISerializer> receive_serializer(createSerializer());
78 mpAllGather(pm.get(), send_serializer.get(), receive_serializer.get());
79 receive_serializer->setMode(ISerializer::ModeGet);
80 UniqueArray<UniqueArray<Int32>> receive_buf(3);
81 receive_serializer->getArray(receive_buf[0]);
82 receive_serializer->getArray(receive_buf[1]);
83 receive_serializer->getArray(receive_buf[2]);
84
85 //UniqueArray<Int32> expected_receive_buf = { 1, 12, 4, -3, 27, 0, -5, 32, 8, -1, 8932 };
86
87 ASSERT_EQ(send_buf[0], receive_buf[0]);
88 ASSERT_EQ(send_buf[1], receive_buf[1]);
89 ASSERT_EQ(send_buf[2], receive_buf[2]);
90}
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
94
95namespace
96{
97
98template <typename DataType>
99void _doTestFloat16(IMessagePassingMng* pm)
100{
101 ITraceMng* tm = pm->traceMng();
102 Int32 nb_rank = pm->commSize();
103 ASSERT_EQ(pm->commSize(), 2);
104 Int32 my_rank = pm->commRank();
105 UniqueArray<DataType> send_buf = { DataType{ -1.2f }, DataType{ 4.5f }, DataType{ 3.2e5f } };
106 UniqueArray<DataType> receive_buf(send_buf.size());
107 if (my_rank == 0) {
108 mpSend(pm, send_buf, 1);
109 }
110 else {
111 mpReceive(pm, receive_buf, 0);
112 ASSERT_EQ(send_buf, receive_buf);
113 }
114
115 // Test reductions
116 {
117 UniqueArray<DataType> values(nb_rank);
118 DataType expected_sum(0.0f);
119 for (Int32 i = 0; i < nb_rank; ++i) {
120 values[i] = (static_cast<float>(i) - 1.2f) * 3.4f;
121 expected_sum = expected_sum + values[i];
122 }
123 DataType expected_min = values[0];
124 DataType expected_max = values[nb_rank - 1];
125 DataType my_value(values[my_rank]);
126 DataType sum_result = mpAllReduce(pm, eReduceType::ReduceSum, my_value);
127 tm->info() << "Sum=" << sum_result;
128 ASSERT_EQ(expected_sum, sum_result);
129
130 DataType max_result = mpAllReduce(pm, eReduceType::ReduceMax, my_value);
131 tm->info() << "Max=" << max_result;
132 ASSERT_EQ(expected_max, max_result);
133
134 DataType min_result = mpAllReduce(pm, eReduceType::ReduceMin, my_value);
135 tm->info() << "Min=" << min_result;
136 ASSERT_EQ(expected_min, min_result);
137 }
138}
139
140} // namespace
141
142TEST(MessagePassingMpi, Float16)
143{
144 // Tests only the call. Tests with actual values
145 // are done in Arcane.
146 Ref<IMessagePassingMng> pm(global_message_passing_mng);
147 _doTestFloat16<Float16>(pm.get());
148 _doTestFloat16<BFloat16>(pm.get());
149}
150
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
#define ASSERT_TRUE(condition)
Checks that condition is true.
Definition Assertion.h:128
Brief list of message exchange functions.
Management of references to a C++ class.
Integer size() const
Number of elements in the vector.
virtual TraceMessage info()=0
Stream for an information message.
Communicator for message exchange.
Interface of the message passing manager.
virtual ITraceMng * traceMng() const =0
Trace manager associated to this instance.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual Int32 commSize() const =0
Number of instances in the communicator.
Reference to an instance.
1D data vector with value semantics (STL style).
@ ReduceMin
Minimum of values.
@ ReduceMax
Maximum of values.
Namespace containing the types and declarations that manage the message-passing parallelism mechanism...
C char mpAllReduce(IMessagePassingMng *pm, eReduceType rt, char v)
void mpAllGather(IMessagePassingMng *pm, const ISerializer *send_serializer, ISerializer *recv_serializer)
allGather() message for serialization
Definition Messages.cc:319
Request mpReceive(IMessagePassingMng *pm, ISerializer *values, const PointToPointMessageInfo &message)
Receive message using an ISerializer.
Definition Messages.cc:300
Request mpSend(IMessagePassingMng *pm, const ISerializer *values, const PointToPointMessageInfo &message)
Send message using an ISerializer.
Definition Messages.cc:289
Namespace of Arccore.
Arcane::Float16 Float16
Type 'Float16' (binary16).
ARCCORE_SERIALIZE_EXPORT Ref< ISerializer > createSerializer()
Creates an instance of ISerializer.