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/*---------------------------------------------------------------------------*/
53struct ARCCORE_ALINA_EXPORT AlinaCommunicator
54{
55 private:
56
57 MPI_Comm m_mpi_communicator = MPI_COMM_NULL;
58
59 public:
60
61 int rank = 0;
62 int size = 0;
63 Ref<IMessagePassingMng> m_message_passing_mng;
64
65 AlinaCommunicator() = default;
66
67 explicit AlinaCommunicator(IMessagePassingMng* mpm_comm);
68 explicit AlinaCommunicator(const Ref<IMessagePassingMng>& mpm_comm);
69
70 MPI_Comm mpiCommunicator() const;
71 IMessagePassingMng* messagePassingMng() const { return m_message_passing_mng.get(); }
72
73 static AlinaCommunicator createFromMPI(MPI_Comm comm);
74
76 template <typename T>
78 {
79 // TODO: Use scan.
80 UniqueArray<T> v(size + 1);
81 v[0] = 0;
82 T v0 = n;
83 ConstArrayView<T> v0_view(1, &v0);
84 ArrayView<T> out_view(static_cast<Int32>(size), &v[1]);
85 mpAllGather(m_message_passing_mng.get(), v0_view, out_view);
86 std::partial_sum(v.begin(), v.end(), v.begin());
87 return v;
88 }
89
90 std::complex<long double> reduceSum(const std::complex<long double>& lval) const
91 {
92 return _reduceSumForComplex(lval);
93 }
94 std::complex<double> reduceSum(const std::complex<double>& lval) const
95 {
96 return _reduceSumForComplex(lval);
97 }
98 std::complex<float> reduceSum(const std::complex<float>& lval) const
99 {
100 return _reduceSumForComplex(lval);
101 }
102
103 template <typename T> T reduceSum(const T& lval) const
104 {
105 return mpAllReduce(m_message_passing_mng.get(), MessagePassing::eReduceType::ReduceSum, lval);
106 }
107
108 void waitAll(ArrayView<MessagePassing::Request> requests) const
109 {
110 mpWaitAll(m_message_passing_mng.get(), requests);
111 }
112 void wait(MessagePassing::Request request) const
113 {
114 ArrayView<MessagePassing::Request> requests(1, &request);
115 mpWaitAll(m_message_passing_mng.get(), requests);
116 }
117
127 void check(bool cond, const String& message);
128
129 void barrier() { mpBarrier(m_message_passing_mng.get()); }
130
131 template <typename T> MessagePassing::Request
132 doIReceive(T* buf, int count, int source, int tag) const
133 {
134 using namespace Arcane::MessagePassing;
135 Span<T> s(buf, count);
136 Span<unsigned char> schar(reinterpret_cast<unsigned char*>(s.data()), s.sizeBytes());
137 PointToPointMessageInfo msg_info(MessageRank{ source }, MessageTag{ tag }, eBlockingType::NonBlocking);
138 return mpReceive(m_message_passing_mng.get(), schar, msg_info);
139 }
140
141 template <typename T> void
142 doReceive(T* buf, int count, int source, int tag) const
143 {
144 using namespace Arcane::MessagePassing;
145 Span<T> s(buf, count);
146 Span<unsigned char> schar(reinterpret_cast<unsigned char*>(s.data()), s.sizeBytes());
147 PointToPointMessageInfo msg_info(MessageRank{ source }, MessageTag{ tag }, eBlockingType::Blocking);
148 mpReceive(m_message_passing_mng.get(), schar, msg_info);
149 }
150
151 template <typename T> MessagePassing::Request
152 doISend(const T* buf, int count, int dest, int tag) const
153 {
154 using namespace Arcane::MessagePassing;
155 Span<const T> s(buf, count);
156 Span<const unsigned char> schar(reinterpret_cast<const unsigned char*>(s.data()), s.sizeBytes());
157 PointToPointMessageInfo msg_info(MessageRank{ dest }, MessageTag{ tag }, eBlockingType::NonBlocking);
158 return mpSend(m_message_passing_mng.get(), schar, msg_info);
159 }
160
161 template <typename T> void
162 doSend(const T* buf, int count, int dest, int tag) const
163 {
164 using namespace Arcane::MessagePassing;
165 Span<const T> s(buf, count);
166 Span<const unsigned char> schar(reinterpret_cast<const unsigned char*>(s.data()), s.sizeBytes());
167 PointToPointMessageInfo msg_info(MessageRank{ dest }, MessageTag{ tag }, eBlockingType::Blocking);
168 mpSend(m_message_passing_mng.get(), schar, msg_info);
169 }
170
171 private:
172
173 template <typename T> std::complex<T>
174 _reduceSumForComplex(const std::complex<T>& lval) const
175 {
176 // Specialisation for 'std::complex<T>' as 2 T.
177 FixedArray<T, 2> values = { { lval.real(), lval.imag() } };
178 mpAllReduce(m_message_passing_mng.get(), MessagePassing::eReduceType::ReduceSum, values.view());
179 return std::complex<T>(values[0], values[1]);
180 }
181
182 void _init();
183};
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
188} // namespace Arcane::Alina
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
193#endif
Brief list of message exchange functions.
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.