Arcane  v3.16.0.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-2024 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/* Gère la sérialisation/désérialisation des variables d'une famille. */
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 * plutôt qu'une instance de cette classe gère la sérialisation des variables
39 * de la famille mère et de toutes les familles filles, il faudrait une
40 * instance par famille.
41 */
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45namespace Arcane
46{
47class ItemFamilyExchange;
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53namespace Arcane::mesh
54{
55
56namespace
57{
58const Integer VARIABLE_MAGIC_NUMBER = 0x3a9e4324;
59}
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63ItemFamilyVariableSerializer::
64ItemFamilyVariableSerializer(IItemFamily* family)
65: TraceAccessor(family->traceMng())
66, m_item_family(family)
67{
68}
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73ItemFamilyVariableSerializer::
74~ItemFamilyVariableSerializer()
75{
76}
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
81void ItemFamilyVariableSerializer::
82initialize()
83{
84 // Détermine la liste des variables a échanger
85 // On y intégre aussi les variables issues des familles enfants
86 // TODO: il faudrait récupérer directement les variables de chaque
87 // famille via IItemFamily::usedVariables() mais cette méthode ne garantit
88 // par l'ordre alphabétique des envois. En pensant par un std::map, on
89 // devrait pouvoir s'en sortir.
90 IVariableMng* vm = m_item_family->mesh()->variableMng();
91 VariableCollection used_vars(vm->usedVariables());
92
93 UniqueArray<IItemFamily*> family_to_exchange;
94 family_to_exchange.add(m_item_family); // La famille courante
95 IItemFamilyCollection child_families = m_item_family->childFamilies();
96 for( IItemFamily* child_family : child_families )
97 family_to_exchange.add(child_family);
98
99 for (Integer i=0; i<family_to_exchange.size(); ++i ){
100 IItemFamily* current_family = family_to_exchange[i];
101 info(4) << " Serializing family " << current_family->fullName();
102
103 // TODO: récupérer directement les variables utilisées de la famille
104 // via ItemFamily::usedVariables
105 for( VariableCollection::Enumerator i_var(used_vars); ++i_var; ){
106 IVariable* var = *i_var;
107 // TODO: vérifier s'il faut échanger toutes les variables.
108 // Faut-il envoyer les variables PNoDump ?
109 // TODO: appeler le writeObservable de IVariableMng ou en faire
110 // un spécifique pour l'équilibrage
111 // TODO: vérifier que tout les sous-domaines ont les mêmes valeurs
112 // pour m_variables_to_exchange avec les variables dans le même ordre.
113 bool no_exchange = (var->property() & IVariable::PNoExchange);
114 if (no_exchange)
115 continue;
116 IItemFamily* var_family = var->itemFamily();
117 if (var_family==current_family) {
118 debug(Trace::High) << "Add variable " << var->fullName() << " to serialize";
120 }
121 }
122 }
123 debug() << "Number of variables to serialize: " << m_variables_to_exchange.size();
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
132void ItemFamilyVariableSerializer::
133_checkSerialization(ISerializer* sbuf,Int32ConstArrayView local_ids)
134{
135 switch(sbuf->mode()){
136 case ISerializer::ModeReserve:
137 // Réserve pour la liste uniqueId() des entités transférées
138 sbuf->reserveInteger(1); // Nombre magique pour readVariables();
139 sbuf->reserveInteger(1); // Nombre d'entités sérialisées.
140 break;
142 // Sérialise le nombre d'entités transférées
143 sbuf->put(VARIABLE_MAGIC_NUMBER);
144 sbuf->put(local_ids.size());
145 break;
147 // Vérifie pas d'erreurs de sérialisation.
148 Integer magic_number = sbuf->getInteger();
149 if (magic_number!=VARIABLE_MAGIC_NUMBER)
150 ARCANE_FATAL("Internal error: bad magic number expected={0} found={1}",
151 VARIABLE_MAGIC_NUMBER,magic_number);
152
153 // Récupère le nombre d'entités transférées pour vérification
154 Integer nb_item = sbuf->getInteger();
155 if (local_ids.size()!=nb_item){
156 // Depuis la 2.4.0 de Arcane 'm_family_serializer' se charge de
157 // récupérer les localId() des entités envoyées. Le tableau
158 // m_receive_local_ids[i] doit donc toujours être correct.
159 ARCANE_FATAL("Bad value for received_items family={0} n={1} expected={2}",
160 m_item_family->name(),local_ids,nb_item);
161 }
162 break;
163 }
164}
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
172void ItemFamilyVariableSerializer::
173_checkSerializationVariable(ISerializer* sbuf,IVariable* var)
174{
175 String var_full_name = var->fullName();
176 switch(sbuf->mode()){
177 case ISerializer::ModeReserve:
178 // Réserve pour le nom de la variable
179 sbuf->reserve(var_full_name);
180 break;
182 sbuf->put(var_full_name);
183 break;
185 {
186 String expected_name;
187 sbuf->get(expected_name);
188 if (expected_name!=var_full_name)
189 ARCANE_FATAL("Incoherent variable var={0} expected={1}",
190 var_full_name,expected_name);
191 }
192 break;
193 }
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
203void ItemFamilyVariableSerializer::
204serialize(const ItemFamilySerializeArgs& args)
205{
206 ISerializer* sbuf = args.serializer();
207 Int32ConstArrayView local_ids = args.localIds();
208
209 bool is_recv = (sbuf->mode()==ISerializer::ModeGet);
210 String mode_str = (is_recv) ? "recv" :"send";
211 const bool is_debug = arcaneIsDebug();
212
213 Int32 owner_rank = (is_recv) ? m_item_family->parallelMng()->commRank() : args.rank();
214
215 _checkSerialization(sbuf,local_ids);
216
218 info(4) << "-- Serializing variable " << var->fullName()
219 << " group=" << var->itemGroup().name()
220 << " (n=" << var->itemGroup().size() << ")"
221 << " mode=" << (int)sbuf->mode()
222 << " target_rank=" << args.rank();
223
225
226 if (is_debug){
227 ENUMERATE_ITEM(iitem, m_item_family->view(local_ids)){
228 debug(Trace::Highest) << "To " << mode_str << " : " << ItemPrinter(*iitem);
229 }
230 debug(Trace::High) << "To " << mode_str << " count = " << local_ids.size();
231 }
232
233 if (var->itemFamily() != m_item_family){
234 IItemFamily * var_family = var->itemFamily();
235 ItemVector dest_items = MeshToMeshTransposer::transpose(m_item_family,
236 var_family,
237 m_item_family->view(local_ids),
238 false);
239 Int32UniqueArray dest_lids; dest_lids.reserve(dest_items.size());
240 ENUMERATE_ITEM(iitem, dest_items) {
241 Int32 lid = iitem.localId();
242 if (lid != NULL_ITEM_LOCAL_ID && iitem->owner() == owner_rank) {
243 dest_lids.add(lid);
244 }
245 }
246 debug(Trace::High) << "Serializing " << dest_lids.size() << " sub-items";
247
248 if (var->isPartial())
249 _serializePartialVariable(var,sbuf,dest_lids);
250 else
251 var->serialize(sbuf,dest_lids);
252 }
253 else{
254 if (var->isPartial())
255 _serializePartialVariable(var,sbuf,local_ids);
256 else
257 var->serialize(sbuf,local_ids);
258 }
259 }
260}
261
262/*---------------------------------------------------------------------------*/
263/*---------------------------------------------------------------------------*/
282void ItemFamilyVariableSerializer::
283_serializePartialVariable(IVariable* var,ISerializer* sbuf,Int32ConstArrayView local_ids)
284{
285 String var_full_name = var->fullName();
286
287 ItemGroup group = var->itemGroup();
288 ISerializer::eMode mode = sbuf->mode();
289 switch(mode){
290 case ISerializer::ModeReserve:
292 {
293 Int32UniqueArray indexes_to_send;
294 Int64UniqueArray unique_ids_to_send;
295 std::set<Int32> items_to_send;
296 for( Integer i=0, n=local_ids.size(); i<n; ++i ){
297 items_to_send.insert(local_ids[i]);
298 }
299 ENUMERATE_ITEM(iitem,group){
300 if (items_to_send.find(iitem.itemLocalId())!=items_to_send.end()){
301 indexes_to_send.add(iitem.index());
302 unique_ids_to_send.add((*iitem).uniqueId());
303 }
304 }
305 Integer nb_item_to_send = indexes_to_send.size();
306 if (mode==ISerializer::ModeReserve){
307 // Réserve pour le nombre d'élément et pour chaque élément
308 sbuf->reserveInt64(1);
309 sbuf->reserveSpan(eBasicDataType::Int64,nb_item_to_send);
310 }
311 else{
312 sbuf->putInt64(nb_item_to_send);
313 sbuf->putSpan(unique_ids_to_send);
314 }
315 var->serialize(sbuf,indexes_to_send);
316 }
317 break;
319 {
320 Int32UniqueArray indexes;
321 Int64UniqueArray unique_ids;
322 String expected_name;
323 //sbuf->get(expected_name);
324 //if (expected_name!=var_full_name)
325 //ARCANE_FATAL("Incoherent variable var={0} expected={1}",
326 //var_full_name,expected_name);
327 Int64 nb_item = sbuf->getInt64();
328 unique_ids.resize(nb_item);
329 sbuf->getSpan(unique_ids);
330 Integer nb_item_in_variable = group.size();
331 HashTableMapT<Int64,Int32> unique_ids_to_index(nb_item_in_variable,true);
332 ENUMERATE_ITEM(iitem,group){
333 unique_ids_to_index.nocheckAdd((*iitem).uniqueId(),iitem.index());
334 }
335 indexes.resize(nb_item);
336 for( Integer i=0; i<nb_item; ++i ){
337 // Vérifie que l'entité est bien présente. C'est normalement le cas sauf
338 // si \a group n'est pas cohérent entre les PE (c'est à dire par exemple une
339 // entité \a x présente sur 2 PE mais qui est dans \a group que pour un seul
340 // des deux PE).
341 HashTableMapT<Int64,Int32>::Data* data = unique_ids_to_index.lookup(unique_ids[i]);
342 if (!data)
343 ARCANE_FATAL("Can not find item with unique_id={0} index={1}",unique_ids[i],i);
344 indexes[i] = data->value();
345 }
346
347 var->serialize(sbuf,indexes);
348 }
349 break;
350 }
351}
352
353/*---------------------------------------------------------------------------*/
354/*---------------------------------------------------------------------------*/
355
356} // End namespace Arcane::mesh
357
358/*---------------------------------------------------------------------------*/
359/*---------------------------------------------------------------------------*/
360
#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:56
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:145
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é
UniqueArray< IVariable * > m_variables_to_exchange
Liste des variables à échanger.
void _serializePartialVariable(IVariable *var, ISerializer *sbuf, Int32ConstArrayView local_ids)
Serialise une variable partielle.
void _checkSerializationVariable(ISerializer *sbuf, IVariable *var)
Sérialise le nom de la variable pour vérifier que la désérialisation est correcte.
void _checkSerialization(ISerializer *sbuf, Int32ConstArrayView local_ids)
Sérialize un nombre magique et le nombre d'entité afin de vérifier que la désérialisation est correct...
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:35
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.
-*- 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:426
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:569
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:428
std::int32_t Int32
Type entier signé sur 32 bits.