Arcane  4.2.3.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Variable.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/* Variable.cc (C) 2000-2026 */
9/* */
10/* Classe gérant une variable. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13#ifndef ARCANE_VARIABLE_CC
14#define ARCANE_VARIABLE_CC
15/*---------------------------------------------------------------------------*/
16/*---------------------------------------------------------------------------*/
17
18#include "arcane/utils/List.h"
19#include "arcane/utils/FatalErrorException.h"
20#include "arcane/utils/OStringStream.h"
21#include "arcane/utils/Iterator.h"
22#include "arcane/utils/Iostream.h"
23#include "arcane/utils/String.h"
24#include "arcane/utils/ITraceMng.h"
25#include "arcane/utils/PlatformUtils.h"
26#include "arcane/utils/IStackTraceService.h"
27#include "arcane/utils/MemoryAccessInfo.h"
28#include "arcane/utils/NotImplementedException.h"
29#include "arcane/utils/ScopedPtr.h"
30#include "arcane/utils/StringBuilder.h"
31#include "arcane/utils/MemoryView.h"
32#include "arcane/utils/Convert.h"
33
34#include "arcane/core/ItemGroupObserver.h"
35#include "arcane/core/Variable.h"
36#include "arcane/core/VarRefEnumerator.h"
37#include "arcane/core/IVariableAccessor.h"
38#include "arcane/core/ItemGroup.h"
39#include "arcane/core/IMesh.h"
40#include "arcane/core/IItemFamily.h"
41#include "arcane/core/ISubDomain.h"
42#include "arcane/core/VariableInfo.h"
43#include "arcane/core/ISerializer.h"
44#include "arcane/core/VariableBuildInfo.h"
45#include "arcane/core/VariableComputeFunction.h"
46#include "arcane/core/CommonVariables.h"
47#include "arcane/core/Observable.h"
48#include "arcane/core/IVariableMng.h"
49#include "arcane/core/IDataReader.h"
50#include "arcane/core/IDataWriter.h"
51#include "arcane/core/IParallelMng.h"
52#include "arcane/core/VariableDependInfo.h"
53#include "arcane/core/IParallelReplication.h"
54#include "arcane/core/VariableMetaData.h"
55#include "arcane/core/IMeshMng.h"
56#include "arcane/core/MeshHandle.h"
57#include "arcane/core/VariableComparer.h"
58#include "arcane/core/datatype/DataAllocationInfo.h"
59#include "arcane/core/internal/IItemFamilyInternal.h"
60#include "arcane/core/internal/IVariableMngInternal.h"
61#include "arcane/core/internal/IVariableInternal.h"
62#include "arcane/core/internal/IDataInternal.h"
63#include "arcane/core/internal/IParallelMngInternal.h"
64
65#include <map>
66#include <set>
67#include <atomic>
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72namespace Arcane
73{
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78const char* IVariable::TAG_POST_PROCESSING = "PostProcessing";
79const char* IVariable::TAG_POST_PROCESSING_AT_THIS_ITERATION = "PostProcessingAtThisIteration";
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
84/*
85 * \brief Partie privée d'une variable.
86 */
87class VariablePrivate
88: public IVariableInternal
89{
90 public:
91
92 VariablePrivate(const VariableBuildInfo& v, const VariableInfo& vi, Variable* var);
93
94 public:
95
96 static std::atomic<Int64> modified_time_global_value;
97
98 public:
99
100 ISubDomain* m_sub_domain = nullptr;
101 IDataFactoryMng* m_data_factory_mng = nullptr;
102 MeshHandle m_mesh_handle; //!< Maillage (peut être nul)
103 Ref<IData> m_data; //!< Données de la variable
104 ItemGroup m_item_group; //!< Groupe d'entité sur lequel est associé la variable
105 IItemFamily* m_item_family = nullptr; //!< Familly d'entité (peut être nul)
106 VariableInfo m_infos; //!< Infos caractéristiques de la variable
107 int m_property = 0; //!< Propriétés de la variable
108 bool m_is_partial = false; //!< Vrai si la variable est partielle
109 bool m_need_property_update = false;
110 bool m_is_used = false; //!< Etat d'utilisation de la variable
111 bool m_has_valid_data = false; //!< Vrai si les données sont valide
112 Real m_last_update_time = 0.0; //!< Temps physique de la dernière mise à jour
113 VariableRef* m_first_reference = nullptr; //! Première référence sur la variable
115 UniqueArray<VariableDependInfo> m_depends; //!< Liste des dépendances de cette variable
116 Int64 m_modified_time = 0; //!< Tag de la dernière modification
118 AutoDetachObservable m_write_observable; //!< Observable en écriture
119 AutoDetachObservable m_read_observable; //!< Observable en lecture
120 AutoDetachObservable m_on_size_changed_observable; //!< Observable en redimensionnement
121 std::map<String, String> m_tags; //!< Liste des tags
122 bool m_has_recursive_depend = true; //!< Vrai si les dépendances sont récursives
123 bool m_want_shrink = false;
124 Variable* m_variable = nullptr; //!< Variable associée
125
126 public:
127
128 /*!
129 * \brief Sérialise le `hashid`.
130 *
131 * Lors de la désérialisation, vérifie que le `hashid` est correctement
132 * et si ce n'est pas le cas renvoie une exception.
133 */
135 {
136 switch (sbuf->mode()) {
137 case ISerializer::ModeReserve:
138 sbuf->reserveSpan(eBasicDataType::Byte, HASHID_SIZE);
139 break;
141 sbuf->putSpan(Span<const Byte>(m_hash_id, HASHID_SIZE));
142 break;
144 Byte read_hash_id_buf[HASHID_SIZE];
145 Span<Byte> read_span(read_hash_id_buf, HASHID_SIZE);
146 sbuf->getSpan(read_span);
147 Span<const Byte> ref_span(m_hash_id, HASHID_SIZE);
148 if (ref_span != Span<const Byte>(read_span))
149 ARCANE_FATAL("Bad hashid for variable name='{0}'\n"
150 " expected_hash_id='{1}'\n"
151 " hash_id ='{2}'\n"
152 " This may be due to incoherence in variable list (order) between ranks"
153 " during serialization",
154 m_infos.fullName(), String(ref_span), String(read_span));
155 } break;
156 }
157 }
158
159 public:
160
161 //!@{ \name Implémentation de IVariableInternal
162 String computeComparisonHashCollective(IHashAlgorithm* hash_algo, IData* sorted_data) override;
163 void changeAllocator(const MemoryAllocationOptions& alloc_info) override;
164 void resize(const VariableResizeArgs& resize_args) override;
165 VariableComparerResults compareVariable(const VariableComparerArgs& compare_args) override;
166 IParallelMng* replicaParallelMng() const;
167 //!@}
168
169 private:
170
171 static const int HASHID_SIZE = 64;
172 /*!
173 * \brief hash de la variable pour vérifier la cohérence de la sérialisation.
174 *
175 * Les 16 premiers octets sont le hash du nom au format hexadécimal (issu d'un Int64)
176 * et les suivants sont le nom complet (fullName()), éventuellement tronqué, de la variable.
177 * Les éventuels caractères restants sont des '~'.
178 */
179 Byte m_hash_id[HASHID_SIZE];
180
181 void _setHashId()
182 {
183 constexpr Int64 hashid_hexa_length = 16;
184 constexpr Int64 name_length = HASHID_SIZE - hashid_hexa_length;
185 Span<Byte> hash_id(m_hash_id, HASHID_SIZE);
186 hash_id.fill('~');
187 const String& full_name = m_infos.fullName();
188 Int64 hash_value = IntegerHashFunctionT<StringView>::hashfunc(full_name.view());
189 Convert::toHexaString(hash_value, hash_id);
190 Span<const Byte> bytes = full_name.bytes();
191 if (bytes.size() > name_length)
192 bytes = bytes.subspan(0, name_length);
193 auto hash_id2 = hash_id.subspan(hashid_hexa_length, name_length);
194 hash_id2.copy(bytes);
195 }
196};
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201std::atomic<Int64> VariablePrivate::modified_time_global_value = 1;
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
208{
209 Int64 v = VariablePrivate::modified_time_global_value;
210 ++VariablePrivate::modified_time_global_value;
211 return v;
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217VariablePrivate::
218VariablePrivate(const VariableBuildInfo& v, const VariableInfo& vi, Variable* var)
219: m_sub_domain(v._subDomain())
220, m_data_factory_mng(v.dataFactoryMng())
221, m_mesh_handle(v.meshHandle())
222, m_infos(vi)
223, m_property(v.property())
224, m_is_partial(vi.isPartial())
225, m_variable(var)
226{
227 _setHashId();
228 m_infos.setDefaultItemGroupName();
229
230 // Pour test uniquement
231 if (!platform::getEnvironmentVariable("ARCANE_NO_RECURSIVE_DEPEND").null())
232 m_has_recursive_depend = false;
233
234 // Pour teste de libération mémoire.
235 {
236 String str = platform::getEnvironmentVariable("ARCANE_VARIABLE_SHRINK_MEMORY");
237 if (str == "1")
238 m_want_shrink = true;
239 }
240}
241
242/*---------------------------------------------------------------------------*/
243/*---------------------------------------------------------------------------*/
244
245//! Observer des évènements sur ItemGroup sous-jacent.
246class ItemGroupPartialVariableObserver
247: public IItemGroupObserver
248{
249 public:
250
251 explicit ItemGroupPartialVariableObserver(IVariable* var)
252 : m_var(var)
253 {
254 ARCANE_ASSERT((m_var), ("Variable pointer null"));
255
256 if (var->itemGroup().isAllItems())
257 ARCANE_FATAL("No observer should be attached on all items group");
258 }
259
260 void executeExtend(const Int32ConstArrayView* info) override
261 {
262 const Int32ConstArrayView& new_ids = *info;
263 if (new_ids.empty())
264 return;
265 ItemGroup group = m_var->itemGroup();
266 SharedPtrT<GroupIndexTable> id_to_index = group.localIdToIndex();
267
268 const Integer old_size = id_to_index->size();
269 const Integer group_size = group.size();
270 if (group_size != (old_size + new_ids.size()))
271 ARCANE_FATAL("Inconsistent extended size");
272 m_var->resizeFromGroup();
273 //id_to_index->update();
274 }
275
276 void executeReduce(const Int32ConstArrayView* info) override
277 {
278 // contient la liste des localids des items supprimés dans l'ancien groupe
279 const Int32ConstArrayView& removed_lids = *info;
280 if (removed_lids.empty())
281 return;
282 ItemGroup group = m_var->itemGroup();
283 SharedPtrT<GroupIndexTable> id_to_index = group.localIdToIndex();
284
285 const Integer old_size = id_to_index->size();
286 const Integer group_size = group.size();
287
288 if (group_size != (old_size - removed_lids.size()))
289 ARCANE_FATAL("Inconsistent reduced size {0} vs {1}", group_size, old_size);
290 [[maybe_unused]] ItemVectorView view = group.view();
291 Int32UniqueArray source;
292 Int32UniqueArray destination;
293 source.reserve(group_size);
294 destination.reserve(group_size);
295 for (Integer i = 0, index = 0, removed_index = 0; i < old_size; ++i) {
296 if (removed_index < removed_lids.size() &&
297 id_to_index->keyLocalId(i) == removed_lids[removed_index]) {
298 ++removed_index;
299 }
300 else {
301 ARCANE_ASSERT((id_to_index->keyLocalId(i) == view[index].localId()),
302 ("Inconsistent key (pos=%d,key=%d) vs (pos=%d,key=%d)",
303 i, id_to_index->keyLocalId(i), index, view[index].localId()));
304 if (i != index) {
305 destination.add(index);
306 source.add(i);
307 }
308 ++index;
309 }
310 }
311 m_var->copyItemsValues(source, destination);
312 m_var->resizeFromGroup();
313 }
314
315 void executeCompact(const Int32ConstArrayView* info) override
316 {
317 const Int32ConstArrayView& ids = *info;
318 if (ids.empty())
319 return;
320 ItemGroup group = m_var->itemGroup();
321 SharedPtrT<GroupIndexTable> id_to_index = group.localIdToIndex();
322 m_var->compact(*info);
323 //id_to_index->compact(info);
324 }
325
326 void executeInvalidate() override
327 {
328 ItemGroup group = m_var->itemGroup();
329 SharedPtrT<GroupIndexTable> id_to_index = group.localIdToIndex();
330 m_var->resizeFromGroup();
331 //id_to_index->update();
332 }
333
334 bool needInfo() const override { return true; }
335
336 private:
337
338 IVariable* m_var = nullptr;
339};
340
341/*---------------------------------------------------------------------------*/
342/*---------------------------------------------------------------------------*/
343
345Variable(const VariableBuildInfo& v, const VariableInfo& vi)
347, m_p(new VariablePrivate(v, vi, this))
348{
349}
350
351/*---------------------------------------------------------------------------*/
352/*---------------------------------------------------------------------------*/
353
355~Variable()
356{
357 //NOTE: si la variable possède un groupe, c'est le IVariableMng
358 // qui supprime la référence de cette variable sur le groupe
359 delete m_p;
360}
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
365bool Variable::
366_hasReference() const
367{
368 return m_p->m_first_reference;
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
373
376{
377 _checkSetProperty(ref);
378 ++m_p->m_nb_reference;
379 ref->setNextReference(m_p->m_first_reference);
380 if (m_p->m_first_reference) {
381 VariableRef* _list = m_p->m_first_reference;
382 if (_list->previousReference())
383 _list->previousReference()->setNextReference(ref);
384 _list->setPreviousReference(ref);
385 }
386 else {
387 ref->setPreviousReference(0);
388 }
389 m_p->m_first_reference = ref;
390}
391
392/*---------------------------------------------------------------------------*/
393/*---------------------------------------------------------------------------*/
394
397{
398 {
399 VariableRef* tmp = ref;
400 if (tmp->previousReference())
401 tmp->previousReference()->setNextReference(tmp->nextReference());
402 if (tmp->nextReference())
403 tmp->nextReference()->setPreviousReference(tmp->previousReference());
404 if (m_p->m_first_reference == tmp)
405 m_p->m_first_reference = m_p->m_first_reference->nextReference();
406 }
407 // La référence peut être utilisée par la suite donc il ne faut pas oublier
408 // de supprimer le précédent et le suivant.
409 ref->setNextReference(0);
410 ref->setPreviousReference(0);
411
412 --m_p->m_nb_reference;
413 _checkSetProperty(ref);
414
415 // Lorsqu'il n'y a plus de références sur cette variable, le signale au
416 // gestionnaire de variable, sauf s'il s'agit d'une variable persistante
417 if (!_hasReference()) {
418 bool is_persistant = property() & IVariable::PPersistant;
419 if (!is_persistant) {
420 //m_p->m_trace->info() << " REF PROPERTY name=" << name() << " " << ref->referenceProperty();
421 _removeMeshReference();
422 ISubDomain* sd = m_p->m_sub_domain;
423 IVariableMng* vm = sd->variableMng();
424 vm->_internalApi()->removeVariable(this);
425 }
426 }
427}
428
429/*---------------------------------------------------------------------------*/
430/*---------------------------------------------------------------------------*/
431
433firstReference() const
434{
435 return m_p->m_first_reference;
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
441void Variable::
442_checkSetProperty(VariableRef* ref)
443{
444 // Garantie que la propriété est correctement mise à jour avec la valeur
445 // de la seule référence.
446 if (!_hasReference()) {
447 m_p->m_property = ref->referenceProperty();
448 m_p->m_need_property_update = false;
449 }
450 else
451 m_p->m_need_property_update = true;
452}
453
454/*---------------------------------------------------------------------------*/
455/*---------------------------------------------------------------------------*/
456
458nbReference() const
459{
460 return m_p->m_nb_reference;
461}
462
463/*---------------------------------------------------------------------------*/
464/*---------------------------------------------------------------------------*/
465
467subDomain()
468{
469 return m_p->m_sub_domain;
470}
471
472/*---------------------------------------------------------------------------*/
473/*---------------------------------------------------------------------------*/
474
476variableMng() const
477{
478 return m_p->m_sub_domain->variableMng();
479}
480
481/*---------------------------------------------------------------------------*/
482/*---------------------------------------------------------------------------*/
483
485name() const
486{
487 return m_p->m_infos.localName();
488}
489
490/*---------------------------------------------------------------------------*/
491/*---------------------------------------------------------------------------*/
492
494fullName() const
495{
496 return m_p->m_infos.fullName();
497}
498
499/*---------------------------------------------------------------------------*/
500/*---------------------------------------------------------------------------*/
501
503itemFamilyName() const
504{
505 return m_p->m_infos.itemFamilyName();
506}
507
508/*---------------------------------------------------------------------------*/
509/*---------------------------------------------------------------------------*/
510
512itemGroupName() const
513{
514 return m_p->m_infos.itemGroupName();
515}
516
517/*---------------------------------------------------------------------------*/
518/*---------------------------------------------------------------------------*/
519
521meshName() const
522{
523 return m_p->m_infos.meshName();
524}
525
526/*---------------------------------------------------------------------------*/
527/*---------------------------------------------------------------------------*/
528
530dataType() const
531{
532 return m_p->m_infos.dataType();
533}
534
535/*---------------------------------------------------------------------------*/
536/*---------------------------------------------------------------------------*/
537
538/*!
539 * \todo traiter le cas PSubDomainPrivate.
540 */
542property() const
543{
544 if (!m_p->m_need_property_update)
545 return m_p->m_property;
546
547 // Les propriétés de la variable dépendent de ce que chaque
548 // référence souhaite et il faut les remettre à jour lorsque ces
549 // dernières changent.
550 // Par exemple, si toutes les références sont PNoDump et qu'une seule
551 // ne l'est pas, la variable ne doit pas l'être.
552 m_p->m_need_property_update = false;
553
554 bool want_dump = false;
555 bool want_sync = false;
556 bool want_replica_sync = false;
557 bool sub_domain_depend = false;
558 bool execution_depend = false;
559 bool want_private = false;
560 bool want_restore = false;
561 bool want_notemporary = false;
562 bool want_exchange = false;
563 bool want_persistant = false;
564 bool want_shmem = false;
565 bool want_dumpnull = false;
566
567 int property = 0;
568 for (VarRefEnumerator i(this); i.hasNext(); ++i) {
569 VariableRef* vref = *i;
570 int p = vref->referenceProperty();
571 if (!(p & IVariable::PNoDump))
572 want_dump = true;
573 if (!(p & IVariable::PNoNeedSync))
574 want_sync = true;
575 if (!(p & IVariable::PNoReplicaSync))
576 want_replica_sync = true;
578 sub_domain_depend = true;
580 execution_depend = true;
581 if ((p & IVariable::PPersistant))
582 want_persistant = true;
583 if ((p & IVariable::PPrivate))
584 want_private = true;
585 if (!(p & IVariable::PNoRestore))
586 want_restore = true;
587 if (!(p & IVariable::PNoExchange))
588 want_exchange = true;
589 if (!(p & IVariable::PTemporary))
590 want_notemporary = true;
591 if ((p & IVariable::PInShMem))
592 want_shmem = true;
593 if ((p & IVariable::PDumpNull))
594 want_dumpnull = true;
595 }
596
597 if (!want_dump)
598 property |= IVariable::PNoDump;
599 if (!want_sync)
600 property |= IVariable::PNoNeedSync;
601 if (!want_replica_sync)
602 property |= IVariable::PNoReplicaSync;
603 if (sub_domain_depend)
604 property |= IVariable::PSubDomainDepend;
605 if (execution_depend)
606 property |= IVariable::PExecutionDepend;
607 if (want_private)
608 property |= IVariable::PPrivate;
609 if (want_persistant)
610 property |= IVariable::PPersistant;
611 if (!want_restore)
612 property |= IVariable::PNoRestore;
613 if (!want_exchange)
614 property |= IVariable::PNoExchange;
615 if (!want_notemporary)
616 property |= IVariable::PTemporary;
617 if (want_shmem)
618 property |= IVariable::PInShMem;
619 if (want_dumpnull)
620 property |= IVariable::PDumpNull;
621
622 m_p->m_property = property;
623 return m_p->m_property;
624}
625
626/*---------------------------------------------------------------------------*/
627/*---------------------------------------------------------------------------*/
628
631{
632 m_p->m_need_property_update = true;
633}
634
635/*---------------------------------------------------------------------------*/
636/*---------------------------------------------------------------------------*/
637
639setUsed(bool is_used)
640{
641 if (m_p->m_is_used == is_used)
642 return;
643
644 m_p->m_is_used = is_used;
645
646 eItemKind ik = itemKind();
647
648 if (m_p->m_is_used) {
649 if (m_p->m_property & IVariable::PInShMem) {
650 if (m_p->m_property & IVariable::PSubDomainPrivate) {
651 ARCANE_FATAL("Variable avec la propriété PInShMem doit être dans tous les sous-domaines (la propriété PSubDomainPrivate ne peut pas être définie avec PInShMem)");
652 }
653 if (m_p->m_data->_commonInternal()->numericData() == nullptr) {
654 ARCANE_FATAL("Variable sans NumericData ne peut pas changer d'allocateur");
655 }
656 // TODO: Même si changeAllocator() avec le même allocateur déjà en
657 // place fait simplement un return, ça reste moche...
658 IParallelMng* pm{};
659 if (m_p->m_mesh_handle.hasMesh()) {
660 pm = m_p->m_mesh_handle.mesh()->parallelMng();
661 }
662 else {
663 pm = subDomain()->parallelMng();
664 }
665 m_p->changeAllocator(pm->_internalApi()->machineShMemWinMemoryAllocator());
666 }
667
668 if (m_p->m_item_group.null() && ik != IK_Unknown) {
669 _checkSetItemFamily();
670 _checkSetItemGroup();
671 // Attention à ne pas reinitialiser les valeurs lorsque ces dernières
672 // sont valides, ce qui est le cas par exemple après une protection.
673 if (!m_p->m_has_valid_data) {
675 // Historiquement on remplissait dans tous les cas la variable avec le
676 // constructeur par défaut
677 // de la donnée en appelant systématiquement fillDefautt(). Cependant,
678 // ce n'était pas le comportement souhaité qui doit être celui défini par
679 // getGlobalDataInitialisationPolicy() (dans DataTypes.h).
680 // On ne le fait maintenant que si le mode d'initialisation est égal
681 // à DIP_Legacy. Ce mode doit à terme disparaître.
683 m_p->m_data->fillDefault();
684 m_p->m_has_valid_data = true;
685 }
686 }
687 }
688 else {
689 _removeMeshReference();
690 if (ik == IK_Unknown)
691 resize(0);
692 else
694 // Indique que les valeurs ne sont plus valides
695 m_p->m_has_valid_data = false;
696 }
697
698 for (VarRefEnumerator i(this); i.hasNext(); ++i) {
699 VariableRef* ref = *i;
700 ref->internalSetUsed(m_p->m_is_used);
701 }
702}
703
704/*---------------------------------------------------------------------------*/
705/*---------------------------------------------------------------------------*/
706
707void Variable::
708_removeMeshReference()
709{
710 IItemFamily* family = m_p->m_item_family;
711 if (family)
712 family->_internalApi()->removeVariable(this);
713
714 if (isPartial())
715 m_p->m_item_group.internal()->detachObserver(this);
716
717 m_p->m_item_group = ItemGroup();
718 m_p->m_item_family = 0;
719}
720
721/*---------------------------------------------------------------------------*/
722/*---------------------------------------------------------------------------*/
723
725isUsed() const
726{
727 return m_p->m_is_used;
728}
729
730/*---------------------------------------------------------------------------*/
731/*---------------------------------------------------------------------------*/
732
733namespace
734{
735
736 String _buildVariableFullType(const IVariable* var)
737 {
738 StringBuilder full_type_b;
739 full_type_b = dataTypeName(var->dataType());
740 full_type_b += ".";
741 full_type_b += itemKindName(var->itemKind());
742 full_type_b += ".";
743 full_type_b += var->dimension();
744 full_type_b += ".";
745 full_type_b += var->multiTag();
746 if (var->isPartial())
747 full_type_b += ".Partial";
748 return full_type_b.toString();
749 }
750
751} // namespace
752
753/*---------------------------------------------------------------------------*/
754/*---------------------------------------------------------------------------*/
755
756VariableMetaData* Variable::
757_createMetaData() const
758{
759 auto vmd = new VariableMetaData(name(), meshName(), itemFamilyName(),
761 vmd->setFullType(_buildVariableFullType(this));
762 vmd->setMultiTag(String::fromNumber(multiTag()));
763 vmd->setProperty(property());
764 return vmd;
765}
766
767/*---------------------------------------------------------------------------*/
768/*---------------------------------------------------------------------------*/
769
771createMetaData() const
772{
773 return _createMetaData();
774}
775
776/*---------------------------------------------------------------------------*/
777/*---------------------------------------------------------------------------*/
778
780createMetaDataRef() const
781{
782 return makeRef(_createMetaData());
783}
784
785/*---------------------------------------------------------------------------*/
786/*---------------------------------------------------------------------------*/
787
790{
791 //cout << "** SYNC REFERENCE N=" << m_p->m_nb_reference << " F=" << m_p->m_first_reference << '\n';
792 for (VarRefEnumerator i(this); i.hasNext(); ++i) {
793 VariableRef* ref = *i;
794 //cout << "** SYNC REFERENCE V=" << ref << '\n';
795 ref->updateFromInternal();
796 }
797 // Il faut le faire après la mise à jour des références
798 // car les observateurs peuvent lire les valeurs via une référence
800}
801
802/*---------------------------------------------------------------------------*/
803/*---------------------------------------------------------------------------*/
804
806checkIfSync(int max_print)
807{
808 VariableComparerArgs compare_args;
809 compare_args.setCompareMode(eVariableComparerCompareMode::Sync);
810 compare_args.setMaxPrint(max_print);
811 compare_args.setCompareGhost(true);
812 VariableComparerResults results = _compareVariable(compare_args);
813 return results.nbDifference();
814}
815
816/*---------------------------------------------------------------------------*/
817/*---------------------------------------------------------------------------*/
818
821{
822 VariableComparerArgs compare_args;
823 compare_args.setCompareMode(eVariableComparerCompareMode::SameOnAllReplica);
824 compare_args.setMaxPrint(max_print);
826 return r.nbDifference();
827}
828
829/*---------------------------------------------------------------------------*/
830/*---------------------------------------------------------------------------*/
831
833checkIfSame(IDataReader* reader, Integer max_print, bool compare_ghost)
834{
835 VariableComparerArgs compare_args;
836 compare_args.setMaxPrint(max_print);
837 compare_args.setCompareGhost(compare_ghost);
838 compare_args.setDataReader(reader);
840 return r.nbDifference();
841}
842
843/*---------------------------------------------------------------------------*/
844/*---------------------------------------------------------------------------*/
845
847mesh() const
848{
849 if (m_p->m_mesh_handle.hasMesh())
850 return m_p->m_mesh_handle.mesh();
851 return nullptr;
852}
853
854/*---------------------------------------------------------------------------*/
855/*---------------------------------------------------------------------------*/
856
858meshHandle() const
859{
860 return m_p->m_mesh_handle;
861}
862
863/*---------------------------------------------------------------------------*/
864/*---------------------------------------------------------------------------*/
865
867itemGroup() const
868{
869 return m_p->m_item_group;
870}
871
872/*---------------------------------------------------------------------------*/
873/*---------------------------------------------------------------------------*/
874
876itemKind() const
877{
878 return m_p->m_infos.itemKind();
879}
880
881/*---------------------------------------------------------------------------*/
882/*---------------------------------------------------------------------------*/
883
885dimension() const
886{
887 return m_p->m_infos.dimension();
888}
889
890/*---------------------------------------------------------------------------*/
891/*---------------------------------------------------------------------------*/
892
894multiTag() const
895{
896 return m_p->m_infos.multiTag();
897}
898
899/*---------------------------------------------------------------------------*/
900/*---------------------------------------------------------------------------*/
901
903isPartial() const
904{
905 return m_p->m_is_partial;
906}
907
908/*---------------------------------------------------------------------------*/
909/*---------------------------------------------------------------------------*/
910
912itemFamily() const
913{
914 return m_p->m_item_family;
915}
916
917/*---------------------------------------------------------------------------*/
918/*---------------------------------------------------------------------------*/
919
922{
923 m_p->m_data = data;
924 if (!data.get()) {
925 ARCANE_FATAL("Données invalides : nom={0} type de données={1} dimension={2} multitag={3}",
926 m_p->m_infos.fullName(), m_p->m_infos.dataType(),
927 m_p->m_infos.dimension(), m_p->m_infos.multiTag());
928 }
929 data->setName(m_p->m_infos.fullName());
930}
931
932/*---------------------------------------------------------------------------*/
933/*---------------------------------------------------------------------------*/
934
936_setValidData(bool valid_data)
937{
938 m_p->m_has_valid_data = valid_data;
939}
940
941/*---------------------------------------------------------------------------*/
942/*---------------------------------------------------------------------------*/
943
945_hasValidData() const
946{
947 return m_p->m_has_valid_data;
948}
949
950/*---------------------------------------------------------------------------*/
951/*---------------------------------------------------------------------------*/
952
953void Variable::
954_setProperty(int property)
955{
956 m_p->m_property |= property;
957}
958
959/*---------------------------------------------------------------------------*/
960/*---------------------------------------------------------------------------*/
961
963dataFactoryMng() const
964{
965 return m_p->m_data_factory_mng;
966}
967
968/*---------------------------------------------------------------------------*/
969/*---------------------------------------------------------------------------*/
970
973{
974 debug(Trace::High) << "Sérialisation (partielle) de la variable nom=" << fullName();
975 m_p->serializeHashId(sbuffer);
976 m_p->m_data->serialize(sbuffer, ids, operation);
977 // En mode lecture, les données sont modifiées
978 if (sbuffer->mode() == ISerializer::ModeGet)
980}
981
982/*---------------------------------------------------------------------------*/
983/*---------------------------------------------------------------------------*/
984
986serialize(ISerializer* sbuffer, IDataOperation* operation)
987{
988 debug(Trace::High) << "Sérialisation (complète) de la variable nom=" << fullName();
989
990 m_p->serializeHashId(sbuffer);
991 m_p->m_data->serialize(sbuffer, operation);
992 // En mode lecture, les données sont modifiées
993 if (sbuffer->mode() == ISerializer::ModeGet)
995}
996
997/*---------------------------------------------------------------------------*/
998/*---------------------------------------------------------------------------*/
999
1000void Variable::
1001_resize(const VariableResizeArgs& resize_args)
1002{
1003 eItemKind ik = itemKind();
1004 // Si dim1 vaut -1, le redimensionnement ne concerne que dim2.
1005 if (ik != IK_Unknown && resize_args.newSize() != -1) {
1006 ARCANE_FATAL("Cet appel est invalide pour une variable d'élément. Utilisez resizeFromGroup() à la place");
1007 }
1008 _internalResize(resize_args);
1010}
1011
1012/*---------------------------------------------------------------------------*/
1013/*---------------------------------------------------------------------------*/
1014
1016resize(Integer new_size)
1017{
1018 _resize(VariableResizeArgs(new_size));
1019}
1020
1021/*---------------------------------------------------------------------------*/
1022/*---------------------------------------------------------------------------*/
1023
1026{
1027 eItemKind ik = itemKind();
1028 if (ik == IK_Unknown)
1029 return;
1030 Integer new_size = 0;
1031 IItemFamily* family = m_p->m_item_family;
1032 if (family) {
1033 if (m_p->m_item_group.isAllItems())
1034 new_size = m_p->m_item_family->maxLocalId();
1035 else
1036 new_size = m_p->m_item_group.size();
1037 }
1038 else {
1039 ItemGroup group = m_p->m_item_group;
1040 if (!group.null()) {
1041 ARCANE_FATAL("Variable '{0}' has group but no family", fullName());
1042 }
1043 }
1044 debug(Trace::High) << "Variable::resizeFromGroup() var='" << fullName()
1045 << "' with " << new_size << " items "
1046 << " this=" << this;
1047 _internalResize(VariableResizeArgs(new_size, new_size / 20));
1049}
1050
1051/*---------------------------------------------------------------------------*/
1052/*---------------------------------------------------------------------------*/
1053
1054void Variable::
1055_checkSetItemFamily()
1056{
1057 if (m_p->m_item_family || !m_p->m_item_group.null())
1058 return;
1059
1060 if (m_p->m_mesh_handle.isNull())
1061 m_p->m_mesh_handle = m_p->m_sub_domain->meshMng()->findMeshHandle(m_p->m_infos.meshName());
1062
1063 IMesh* mesh = m_p->m_mesh_handle.mesh();
1064 if (!mesh)
1065 ARCANE_FATAL("No mesh named '{0}' exists for variable '{1}'", m_p->m_infos.meshName(), name());
1066
1067 eItemKind ik = itemKind();
1068
1069 IItemFamily* family = 0;
1070 const String& family_name = m_p->m_infos.itemFamilyName();
1071 if (ik == IK_Particle || ik == IK_DoF) {
1072 if (family_name.null()) {
1073 ARCANE_FATAL("family name not specified for variable {0}", name());
1074 }
1075 family = mesh->findItemFamily(ik, family_name, true);
1076 }
1077 else {
1078 family = mesh->itemFamily(ik);
1079 }
1080
1081 if (family && family->itemKind() != itemKind())
1082 ARCANE_FATAL("Bad family kind '{0}' '{1}'", family->itemKind(), itemKind());
1083
1084 if (family && family->name() != itemFamilyName())
1085 ARCANE_FATAL("Incoherent family name. var={0} from_type={1} given={2}",
1086 name(), family->name(), itemFamilyName());
1087
1088 if (!family)
1089 ARCANE_FATAL("Family not found");
1090
1091 if (isPartial() && !family->hasUniqueIdMap())
1092 ARCANE_FATAL("Cannot have partial variable for a family without unique id map");
1093
1094 m_p->m_item_family = family;
1095 debug(Trace::High) << "Variable::setItemFamily() name=" << name()
1096 << " family=" << family
1097 << " familyname='" << family_name << "'";
1098 family->_internalApi()->addVariable(this);
1099}
1100
1101/*---------------------------------------------------------------------------*/
1102/*---------------------------------------------------------------------------*/
1103
1104void Variable::
1105_checkSetItemGroup()
1106{
1107 if (!m_p->m_item_group.null())
1108 return;
1109 const String& group_name = m_p->m_infos.itemGroupName();
1110 //info() << " CHECK SET GROUP var=" << name() << " group=" << group_name;
1111 if (group_name.null()) {
1112 m_p->m_item_group = m_p->m_item_family->allItems();
1113 }
1114 else
1115 m_p->m_item_group = m_p->m_item_family->findGroup(group_name, true);
1116
1117 ItemGroupImpl* internal = m_p->m_item_group.internal();
1118 // (HP) TODO: faut il garder ce controle hérité de l'ancienne implémentation de addVariable
1119 if (internal->parent() && (mesh()->parallelMng()->isParallel() && internal->isOwn()))
1120 ARCANE_FATAL("Cannot add variable ({0}) on a own group (name={1})",
1121 fullName(), internal->name());
1122 if (isPartial()) {
1123 if (group_name.empty())
1124 ARCANE_FATAL("Cannot create a partial variable with an empty item_group_name");
1125 debug(Trace::High) << "Attach ItemGroupPartialVariableObserver from " << fullName()
1126 << " to " << m_p->m_item_group.name();
1127 internal->attachObserver(this, new ItemGroupPartialVariableObserver(this));
1128 }
1129}
1130
1131/*---------------------------------------------------------------------------*/
1132/*---------------------------------------------------------------------------*/
1133
1136{
1137 return &(m_p->m_write_observable);
1138}
1139
1140/*---------------------------------------------------------------------------*/
1141/*---------------------------------------------------------------------------*/
1142
1145{
1146 return &(m_p->m_read_observable);
1147}
1148
1149/*---------------------------------------------------------------------------*/
1150/*---------------------------------------------------------------------------*/
1151
1154{
1155 return &(m_p->m_on_size_changed_observable);
1156}
1157
1158/*---------------------------------------------------------------------------*/
1159/*---------------------------------------------------------------------------*/
1160
1161/*---------------------------------------------------------------------------*/
1162/*---------------------------------------------------------------------------*/
1163
1165update()
1166{
1167 update(DPT_PreviousTime);
1168}
1169
1170/*---------------------------------------------------------------------------*/
1171/*---------------------------------------------------------------------------*/
1172
1173void Variable::
1174update(Real wanted_time)
1175{
1176 if (m_p->m_last_update_time < wanted_time) {
1177 for (Integer k = 0, n = m_p->m_depends.size(); k < n; ++k) {
1178 VariableDependInfo& vdi = m_p->m_depends[k];
1179 if (vdi.dependType() == DPT_PreviousTime)
1180 vdi.variable()->update(wanted_time);
1181 }
1182 }
1183
1184 if (m_p->m_has_recursive_depend) {
1185 for (Integer k = 0, n = m_p->m_depends.size(); k < n; ++k) {
1186 VariableDependInfo& vdi = m_p->m_depends[k];
1187 if (vdi.dependType() == DPT_CurrentTime)
1188 vdi.variable()->update(m_p->m_last_update_time);
1189 }
1190 }
1191
1192 bool need_update = false;
1193 Int64 modified_time = m_p->m_modified_time;
1194 for (Integer k = 0, n = m_p->m_depends.size(); k < n; ++k) {
1195 VariableDependInfo& vdi = m_p->m_depends[k];
1196 Int64 mt = vdi.variable()->modifiedTime();
1197 if (mt > modified_time) {
1198 need_update = true;
1199 break;
1200 }
1201 }
1202 if (need_update) {
1203 IVariableComputeFunction* cf = m_p->m_compute_function.get();
1204 //msg->info() << "Need Compute For Variable <" << name() << "> " << cf;
1205 if (cf) {
1206 //msg->info() << "Compute For Variable <" << name() << ">";
1207 cf->execute();
1208 }
1209 else {
1210 ARCANE_FATAL("No compute function for variable '{0}'", fullName());
1211 }
1212 }
1213}
1214
1215/*---------------------------------------------------------------------------*/
1216/*---------------------------------------------------------------------------*/
1217
1220{
1221 m_p->m_last_update_time = subDomain()->commonVariables().globalTime();
1222 m_p->m_modified_time = IVariable::incrementModifiedTime();
1223}
1224
1225/*---------------------------------------------------------------------------*/
1226/*---------------------------------------------------------------------------*/
1227
1230{
1231 return m_p->m_modified_time;
1232}
1233
1234/*---------------------------------------------------------------------------*/
1235/*---------------------------------------------------------------------------*/
1236
1239{
1240 m_p->m_depends.add(VariableDependInfo(var, dt, TraceInfo()));
1241}
1242
1243/*---------------------------------------------------------------------------*/
1244/*---------------------------------------------------------------------------*/
1245
1247addDepend(IVariable* var, eDependType dt, const TraceInfo& tinfo)
1248{
1249 m_p->m_depends.add(VariableDependInfo(var, dt, tinfo));
1250}
1251
1252/*---------------------------------------------------------------------------*/
1253/*---------------------------------------------------------------------------*/
1254
1257{
1258 ARCANE_UNUSED(var);
1259 throw NotImplementedException(A_FUNCINFO);
1260}
1261
1262/*---------------------------------------------------------------------------*/
1263/*---------------------------------------------------------------------------*/
1264
1267{
1268 m_p->m_compute_function = v;
1269}
1270
1271/*---------------------------------------------------------------------------*/
1272/*---------------------------------------------------------------------------*/
1273
1276{
1277 return m_p->m_compute_function.get();
1278}
1279
1280/*---------------------------------------------------------------------------*/
1281/*---------------------------------------------------------------------------*/
1282
1285{
1286 for (Integer k = 0, n = m_p->m_depends.size(); k < n; ++k) {
1287 VariableDependInfo& vdi = m_p->m_depends[k];
1288 infos.add(vdi);
1289 }
1290}
1291
1292/*---------------------------------------------------------------------------*/
1293/*---------------------------------------------------------------------------*/
1294
1295/*---------------------------------------------------------------------------*/
1296/*---------------------------------------------------------------------------*/
1297
1299addTag(const String& tagname, const String& tagvalue)
1300{
1301 m_p->m_tags[tagname] = tagvalue;
1302}
1303
1304/*---------------------------------------------------------------------------*/
1305/*---------------------------------------------------------------------------*/
1306
1308removeTag(const String& tagname)
1309{
1310 m_p->m_tags.erase(tagname);
1311}
1312
1313/*---------------------------------------------------------------------------*/
1314/*---------------------------------------------------------------------------*/
1315
1317hasTag(const String& tagname)
1318{
1319 return m_p->m_tags.find(tagname) != m_p->m_tags.end();
1320}
1321
1322/*---------------------------------------------------------------------------*/
1323/*---------------------------------------------------------------------------*/
1324
1326tagValue(const String& tagname)
1327{
1328 std::map<String, String>::const_iterator i = m_p->m_tags.find(tagname);
1329 if (i == m_p->m_tags.end())
1330 return String();
1331 return i->second;
1332}
1333
1334/*---------------------------------------------------------------------------*/
1335/*---------------------------------------------------------------------------*/
1336
1339{
1340 setUpToDate();
1343 _setValidData(true);
1344}
1345
1346/*---------------------------------------------------------------------------*/
1347/*---------------------------------------------------------------------------*/
1348
1354
1355/*---------------------------------------------------------------------------*/
1356/*---------------------------------------------------------------------------*/
1357
1359read(IDataReader* reader)
1360{
1361 reader->read(this, data());
1362 notifyEndRead();
1363}
1364
1365/*---------------------------------------------------------------------------*/
1366/*---------------------------------------------------------------------------*/
1367
1369write(IDataWriter* writer)
1370{
1372 writer->write(this, data());
1373}
1374
1375/*---------------------------------------------------------------------------*/
1376/*---------------------------------------------------------------------------*/
1377
1379changeGroupIds(Int32ConstArrayView old_to_new_ids)
1380{
1381 ARCANE_UNUSED(old_to_new_ids);
1382 // pH: default implementation since this method is not yet official
1383}
1384
1385/*---------------------------------------------------------------------------*/
1386/*---------------------------------------------------------------------------*/
1387
1388/*!
1389 * \brief Vérifie qu'il est possible d'échanger les valeurs de l'instance
1390 * avec celle de \a rhs.
1391 *
1392 * Cette méthode étant appelée par une classe dérivée, on est sur que \a rhs
1393 * est du même type C++ que l'instance et donc il n'y a pas besoin de
1394 * vérifier par exemple que les dimensions ou le type des données sont les
1395 * mêmes. Pour que l'échange soit valide, il faut que le maillage, la famille
1396 * et le groupe soit les mêmes. Pour cela, il suffit de vérifier que le
1397 * groupe est le même.
1398 */
1401{
1402 if (!m_p->m_is_used)
1403 ARCANE_FATAL("Can not swap variable values for unused variable (instance)");
1404 if (!rhs->m_p->m_is_used)
1405 ARCANE_FATAL("Can not swap variable values for unused variable (argument)");
1406 if (isPartial() || rhs->isPartial())
1407 ARCANE_FATAL("Can not swap variable values for partial variables");
1408 if (itemGroup() != rhs->itemGroup())
1409 ARCANE_FATAL("Can not swap variable values for variables from different groups");
1410}
1411
1412/*---------------------------------------------------------------------------*/
1413/*---------------------------------------------------------------------------*/
1414
1415bool Variable::
1416_wantShrink() const
1417{
1418 return m_p->m_want_shrink;
1419}
1420
1421/*---------------------------------------------------------------------------*/
1422/*---------------------------------------------------------------------------*/
1423
1426{
1427 data()->setAllocationInfo(v);
1428 // Il est possible que le changement d'allocation modifie les données
1429 // allouées. Il faut donc synchroniser les références.
1431}
1432
1433/*---------------------------------------------------------------------------*/
1434/*---------------------------------------------------------------------------*/
1435
1437allocationInfo() const
1438{
1439 return data()->allocationInfo();
1440}
1441
1442/*---------------------------------------------------------------------------*/
1443/*---------------------------------------------------------------------------*/
1444
1445IVariableInternal* Variable::
1447{
1448 return m_p;
1449}
1450
1451/*---------------------------------------------------------------------------*/
1452/*---------------------------------------------------------------------------*/
1453
1454/*---------------------------------------------------------------------------*/
1455/*---------------------------------------------------------------------------*/
1456
1457String VariablePrivate::
1458computeComparisonHashCollective(IHashAlgorithm* hash_algo,
1459 IData* sorted_data)
1460{
1461 ARCANE_CHECK_POINTER(hash_algo);
1462 ARCANE_CHECK_POINTER(sorted_data);
1463
1464 INumericDataInternal* num_data = sorted_data->_commonInternal()->numericData();
1465 if (!num_data)
1466 return {};
1467 if (!m_item_family)
1468 return {};
1469
1470 IParallelMng* pm = m_item_family->parallelMng();
1471 Int32 my_rank = pm->commRank();
1472 Int32 master_rank = pm->masterIORank();
1473 ConstMemoryView memory_view = num_data->memoryView();
1474
1475 UniqueArray<Byte> bytes;
1476
1477 pm->gatherVariable(Arccore::asSpan<Byte>(memory_view.bytes()).smallView(), bytes, master_rank);
1478
1479 String hash_string;
1480 if (my_rank == master_rank) {
1481 HashAlgorithmValue hash_value;
1482 hash_algo->computeHash(asBytes(bytes), hash_value);
1483 hash_string = Convert::toHexaString(asBytes(hash_value.bytes()));
1484 }
1485 return hash_string;
1486}
1487
1488/*---------------------------------------------------------------------------*/
1489/*---------------------------------------------------------------------------*/
1490
1491void VariablePrivate::
1492changeAllocator(const MemoryAllocationOptions& mem_options)
1493{
1494 INumericDataInternal* dx = m_data->_commonInternal()->numericData();
1495 if (dx) {
1496 dx->changeAllocator(mem_options);
1497 m_variable->syncReferences();
1498 }
1499}
1500
1501/*---------------------------------------------------------------------------*/
1502/*---------------------------------------------------------------------------*/
1503
1504void VariablePrivate::
1505resize(const VariableResizeArgs& resize_args)
1506{
1507 return m_variable->_resize(resize_args);
1508}
1509
1510/*---------------------------------------------------------------------------*/
1511/*---------------------------------------------------------------------------*/
1512
1513VariableComparerResults VariablePrivate::
1514compareVariable(const VariableComparerArgs& compare_args)
1515{
1516 return m_variable->_compareVariable(compare_args);
1517}
1518
1519/*---------------------------------------------------------------------------*/
1520/*---------------------------------------------------------------------------*/
1521
1522IParallelMng* VariablePrivate::
1523replicaParallelMng() const
1524{
1525 //TODO: regarder si la variable est utilisée.
1526 IMesh* mesh = m_variable->mesh();
1527 // TODO: faut-il prendre le sous-domaine dans ce cas ?
1528 IParallelMng* pm = (mesh) ? mesh->parallelMng() : m_variable->subDomain()->parallelMng();
1529 IParallelReplication* pr = pm->replication();
1530 if (!pr->hasReplication())
1531 return nullptr;
1532 return pr->replicaParallelMng();
1533}
1534
1535/*---------------------------------------------------------------------------*/
1536/*---------------------------------------------------------------------------*/
1537
1538} // End namespace Arcane
1539
1540/*---------------------------------------------------------------------------*/
1541/*---------------------------------------------------------------------------*/
1542
1543#endif
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Classe de base des vecteurs 1D de données.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
Observable qui appelle automatiquement IObservable::detachAllObservers() dans le destructeur.
Real globalTime() const
Temps courant.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr bool empty() const noexcept
true si le tableau est vide (size()==0)
Informations sur l'allocation d'une donnée.
Interface de lecture des données d'une variable.
Definition IDataReader.h:34
virtual void read(IVariable *var, IData *data)=0
Lit les données data de la variable var.
Interface d'écriture des données d'une variable.
Definition IDataWriter.h:44
virtual void write(IVariable *var, IData *data)=0
Ecrit les données data de la variable var.
Interface d'une donnée.
Definition IData.h:33
virtual DataAllocationInfo allocationInfo() const =0
Informations sur l'allocation.
virtual void setAllocationInfo(const DataAllocationInfo &v)=0
Positionne les informations sur l'allocation.
Interface d'un algorithme de hashage.
virtual void computeHash(Span< const std::byte > input, HashAlgorithmValue &value)
Calcule la valeur du hash pour le tableau input.
Interface d'une famille d'entités.
Definition IItemFamily.h:86
virtual bool hasUniqueIdMap() const =0
Indique si la famille possède une table de conversion uniqueId vers localId.
virtual String name() const =0
Nom de la famille.
virtual eItemKind itemKind() const =0
Genre des entités.
virtual IItemFamilyInternal * _internalApi()=0
API interne à Arcane.
virtual IItemFamily * findItemFamily(eItemKind ik, const String &name, bool create_if_needed=false, bool register_modifier_if_created=false)=0
Retourne la famille de nom name.
virtual MeshHandle * findMeshHandle(const String &name, bool throw_exception)=0
Recherche le maillage de nom name.
virtual void notifyAllObservers()=0
Notifie tous les observateurs.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual IParallelMngInternal * _internalApi()=0
API interne à Arcane.
@ ModePut
Le sérialiseur attend des reserve().
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 reserveSpan(eBasicDataType dt, Int64 n)=0
Réserve de la mémoire pour n valeurs de dt.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:77
virtual const CommonVariables & commonVariables() const =0
Informations sur les variables standards.
virtual IParallelMng * parallelMng()=0
Retourne le gestionnaire de parallélisme.
virtual IMeshMng * meshMng() const =0
Retourne le gestionnaire de maillage.
virtual IVariableMng * variableMng()=0
Retourne le gestionnaire de variables.
Interface de la classe functor de re-calcul d'une variable.
Interface du gestionnaire de variables.
virtual IVariableMngInternal * _internalApi()=0
API interne à Arcane.
Interface d'une variable.
Definition IVariable.h:39
virtual eDataType dataType() const =0
Type de la donnée gérée par la variable (Real, Integer, ...).
eDependType
Type des dépendances.
Definition IVariable.h:44
@ PSubDomainDepend
Indique que la valeur de la variable est dépendante du sous-domaine.
Definition IVariable.h:81
@ PNoExchange
Indique que la variable ne doit pas être échangée.
Definition IVariable.h:133
@ PNoReplicaSync
Indique que la variable n'a pas forcément la même valeur entre les réplicas.
Definition IVariable.h:149
@ PTemporary
Indique que la variable est temporaire.
Definition IVariable.h:116
@ PInShMem
Indique que la variable doit être alloué en mémoire partagée.
Definition IVariable.h:158
@ PExecutionDepend
Indique que la valeur de la variable est dépendante de l'exécution.
Definition IVariable.h:96
@ PPrivate
Indique que la variable est privée.
Definition IVariable.h:104
@ PPersistant
Indique que la variable est persistante.
Definition IVariable.h:140
@ PNoRestore
Indique que la variable ne doit pas être restaurée.
Definition IVariable.h:123
@ PSubDomainPrivate
Indique que la variable est privée au sous-domaine.
Definition IVariable.h:89
@ PNoNeedSync
Indique que la variable n'est pas nécessairement synchronisée.
Definition IVariable.h:70
@ PNoDump
Indique que la variable ne doit pas être sauvegardée.
Definition IVariable.h:62
@ PDumpNull
Indique que la sauvegarde sera nulle pour cette variable et pour ce sous-domaine.
Definition IVariable.h:169
virtual eItemKind itemKind() const =0
Genre des entités du maillage sur lequel repose la variable.
virtual bool isPartial() const =0
Indique si la variable est partielle.
virtual Integer dimension() const =0
Dimension de la variable.
virtual IData * data()=0
Données associées à la variable.
virtual ItemGroup itemGroup() const =0
Groupe du maillage associé.
static Int64 incrementModifiedTime()
Incrémente le compteur de modification et retourne sa valeur avant modification.
Definition Variable.cc:207
virtual Integer multiTag() const =0
Indique si la variable est un tableau à taille multiple.
virtual void update()=0
Recalcule la variable si nécessaire.
static const char * TAG_POST_PROCESSING
Tag utilisé pour indiquer si une variable sera post-traitée.
Definition IVariable.h:175
static const char * TAG_POST_PROCESSING_AT_THIS_ITERATION
Tag utilisé pour indiquer si une variable sera post-traitée à cette itération.
Definition IVariable.h:178
void detachObserver(const void *ref)
Détache un observer.
void executeExtend(const Int32ConstArrayView *info) override
Execute l'action associée à l'extension.
Definition Variable.cc:260
void executeReduce(const Int32ConstArrayView *info) override
Execute l'action associée à l'extension.
Definition Variable.cc:276
void executeInvalidate() override
Execute l'action associée à l'invalidation.
Definition Variable.cc:326
void executeCompact(const Int32ConstArrayView *info) override
Éxecute l'action associée au compactage.
Definition Variable.cc:315
bool needInfo() const override
Indique si l'observer aura besoin d'information de transition.
Definition Variable.cc:334
Groupe d'entités de maillage.
Definition ItemGroup.h:49
SharedPtrT< GroupIndexTable > localIdToIndex() const
Table des local ids vers une position pour toutes les entités du groupe.
Definition ItemGroup.h:307
ItemVectorView view() const
Vue sur les entités du groupe.
Definition ItemGroup.cc:583
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
bool isAllItems() const
Indique si le groupe est celui de toutes les entités.
Definition ItemGroup.cc:610
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
Vue sur un vecteur d'entités.
Handle sur un maillage.
Definition MeshHandle.h:48
bool isNull() const
Indique si le handle est nul (il ne référence aucun maillage existant ou non).
IMesh * mesh() const
Maillage associé.
Référence à une instance.
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
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:721
Constructeur de chaîne de caractère unicode.
String toString() const
Retourne la chaîne de caractères construite.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:305
Span< const Byte > bytes() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:292
StringView view() const
Retourne une vue sur la chaîne actuelle.
Definition String.cc:368
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
Arguments des méthodes de VariableComparer.
void setMaxPrint(Int32 v)
Positionne le nombre d'erreurs à afficher dans le listing.
void setCompareGhost(bool v)
Indique sur quelles entités on fait la comparaison.
Résultats d'une opération de comparaison.
Informations sur une dépendance de variable.
IVariable::eDependType dependType() const
Type de dépendance.
IVariable * variable() const
Variable.
Infos caractérisant une variable.
const String & itemFamilyName() const
Nom de la famille d'entité à laquelle la variable est associée.
const String & meshName() const
Nom du maillage auquel la variable est associée.
const String & fullName() const
Nom complet de la variable (associé à la famille).
void setDefaultItemGroupName()
Si null, change itemGroupName() en le nom du groupe de toutes les entités de la famille.
Meta-données sur une variable.
bool m_has_recursive_depend
Vrai si les dépendances sont récursives.
Definition Variable.cc:122
VariableInfo m_infos
Infos caractéristiques de la variable.
Definition Variable.cc:106
IItemFamily * m_item_family
Familly d'entité (peut être nul).
Definition Variable.cc:105
Integer m_nb_reference
Première référence sur la variable.
Definition Variable.cc:114
UniqueArray< VariableDependInfo > m_depends
Liste des dépendances de cette variable.
Definition Variable.cc:115
int m_property
Propriétés de la variable.
Definition Variable.cc:107
AutoDetachObservable m_on_size_changed_observable
Observable en redimensionnement.
Definition Variable.cc:120
Real m_last_update_time
Temps physique de la dernière mise à jour.
Definition Variable.cc:112
Int64 m_modified_time
Tag de la dernière modification.
Definition Variable.cc:116
MeshHandle m_mesh_handle
Maillage (peut être nul).
Definition Variable.cc:102
std::map< String, String > m_tags
Liste des tags.
Definition Variable.cc:121
ItemGroup m_item_group
Groupe d'entité sur lequel est associé la variable.
Definition Variable.cc:104
bool m_is_used
Etat d'utilisation de la variable.
Definition Variable.cc:110
void serializeHashId(ISerializer *sbuf)
Sérialise le hashid.
Definition Variable.cc:134
ScopedPtrT< IVariableComputeFunction > m_compute_function
Fonction de calcul.
Definition Variable.cc:117
AutoDetachObservable m_read_observable
Observable en lecture.
Definition Variable.cc:119
AutoDetachObservable m_write_observable
Observable en écriture.
Definition Variable.cc:118
bool m_has_valid_data
Vrai si les données sont valide.
Definition Variable.cc:111
bool m_is_partial
Vrai si la variable est partielle.
Definition Variable.cc:108
Variable * m_variable
Variable associée.
Definition Variable.cc:124
Ref< IData > m_data
Données de la variable.
Definition Variable.cc:103
Référence à une variable.
Definition VariableRef.h:56
virtual void updateFromInternal()
Mise à jour à partir de la partie interne.
VariableRef * previousReference()
Référence précédente (ou null) sur variable().
virtual int referenceProperty() const
Propriétés de la référence (interne).
VariableRef * nextReference()
Référence suivante (ou null) sur variable().
void resizeFromGroup() override
Positionne le nombre d'éléments pour une variable du maillage.
Definition Variable.cc:1025
String itemGroupName() const final
Nom du groupe d'entité associée.
Definition Variable.cc:512
IMesh * mesh() const final
Maillage auquel est associé la variable.
Definition Variable.cc:847
void notifyBeginWrite() override
Notifie du début d'écriture de data().
Definition Variable.cc:1350
Integer nbReference() const override
Nombre de références sur cette variable.
Definition Variable.cc:458
void removeVariableRef(VariableRef *ref) override
Supprime une référence à cette variable.
Definition Variable.cc:396
void _checkSwapIsValid(Variable *rhs)
Vérifie qu'il est possible d'échanger les valeurs de l'instance avec celle de rhs.
Definition Variable.cc:1400
bool isUsed() const override
Etat d'utilisation de la variable.
Definition Variable.cc:725
Variable(const VariableBuildInfo &v, const VariableInfo &vi)
Créé une variable lié à la référence v.
Definition Variable.cc:345
void _setData(const Ref< IData > &data)
Positionne la donnée.
Definition Variable.cc:921
void _setValidData(bool valid_data)
Indique si les données de la variable sont valides.
Definition Variable.cc:936
VariableMetaData * createMetaData() const override
Créé une instance contenant les meta-données de la variable.
Definition Variable.cc:771
IVariableComputeFunction * computeFunction() override
Fonction utilisée pour mettre à jour la variable.
Definition Variable.cc:1275
Ref< VariableMetaData > createMetaDataRef() const override
Créé une instance contenant les meta-données de la variable.
Definition Variable.cc:780
bool isPartial() const override
Indique si la variable est partielle.
Definition Variable.cc:903
String tagValue(const String &tagname) override
Valeur du tag tagname. La chaîne est nulle si le tag n'existe pas.
Definition Variable.cc:1326
void notifyReferencePropertyChanged() override
Indique que les propriétés d'une des références à cette variable ont changé (interne).
Definition Variable.cc:630
IVariableMng * variableMng() const override
Gestionnaire de variable associé à la variable.
Definition Variable.cc:476
void removeTag(const String &tagname) override
Supprime le tag tagname.
Definition Variable.cc:1308
void addDepend(IVariable *var, eDependType dt) override
Ajoute var à la liste des dépendances.
Definition Variable.cc:1238
String name() const final
Nom de la variable.
Definition Variable.cc:485
IObservable * readObservable() override
Observable en lecture.
Definition Variable.cc:1144
virtual VariableComparerResults _compareVariable(const VariableComparerArgs &compare_args)=0
Comparaison de valeurs entre variables.
void serialize(ISerializer *sbuffer, IDataOperation *operation) override
Definition Variable.cc:986
ItemGroup itemGroup() const final
Groupe du maillage associé.
Definition Variable.cc:867
IObservable * onSizeChangedObservable() override
Observable en redimensionnement.
Definition Variable.cc:1153
void notifyEndRead() override
Notifie de la modification externe de data().
Definition Variable.cc:1338
void read(IDataReader *d) override
Definition Variable.cc:1359
void syncReferences() override
Synchronise les références.
Definition Variable.cc:789
void setUsed(bool v) override
Positionne l'état d'utilisation de la variable.
Definition Variable.cc:639
VariableRef * firstReference() const override
Première réference (ou null) sur cette variable.
Definition Variable.cc:433
String fullName() const final
Nom complet de la variable (avec le préfixe de la famille).
Definition Variable.cc:494
eItemKind itemKind() const override
Genre des entités du maillage sur lequel repose la variable.
Definition Variable.cc:876
ISubDomain * subDomain() override
Sous-domaine associé à la variable (TODO rendre obsolète fin 2023).
Definition Variable.cc:467
void update() override
Recalcule la variable si nécessaire.
Definition Variable.cc:1165
Integer dimension() const override
Dimension de la variable.
Definition Variable.cc:885
Int64 modifiedTime() override
Temps auquel la variable a été mise à jour.
Definition Variable.cc:1229
void setUpToDate() override
Indique que la variable vient d'être mise à jour.
Definition Variable.cc:1219
void addTag(const String &tagname, const String &tagvalue) override
Ajoute le tag tagname avev la valeur tagvalue.
Definition Variable.cc:1299
Int32 checkIfSame(IDataReader *reader, Integer max_print, bool compare_ghost) final
Vérifie que la variable est identique à une valeur de référence.
Definition Variable.cc:833
~Variable() override
Libère les ressources.
Definition Variable.cc:355
bool _hasValidData() const
Indique si les données de la variable sont valides.
Definition Variable.cc:945
IObservable * writeObservable() override
Observable en écriture.
Definition Variable.cc:1135
void addVariableRef(VariableRef *ref) override
Ajoute une référence à cette variable.
Definition Variable.cc:375
Integer multiTag() const override
Indique si la variable est un tableau à taille multiple.
Definition Variable.cc:894
void setComputeFunction(IVariableComputeFunction *v) override
Positionne la fonction de recalcul de la variable.
Definition Variable.cc:1266
void resize(Integer n) override
Positionne le nombre d'éléments pour une variable tableau.
Definition Variable.cc:1016
IVariableInternal * _internalApi() override
API interne à Arcane.
Definition Variable.cc:1446
IItemFamily * itemFamily() const final
Famille d'entité associée.
Definition Variable.cc:912
eDataType dataType() const override
Type de la donnée gérée par la variable (Real, Integer, ...).
Definition Variable.cc:530
void write(IDataWriter *d) override
Sauve la variable.
Definition Variable.cc:1369
IDataFactoryMng * dataFactoryMng() const final
Fabrique de données associées à la variable.
Definition Variable.cc:963
void changeGroupIds(Int32ConstArrayView old_to_new_ids) override
pH : EXPERIMENTAL
Definition Variable.cc:1379
void removeDepend(IVariable *var) override
Supprime var de la liste des dépendances.
Definition Variable.cc:1256
String itemFamilyName() const final
Nom de la famille associée (nul si aucune).
Definition Variable.cc:503
Int32 checkIfSync(Integer max_print) final
Vérifie si la variable est bien synchronisée.
Definition Variable.cc:806
DataAllocationInfo allocationInfo() const override
Informations sur l'allocation.
Definition Variable.cc:1437
int property() const override
Definition Variable.cc:542
Int32 checkIfSameOnAllReplica(Integer max_print) final
Vérifie si la variable a les mêmes valeurs sur tous les réplicas.
Definition Variable.cc:820
void dependInfos(Array< VariableDependInfo > &infos) override
Infos de dépendances.
Definition Variable.cc:1284
bool hasTag(const String &tagname) override
true si la variable possède le tag tagname
Definition Variable.cc:1317
void setAllocationInfo(const DataAllocationInfo &v) override
Positionne les informations sur l'allocation.
Definition Variable.cc:1425
MeshHandle meshHandle() const final
Maillage auquel est associé la variable.
Definition Variable.cc:858
String meshName() const final
Nom du maillage associé (nul si aucun).
Definition Variable.cc:521
String toHexaString(ByteConstArrayView input)
Converti un tableau d'octet en sa représentation hexadécimale.
String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
@ DIP_Legacy
Initialisation en mode historique.
Definition DataTypes.h:161
std::int64_t Int64
Type entier signé sur 64 bits.
eDataInitialisationPolicy getGlobalDataInitialisationPolicy()
Récupère la politique d'initialisation des variables.
Definition DataTypes.cc:162
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:480
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:339
@ SameOnAllReplica
Vérifie que les valeurs de la variable sont les même sur tous les replica.
@ Sync
Vérifie que la variable est bien synchronisée.
eItemKind
Genre d'entité de maillage.
@ IK_Particle
Entité de maillage de genre particule.
@ IK_Unknown
Entité de maillage de genre inconnu ou non initialisé
@ IK_DoF
Entité de maillage de genre degre de liberte.
const char * itemKindName(eItemKind kind)
Nom du genre d'entité.
double Real
Type représentant un réel.
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Convertit la vue en un tableau d'octets non modifiables.
Definition Span.h:1028
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:42
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
eDataType
Type d'une donnée.
Definition DataTypes.h:39
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Definition DataTypes.cc:70
std::int32_t Int32
Type entier signé sur 32 bits.
Span< DataType > asSpan(Span< std::byte, Extent > bytes)
Convertit un Span<std::byte> en un Span<DataType>.
Definition Span.h:1120