Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
TransferValuesParallelOperation.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/*---------------------------------------------------------------------------*/
8/* TransferValuesParallelOperation.cc (C) 2000-2025 */
9/* */
10/* Value transfer across different processors. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Array.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/ArgumentException.h"
18#include "arcane/utils/FatalErrorException.h"
19#include "arcane/utils/CheckedConvert.h"
20
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/Timer.h"
23#include "arcane/core/ISerializer.h"
24#include "arcane/core/internal/SerializeMessage.h"
25
26#include "arcane/impl/TransferValuesParallelOperation.h"
27
28#include "arccore/message_passing/PointToPointSerializerMng.h"
29
30#include <map>
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arcane
36{
37using namespace Arccore::MessagePassing;
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42TransferValuesParallelOperation::
43TransferValuesParallelOperation(IParallelMng* pm)
44: m_parallel_mng(pm)
45{
46}
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51TransferValuesParallelOperation::
52~TransferValuesParallelOperation()
53{
54}
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
59IParallelMng* TransferValuesParallelOperation::
60parallelMng()
61{
62 return m_parallel_mng;
63}
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
68void TransferValuesParallelOperation::
69setTransferRanks(Int32ConstArrayView ranks)
70{
71 m_ranks = ranks;
72}
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
77void TransferValuesParallelOperation::
78addArray(Int32ConstArrayView send_values, SharedArray<Int32> recv_values)
79{
80 m_send32_values.add(send_values);
81 m_recv32_values.add(recv_values);
82}
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
87void TransferValuesParallelOperation::
88addArray(Int64ConstArrayView send_values, SharedArray<Int64> recv_values)
89{
90 m_send64_values.add(send_values);
91 m_recv64_values.add(recv_values);
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
97void TransferValuesParallelOperation::
98addArray(RealConstArrayView send_values, SharedArray<Real> recv_values)
99{
100 m_send_real_values.add(send_values);
101 m_recv_real_values.add(recv_values);
102}
103
104/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106
107template <typename U> void TransferValuesParallelOperation::
108_putArray(ISerializer* s,
109 Span<const Int32> z_indexes,
111 Array<U>& tmp_values)
112{
113 Int64 nb = z_indexes.size();
114 tmp_values.resize(nb);
115 for (Integer z = 0, zs = arrays.size(); z < zs; ++z) {
116 Span<const U> v = arrays[z];
117 for (Integer zz = 0; zz < nb; ++zz)
118 tmp_values[zz] = v[z_indexes[zz]];
119 s->putSpan(tmp_values);
120 }
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126template <typename U> void TransferValuesParallelOperation::
127_getArray(ISerializer* s, Integer nb, UniqueArray<SharedArray<U>>& arrays,
128 Array<U>& tmp_values)
129{
130 tmp_values.resize(nb);
131 for (Integer z = 0, zs = arrays.size(); z < zs; ++z) {
132 s->getSpan(tmp_values);
133 for (Integer zz = 0; zz < nb; ++zz)
134 arrays[z].add(tmp_values[zz]);
135 }
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
141void TransferValuesParallelOperation::
142transferValues()
143{
144 String func_name = "TransfertValuesParallelOperation::transferValues()";
145 IParallelMng* pm = m_parallel_mng;
146 Timer::Phase tphase(pm->timeStats(), TP_Communication);
147
148 if (!pm->isParallel()) {
149 throw NotImplementedException(func_name, "in sequential");
150 }
151
152 ITraceMng* trace = pm->traceMng();
153
154 Int32 my_rank = pm->commRank();
155 Int32 nb_send = m_ranks.size();
156
157 Int64 nb_send_int32 = m_send32_values.size();
158 Int64 nb_send_int64 = m_send64_values.size();
159 Int64 nb_send_real = m_send_real_values.size();
160
161 if (nb_send_int32 != m_recv32_values.size())
162 throw ArgumentException(func_name, "Int32 send_array and Int32 recv_array do not have the same size");
163 if (nb_send_int64 != m_recv64_values.size())
164 throw ArgumentException(func_name, "Int64 send_array and Int64 recv_array do not have the same size");
165 if (nb_send_real != m_recv_real_values.size())
166 throw ArgumentException(func_name, "Real send_array and Real recv_array do not have the same size");
167
168 for (Int64 i = 0; i < nb_send_int32; ++i) {
169 if (m_send32_values[i].size() != nb_send)
170 throw ArgumentException(func_name, "Int32 array and ranks do not have the same size");
171 }
172 for (Int64 i = 0; i < nb_send_int64; ++i) {
173 if (m_send64_values[i].size() != nb_send)
174 throw ArgumentException(func_name, "Int64 array and ranks do not have the same size");
175 }
176 for (Int64 i = 0; i < nb_send_real; ++i) {
177 if (m_send_real_values[i].size() != nb_send)
178 throw ArgumentException(func_name, "Real array and ranks do not have the same size");
179 }
180
181 typedef std::map<Int32, SharedArray<Int32>> SubDomainIndexMap;
182 SubDomainIndexMap sub_domain_list;
183
184 for (Integer i = 0; i < nb_send; ++i) {
185 Int32 sd = m_ranks[i];
186 if (sd == NULL_SUB_DOMAIN_ID)
187 ARCANE_FATAL("null sub_domain_id");
188 if (sd == my_rank)
189 ARCANE_FATAL("can not transfer to myself");
190 }
191
192 for (Integer i = 0; i < nb_send; ++i) {
193 Int32 sd = m_ranks[i];
194 Int32Array& indexes = sub_domain_list[sd];
195 indexes.add(i);
196 }
197
198 UniqueArray<Int64> sub_domain_nb_to_send;
199 for (SubDomainIndexMap::const_iterator b = sub_domain_list.begin();
200 b != sub_domain_list.end(); ++b) {
201 Int32 sd = b->first;
202 Int64 n = b->second.size();
203 sub_domain_nb_to_send.add(my_rank);
204 sub_domain_nb_to_send.add(sd);
205 sub_domain_nb_to_send.add(n);
206 }
207 UniqueArray<Int64> total_sub_domain_nb_to_send;
208 pm->allGatherVariable(sub_domain_nb_to_send, total_sub_domain_nb_to_send);
209 SharedArray<Int32> tmp_values_int32;
210 SharedArray<Int64> tmp_values_int64;
211 SharedArray<Real> tmp_values_real;
212 PointToPointSerializerMng serializer_mng(pm->messagePassingMng());
213 for (Int64 i = 0, n = total_sub_domain_nb_to_send.size(); i < n; i += 3) {
214 Int32 rank_send = CheckedConvert::toInt32(total_sub_domain_nb_to_send[i]);
215 Int32 rank_recv = CheckedConvert::toInt32(total_sub_domain_nb_to_send[i + 1]);
216 //Integer nb_exchange = total_sub_domain_nb_to_send[i+2];
217 if (rank_send == rank_recv)
218 continue;
219 if (rank_recv == my_rank) {
220 serializer_mng.addReceiveMessage(MessageRank(rank_send));
221 trace->info() << " ADD RECV MESSAGE recv=" << rank_recv << " send=" << rank_send;
222 }
223 else if (rank_send == my_rank) {
224 trace->info() << " ADD SEND MESSAGE recv=" << rank_recv << " send=" << rank_send;
225 //sm = new SerializeMessage(rank_send,rank_recv,ISerializeMessage::MT_Send);
226 auto sm = serializer_mng.addSendMessage(MessageRank(rank_recv));
227 ISerializer* s = sm->serializer();
228 s->setMode(ISerializer::ModeReserve);
229 IntegerConstArrayView z_indexes = sub_domain_list.find(rank_recv)->second;
230 Integer nb = z_indexes.size();
231 trace->info() << " ADD SIZE int32=" << nb * nb_send_int32
232 << " int64=" << nb * nb_send_int64
233 << " real=" << nb * nb_send_real;
234 s->reserveInteger(1); // Pour la taille
235 for (Integer k = 0; k < nb; ++k) {
236 s->reserveSpan(eBasicDataType::Int32, nb_send_int32);
237 s->reserveSpan(eBasicDataType::Int64, nb_send_int64);
238 s->reserveSpan(eBasicDataType::Real, nb_send_real);
239 }
240 s->allocateBuffer();
242 s->putInteger(nb);
243
244 _putArray(s, z_indexes, m_send32_values, tmp_values_int32);
245 _putArray(s, z_indexes, m_send64_values, tmp_values_int64);
246 _putArray(s, z_indexes, m_send_real_values, tmp_values_real);
247 }
248 }
249
250 auto func = [&](ISerializeMessage* sm) {
251 if (!sm->isSend()) {
252 trace->info() << " GET RECV MESSAGE recv=" << sm->destination();
253 ISerializer* s = sm->serializer();
255 Integer nb = s->getInteger();
256 trace->info() << " GET SIZE nb=" << nb;
257
258 _getArray(s, nb, m_recv32_values, tmp_values_int32);
259 _getArray(s, nb, m_recv64_values, tmp_values_int64);
260 _getArray(s, nb, m_recv_real_values, tmp_values_real);
261 }
262 };
263 serializer_mng.waitMessages(Parallel::WaitAll, func);
264}
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
268
269} // End namespace Arcane
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
Base class for 1D data vectors.
void resize(Int64 s)
Changes the number of elements in the array to s.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Interface of the parallelism manager for a subdomain.
virtual ITraceMng * traceMng() const =0
Trace manager.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual ITimeStats * timeStats() const =0
Associated statistics manager (can be null).
virtual void allGatherVariable(ConstArrayView< char > send_buf, Array< char > &recv_buf)=0
Performs an all-gather operation across all processors.
virtual IMessagePassingMng * messagePassingMng() const =0
Associated Arccore message passing manager.
virtual bool isParallel() const =0
Returns true if the execution is parallel.
virtual Integer getInteger()=0
Retrieve a size.
virtual void allocateBuffer()=0
Allocates the serializer memory.
virtual void putInteger(Integer value)=0
Add the integer value.
virtual void putSpan(Span< const Real > values)
Add the array values.
virtual void getSpan(Span< Real > values)
Retrieve the array values.
virtual void reserveSpan(eBasicDataType dt, Int64 n)=0
Reserves memory for n values of dt.
virtual void setMode(eMode new_mode)=0
Sets the current mode.
virtual TraceMessage info()=0
Stream for an information message.
Point-to-point communications using 'ISerializer'.
Integer waitMessages(eWaitType wt, std::function< void(ISerializeMessage *)> functor)
Waits for the messages to finish execution.
Ref< ISerializeMessage > addSendMessage(MessageRank receiver_rank)
Creates a sending serialization message.
Ref< ISerializeMessage > addReceiveMessage(MessageRank sender_rank)
Creates a receiving serialization message.
1D vector of data with reference semantics.
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Definition Span.h:327
View of an array of elements of type T.
Definition Span.h:635
Positions the phase of the currently executing action.
Definition Timer.h:142
1D data vector with value semantics (STL style).
void add(ArrayView< T > lhs, ConstArrayView< T > copy_array)
Adds the array copy_array to the instance.
Definition MathUtils.h:927
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:480
Array< Int32 > Int32Array
Dynamic one-dimensional array of 32-bit integers.
Definition UtilsTypes.h:127
ConstArrayView< Integer > IntegerConstArrayView
C equivalent of a 1D array of integers.
Definition UtilsTypes.h:486
std::int32_t Int32
Signed integer type of 32 bits.
ConstArrayView< Real > RealConstArrayView
C equivalent of a 1D array of reals.
Definition UtilsTypes.h:488