Arcane  4.1.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ItemFamilyVariableSerializer.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/* ItemFamilyVariableSerializer.cc (C) 2000-2024 */
9/* */
10/* Manages the serialization/deserialization of variables for a family. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/NotSupportedException.h"
15#include "arcane/utils/HashTableMap.h"
16#include "arcane/utils/Collection.h"
17
18#include "arcane/core/VariableTypes.h"
20#include "arcane/core/ItemPrinter.h"
21#include "arcane/core/ISerializer.h"
22#include "arcane/core/IItemFamily.h"
23#include "arcane/core/ItemVector.h"
24#include "arcane/core/MeshToMeshTransposer.h"
25#include "arcane/core/ItemFamilySerializeArgs.h"
26#include "arcane/core/IParallelMng.h"
27// TODO: a supprimer
28#include "arcane/core/IMesh.h"
29#include "arcane/core/IVariableMng.h"
30#include "arcane/core/ISubDomain.h"
31
32#include "arcane/mesh/ItemFamilyVariableSerializer.h"
33
34#include <set>
35
36/*
37 * NOTE:
38 * Instead of one instance of this class managing the serialization of variables
39 * for the parent family and all child families, an instance per family would be necessary.
40 */
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44namespace Arcane
45{
46class ItemFamilyExchange;
47}
48
49/*---------------------------------------------------------------------------*/
50/*---------------------------------------------------------------------------*/
51
52namespace Arcane::mesh
53{
54
55namespace
56{
57 const Integer VARIABLE_MAGIC_NUMBER = 0x3a9e4324;
58}
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
62ItemFamilyVariableSerializer::
63ItemFamilyVariableSerializer(IItemFamily* family)
64: TraceAccessor(family->traceMng())
65, m_item_family(family)
66{
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72ItemFamilyVariableSerializer::
73~ItemFamilyVariableSerializer()
74{
75}
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
80void ItemFamilyVariableSerializer::
81initialize()
82{
83 // Determines the list of variables to exchange
84 // It also includes variables from child families
85 // TODO: it would be necessary to retrieve the variables of each
86 // family via IItemFamily::usedVariables(), but this method does not guarantee
87 // alphabetical order of transmission. By thinking with an std::map, we
88 // should be able to manage it.
89 IVariableMng* vm = m_item_family->mesh()->variableMng();
90 VariableCollection used_vars(vm->usedVariables());
91
92 UniqueArray<IItemFamily*> family_to_exchange;
93 family_to_exchange.add(m_item_family); // The current family
94 IItemFamilyCollection child_families = m_item_family->childFamilies();
95 for (IItemFamily* child_family : child_families)
96 family_to_exchange.add(child_family);
97
98 for (Integer i = 0; i < family_to_exchange.size(); ++i) {
99 IItemFamily* current_family = family_to_exchange[i];
100 info(4) << " Serializing family " << current_family->fullName();
101
102 // TODO: retrieve the variables used by the family
103 // via ItemFamily::usedVariables
104 for (VariableCollection::Enumerator i_var(used_vars); ++i_var;) {
105 IVariable* var = *i_var;
106 // TODO: check if all variables need to be exchanged.
107 // Should PNoDump variables be sent?
108 // TODO: call the writeObservable of IVariableMng or make
109 // a specific one for balancing
110 // TODO: check that all sub-domains have the same values
111 // for m_variables_to_exchange with the variables in the same order.
112 bool no_exchange = (var->property() & IVariable::PNoExchange);
113 if (no_exchange)
114 continue;
115 IItemFamily* var_family = var->itemFamily();
116 if (var_family == current_family) {
117 debug(Trace::High) << "Add variable " << var->fullName() << " to serialize";
119 }
120 }
121 }
122 debug() << "Number of variables to serialize: " << m_variables_to_exchange.size();
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
131void ItemFamilyVariableSerializer::
132_checkSerialization(ISerializer* sbuf, Int32ConstArrayView local_ids)
133{
134 switch (sbuf->mode()) {
135 case ISerializer::ModeReserve:
136 // Reserves for the uniqueId() list of transferred entities
137 sbuf->reserveInteger(1); // Magic number for readVariables();
138 sbuf->reserveInteger(1); // Number of serialized entities.
139 break;
141 // Serializes the number of transferred entities
142 sbuf->put(VARIABLE_MAGIC_NUMBER);
143 sbuf->put(local_ids.size());
144 break;
146 // Checks for serialization errors.
147 Integer magic_number = sbuf->getInteger();
148 if (magic_number != VARIABLE_MAGIC_NUMBER)
149 ARCANE_FATAL("Internal error: bad magic number expected={0} found={1}",
150 VARIABLE_MAGIC_NUMBER, magic_number);
151
152 // Retrieves the number of transferred entities for verification
153 Integer nb_item = sbuf->getInteger();
154 if (local_ids.size() != nb_item) {
155 // Since Arcane 2.4.0, 'm_family_serializer' is responsible for
156 // retrieving the localId() of the sent entities. The array
157 // m_receive_local_ids[i] must therefore always be correct.
158 ARCANE_FATAL("Bad value for received_items family={0} n={1} expected={2}",
159 m_item_family->name(), local_ids, nb_item);
160 }
161 break;
162 }
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
171void ItemFamilyVariableSerializer::
172_checkSerializationVariable(ISerializer* sbuf, IVariable* var)
173{
174 String var_full_name = var->fullName();
175 switch (sbuf->mode()) {
176 case ISerializer::ModeReserve:
177 // Reserves for the variable name
178 sbuf->reserve(var_full_name);
179 break;
181 sbuf->put(var_full_name);
182 break;
184 String expected_name;
185 sbuf->get(expected_name);
186 if (expected_name != var_full_name)
187 ARCANE_FATAL("Incoherent variable var={0} expected={1}",
188 var_full_name, expected_name);
189 } break;
190 }
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
200void ItemFamilyVariableSerializer::
201serialize(const ItemFamilySerializeArgs& args)
202{
203 ISerializer* sbuf = args.serializer();
204 Int32ConstArrayView local_ids = args.localIds();
205
206 bool is_recv = (sbuf->mode() == ISerializer::ModeGet);
207 String mode_str = (is_recv) ? "recv" : "send";
208 const bool is_debug = arcaneIsDebug();
209
210 Int32 owner_rank = (is_recv) ? m_item_family->parallelMng()->commRank() : args.rank();
211
212 _checkSerialization(sbuf, local_ids);
213
215 info(4) << "-- Serializing variable " << var->fullName()
216 << " group=" << var->itemGroup().name()
217 << " (n=" << var->itemGroup().size() << ")"
218 << " mode=" << (int)sbuf->mode()
219 << " target_rank=" << args.rank();
220
222
223 if (is_debug) {
224 ENUMERATE_ITEM (iitem, m_item_family->view(local_ids)) {
225 debug(Trace::Highest) << "To " << mode_str << " : " << ItemPrinter(*iitem);
226 }
227 debug(Trace::High) << "To " << mode_str << " count = " << local_ids.size();
228 }
229
230 if (var->itemFamily() != m_item_family) {
231 IItemFamily* var_family = var->itemFamily();
232 ItemVector dest_items = MeshToMeshTransposer::transpose(m_item_family,
233 var_family,
234 m_item_family->view(local_ids),
235 false);
236 Int32UniqueArray dest_lids;
237 dest_lids.reserve(dest_items.size());
238 ENUMERATE_ITEM (iitem, dest_items) {
239 Int32 lid = iitem.localId();
240 if (lid != NULL_ITEM_LOCAL_ID && iitem->owner() == owner_rank) {
241 dest_lids.add(lid);
242 }
243 }
244 debug(Trace::High) << "Serializing " << dest_lids.size() << " sub-items";
245
246 if (var->isPartial())
247 _serializePartialVariable(var, sbuf, dest_lids);
248 else
249 var->serialize(sbuf, dest_lids);
250 }
251 else {
252 if (var->isPartial())
253 _serializePartialVariable(var, sbuf, local_ids);
254 else
255 var->serialize(sbuf, local_ids);
256 }
257 }
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
280void ItemFamilyVariableSerializer::
281_serializePartialVariable(IVariable* var, ISerializer* sbuf, Int32ConstArrayView local_ids)
282{
283 String var_full_name = var->fullName();
284
285 ItemGroup group = var->itemGroup();
286 ISerializer::eMode mode = sbuf->mode();
287 switch (mode) {
288 case ISerializer::ModeReserve:
290 Int32UniqueArray indexes_to_send;
291 Int64UniqueArray unique_ids_to_send;
292 std::set<Int32> items_to_send;
293 for (Integer i = 0, n = local_ids.size(); i < n; ++i) {
294 items_to_send.insert(local_ids[i]);
295 }
296 ENUMERATE_ITEM (iitem, group) {
297 if (items_to_send.find(iitem.itemLocalId()) != items_to_send.end()) {
298 indexes_to_send.add(iitem.index());
299 unique_ids_to_send.add((*iitem).uniqueId());
300 }
301 }
302 Integer nb_item_to_send = indexes_to_send.size();
303 if (mode == ISerializer::ModeReserve) {
304 // Reserves for the number of elements and for each element
305 sbuf->reserveInt64(1);
306 sbuf->reserveSpan(eBasicDataType::Int64, nb_item_to_send);
307 }
308 else {
309 sbuf->putInt64(nb_item_to_send);
310 sbuf->putSpan(unique_ids_to_send);
311 }
312 var->serialize(sbuf, indexes_to_send);
313 } break;
315 Int32UniqueArray indexes;
316 Int64UniqueArray unique_ids;
317 String expected_name;
318 //sbuf->get(expected_name);
319 //if (expected_name!=var_full_name)
320 //ARCANE_FATAL("Incoherent variable var={0} expected={1}",
321 //var_full_name,expected_name);
322 Int64 nb_item = sbuf->getInt64();
323 unique_ids.resize(nb_item);
324 sbuf->getSpan(unique_ids);
325 Integer nb_item_in_variable = group.size();
326 HashTableMapT<Int64, Int32> unique_ids_to_index(nb_item_in_variable, true);
327 ENUMERATE_ITEM (iitem, group) {
328 unique_ids_to_index.nocheckAdd((*iitem).uniqueId(), iitem.index());
329 }
330 indexes.resize(nb_item);
331 for (Integer i = 0; i < nb_item; ++i) {
332 // Checks that the entity is present. This is normally the case unless
333 // \a group is not consistent between the PE (that is, for example an
334 // entity \a x present on 2 PE but which is in \a group only for one
335 // of the two PE).
336 HashTableMapT<Int64, Int32>::Data* data = unique_ids_to_index.lookup(unique_ids[i]);
337 if (!data)
338 ARCANE_FATAL("Can not find item with unique_id={0} index={1}", unique_ids[i], i);
339 indexes[i] = data->value();
340 }
341
342 var->serialize(sbuf, indexes);
343 } break;
344 }
345}
346
347/*---------------------------------------------------------------------------*/
348/*---------------------------------------------------------------------------*/
349
350} // End namespace Arcane::mesh
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour itérer sur les entités du maillage.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Integer size() const
Nombre d'éléments du vecteur.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Table de hachage pour tableaux associatifs.
void nocheckAdd(KeyTypeConstRef id, const ValueType &value)
Ajoute la valeur value correspondant à la clé id.
Data * lookup(KeyTypeConstRef id)
Recherche la valeur correspondant à la clé id.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual String fullName() const =0
Nom complet de la famille (avec celui du maillage).
virtual ItemVectorView view(Int32ConstArrayView local_ids)=0
Vue sur les entités.
virtual void reserve(eBasicDataType dt, Int64 n)=0
Réserve de la mémoire pour n objets de type dt.
virtual Integer getInteger()=0
Récupère une taille.
eMode
Mode de fonctionnement du sérialiseur.
@ ModePut
Le sérialiseur attend des reserve().
virtual Int64 getInt64()=0
Récupère une taille.
virtual void put(Span< const Real > values)=0
Ajoute le tableau values.
virtual void putSpan(Span< const Real > values)
Ajoute le tableau values.
virtual eMode mode() const =0
Mode de fonctionnement actuel.
virtual void getSpan(Span< Real > values)
Récupère le tableau values.
virtual void get(ArrayView< Real > values)=0
Récupère le tableau values.
virtual void reserveSpan(eBasicDataType dt, Int64 n)=0
Réserve de la mémoire pour n valeurs de dt.
virtual void putInt64(Int64 value)=0
Ajoute l'entier value.
Interface du gestionnaire de variables.
virtual VariableCollection usedVariables()=0
Liste des variables utilisées.
Interface d'une variable.
Definition IVariable.h:39
virtual String fullName() const =0
Nom complet de la variable (avec le préfixe de la famille).
@ PNoExchange
Indique que la variable ne doit pas être échangée.
Definition IVariable.h:133
virtual int property() const =0
Retourne les propriétés de la variable.
virtual ItemGroup itemGroup() const =0
Groupe du maillage associé.
virtual void serialize(ISerializer *sbuffer, IDataOperation *operation=0)=0
virtual IItemFamily * itemFamily() const =0
Famille d'entité associée.
Arguments des callbacks de sérialisation des familles d'entités.
Int32 rank() const
Rang de la source ou de la destination.
Int32ConstArrayView localIds() const
Indices locaux des entités. En sérialisation, il s'agit des indices locaux des entités envoyées au ra...
ISerializer * serializer() const
Sérialiseur associé
Groupe d'entités de maillage.
Definition ItemGroup.h:49
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:34
Vecteur d'entités.
Definition ItemVector.h:59
Int32 size() const
Nombre d'éléments du vecteur.
Definition ItemVector.h:105
static ItemVector transpose(IMesh *meshA, IMesh *meshB, ItemVectorView itemsA, bool do_fatal=false)
Transpose itemsA from meshB to items on meshB.
Chaîne de caractères unicode.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
Collection de variables.
void _serializePartialVariable(IVariable *var, ISerializer *sbuf, Int32ConstArrayView local_ids)
Serialise une variable partielle.
void _checkSerializationVariable(ISerializer *sbuf, IVariable *var)
Serializes the variable name to verify that deserialization is correct.
void _checkSerialization(ISerializer *sbuf, Int32ConstArrayView local_ids)
Serializes a magic number and the number of entities to verify that deserialization is correct.
UniqueArray< IVariable * > m_variables_to_exchange
List of variables to exchange.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:339
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:482
Collection< IItemFamily * > IItemFamilyCollection
Collection de familles d'entités.
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
Definition Misc.cc:80
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:341
std::int32_t Int32
Type entier signé sur 32 bits.