Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
VariableMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* VariableMng.cc (C) 2000-2025 */
9/* */
10/* Classe gérant l'ensemble des variables. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/VariableMng.h"
15
16#include "arcane/utils/Deleter.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/FatalErrorException.h"
19#include "arcane/utils/PlatformUtils.h"
20#include "arcane/utils/JSONWriter.h"
21#include "arcane/utils/OStringStream.h"
22#include "arcane/utils/Math.h"
23
24#include "arcane/core/ArcaneException.h"
25#include "arcane/core/VarRefEnumerator.h"
26#include "arcane/core/IModule.h"
27#include "arcane/core/ISubDomain.h"
28#include "arcane/core/IObservable.h"
29#include "arcane/core/VariableInfo.h"
30#include "arcane/core/VariableBuildInfo.h"
31#include "arcane/core/VariableFactoryRegisterer.h"
32#include "arcane/core/IVariableFactory.h"
33#include "arcane/core/ItemGroup.h"
34#include "arcane/core/IMesh.h"
35#include "arcane/core/MeshHandle.h"
36#include "arcane/core/IParallelMng.h"
37#include "arcane/core/ITimeLoopMng.h"
38#include "arcane/core/IEntryPoint.h"
39#include "arcane/core/Properties.h"
40#include "arcane/core/VariableStatusChangedEventArgs.h"
41
42#include "arcane/impl/VariableUtilities.h"
43#include "arcane/impl/internal/VariableSynchronizerMng.h"
44
45#include <exception>
46#include <set>
47#include <vector>
48
49// TODO: gérer le hash en version 64 bits.
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54namespace Arcane
55{
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
59
60extern "C++" IVariableMng*
61arcaneCreateVariableMng(ISubDomain* sd)
62{
63 auto vm = new VariableMng(sd);
64 vm->build();
65 vm->initialize();
66 return vm;
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
79, m_sub_domain(sd)
80, m_parallel_mng(sd->parallelMng())
81, m_vni_map(2000,true)
82, m_write_observable(IObservable::createDefault())
83, m_read_observable(IObservable::createDefault())
84, m_utilities(new VariableUtilities(this))
85, m_variable_io_writer_mng(new VariableIOWriterMng(this))
86, m_variable_io_reader_mng(new VariableIOReaderMng(this))
87, m_variable_synchronizer_mng(new VariableSynchronizerMng(this))
88{
89}
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
100{
101 delete m_variable_synchronizer_mng;
102
103 delete m_variable_io_reader_mng;
104 delete m_variable_io_writer_mng;
105 delete m_utilities;
106
107 m_write_observable->detachAllObservers();
108 m_read_observable->detachAllObservers();
109
110 delete m_write_observable;
111 delete m_read_observable;
112
113 m_variable_factories.each(Deleter());
114}
115
116/*---------------------------------------------------------------------------*/
117/*---------------------------------------------------------------------------*/
118
120build()
121{
122 String s = platform::getEnvironmentVariable("ARCANE_TRACE_VARIABLE_CREATION");
123 if (!s.null())
124 VariableRef::setTraceCreation(true);
125}
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
132{
133 m_time_stats = m_parallel_mng->timeStats();
134
135 VariableFactoryRegisterer* vff = VariableFactoryRegisterer::firstVariableFactory();
136 while (vff){
137 IVariableFactory* vf = vff->createFactory();
138 String full_name = vf->fullTypeName();
139 // Vérifie qu'aucune fabrique avec le même nom n'existe.
140 if (m_variable_factory_map.find(full_name)!=m_variable_factory_map.end()){
141 ARCANE_FATAL("VariableFactoryMap already contains a factory for the same type '{0}'",
142 full_name);
143 }
144 m_variable_factory_map.insert(VariableFactoryPair(full_name,vf));
145 m_variable_factories.add(vf);
146 info(5) << "Add variable factory kind=" << vff->itemKind()
147 << " data_type=" << vff->dataType()
148 << " dim=" << vff->dimension()
149 << " multi_tag=" << vff->multiTag()
150 << " full_name=" << full_name
151 << " addr=" << vf;
152 vff = vff->nextVariableFactory();
153 }
154
155 m_variable_synchronizer_mng->initialize();
156}
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
163{
164 //ATTENTION: ceci entraine des appels à removeVariable()
166
167 OStringStream var_str;
168 UniqueArray<IVariable*> remaining_vars;
169 for( const auto& i : m_full_name_variable_map ){
170 IVariable* v = i.second;
171 if (v->nbReference()==0)
172 delete v;
173 else{
174 remaining_vars.add(v);
175 var_str() << " " << v->fullName() << " (" << v->nbReference() << ")";
176 }
177 }
178 bool is_check = arcaneIsCheck();
179 const bool has_remaining_vars = !remaining_vars.empty();
180 if (has_remaining_vars && is_check)
181 pwarning() << "The following variables are still referenced: "
182 << var_str.str()
183 << " (set the environment variable ARCANE_TRACE_VARIABLE_CREATION"
184 << " to get the stack trace)";
185 bool has_trace = VariableRef::hasTraceCreation();
186 if (has_trace){
187 for( const auto& i : remaining_vars ){
188 for( VarRefEnumerator ivar(i); ivar.hasNext(); ++ivar ){
189 VariableRef* var = *ivar;
190 info() << " variable name=" << var->name()
191 << " stack=" << var->assignmentStackTrace();
192 }
193 }
194 }
195
196 // Appelle explicitement 'unregisterVariable()' sur les variables restantes.
197 // Sans cela, si ensuite l'instance 'this' est détruite avant que les variables
198 // restantent ne le soit cela va provoquer un plantage (Read after free). Cela
199 // n'arrive normalement pas pour le C++ mais peut arriver pour le wrapping.
200 if (has_remaining_vars){
201 // Recopie les références dans un tableau temporaire
202 // car les appels à unregisterVariable() modifient l'itérateur ivar
203 // et aussi m_full_name_variable_map.
204 UniqueArray<VariableRef*> remaining_refs;
205 for( const auto& i : remaining_vars )
206 for( VarRefEnumerator ivar(i); ivar.hasNext(); ++ivar )
207 remaining_refs.add(*ivar);
208 for( VariableRef* r : remaining_refs )
209 r->unregisterVariable();
210 if (is_check)
211 info() << "Remaining variables after cleanup n=" << m_full_name_variable_map.size();
212 }
213
215}
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
222{
223 for( const auto& i : m_full_name_variable_map ){
224 IVariable* v = i.second;
225 ItemGroup group = v->itemGroup();
226 if (group.null())
227 continue;
228 if (group.mesh()==mesh){
229 v->setUsed(false);
230 }
231 }
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
239{
240 ARCANE_UNUSED(ref);
241 ++m_nb_created_variable_reference;
242}
243
244/*---------------------------------------------------------------------------*/
245/*---------------------------------------------------------------------------*/
246
249{
250 ARCANE_UNUSED(ref);
251}
252
253/*---------------------------------------------------------------------------*/
254/*---------------------------------------------------------------------------*/
255
258{
259 const String& full_name = var->fullName();
260 subDomain()->checkId("VariableMng::checkVariable()",full_name);
261 if (var->itemKind()!=IK_Unknown && var->itemFamilyName().null())
262 ARCANE_FATAL("Bad Variable full-name={0} name={1}",var->fullName(),var->name());
263
264 info(5) << "Add variable"
265 << " name=" << var->name()
266 << " full_name=" << full_name
267 << " datatype=" << var->dataType()
268 << " kind=" << var->itemKind();
269
271 vni.m_local_name = var->name();
272 vni.m_family_name = var->itemFamilyName();
273 vni.m_mesh_name = var->meshName();
274 m_vni_map.add(vni,var);
275
276 m_full_name_variable_map.insert(FullNameVariablePair(full_name,var));
277 m_variables_changed = true;
278 m_used_variables_changed = true;
279 ++m_nb_created_variable;
281 IModule* module = nullptr;
282 if (ep)
283 module = ep->module();
284 m_variable_creation_modules.insert(std::make_pair(var,module));
286 m_on_variable_added.notify(eargs);
287}
288
289/*---------------------------------------------------------------------------*/
290/*---------------------------------------------------------------------------*/
291
294{
295 int p = var->property();
296 if (p & IVariable::PTemporary){
297 debug() << "** ** REMOVE " << var->name() << " " << var->nbReference()
298 << " property=" << p
299 << " nodump=" << (p & IVariable::PNoDump)
300 << " tmp=" << (p & IVariable::PTemporary)
301 << " norestore=" << (p & IVariable::PNoRestore);
302 }
304 m_on_variable_removed.notify(eargs);
305 {
306 ItemGroup var_group = var->itemGroup();
307 // Retire cette variable de tous les groupes [bien défini mais sur ItemGroupImplNull]
308 if (!var_group.null())
309 var_group.internal()->detachObserver(var);
310 // Retire cette variable des variables existantes, puis la détruit
312 {
314 vni.m_local_name = var->name();
315 vni.m_family_name = var->itemFamilyName();
316 vni.m_mesh_name = var->meshName();
317 m_vni_map.remove(vni);
318 }
319 m_variables_changed = true;
320 m_used_variables_changed = true;
321 m_variable_creation_modules.erase(var);
322 delete var;
323 }
324}
325
326/*---------------------------------------------------------------------------*/
327/*---------------------------------------------------------------------------*/
328
330checkVariable(const VariableInfo& infos)
331{
333 vni.m_local_name = infos.localName();
334 vni.m_family_name = infos.itemFamilyName();
335 vni.m_mesh_name = infos.meshName();
336
337 if (infos.itemKind()!=IK_Unknown && infos.meshName().null())
338 ARCANE_FATAL("Mesh variable without a mesh full-name={0} name={1}",infos.fullName(),infos.localName());
339
340 // Si variable du maillage, vérifie qu'aucune variable globale non lié à un maillage
341 // ne porte le même nom.
342 if (arcaneIsCheck()){
343 if (!infos.meshName().null()){
344 String check_name = infos.localName();
345 if (findVariableFullyQualified(check_name)){
346 ARCANE_FATAL("Mesh variable has the same name that a global variable (name={0})",check_name);
347 }
348 }
349 else{
350 // Si variable globale, vérifie qu'aucune variable du maillage ne porte le même nom.
351 String check_name = String("Mesh0_")+infos.localName();
352 if (findVariableFullyQualified(check_name)){
353 ARCANE_FATAL("Global variable has the same name that a mesh variable (name={0})",check_name);
354 }
355 }
356 }
357
358 IVariable* var = nullptr;
359 //VNIMap::Data* var_data = m_vni_map.lookup(vni);
360
361 //cerr << "** CHECK " << name << ' ' << infos.dataType() << ' ' << infos.kind() << '\n';
362 VNIMap::Data* var_data = m_vni_map.lookup(vni);
363 if (var_data){
364 // Une variable de même nom que \a var existe déjà.
365 // Il faut dans ce cas vérifier que son genre et son type sont les même.
366 // elle a le même genre et le même type.
367 var = var_data->value();
368 //cerr << "** FIND " << prv->name() << ' ' << prv->dataType() << ' ' << prv->kind() << '\n';
369 if (infos.dataType()!=var->dataType() ||
370 infos.itemKind()!=var->itemKind() ||
371 infos.dimension()!=var->dimension()){
372 throw BadVariableKindTypeException(A_FUNCINFO,var,infos.itemKind(),
373 infos.dataType(),infos.dimension());
374 }
375 // For partial variable: if exists already must be defined on the same group, otherwise fatal
376 if (infos.isPartial()) {
377 if (infos.itemGroupName() != var->itemGroupName())
378 throw BadPartialVariableItemGroupNameException(A_FUNCINFO, var, infos.itemGroupName());
379 }
380 }
381 return var;
382}
383
384/*---------------------------------------------------------------------------*/
385/*---------------------------------------------------------------------------*/
386
388findVariable(const String& name)
389{
391 if (v)
392 return v;
393 v = findVariableFullyQualified(String("Node_")+name);
394 if (v)
395 return v;
396 v = findVariableFullyQualified(String("Edge_")+name);
397 if (v)
398 return v;
399 v = findVariableFullyQualified(String("Face_")+name);
400 if (v)
401 return v;
402 v = findVariableFullyQualified(String("Cell_")+name);
403 if (v)
404 return v;
405 return nullptr;
406}
407
408/*---------------------------------------------------------------------------*/
409/*---------------------------------------------------------------------------*/
410
412findMeshVariable(IMesh* mesh,const String& name)
413{
414 String mesh_name = mesh->name();
415 mesh_name = mesh_name + "_";
416 IVariable* v = findVariableFullyQualified(mesh_name+name);
417 if (v)
418 return v;
419 v = findVariableFullyQualified(mesh_name+"Node_"+name);
420 if (v)
421 return v;
422 v = findVariableFullyQualified(mesh_name+"Edge_"+name);
423 if (v)
424 return v;
425 v = findVariableFullyQualified(mesh_name+"Face_"+name);
426 if (v)
427 return v;
428 v = findVariableFullyQualified(mesh_name+"Cell_"+name);
429 if (v)
430 return v;
431 return nullptr;
432}
433
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
439{
440 auto i = m_full_name_variable_map.find(name);
441 if (i!=m_full_name_variable_map.end())
442 return i->second;
443 return nullptr;
444}
445
446/*---------------------------------------------------------------------------*/
447/*---------------------------------------------------------------------------*/
448
451{
452 bool is_bad = true;
453 String name;
454 while (is_bad){
455 name = String("ArcaneTemporary") + m_generate_name_id;
456 // Vérifie que le nom généré ne correspond pas à une variable existante
457 if (findVariable(name))
459 else
460 is_bad = false;
461 }
462 info() << "** GENERATED NAME =" << name;
463 return name;
464}
465
466/*---------------------------------------------------------------------------*/
467/*---------------------------------------------------------------------------*/
468
470dumpList(std::ostream& o,IModule* c)
471{
472 o << " ** VariableMng::Variable list\n";
473 for( const auto& i : m_full_name_variable_map ){
474 for( VarRefEnumerator ivar(i.second); ivar.hasNext(); ++ivar ){
475 if ((*ivar)->module()!=c)
476 continue;
477 _dumpVariable(*(*ivar),o);
478 }
479 }
480}
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
484
486dumpList(std::ostream& o)
487{
488 o << " ** VariableMng::Variable list\n";
489 for( const auto& i : m_full_name_variable_map ){
490 for( VarRefEnumerator ivar(i.second); ivar.hasNext(); ++ivar ){
491 _dumpVariable(*(*ivar),o);
492 }
493 }
494 {
495 Real mem_used = 0;
496 for( const auto& i : m_full_name_variable_map )
497 mem_used += i.second->allocatedMemory();
498 o << " ** VariableMng::Allocated memory : " << mem_used;
499 o << '\n';
500 }
501}
502
503/*---------------------------------------------------------------------------*/
504/*---------------------------------------------------------------------------*/
505
507_dumpVariable(const VariableRef& var,std::ostream& o)
508{
509 o << " ** Variable: " << &var << " : ";
510 o.width(15);
511 o << var.name() << " = ";
512 var.print(o);
513 o << " (Type " << var.dataType() << ")\n";
514}
515
516/*---------------------------------------------------------------------------*/
517/*---------------------------------------------------------------------------*/
518
520initializeVariables(bool is_continue)
521{
522 ARCANE_UNUSED(is_continue);
523
524 info() << "Initialisation des variables";
525 for( const auto& i : m_full_name_variable_map ){
526 for( VarRefEnumerator ivar(i.second); ivar.hasNext(); ++ivar ){
527 VariableRef* var_ref = *ivar;
528 IModule* module = var_ref->module();
529 if (module && !module->used())
530 continue;
531 IVariable* var = var_ref->variable();
532 if (var->isUsed())
533 continue;
534 var_ref->setUsed(true);
535 }
536 }
537}
538
539/*---------------------------------------------------------------------------*/
540/*---------------------------------------------------------------------------*/
541
544{
545 for( const auto& i : m_full_name_variable_map ){
546 for( VarRefEnumerator ivar(i.second); ivar.hasNext(); ++ivar ){
547 if ((*ivar)->module()==c)
548 v.add(*ivar);
549 }
550 }
551}
552
553/*---------------------------------------------------------------------------*/
554/*---------------------------------------------------------------------------*/
555
557variables()
558{
559 if (m_variables_changed){
560 m_variables_changed = false;
561 m_variables.clear();
562 for( const auto& i : m_full_name_variable_map ){
563 m_variables.add(i.second);
564 }
565 }
566 return m_variables;
567}
568
569/*---------------------------------------------------------------------------*/
570/*---------------------------------------------------------------------------*/
571
574{
575 if (m_used_variables_changed){
576 m_used_variables_changed = false;
577 m_used_variables.clear();
578 for( const auto& i : m_full_name_variable_map ){
579 IVariable* var = i.second;
580 if (var->isUsed())
581 m_used_variables.add(var);
582 }
583 }
584 return m_used_variables;
585}
586
587/*---------------------------------------------------------------------------*/
588/*---------------------------------------------------------------------------*/
589
590bool VariableMng::
591isVariableToSave(IVariable& var)
592{
593 if (!var.isUsed())
594 return false;
595 bool no_dump = var.property() & (IVariable::PNoDump|IVariable::PTemporary);
596 if (no_dump)
597 return false;
599 if (mesh && !mesh->properties()->getBool("dump"))
600 return false;
601 return true;
602}
603
604/*---------------------------------------------------------------------------*/
605/*---------------------------------------------------------------------------*/
606
609{
610 m_variable_io_writer_mng->writeCheckpoint(service);
611}
612
613/*---------------------------------------------------------------------------*/
614/*---------------------------------------------------------------------------*/
615
618{
619 m_variable_io_writer_mng->writePostProcessing(post_processor);
620}
621
622/*---------------------------------------------------------------------------*/
623/*---------------------------------------------------------------------------*/
624
627{
628 m_variable_io_writer_mng->writeVariables(writer,vars,false);
629}
630
631/*---------------------------------------------------------------------------*/
632/*---------------------------------------------------------------------------*/
633
636{
637 m_variable_io_writer_mng->writeVariables(writer,filter,false);
638}
639
640/*---------------------------------------------------------------------------*/
641/*---------------------------------------------------------------------------*/
642
643VariableRef* VariableMng::
644_createVariableFromType(const String& full_type,const VariableBuildInfo& vbi)
645{
646 auto i = m_variable_factory_map.find(full_type);
647 if (i==m_variable_factory_map.end())
648 ARCANE_FATAL("No factory to create variable name={0} type={1}",vbi.name(),full_type);
649
650 IVariableFactory* vf = i->second;
651 info(5) << "Automatic creation of the variable"
652 << " name=" << vbi.name()
653 << " family=" << vbi.itemFamilyName()
654 << " type=" << full_type
655 << " vf=" << vf;
656 VariableRef* var_ref = vf->createVariable(vbi);
657 // Ajoute la variable à une liste pour être sur qu'elle sera bien
658 // détruite.
659 m_auto_create_variables.add(var_ref);
660 return var_ref;
661}
662
663/*---------------------------------------------------------------------------*/
664/*---------------------------------------------------------------------------*/
665
666/*---------------------------------------------------------------------------*/
667/*---------------------------------------------------------------------------*/
668
671{
672 m_variable_io_reader_mng->readCheckpoint(service);
673}
674
675/*---------------------------------------------------------------------------*/
676/*---------------------------------------------------------------------------*/
677
680{
681 m_variable_io_reader_mng->readCheckpoint(infos);
682}
683
684/*---------------------------------------------------------------------------*/
685/*---------------------------------------------------------------------------*/
686
689{
690 m_variable_io_reader_mng->readVariables(reader,filter);
691}
692
693/*---------------------------------------------------------------------------*/
694/*---------------------------------------------------------------------------*/
700{
701 Real total_size = 0;
702 if (vars.empty()){
703 for( const auto& i : m_full_name_variable_map ){
704 IVariable* var = i.second;
705 if (var->isUsed()){
706 Real n = (Real)(var->allocatedMemory());
707 total_size += n;
708 }
709 }
710 }
711 else{
712 for( VariableCollection::Enumerator i(vars); ++i; ){
713 IVariable* var = *i;
714 if (var->isUsed())
715 total_size += (Real)(var->allocatedMemory());
716 }
717 }
718 total_size /= 1.0e6;
719
720 return total_size;
721}
722
723/*---------------------------------------------------------------------------*/
724/*---------------------------------------------------------------------------*/
725
727synchronizerMng() const
728{
729 return m_variable_synchronizer_mng;
730}
731
732/*---------------------------------------------------------------------------*/
733/*---------------------------------------------------------------------------*/
736{
737 public:
738 bool operator()(IVariable* v1,IVariable* v2)
739 {
740 return v1->allocatedMemory() > v2->allocatedMemory();
741 }
742};
743
745dumpStats(std::ostream& ostr,bool is_verbose)
746{
747 ostr.precision(20);
748 ostr << "\nMemory statistics for variables:\n";
749 ostr << " Number of created variables: " << m_nb_created_variable << '\n';
750 ostr << " Number of created variables reference: " << m_nb_created_variable_reference << '\n';
751 ostr << " Number of currently allocated variables: " << m_full_name_variable_map.size() << '\n';
752 ostr << " Number of currently reference: " << m_variables_ref.count() << '\n';
753
754 // Statistiques sur la mémoire utilisée
755 Integer total_nb_var = 0;
756 Integer nb_var[NB_ITEM_KIND];
757 Real mem_used[NB_ITEM_KIND];
758 Real mem_used_array = 0.;
759 Real mem_used_particle = 0.;
760 Real mem_used_link = 0.;
761 Real total_mem_used = 0.;
762 Integer nb_var_array = 0;
763 Integer nb_var_particle = 0;
764 Integer nb_var_link = 0;
765 for( Integer i=0; i<NB_ITEM_KIND; ++i ){
766 mem_used[i] = 0;
767 nb_var[i] = 0;
768 }
769
770 // Récupère le nombre de mailles pour faire des stats d'utilisation
771 // mémoire moyenne par maille.
772 Integer nb_cell = 1;
773 if (subDomain()->defaultMesh())
774 nb_cell = subDomain()->defaultMesh()->allCells().size();
775 if (nb_cell==0)
776 nb_cell = 1;
777
778 typedef std::map<IModule*,std::set<IVariable*> > ModuleVariableMap;
779 std::set<IVariable*> variables_with_module;
780 UniqueArray<IVariable*> memory_sorted_variables;
781
782 ModuleVariableMap modules_variables;
783 for( const auto& i : m_full_name_variable_map ){
784 //for( VariableRefList::Enumerator ivar(m_variables_ref); ++ivar; ){
785 IVariable* var = i.second;
786 if (!var->isUsed())
787 continue;
788 // Pas de statistiques sur les variables scalaires
789 if (var->dimension()==0)
790 continue;
791 for( VarRefEnumerator ivar(var); ivar.hasNext(); ++ivar ){
792 VariableRef* vref = *ivar;
793 IModule* var_module = vref->module();
794 // Si la variable n'a pas de module, recherche le module éventuel
795 // qui l'a créée
796 if (!var_module)
797 var_module = m_variable_creation_modules[var];
798 if (var_module){
799 variables_with_module.insert(var);
800 modules_variables[var_module].insert(var);
801 }
802 }
803 }
804
805 for( const auto& i : m_full_name_variable_map ){
806 IVariable* var = i.second;
807 // Pas de statistiques sur les variables non utilisées
808 if (!var->isUsed())
809 continue;
810 // Pas de statistiques sur les variables scalaires
811 if (var->dimension()==0)
812 continue;
813 memory_sorted_variables.add(var);
814 // Si la variable n'a pas de module associé, la place dans
815 // la liste des variables sans module
816 if (variables_with_module.find(var)==variables_with_module.end())
817 modules_variables[0].insert(var);
818 ++total_nb_var;
819 eItemKind ik = var->itemKind();
820 Real mem = var->allocatedMemory();
821 total_mem_used += mem;
822 if (is_verbose)
823 ostr << "Var: <" << var->name() << "> Kind=" << itemKindName(ik) << " Mem=" << mem << '\n';
824 switch(ik){
825 case IK_Node:
826 case IK_Edge:
827 case IK_Face:
828 case IK_Cell:
829 case IK_DoF:
830 mem_used[ik] += mem;
831 ++nb_var[ik];
832 break;
833 case IK_Particle:
834 mem_used_particle += mem;
835 ++nb_var_particle;
836 break;
837 case IK_Unknown:
838 mem_used_array += mem;
839 ++nb_var_array;
840 break;
841 }
842 }
843
844 ostr << "Memory repartition by module:\n";
845 ostr << Trace::Width(30) << ""
846 << Trace::Width(7) << ""
847 << Trace::Width(12) << ""
848 << Trace::Width(14) << "Memory (Mo)"
849 << Trace::Width(10) << ""
850 << Trace::Width(7) << " "
851 << Trace::Width(13) << "Memory (Ko)"
852 << '\n';
853 ostr << Trace::Width(30) << "Module"
854 << Trace::Width(7) << "Nvar"
855 << Trace::Width(12) << "Private"
856 << Trace::Width(12) << "Shared"
857 << Trace::Width(12) << "Total"
858 << Trace::Width(7) << "%"
859 << Trace::Width(13) << "per cell"
860 << "\n\n";
861 String pr_true("X ");
862 String pr_false(" ");
863 for( ModuleVariableMap::const_iterator imodvar = modules_variables.begin();
864 imodvar!=modules_variables.end(); ++imodvar ){
865 IModule* module = imodvar->first;
866 Real private_mem_used = 0.0;
867 Real shared_mem_used = 0.0;
868 for( std::set<IVariable*>::const_iterator i = imodvar->second.begin();
869 i!=imodvar->second.end(); ++i ){
870 IVariable* var = *i;
871 Real mem_used2 = var->allocatedMemory();
872 bool is_private = var->nbReference()==1;
873 if (is_private)
874 private_mem_used += mem_used2;
875 else
876 shared_mem_used += mem_used2;
877 if (is_verbose)
878 ostr << "Var: <" << var->name() << "> Kind=" << itemKindName(var->itemKind())
879 << " Mem=" << mem_used << " private?=" << is_private << '\n';
880 }
881 String module_name = "None";
882 if (module)
883 module_name = module->name();
884 Real module_mem_used = private_mem_used + shared_mem_used;
885 ostr << Trace::Width(30) << module_name
886 << Trace::Width(7) << imodvar->second.size()
887 << Trace::Width(12) << String::fromNumber(private_mem_used / 1e6,3)
888 << Trace::Width(12) << String::fromNumber(shared_mem_used / 1e6,3)
889 << Trace::Width(12) << String::fromNumber(module_mem_used / 1e6,3)
890 << Trace::Width(7) << String::fromNumber(100.0 * module_mem_used / total_mem_used,1) << "%"
891 << Trace::Width(12) << String::fromNumber(module_mem_used / ((Real)nb_cell * 1000.0) ,2)
892 << '\n';
893 }
894 ostr << '\n';
895 ostr << Trace::Width(30) << "TOTAL"
896 << Trace::Width(7) << total_nb_var
897 << Trace::Width(12) << ""
898 << Trace::Width(12) << ""
899 << Trace::Width(12) << String::fromNumber(total_mem_used/ 1e6,3)
900 << Trace::Width(7) << " "
901 << Trace::Width(13) << String::fromNumber(total_mem_used / ((Real)nb_cell * 1000.0) ,2)
902 << '\n';
903
904 if (is_verbose){
905 for( Integer i=0; i<NB_ITEM_KIND; ++i ){
906 ostr << "Variable " << itemKindName((eItemKind)i) << " N=" << nb_var[i]
907 << " Mémoire=" << mem_used[i] << '\n';
908 }
909 ostr << "Variable Particle N=" << nb_var_particle
910 << " Mémoire=" << mem_used_particle << '\n';
911 ostr << "Variable Link N=" << nb_var_link
912 << " Mémoire=" << mem_used_link << '\n';
913 ostr << "Variable Array N=" << nb_var_array
914 << " Mémoire=" << mem_used_array << '\n';
915 ostr << "Variable Total N=" << total_nb_var
916 << " Mémoire=" << total_mem_used << '\n';
917 }
918
919 std::sort(std::begin(memory_sorted_variables),std::end(memory_sorted_variables),
921
922
923 Integer nb_var_to_display = memory_sorted_variables.size();
924 if (!is_verbose)
925 nb_var_to_display = math::min(nb_var_to_display,15);
926 ostr << "\nBiggest variables (D=Dump, E=Exchange R=Restore):\n";
927 ostr << Trace::Width(45) << "Variable"
928 << Trace::Width(10) << "Kind"
929 << Trace::Width(16) << "Memory (Ko)"
930 << Trace::Width(14) << "per cell (o)"
931 << Trace::Width(7) << "D E R"
932 << "\n\n";
933 for( Integer i=0; i<nb_var_to_display; ++i ){
934 IVariable* var = memory_sorted_variables[i];
935 Real mem_used2 = var->allocatedMemory();
936 //ostr << "Var: <" << var->name() << "> Kind=" << itemKindName(var->itemKind())
937 //<< " Mem=" <<var->allocatedMemory() << '\n';
938
939 StringBuilder properties;
940 int var_property = var->property();
941 bool is_no_exchange = (var_property & IVariable::PNoExchange);
942 if (var->itemKind()==IK_Unknown)
943 // Seules les variables du maillage peuvent s'échanger
944 is_no_exchange = true;
945 properties += (var_property & IVariable::PNoDump) ? pr_false : pr_true;
946 properties += (is_no_exchange) ? pr_false : pr_true;
947 properties += (var_property & IVariable::PNoRestore) ? pr_false : pr_true;
948 ostr << Trace::Width(45) << var->name()
949 << Trace::Width(10) << itemKindName(var->itemKind())
950 << Trace::Width(14) << String::fromNumber(mem_used2 / 1e3,3)
951 << Trace::Width(12) << String::fromNumber(mem_used2 / ((Real)nb_cell),1)
952 << Trace::Width(12) << properties.toString()
953 << '\n';
954 }
955}
956
957/*---------------------------------------------------------------------------*/
958/*---------------------------------------------------------------------------*/
959
962{
963 writer.writeKey("Variables");
964 writer.beginArray();
965 for( const auto& i : m_full_name_variable_map ){
966 IVariable* var = i.second;
967 if (var->dimension()==0)
968 continue;
969 {
970 JSONWriter::Object o(writer);
971 writer.write("Used",var->isUsed());
972 Real mem = var->allocatedMemory();
973 writer.write("Name",var->name());
974 writer.write("DataType",dataTypeName(var->dataType()));
975 writer.write("Dimension",(Int64)var->dimension());
976 writer.write("NbElement",(Int64)var->nbElement());
977 writer.write("ItemFamily",var->itemFamilyName());
978 writer.write("Mesh",var->meshName());
979 writer.write("Group",var->itemGroupName());
980 writer.write("Property",(Int64)var->property());
981 writer.write("AllocatedMemory",mem);
982 }
983 }
984 writer.endArray();
985}
986
987/*---------------------------------------------------------------------------*/
988/*---------------------------------------------------------------------------*/
989
990} // End namespace Arcane
991
992/*---------------------------------------------------------------------------*/
993/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Integer size() const
Nombre d'éléments du vecteur.
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Exception sur un nom de groupe d'items de variable partielle non valide.
Exception sur un genre/type de variable non valide.
Informations de relecture d'une protection.
Classe utilitaire pour la destruction des objets alloués par new.
Definition Deleter.h:31
Interface du service de lecture d'une protection/reprise.
Interface du service d'écriture d'une protection/reprise.
Interface de lecture des données d'une variable.
Definition IDataReader.h:41
Interface d'écriture des données d'une variable.
Definition IDataWriter.h:49
Interface d'un point d'entrée d'un module.
Definition IEntryPoint.h:34
virtual CellGroup allCells()=0
Groupe de toutes les mailles.
Interface d'un module.
Definition IModule.h:39
virtual bool used() const =0
true si le module est utilisé.
Interface d'un observable.
Interface d'un écrivain pour les informations de post-traitement.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
virtual void checkId(const String &where, const String &id)=0
Vérifie qu'un identifiant est valide.
virtual IMesh * defaultMesh()=0
Maillage par défaut.
virtual ITimeLoopMng * timeLoopMng()=0
Retourne le gestionnaire de la boucle en temps.
virtual IEntryPoint * currentEntryPoint()=0
Retourne le point d'entrée en cours d'exécution ou 0 s'il n'y en a pas.
Interface d'une fabrique de variables.
virtual const String & fullTypeName() const =0
Nom complet du type de la variable.
Fonctor d'un filtre applicable sur des variables.
Interface du gestionnaire de variables.
Interface du gestionnaire de synchronisation des variables.
Interface d'une variable.
Definition IVariable.h:56
virtual Real allocatedMemory() const =0
Taille mémoire (en Koctet) utilisée par la variable.
virtual eDataType dataType() const =0
Type de la donnée gérée par la variable (Real, Integer, ...)
virtual String meshName() const =0
Nom du maillage associé (nul si aucun).
virtual void setUsed(bool v)=0
Positionne l'état d'utilisation de la variable.
virtual String itemFamilyName() const =0
Nom de la famille associée (nul si aucune).
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
@ PTemporary
Indique que la variable est temporaire.
Definition IVariable.h:128
@ PNoRestore
Indique que la variable ne doit pas être restaurée.
Definition IVariable.h:135
@ PNoDump
Indique que la variable ne doit pas être sauvegardée.
Definition IVariable.h:74
virtual int property() const =0
Retourne les propriétés de la variable.
virtual eItemKind itemKind() const =0
Type des entités du maillage sur lequel repose la variable.
virtual Integer nbReference() const =0
Nombre de références sur cette variable.
virtual Integer dimension() const =0
Dimension de la variable.
virtual bool isUsed() const =0
Etat d'utilisation de la variable.
virtual ItemGroup itemGroup() const =0
Groupe du maillage associé.
virtual Integer nbElement() const =0
Nombre d'éléments de la variable.
virtual String itemGroupName() const =0
Nom du groupe d'entité associée.
virtual MeshHandle meshHandle() const =0
Maillage auquel est associé la variable.
virtual String name() const =0
Nom de la variable.
void detachObserver(const void *ref)
Détache un observer.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
ItemGroupImpl * internal() const
Retourne l'implémentation du groupe.
Definition ItemGroup.h:120
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
IMesh * mesh() const
Maillage auquel appartient ce groupe (0 pour le group nul)
Definition ItemGroup.h:126
Ecrivain au format JSON.
Definition JSONWriter.h:33
IMesh * _internalMeshOrNull() const
Definition MeshHandle.h:179
Flot de sortie lié à une String.
Constructeur de chaîne de caractère unicode.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
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.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage pwarning() const
Formattage du flot en longueur.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
Collection de variables.
Enregistreur d'une fabrique de variables.
Integer dimension() const
Dimension de la variable créée par cette fabrique.
IVariableFactory * createFactory()
Créé une fabrique pour ce type de variable.
Integer multiTag() const
Tag indiquant le type multiple (0 si non multiple, 1 si multiple, 2 si multiple deprecated)
eDataType dataType() const
Type de données de la variable créée par cette fabrique.
eItemKind itemKind() const
Genre des variables de données de la variable créée par cette fabrique.
VariableFactoryRegisterer * nextVariableFactory() const
VariableFactory suivant (0 si le dernier)
Infos caractérisant une variable.
bool isPartial() const
Indique si la variable est partielle.
const String & itemFamilyName() const
Nom de la famille d'entité à laquelle la variable est associée.
const String & localName() const
Nom de la variable.
eItemKind itemKind() const
Type d'entité de maillage.
const String & itemGroupName() const
Nom du groupe d'entité à laquelle la variable est associée.
Integer dimension() const
Dimension.
eDataType dataType() const
Type des éléments.
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)
Gestionnaire de variables.
Definition VariableMng.h:56
IVariable * checkVariable(const VariableInfo &infos) override
Vérifie une variable.
Real exportSize(const VariableCollection &vars) override
IVariable * findVariableFullyQualified(const String &name) override
Retourne la variable de nom complet name ou 0 si aucune de se nom existe.
void dumpList(std::ostream &, IModule *) override
Affiche la liste des variables du gestionnaire lié à un module.
void _dumpVariable(const VariableRef &v, std::ostream &o)
Ecrit la valeur de la variable v sur le flot o.
void addVariable(IVariable *var) override
Ajoute une variable.
ISubDomain * m_sub_domain
Gestionnaire de sous-domaine.
void dumpStatsJSON(JSONWriter &writer) override
Ecrit les statistiques avec l'écrivain writer.
Integer m_generate_name_id
Numéro utilisé pour générer un nom de variable.
List< VariableRef * > m_auto_create_variables
Liste des variables créées automatiquement lors d'une reprise.
FullNameVariableMap m_full_name_variable_map
Liste des variables par nom complet.
void readVariables(IDataReader *, IVariableFilter *) override
Relit toutes les variables.
void writeVariables(IDataWriter *, const VariableCollection &vars) override
Exporte les variables.
void detachMeshVariables(IMesh *mesh) override
Détache les variables associées au maillage mesh.
ITraceMng * traceMng() override
Gestionnaire de messages.
String generateTemporaryVariableName() override
Génère un nom pour une variable temporaire.
void removeVariableRef(VariableRef *) override
Supprime une référence à une variable.
ISubDomain * subDomain() override
Gestionnaire du sous-domaine.
IVariable * findVariable(const String &name) override
Retourne la variable de nom name ou 0 si aucune de se nom existe.
VariableFactoryMap::value_type VariableFactoryPair
Paire de la liste des variables par nom complet.
VariableCollection usedVariables() override
Liste des variables utilisées.
void removeVariable(IVariable *var) override
Supprime une variable.
void build() override
Construit les membres de l'instance.
void addVariableRef(VariableRef *ref) override
Ajoute une référence à une variable.
IVariable * findMeshVariable(IMesh *mesh, const String &name) override
Retourne la variable du maillage de nom name ou 0 si aucune de se nom existe.
void initialize() override
Initialise l'instance. L'instance n'est pas utilisable tant que cette méthode n'a pas été appelée.
void removeAllVariables() override
Supprime et détruit les variables gérées par ce gestionnaire.
VariableRefList m_variables_ref
Liste des variables.
FullNameVariableMap::value_type FullNameVariablePair
Paire de la liste des variables par nom complet.
void writeCheckpoint(ICheckpointWriter *) override
Ecrit les variables pour une protection.
IParallelMng * parallelMng() const override
Gestionnaire de parallélisme associé
void writePostProcessing(IPostProcessorWriter *writer) override
Ecrit les variables pour un post-traitement.
IVariableSynchronizerMng * synchronizerMng() const override
Interface du gestionnaire de synchronisation des variables.
~VariableMng() override
Détruit le gestionnaire.
VariableCollection variables() override
Liste des variables.
void initializeVariables(bool) override
Initialise les variables.
void dumpStats(std::ostream &ostr, bool is_verbose) override
Ecrit les statistiques sur les variables sur le flot ostr.
VariableMng(ISubDomain *sd)
Construit un gestionnaire de variable pour le cas pn.
void readCheckpoint(ICheckpointReader *) override
Relit toutes les variables d'une protection.
Référence à une variable.
Definition VariableRef.h:56
virtual eDataType dataType() const
Type de la variable (Real, Integer, ...)
virtual void print(std::ostream &o) const
Affiche la valeur de la variable.
virtual IModule * module() const
Module associé à la variable (ou nullptr, s'il n'y en a pas)
IVariable * variable() const
Variable associée.
String name() const
Nom de la variable.
const String & assignmentStackTrace() const
Pile d'appel au moment de l'assignation de cette instance.
Trieur de variable suivant leur taille mémoire utilisée.
Arguments de l'évènement notifiant un changement de l'état d'une variable.
Gestionnaire des synchroniseurs de variables.
Fonctions utilitaires sur les variables.
__host__ __device__ Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
Definition MathUtils.h:336
ARCCORE_BASE_EXPORT String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
Collection< VariableRef * > VariableRefCollection
Collection de variables.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
eItemKind
Genre d'entité de maillage.
@ IK_Particle
Entité de maillage de genre particule.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Unknown
Entité de maillage de genre inconnu ou non initialisé
@ IK_Face
Entité de maillage de genre face.
@ IK_DoF
Entité de maillage de genre degre de liberte.
@ IK_Edge
Entité de maillage de genre arête.
const char * itemKindName(eItemKind kind)
Nom du genre d'entité.
double Real
Type représentant un réel.
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Definition DataTypes.cc:70