Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
VariableParallelOperationBase.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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/* VariableParallelOperationBase.cc (C) 2000-2023 */
9/* */
10/* Classe de base des opérations parallèles sur des variables. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/parallel/VariableParallelOperationBase.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/ScopedPtr.h"
18
19#include "arcane/IParallelMng.h"
20#include "arcane/ISerializer.h"
21#include "arcane/ISerializeMessage.h"
22#include "arcane/IParallelExchanger.h"
23#include "arcane/ISubDomain.h"
24#include "arcane/IVariable.h"
25#include "arcane/IItemFamily.h"
26#include "arcane/ItemInternal.h"
27#include "arcane/ItemGroup.h"
28#include "arcane/ParallelMngUtils.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane::Parallel
34{
35
36namespace
37{
38 const Int64 SERIALIZE_MAGIC_NUMBER = 0x4cf92789;
39}
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44VariableParallelOperationBase::
45VariableParallelOperationBase(IParallelMng* pm)
46: TraceAccessor(pm->traceMng())
47, m_parallel_mng(pm)
48, m_item_family(nullptr)
49{
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55void VariableParallelOperationBase::
56setItemFamily(IItemFamily* family)
57{
58 if (m_item_family)
59 ARCANE_FATAL("family already set");
60 m_item_family = family;
61}
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66IItemFamily* VariableParallelOperationBase::
67itemFamily()
68{
69 return m_item_family;
70}
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
74
75void VariableParallelOperationBase::
76addVariable(IVariable* variable)
77{
78 if (!m_item_family)
79 ARCANE_FATAL("family not set. call setItemFamily()");
80 if (variable->itemGroup().itemFamily()!=m_item_family)
81 ARCANE_FATAL("variable->itemFamily() and itemFamily() differ");
82 m_variables.add(variable);
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88void VariableParallelOperationBase::
89applyOperation(IDataOperation* operation)
90{
91 if (m_variables.empty())
92 return;
93
94#ifdef ARCANE_DEBUG
95 const bool is_debug_print = true;
96#else
97 const bool is_debug_print = false;
98#endif
99 IParallelMng* pm = m_parallel_mng;
100 Integer nb_rank = pm->commSize();
101 m_items_to_send.clear();
102 m_items_to_send.resize(nb_rank);
103 _buildItemsToSend();
104
106 m_messages.reserve(nb_rank);
107
108 auto exchanger {ParallelMngUtils::createExchangerRef(pm)};
109
110 for( Integer i=0; i<nb_rank; ++i )
111 if (!m_items_to_send[i].empty())
112 exchanger->addSender(i);
113
114 bool no_exchange = exchanger->initializeCommunicationsMessages();
115 if (no_exchange)
116 return;
117
118 ItemInfoListView item_list(m_item_family);
119 // Génère les infos pour chaque processeur à qui on va envoyer des entités
120 for( Integer i=0, is=exchanger->nbSender(); i<is; ++i ){
121 ISerializeMessage* comm = exchanger->messageToSend(i);
122 Int32 dest_sub_domain = comm->destination().value();
123 ConstArrayView<ItemLocalId> dest_items_internal = m_items_to_send[dest_sub_domain];
124
125 Integer nb_item = dest_items_internal.size();
126 debug() << "Number of items to serialize: " << nb_item << " subdomain=" << dest_sub_domain;
127
128 UniqueArray<Int32> dest_items_local_id(nb_item);
129 UniqueArray<Int64> dest_items_unique_id(nb_item);
130 for( Integer z=0; z<nb_item; ++z ){
131 Item item = item_list[dest_items_internal[z]];
132 dest_items_local_id[z] = item.localId();
133 dest_items_unique_id[z] = item.uniqueId().asInt64();
134 }
135 ISerializer* sbuf = comm->serializer();
136
137 // Réserve la mémoire pour la sérialisation
138 sbuf->setMode(ISerializer::ModeReserve);
139
140 // Réserve pour le magic number
141 sbuf->reserve(DT_Int64,1);
142
143 // Réserve pour la liste uniqueId() des entités transférées
144 sbuf->reserve(DT_Int64,1);
145 sbuf->reserveSpan(dest_items_unique_id);
146
147 // Réserve pour chaque variable
148 for( VariableList::Enumerator i_var(m_variables); ++i_var; ){
149 IVariable* var = *i_var;
150 debug(Trace::High) << "Serialize variable (reserve)" << var->name();
151 var->serialize(sbuf,dest_items_local_id);
152 }
153
154 sbuf->allocateBuffer();
155
156 // Sérialise les infos
157 sbuf->setMode(ISerializer::ModePut);
158
159 // Sérialise le magic number
160 sbuf->putInt64(SERIALIZE_MAGIC_NUMBER);
161
162 // Sérialise la liste des uniqueId() des entités transférées
163 sbuf->putInt64(nb_item);
164 sbuf->putSpan(dest_items_unique_id);
165 for( VariableList::Enumerator i_var(m_variables); ++i_var; ){
166 IVariable* var = *i_var;
167 debug(Trace::High) << "Serialise variable (put)" << var->name();
168 var->serialize(sbuf,dest_items_local_id);
169 }
170 }
171
172 exchanger->processExchange();
173
174 {
175 debug() << "VariableParallelOperationBase::readVariables()";
176
177 UniqueArray<Int64> items_unique_id;
178 UniqueArray<Int32> items_local_id;
179
180 // Récupère les infos pour les variables et les remplit
181 for( Integer i=0, n=exchanger->nbReceiver(); i<n; ++i ){
182 ISerializeMessage* comm = exchanger->messageToReceive(i);
183 ISerializer* sbuf = comm->serializer();
184
185 // Désérialize les variables
186 {
187 // Sérialise le magic number
188 Int64 magic_number = sbuf->getInt64();
189 if (magic_number!=SERIALIZE_MAGIC_NUMBER)
190 ARCANE_FATAL("Bad magic number actual={0} expected={1}. This is probably due to incoherent messaging",
191 magic_number,SERIALIZE_MAGIC_NUMBER);
192
193 // Récupère la liste des uniqueId() des entités transférées
194 Int64 nb_item = sbuf->getInt64();
195 items_unique_id.resize(nb_item);
196 sbuf->getSpan(items_unique_id);
197 items_local_id.resize(nb_item);
198 debug(Trace::High) << "Receiving " << nb_item << " items from " << comm->destination().value();
199
200 if (is_debug_print){
201 for( Integer iz=0; iz<nb_item; ++iz )
202 debug(Trace::Highest) << "Receiving uid=" << items_unique_id[iz];
203 }
204
205 itemFamily()->itemsUniqueIdToLocalId(items_local_id,items_unique_id);
206
207 for( VariableList::Enumerator ivar(m_variables); ++ivar; ){
208 IVariable* var = *ivar;
209 var->serialize(sbuf,items_local_id,operation);
210 }
211 }
212 }
213 }
214}
215
216/*---------------------------------------------------------------------------*/
217/*---------------------------------------------------------------------------*/
218
219} // End namespace Arcane::Parallel
220
221/*---------------------------------------------------------------------------*/
222/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Interface d'une famille d'entités.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual ItemGroup itemGroup() const =0
Groupe du maillage associé.
virtual void serialize(ISerializer *sbuffer, IDataOperation *operation=0)=0
virtual String name() const =0
Nom de la variable.
IItemFamily * itemFamily() const
Famille d'entité à laquelle appartient ce groupe (0 pour le group nul)
Definition ItemGroup.h:123
Vue sur une liste pour obtenir des informations sur les entités.
Classe de base d'un élément de maillage.
Definition Item.h:83
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:210
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
virtual void allocateBuffer()=0
Alloue la mémoire du sérialiseur.
virtual void reserveSpan(eDataType dt, Int64 n)=0
Réserve de la mémoire pour n valeurs de dt.
virtual void putSpan(Span< const Real > values)
Ajoute le tableau values.
virtual void getSpan(Span< Real > values)
Récupère le tableau values.
virtual Int64 getInt64()=0
Récupère une taille.
virtual void reserve(eDataType dt, Int64 n)=0
Réserve de la mémoire pour n objets de type dt.
virtual void setMode(eMode new_mode)=0
Positionne le fonctionnement actuel.
virtual void putInt64(Int64 value)=0
Ajoute l'entier value.
virtual ISerializer * serializer()=0
Sérialiseur.
virtual MessageRank destination() const =0
Rang du destinataire (si isSend() est vrai) ou de l'envoyeur.
Int32 value() const
Valeur du rang.
Definition MessageRank.h:72
Vecteur 1D de données avec sémantique par valeur (style STL).
Implémentation de la concurrence.
@ DT_Int64
Donnée de type entier 64 bits.
Definition DataTypes.h:44