Arcane  v4.1.8.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
GatherGroup.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/* GatherGroup.cc (C) 2000-2026 */
9/* */
10/* Classe permettant de gérer les regroupements de données sur le ou les */
11/* sous-domaines écrivains. */
12/*---------------------------------------------------------------------------*/
13/*---------------------------------------------------------------------------*/
14
15#include "arcane/core/internal/GatherGroup.h"
16
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/Array2.h"
19
20#include "arcane/core/IParallelMng.h"
21#include "arcane/core/internal/IParallelMngInternal.h"
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26namespace Arcane
27{
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
33GatherGroup(GatherGroupInfo* gather_group_info)
34: m_gather_group_info(ARCANE_CHECK_POINTER(gather_group_info))
35{
36 ARCANE_FATAL_IF(!gather_group_info->isComputed(), "GatherGroupInfo is not computed");
37}
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
43GatherGroup() = default;
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
48GatherGroup::
49~GatherGroup() = default;
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
56{
57 ARCANE_CHECK_POINTER(m_gather_group_info);
58 IParallelMng* pm = m_gather_group_info->m_parallel_mng;
59 // True si Thread ou Hybride ou MPI sans MPI-IO
60 // False si Séquentiel ou MPI + MPI-IO.
61 return pm->commSize() != 1 && (pm->isThreadImplementation() || !m_gather_group_info->m_use_collective_io);
62}
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
66
69{
70 ARCANE_CHECK_POINTER(m_gather_group_info);
71 IParallelMng* pm = m_gather_group_info->m_parallel_mng;
72
73 // Si séquentiel ou MPI + MPI-IO.
74 if ((pm->commSize() == 1) || (!pm->isThreadImplementation() && m_gather_group_info->m_use_collective_io)) {
75 out.copy(in);
76 return;
77 }
78
79 const Int32 writer = m_gather_group_info->m_writer;
80
81 if (writer != pm->commRank()) {
82 pm->send(in.constSmallView(), writer);
83 return;
84 }
85
86 out.copy(in);
87
88 const Int32 nb_sender = m_gather_group_info->m_nb_sender_to_writer;
89
90 SmallSpan<const Int32> nb_elem_recved = m_gather_group_info->m_nb_elem_recv.smallSpan();
91
92 UniqueArray<Parallel::Request> requests(nb_sender - 1);
93
94 Int64 old_size = in.size();
95 for (Int32 i = 0; i < nb_sender - 1; ++i) {
96 const Int32 rank = i + writer + 1;
97 const Int64 sizeof_recved = nb_elem_recved[i] * sizeof_elem;
98
99 ArrayView<Byte> recv_elem = out.subSpan(old_size, sizeof_recved).smallView();
100 requests[i] = pm->recv(recv_elem, rank, false);
101
102 old_size += sizeof_recved;
103 }
104 pm->waitAllRequests(requests);
105}
106
107/*---------------------------------------------------------------------------*/
108/*---------------------------------------------------------------------------*/
109
111setGatherGroupInfo(GatherGroupInfo* gather_group_info)
112{
113 ARCANE_CHECK_POINTER(gather_group_info);
114 ARCANE_FATAL_IF(!gather_group_info->isComputed(), "GatherGroupInfo is not computed");
115 m_gather_group_info = gather_group_info;
116}
117
118/*---------------------------------------------------------------------------*/
119/*---------------------------------------------------------------------------*/
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
125GatherGroupInfo(IParallelMng* parallel_mng, bool use_collective_io)
126: m_parallel_mng(parallel_mng)
127, m_use_collective_io(use_collective_io)
128{}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
133GatherGroupInfo::
134~GatherGroupInfo() = default;
135
136/*---------------------------------------------------------------------------*/
137/*---------------------------------------------------------------------------*/
138
140computeSize(Int32 nb_elem_in)
141{
142 if (m_is_computed)
143 return;
144 m_is_computed = true;
145
146 if (m_use_collective_io) {
147 m_writer = m_parallel_mng->_internalApi()->masterParallelIORank();
148 m_nb_sender_to_writer = m_parallel_mng->_internalApi()->nbSendersToMasterParallelIO();
149 }
150 else {
151 m_writer = m_parallel_mng->masterIORank();
152 m_nb_sender_to_writer = m_parallel_mng->commSize();
153 }
154
155 // Si séquentiel ou MPI + MPI-IO.
156 if ((m_parallel_mng->commSize() == 1) || (!m_parallel_mng->isThreadImplementation() && m_use_collective_io)) {
157 m_nb_elem_output = nb_elem_in;
158 m_nb_writer_global = m_parallel_mng->commSize();
159 return;
160 }
161
162 if (m_writer != m_parallel_mng->commRank()) {
163 m_parallel_mng->send({ 1, &nb_elem_in }, m_writer);
164 m_nb_elem_output = 0;
165 }
166 else {
167 m_nb_elem_recv.resizeNoInit(m_nb_sender_to_writer - 1);
168
169 {
170 UniqueArray<Parallel::Request> requests(m_nb_sender_to_writer - 1);
171 for (Int32 i = 0; i < m_nb_sender_to_writer - 1; ++i) {
172 const Int32 rank = i + m_writer + 1;
173 requests[i] = m_parallel_mng->recv({ 1, &m_nb_elem_recv[i] }, rank, false);
174 }
175 m_parallel_mng->waitAllRequests(requests);
176 }
177
178 m_nb_elem_output = nb_elem_in;
179 for (const Int32 size : m_nb_elem_recv) {
180 m_nb_elem_output += size;
181 }
182 }
183
184 m_nb_writer_global = m_parallel_mng->reduce(MessagePassing::ReduceSum, (m_writer == m_parallel_mng->commRank()));
185}
186
187/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189
192{
193 return m_nb_elem_recv.smallSpan();
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198
199} // End namespace Arcane
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL_IF(const,...)
Macro envoyant une exception FatalErrorException si cond est vrai.
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
Vue modifiable d'un tableau d'un type T.
Classe permettant de calculer et de conserver les informations de regroupements.
void computeSize(Int32 nb_elem_in) override
Méthode permettant de calculer les informations de regroupements.
GatherGroupInfo(IParallelMng *parallel_mng, bool use_collective_io)
Constructeur.
SmallSpan< Int32 > nbElemRecvGatherToMasterIO() override
Méthode permettant de connaitre le nombre d'éléments que vont nous envoyer chaque sous-domaine tier.
bool isComputed() override
Méthode permettant de savoir si la méthode computeSize() a déjà été appelée.
GatherGroup()
Constructeur. Pour que l'objet soit utilisable, il est nécessaire d'appeler setGatherGroupInfo().
bool isNeedGather() override
Méthode permettant de savoir si l'on doit effectuer le regroupement ou si l'on peut directement écrir...
void gatherToMasterIO(Int64 sizeof_elem, Span< const Byte > in, Span< Byte > out) override
Méthode permettant de regrouper les données de plusieurs sous-domaines sur un ou plusieurs sous-domai...
void setGatherGroupInfo(GatherGroupInfo *gather_group_info)
Méthode permettant de définir les informations de regroupement.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual bool isThreadImplementation() const =0
Indique si l'implémentation utilise les threads.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void waitAllRequests(ArrayView< Request > rvalues)=0
Bloque en attendant que les requêtes rvalues soient terminées.
Vue d'un tableau d'éléments de type T.
Definition Span.h:801
__host__ __device__ void copy(const U &copy_array)
Recopie le tableau copy_array dans l'instance.
Definition Span.h:475
constexpr ConstArrayView< value_type > constSmallView() const
Vue constante sur cette vue.
Definition Span.h:399
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:325
Vue d'un tableau d'éléments de type T.
Definition Span.h:633
constexpr __host__ __device__ Span< T, DynExtent > subSpan(Int64 abegin, Int64 asize) const
Sous-vue à partir de l'élément abegin et contenant asize éléments.
Definition Span.h:733
Vecteur 1D de données avec sémantique par valeur (style STL).
@ ReduceSum
Somme des valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
std::int32_t Int32
Type entier signé sur 32 bits.