Arcane  4.2.3.0
Developer documentation
Loading...
Searching...
No Matches
MessagePassingUtils.h
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/*---------------------------------------------------------------------------*/
8/* MessagePassingUtils.h (C) 2000-2026 */
9/* */
10/* Various utilities to handle message passing. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_MESSAGEPASSINGUTILS_H
13#define ARCCORE_ALINA_MESSAGEPASSINGUTILS_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16/*
17 * This file is based on the work on AMGCL library (version march 2026)
18 * which can be found at https://github.com/ddemidov/amgcl.
19 *
20 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
21 * SPDX-License-Identifier: MIT
22 */
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26#include "arccore/base/FixedArray.h"
27#include "arccore/common/Array.h"
28
29#include "arccore/message_passing_mpi/StandaloneMpiMessagePassingMng.h"
31#include "arccore/message_passing/PointToPointMessageInfo.h"
32#include "arccore/message_passing/Communicator.h"
33
34#include "arccore/alina/ValueTypeInterface.h"
35#include "arccore/alina/AlinaUtils.h"
36
37#include <vector>
38#include <numeric>
39#include <complex>
40#include <type_traits>
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45namespace Arcane::Alina
46{
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
52struct mpi_init
53{
54 mpi_init(int* argc, char*** argv)
55 {
56 MPI_Init(argc, argv);
57 }
58
59 ~mpi_init()
60 {
61 MPI_Finalize();
62 }
63};
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
69struct mpi_init_thread
70{
71 mpi_init_thread(int* argc, char*** argv)
72 {
73 int _;
74 MPI_Init_thread(argc, argv, MPI_THREAD_MULTIPLE, &_);
75 }
76
77 ~mpi_init_thread()
78 {
79 MPI_Finalize();
80 }
81};
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
88struct ARCCORE_ALINA_EXPORT AlinaCommunicator
89{
90 private:
91
92 MPI_Comm m_mpi_communicator = MPI_COMM_NULL;
93
94 public:
95
96 int rank = 0;
97 int size = 0;
98 Ref<IMessagePassingMng> m_message_passing_mng;
99
100 AlinaCommunicator() = default;
101
102 explicit AlinaCommunicator(MPI_Comm comm);
103
104 explicit AlinaCommunicator(IMessagePassingMng* mpm_comm);
105
106 MPI_Comm mpiCommunicator() const;
107 IMessagePassingMng* messagePassingMng() const { return m_message_passing_mng.get(); }
108
110 template <typename T>
112 {
113 // TODO: Use scan.
114 UniqueArray<T> v(size + 1);
115 v[0] = 0;
116 T v0 = n;
117 ConstArrayView<T> v0_view(1, &v0);
118 ArrayView<T> out_view(static_cast<Int32>(v.size()), &v[1]);
119 mpAllGather(m_message_passing_mng.get(), v0_view, out_view);
120 std::partial_sum(v.begin(), v.end(), v.begin());
121 return v;
122 }
123
124 std::complex<long double> reduceSum(const std::complex<long double>& lval) const
125 {
126 return _reduceSumForComplex(lval);
127 }
128 std::complex<double> reduceSum(const std::complex<double>& lval) const
129 {
130 return _reduceSumForComplex(lval);
131 }
132 std::complex<float> reduceSum(const std::complex<float>& lval) const
133 {
134 return _reduceSumForComplex(lval);
135 }
136
137 template <typename T> T reduceSum(const T& lval) const
138 {
139 return mpAllReduce(m_message_passing_mng.get(), MessagePassing::eReduceType::ReduceSum, lval);
140 }
141
142 void waitAll(ArrayView<MessagePassing::Request> requests) const
143 {
144 mpWaitAll(m_message_passing_mng.get(), requests);
145 }
146 void wait(MessagePassing::Request request) const
147 {
148 ArrayView<MessagePassing::Request> requests(1, &request);
149 mpWaitAll(m_message_passing_mng.get(), requests);
150 }
151
161 void check(bool cond, const String& message);
162
163 void barrier() { mpBarrier(m_message_passing_mng.get()); }
164
165 template <typename T> MessagePassing::Request
166 doIReceive(T* buf, int count, int source, int tag) const
167 {
168 using namespace Arcane::MessagePassing;
169 Span<T> s(buf, count);
170 Span<unsigned char> schar(reinterpret_cast<unsigned char*>(s.data()), s.sizeBytes());
171 PointToPointMessageInfo msg_info(MessageRank{ source }, MessageTag{ tag }, eBlockingType::NonBlocking);
172 return mpReceive(m_message_passing_mng.get(), schar, msg_info);
173 }
174
175 template <typename T> void
176 doReceive(T* buf, int count, int source, int tag) const
177 {
178 using namespace Arcane::MessagePassing;
179 Span<T> s(buf, count);
180 Span<unsigned char> schar(reinterpret_cast<unsigned char*>(s.data()), s.sizeBytes());
181 PointToPointMessageInfo msg_info(MessageRank{ source }, MessageTag{ tag }, eBlockingType::Blocking);
182 mpReceive(m_message_passing_mng.get(), schar, msg_info);
183 }
184
185 template <typename T> MessagePassing::Request
186 doISend(const T* buf, int count, int dest, int tag) const
187 {
188 using namespace Arcane::MessagePassing;
189 Span<const T> s(buf, count);
190 Span<const unsigned char> schar(reinterpret_cast<const unsigned char*>(s.data()), s.sizeBytes());
191 PointToPointMessageInfo msg_info(MessageRank{ dest }, MessageTag{ tag }, eBlockingType::NonBlocking);
192 return mpSend(m_message_passing_mng.get(), schar, msg_info);
193 }
194
195 template <typename T> void
196 doSend(const T* buf, int count, int dest, int tag) const
197 {
198 using namespace Arcane::MessagePassing;
199 Span<const T> s(buf, count);
200 Span<const unsigned char> schar(reinterpret_cast<const unsigned char*>(s.data()), s.sizeBytes());
201 PointToPointMessageInfo msg_info(MessageRank{ dest }, MessageTag{ tag }, eBlockingType::Blocking);
202 mpSend(m_message_passing_mng.get(), schar, msg_info);
203 }
204
205 private:
206
207 template <typename T> std::complex<T>
208 _reduceSumForComplex(const std::complex<T>& lval) const
209 {
210 // Specialisation for 'std::complex<T>' as 2 T.
211 FixedArray<T, 2> values = { { lval.real(), lval.imag() } };
212 mpAllReduce(m_message_passing_mng.get(), MessagePassing::eReduceType::ReduceSum, values.view());
213 return std::complex<T>(values[0], values[1]);
214 }
215};
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
220} // namespace Arcane::Alina
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
225#endif
Brief list of message exchange functions.
Integer size() const
Number of elements in the vector.
Modifiable view of an array of type T.
iterator begin()
Iterator over the first element of the array.
iterator end()
Iterator over the first element after the end of the array.
Constant view of an array of type T.
constexpr __host__ __device__ ArrayView< T > view()
Modifiable view of the array.
Interface of the message passing manager.
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
1D data vector with value semantics (STL style).
C char mpAllReduce(IMessagePassingMng *pm, eReduceType rt, char v)
void mpBarrier(IMessagePassingMng *pm)
Performs a barrier.
Definition Messages.cc:259
void mpAllGather(IMessagePassingMng *pm, const ISerializer *send_serializer, ISerializer *receive_serialize)
allGather() message for serialization
Definition Messages.cc:319
void mpWaitAll(IMessagePassingMng *pm, ArrayView< Request > requests)
Blocks until the requests in requests are finished.
Definition Messages.cc:164
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
std::int32_t Int32
Signed integer type of 32 bits.
UniqueArray< T > exclusive_sum(T n) const
Exclusive sum over mpi communicator.