Arcane  v3.14.10.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-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/* ItemFamilyVariableSerializer.cc (C) 2000-2023 */
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/VariableTypes.h"
19#include "arcane/ItemEnumerator.h"
20#include "arcane/ItemPrinter.h"
21#include "arcane/ISerializer.h"
22#include "arcane/IItemFamily.h"
23#include "arcane/ItemVector.h"
24#include "arcane/MeshToMeshTransposer.h"
25#include "arcane/ItemFamilySerializeArgs.h"
26#include "arcane/IParallelMng.h"
27// TODO: a supprimer
28#include "arcane/IMesh.h"
29#include "arcane/IVariableMng.h"
30#include "arcane/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
94 family_to_exchange.add(m_item_family); // La famille courante
95 IItemFamilyCollection child_families = m_item_family->childFamilies();
98
99 for (Integer i=0; i<family_to_exchange.size(); ++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
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();
118 debug(Trace::High) << "Add variable " << var->fullName() << " to serialize";
119 m_variables_to_exchange.add(var);
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;
141 case ISerializer::ModePut:
142 // Sérialise le nombre d'entités transférées
144 sbuf->put(local_ids.size());
145 break;
146 case ISerializer::ModeGet:
147 // Vérifie pas d'erreurs de sérialisation.
148 Integer magic_number = sbuf->getInteger();
150 ARCANE_FATAL("Internal error: bad magic number expected={0} found={1}",
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;
181 case ISerializer::ModePut:
182 sbuf->put(var_full_name);
183 break;
184 case ISerializer::ModeGet:
185 {
187 sbuf->get(expected_name);
189 ARCANE_FATAL("Incoherent variable var={0} expected={1}",
191 }
192 break;
193 }
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
203void ItemFamilyVariableSerializer::
204serialize(const ItemFamilySerializeArgs& args)
205{
206 ISerializer* sbuf = args.serializer();
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
217 for( IVariable* var : m_variables_to_exchange ){
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
224 _checkSerializationVariable(sbuf,var);
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);
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:
291 case ISerializer::ModePut:
292 {
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->reserve(DT_Int64,1);
309 sbuf->reserveSpan(DT_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;
318 case ISerializer::ModeGet:
319 {
320 Int32UniqueArray indexes;
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();
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).
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.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Interface d'une famille d'entités.
Interface du gestionnaire de variables.
Interface d'une variable.
Definition IVariable.h:54
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:35
Vecteur d'entités.
Definition ItemVector.h:59
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Collection de variables.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Vue constante d'un tableau de type T.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
Definition Misc.cc:163
@ DT_Int64
Donnée de type entier 64 bits.
Definition DataTypes.h:44
Int32 Integer
Type représentant un entier.