Arcane  v3.14.10.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-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* VariableMng.cc (C) 2000-2024 */
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
23#include "arcane/core/ArcaneException.h"
24#include "arcane/core/VarRefEnumerator.h"
25#include "arcane/core/IModule.h"
26#include "arcane/core/ISubDomain.h"
27#include "arcane/core/IObservable.h"
28#include "arcane/core/VariableInfo.h"
29#include "arcane/core/VariableBuildInfo.h"
30#include "arcane/core/VariableFactoryRegisterer.h"
31#include "arcane/core/IVariableFactory.h"
32#include "arcane/core/ItemGroup.h"
33#include "arcane/core/IMesh.h"
34#include "arcane/core/MeshHandle.h"
35#include "arcane/core/IParallelMng.h"
36#include "arcane/core/ITimeLoopMng.h"
37#include "arcane/core/IEntryPoint.h"
38#include "arcane/core/Properties.h"
39#include "arcane/core/VariableStatusChangedEventArgs.h"
40
41#include "arcane/impl/VariableUtilities.h"
42#include "arcane/impl/internal/VariableSynchronizerMng.h"
43
44#include <exception>
45#include <set>
46#include <vector>
47
48// TODO: gérer le hash en version 64 bits.
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53namespace Arcane
54{
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
59extern "C++" IVariableMng*
60arcaneCreateVariableMng(ISubDomain* sd)
61{
62 auto vm = new VariableMng(sd);
63 vm->build();
64 vm->initialize();
65 return vm;
66}
67
68/*---------------------------------------------------------------------------*/
69/*---------------------------------------------------------------------------*/
77: TraceAccessor(sd->traceMng())
78, m_sub_domain(sd)
79, m_parallel_mng(sd->parallelMng())
80, m_vni_map(2000,true)
81, m_write_observable(IObservable::createDefault())
82, m_read_observable(IObservable::createDefault())
83, m_utilities(new VariableUtilities(this))
84, m_variable_io_writer_mng(new VariableIOWriterMng(this))
85, m_variable_io_reader_mng(new VariableIOReaderMng(this))
86, m_variable_synchronizer_mng(new VariableSynchronizerMng(this))
87{
88}
89
90/*---------------------------------------------------------------------------*/
91/*---------------------------------------------------------------------------*/
99{
100 delete m_variable_synchronizer_mng;
101
102 delete m_variable_io_reader_mng;
103 delete m_variable_io_writer_mng;
104 delete m_utilities;
105
106 m_write_observable->detachAllObservers();
107 m_read_observable->detachAllObservers();
108
109 delete m_write_observable;
110 delete m_read_observable;
111
112 m_variable_factories.each(Deleter());
113}
114
115/*---------------------------------------------------------------------------*/
116/*---------------------------------------------------------------------------*/
117
119build()
120{
121 String s = platform::getEnvironmentVariable("ARCANE_TRACE_VARIABLE_CREATION");
122 if (!s.null())
123 VariableRef::setTraceCreation(true);
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
128
131{
132 m_time_stats = m_parallel_mng->timeStats();
133
134 VariableFactoryRegisterer* vff = VariableFactoryRegisterer::firstVariableFactory();
135 while (vff){
136 IVariableFactory* vf = vff->createFactory();
137 String full_name = vf->fullTypeName();
138 // Vérifie qu'aucune fabrique avec le même nom n'existe.
139 if (m_variable_factory_map.find(full_name)!=m_variable_factory_map.end()){
140 ARCANE_FATAL("VariableFactoryMap already contains a factory for the same type '{0}'",
141 full_name);
142 }
143 m_variable_factory_map.insert(VariableFactoryPair(full_name,vf));
144 m_variable_factories.add(vf);
145 info(5) << "Add variable factory kind=" << vff->itemKind()
146 << " data_type=" << vff->dataType()
147 << " dim=" << vff->dimension()
148 << " multi_tag=" << vff->multiTag()
149 << " full_name=" << full_name
150 << " addr=" << vf;
151 vff = vff->nextVariableFactory();
152 }
153
154 m_variable_synchronizer_mng->initialize();
155}
156
157/*---------------------------------------------------------------------------*/
158/*---------------------------------------------------------------------------*/
159
162{
163 //ATTENTION: ceci entraine des appels à removeVariable()
165
168 for( const auto& i : m_full_name_variable_map ){
169 IVariable* v = i.second;
170 if (v->nbReference()==0)
171 delete v;
172 else{
173 remaining_vars.add(v);
174 var_str() << " " << v->fullName() << " (" << v->nbReference() << ")";
175 }
176 }
177 bool is_check = arcaneIsCheck();
178 const bool has_remaining_vars = !remaining_vars.empty();
180 pwarning() << "The following variables are still referenced: "
181 << var_str.str()
182 << " (set the environment variable ARCANE_TRACE_VARIABLE_CREATION"
183 << " to get the stack trace)";
184 bool has_trace = VariableRef::hasTraceCreation();
185 if (has_trace){
186 for( const auto& i : remaining_vars ){
187 for( VarRefEnumerator ivar(i); ivar.hasNext(); ++ivar ){
188 VariableRef* var = *ivar;
189 info() << " variable name=" << var->name()
190 << " stack=" << var->assignmentStackTrace();
191 }
192 }
193 }
194
195 // Appelle explicitement 'unregisterVariable()' sur les variables restantes.
196 // Sans cela, si ensuite l'instance 'this' est détruite avant que les variables
197 // restantent ne le soit cela va provoquer un plantage (Read after free). Cela
198 // n'arrive normalement pas pour le C++ mais peut arriver pour le wrapping.
200 // Recopie les références dans un tableau temporaire
201 // car les appels à unregisterVariable() modifient l'itérateur ivar
202 // et aussi m_full_name_variable_map.
204 for( const auto& i : remaining_vars )
205 for( VarRefEnumerator ivar(i); ivar.hasNext(); ++ivar )
206 remaining_refs.add(*ivar);
208 r->unregisterVariable();
209 if (is_check)
210 info() << "Remaining variables after cleanup n=" << m_full_name_variable_map.size();
211 }
212
214}
215
216/*---------------------------------------------------------------------------*/
217/*---------------------------------------------------------------------------*/
218
221{
222 for( const auto& i : m_full_name_variable_map ){
223 IVariable* v = i.second;
224 ItemGroup group = v->itemGroup();
225 if (group.null())
226 continue;
227 if (group.mesh()==mesh){
228 v->setUsed(false);
229 }
230 }
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
238{
239 ARCANE_UNUSED(ref);
240 ++m_nb_created_variable_reference;
241}
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
248{
249 ARCANE_UNUSED(ref);
250}
251
252/*---------------------------------------------------------------------------*/
253/*---------------------------------------------------------------------------*/
254
257{
258 const String& full_name = var->fullName();
259 subDomain()->checkId("VariableMng::checkVariable()",full_name);
260 if (var->itemKind()!=IK_Unknown && var->itemFamilyName().null())
261 ARCANE_FATAL("Bad Variable full-name={0} name={1}",var->fullName(),var->name());
262
263 info(5) << "Add variable"
264 << " name=" << var->name()
265 << " full_name=" << full_name
266 << " datatype=" << var->dataType()
267 << " kind=" << var->itemKind();
268
270 vni.m_local_name = var->name();
271 vni.m_family_name = var->itemFamilyName();
272 vni.m_mesh_name = var->meshName();
273 m_vni_map.add(vni,var);
274
276 m_variables_changed = true;
277 m_used_variables_changed = true;
278 ++m_nb_created_variable;
279 IEntryPoint* ep = subDomain()->timeLoopMng()->currentEntryPoint();
280 IModule* module = nullptr;
281 if (ep)
282 module = ep->module();
283 m_variable_creation_modules.insert(std::make_pair(var,module));
285 m_on_variable_added.notify(eargs);
286}
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
293{
294 int p = var->property();
296 debug() << "** ** REMOVE " << var->name() << " " << var->nbReference()
297 << " property=" << p
298 << " nodump=" << (p & IVariable::PNoDump)
299 << " tmp=" << (p & IVariable::PTemporary)
300 << " norestore=" << (p & IVariable::PNoRestore);
301 }
303 m_on_variable_removed.notify(eargs);
304 {
305 ItemGroup var_group = var->itemGroup();
306 // Retire cette variable de tous les groupes [bien défini mais sur ItemGroupImplNull]
307 if (!var_group.null())
308 var_group.internal()->detachObserver(var);
309 // Retire cette variable des variables existantes, puis la détruit
310 m_full_name_variable_map.erase(var->fullName());
311 {
313 vni.m_local_name = var->name();
314 vni.m_family_name = var->itemFamilyName();
315 vni.m_mesh_name = var->meshName();
316 m_vni_map.remove(vni);
317 }
318 m_variables_changed = true;
319 m_used_variables_changed = true;
320 m_variable_creation_modules.erase(var);
321 delete var;
322 }
323}
324
325/*---------------------------------------------------------------------------*/
326/*---------------------------------------------------------------------------*/
327
329checkVariable(const VariableInfo& infos)
330{
332 vni.m_local_name = infos.localName();
333 vni.m_family_name = infos.itemFamilyName();
334 vni.m_mesh_name = infos.meshName();
335
336 if (infos.itemKind()!=IK_Unknown && infos.meshName().null())
337 ARCANE_FATAL("Mesh variable without a mesh full-name={0} name={1}",infos.fullName(),infos.localName());
338
339 // Si variable du maillage, vérifie qu'aucune variable globale non lié à un maillage
340 // ne porte le même nom.
341 if (arcaneIsCheck()){
342 if (!infos.meshName().null()){
343 String check_name = infos.localName();
345 ARCANE_FATAL("Mesh variable has the same name that a global variable (name={0})",check_name);
346 }
347 }
348 else{
349 // Si variable globale, vérifie qu'aucune variable du maillage ne porte le même nom.
350 String check_name = String("Mesh0_")+infos.localName();
352 ARCANE_FATAL("Global variable has the same name that a mesh variable (name={0})",check_name);
353 }
354 }
355 }
356
357 IVariable* var = nullptr;
358 //VNIMap::Data* var_data = m_vni_map.lookup(vni);
359
360 //cerr << "** CHECK " << name << ' ' << infos.dataType() << ' ' << infos.kind() << '\n';
361 VNIMap::Data* var_data = m_vni_map.lookup(vni);
362 if (var_data){
363 // Une variable de même nom que \a var existe déjà.
364 // Il faut dans ce cas vérifier que son genre et son type sont les même.
365 // elle a le même genre et le même type.
366 var = var_data->value();
367 //cerr << "** FIND " << prv->name() << ' ' << prv->dataType() << ' ' << prv->kind() << '\n';
368 if (infos.dataType()!=var->dataType() ||
369 infos.itemKind()!=var->itemKind() ||
370 infos.dimension()!=var->dimension()){
371 throw BadVariableKindTypeException(A_FUNCINFO,var,infos.itemKind(),
372 infos.dataType(),infos.dimension());
373 }
374 // For partial variable: if exists already must be defined on the same group, otherwise fatal
375 if (infos.isPartial()) {
376 if (infos.itemGroupName() != var->itemGroupName())
378 }
379 }
380 return var;
381}
382
383/*---------------------------------------------------------------------------*/
384/*---------------------------------------------------------------------------*/
385
387findVariable(const String& name)
388{
390 if (v)
391 return v;
392 v = findVariableFullyQualified(String("Node_")+name);
393 if (v)
394 return v;
395 v = findVariableFullyQualified(String("Edge_")+name);
396 if (v)
397 return v;
398 v = findVariableFullyQualified(String("Face_")+name);
399 if (v)
400 return v;
401 v = findVariableFullyQualified(String("Cell_")+name);
402 if (v)
403 return v;
404 return nullptr;
405}
406
407/*---------------------------------------------------------------------------*/
408/*---------------------------------------------------------------------------*/
409
411findMeshVariable(IMesh* mesh,const String& name)
412{
413 String mesh_name = mesh->name();
414 mesh_name = mesh_name + "_";
416 if (v)
417 return v;
418 v = findVariableFullyQualified(mesh_name+"Node_"+name);
419 if (v)
420 return v;
421 v = findVariableFullyQualified(mesh_name+"Edge_"+name);
422 if (v)
423 return v;
424 v = findVariableFullyQualified(mesh_name+"Face_"+name);
425 if (v)
426 return v;
427 v = findVariableFullyQualified(mesh_name+"Cell_"+name);
428 if (v)
429 return v;
430 return nullptr;
431}
432
433/*---------------------------------------------------------------------------*/
434/*---------------------------------------------------------------------------*/
435
438{
439 auto i = m_full_name_variable_map.find(name);
440 if (i!=m_full_name_variable_map.end())
441 return i->second;
442 return nullptr;
443}
444
445/*---------------------------------------------------------------------------*/
446/*---------------------------------------------------------------------------*/
447
450{
451 bool is_bad = true;
452 String name;
453 while (is_bad){
454 name = String("ArcaneTemporary") + m_generate_name_id;
455 // Vérifie que le nom généré ne correspond pas à une variable existante
456 if (findVariable(name))
458 else
459 is_bad = false;
460 }
461 info() << "** GENERATED NAME =" << name;
462 return name;
463}
464
465/*---------------------------------------------------------------------------*/
466/*---------------------------------------------------------------------------*/
467
469dumpList(std::ostream& o,IModule* c)
470{
471 o << " ** VariableMng::Variable list\n";
472 for( const auto& i : m_full_name_variable_map ){
473 for( VarRefEnumerator ivar(i.second); ivar.hasNext(); ++ivar ){
474 if ((*ivar)->module()!=c)
475 continue;
476 _dumpVariable(*(*ivar),o);
477 }
478 }
479}
480
481/*---------------------------------------------------------------------------*/
482/*---------------------------------------------------------------------------*/
483
485dumpList(std::ostream& o)
486{
487 o << " ** VariableMng::Variable list\n";
488 for( const auto& i : m_full_name_variable_map ){
489 for( VarRefEnumerator ivar(i.second); ivar.hasNext(); ++ivar ){
490 _dumpVariable(*(*ivar),o);
491 }
492 }
493 {
494 Real mem_used = 0;
495 for( const auto& i : m_full_name_variable_map )
496 mem_used += i.second->allocatedMemory();
497 o << " ** VariableMng::Allocated memory : " << mem_used;
498 o << '\n';
499 }
500}
501
502/*---------------------------------------------------------------------------*/
503/*---------------------------------------------------------------------------*/
504
506_dumpVariable(const VariableRef& var,std::ostream& o)
507{
508 o << " ** Variable: " << &var << " : ";
509 o.width(15);
510 o << var.name() << " = ";
511 var.print(o);
512 o << " (Type " << var.dataType() << ")\n";
513}
514
515/*---------------------------------------------------------------------------*/
516/*---------------------------------------------------------------------------*/
517
520{
521 ARCANE_UNUSED(is_continue);
522
523 info() << "Initialisation des variables";
524 for( const auto& i : m_full_name_variable_map ){
525 for( VarRefEnumerator ivar(i.second); ivar.hasNext(); ++ivar ){
527 IModule* module = var_ref->module();
528 if (module && !module->used())
529 continue;
530 IVariable* var = var_ref->variable();
531 if (var->isUsed())
532 continue;
533 var_ref->setUsed(true);
534 }
535 }
536}
537
538/*---------------------------------------------------------------------------*/
539/*---------------------------------------------------------------------------*/
540
543{
544 for( const auto& i : m_full_name_variable_map ){
545 for( VarRefEnumerator ivar(i.second); ivar.hasNext(); ++ivar ){
546 if ((*ivar)->module()==c)
547 v.add(*ivar);
548 }
549 }
550}
551
552/*---------------------------------------------------------------------------*/
553/*---------------------------------------------------------------------------*/
554
556variables()
557{
558 if (m_variables_changed){
559 m_variables_changed = false;
560 m_variables.clear();
561 for( const auto& i : m_full_name_variable_map ){
562 m_variables.add(i.second);
563 }
564 }
565 return m_variables;
566}
567
568/*---------------------------------------------------------------------------*/
569/*---------------------------------------------------------------------------*/
570
573{
574 if (m_used_variables_changed){
575 m_used_variables_changed = false;
576 m_used_variables.clear();
577 for( const auto& i : m_full_name_variable_map ){
578 IVariable* var = i.second;
579 if (var->isUsed())
580 m_used_variables.add(var);
581 }
582 }
583 return m_used_variables;
584}
585
586/*---------------------------------------------------------------------------*/
587/*---------------------------------------------------------------------------*/
588
589bool VariableMng::
590isVariableToSave(IVariable& var)
591{
592 if (!var.isUsed())
593 return false;
595 if (no_dump)
596 return false;
597 IMesh* mesh = var.meshHandle()._internalMeshOrNull();
598 if (mesh && !mesh->properties()->getBool("dump"))
599 return false;
600 return true;
601}
602
603/*---------------------------------------------------------------------------*/
604/*---------------------------------------------------------------------------*/
605
608{
609 m_variable_io_writer_mng->writeCheckpoint(service);
610}
611
612/*---------------------------------------------------------------------------*/
613/*---------------------------------------------------------------------------*/
614
617{
618 m_variable_io_writer_mng->writePostProcessing(post_processor);
619}
620
621/*---------------------------------------------------------------------------*/
622/*---------------------------------------------------------------------------*/
623
626{
627 m_variable_io_writer_mng->writeVariables(writer,vars,false);
628}
629
630/*---------------------------------------------------------------------------*/
631/*---------------------------------------------------------------------------*/
632
635{
636 m_variable_io_writer_mng->writeVariables(writer,filter,false);
637}
638
639/*---------------------------------------------------------------------------*/
640/*---------------------------------------------------------------------------*/
641
642VariableRef* VariableMng::
643_createVariableFromType(const String& full_type,const VariableBuildInfo& vbi)
644{
645 auto i = m_variable_factory_map.find(full_type);
646 if (i==m_variable_factory_map.end())
647 ARCANE_FATAL("No factory to create variable name={0} type={1}",vbi.name(),full_type);
648
649 IVariableFactory* vf = i->second;
650 info(5) << "Automatic creation of the variable"
651 << " name=" << vbi.name()
652 << " family=" << vbi.itemFamilyName()
653 << " type=" << full_type
654 << " vf=" << vf;
655 VariableRef* var_ref = vf->createVariable(vbi);
656 // Ajoute la variable à une liste pour être sur qu'elle sera bien
657 // détruite.
659 return var_ref;
660}
661
662/*---------------------------------------------------------------------------*/
663/*---------------------------------------------------------------------------*/
664
665/*---------------------------------------------------------------------------*/
666/*---------------------------------------------------------------------------*/
667
670{
671 m_variable_io_reader_mng->readCheckpoint(service);
672}
673
674/*---------------------------------------------------------------------------*/
675/*---------------------------------------------------------------------------*/
676
679{
680 m_variable_io_reader_mng->readCheckpoint(infos);
681}
682
683/*---------------------------------------------------------------------------*/
684/*---------------------------------------------------------------------------*/
685
688{
689 m_variable_io_reader_mng->readVariables(reader,filter);
690}
691
692/*---------------------------------------------------------------------------*/
693/*---------------------------------------------------------------------------*/
699{
700 Real total_size = 0;
701 if (vars.empty()){
702 for( const auto& i : m_full_name_variable_map ){
703 IVariable* var = i.second;
704 if (var->isUsed()){
705 Real n = (Real)(var->allocatedMemory());
706 total_size += n;
707 }
708 }
709 }
710 else{
711 for( VariableCollection::Enumerator i(vars); ++i; ){
712 IVariable* var = *i;
713 if (var->isUsed())
714 total_size += (Real)(var->allocatedMemory());
715 }
716 }
717 total_size /= 1.0e6;
718
719 return total_size;
720}
721
722/*---------------------------------------------------------------------------*/
723/*---------------------------------------------------------------------------*/
724
726synchronizerMng() const
727{
728 return m_variable_synchronizer_mng;
729}
730
731/*---------------------------------------------------------------------------*/
732/*---------------------------------------------------------------------------*/
735{
736 public:
737 bool operator()(IVariable* v1,IVariable* v2)
738 {
739 return v1->allocatedMemory() > v2->allocatedMemory();
740 }
741};
742
744dumpStats(std::ostream& ostr,bool is_verbose)
745{
746 ostr.precision(20);
747 ostr << "\nMemory statistics for variables:\n";
748 ostr << " Number of created variables: " << m_nb_created_variable << '\n';
749 ostr << " Number of created variables reference: " << m_nb_created_variable_reference << '\n';
750 ostr << " Number of currently allocated variables: " << m_full_name_variable_map.size() << '\n';
751 ostr << " Number of currently reference: " << m_variables_ref.count() << '\n';
752
753 // Statistiques sur la mémoire utilisée
754 Integer total_nb_var = 0;
755 Integer nb_var[NB_ITEM_KIND];
756 Real mem_used[NB_ITEM_KIND];
757 Real mem_used_array = 0.;
758 Real mem_used_particle = 0.;
759 Real mem_used_link = 0.;
760 Real total_mem_used = 0.;
761 Integer nb_var_array = 0;
762 Integer nb_var_particle = 0;
763 Integer nb_var_link = 0;
764 for( Integer i=0; i<NB_ITEM_KIND; ++i ){
765 mem_used[i] = 0;
766 nb_var[i] = 0;
767 }
768
769 // Récupère le nombre de mailles pour faire des stats d'utilisation
770 // mémoire moyenne par maille.
771 Integer nb_cell = 1;
772 if (subDomain()->defaultMesh())
773 nb_cell = subDomain()->defaultMesh()->allCells().size();
774 if (nb_cell==0)
775 nb_cell = 1;
776
777 typedef std::map<IModule*,std::set<IVariable*> > ModuleVariableMap;
778 std::set<IVariable*> variables_with_module;
780
782 for( const auto& i : m_full_name_variable_map ){
783 //for( VariableRefList::Enumerator ivar(m_variables_ref); ++ivar; ){
784 IVariable* var = i.second;
785 if (!var->isUsed())
786 continue;
787 // Pas de statistiques sur les variables scalaires
788 if (var->dimension()==0)
789 continue;
790 for( VarRefEnumerator ivar(var); ivar.hasNext(); ++ivar ){
792 IModule* var_module = vref->module();
793 // Si la variable n'a pas de module, recherche le module éventuel
794 // qui l'a créée
795 if (!var_module)
796 var_module = m_variable_creation_modules[var];
797 if (var_module){
800 }
801 }
802 }
803
804 for( const auto& i : m_full_name_variable_map ){
805 IVariable* var = i.second;
806 // Pas de statistiques sur les variables non utilisées
807 if (!var->isUsed())
808 continue;
809 // Pas de statistiques sur les variables scalaires
810 if (var->dimension()==0)
811 continue;
813 // Si la variable n'a pas de module associé, la place dans
814 // la liste des variables sans module
816 modules_variables[0].insert(var);
817 ++total_nb_var;
818 eItemKind ik = var->itemKind();
819 Real mem = var->allocatedMemory();
821 if (is_verbose)
822 ostr << "Var: <" << var->name() << "> Kind=" << itemKindName(ik) << " Mem=" << mem << '\n';
823 switch(ik){
824 case IK_Node:
825 case IK_Edge:
826 case IK_Face:
827 case IK_Cell:
828 case IK_DoF:
829 mem_used[ik] += mem;
830 ++nb_var[ik];
831 break;
832 case IK_Particle:
835 break;
836 case IK_Unknown:
838 ++nb_var_array;
839 break;
840 }
841 }
842
843 ostr << "Memory repartition by module:\n";
844 ostr << Trace::Width(30) << ""
845 << Trace::Width(7) << ""
846 << Trace::Width(12) << ""
847 << Trace::Width(14) << "Memory (Mo)"
848 << Trace::Width(10) << ""
849 << Trace::Width(7) << " "
850 << Trace::Width(13) << "Memory (Ko)"
851 << '\n';
852 ostr << Trace::Width(30) << "Module"
853 << Trace::Width(7) << "Nvar"
854 << Trace::Width(12) << "Private"
855 << Trace::Width(12) << "Shared"
856 << Trace::Width(12) << "Total"
857 << Trace::Width(7) << "%"
858 << Trace::Width(13) << "per cell"
859 << "\n\n";
860 String pr_true("X ");
861 String pr_false(" ");
862 for( ModuleVariableMap::const_iterator imodvar = modules_variables.begin();
864 IModule* module = imodvar->first;
865 Real private_mem_used = 0.0;
866 Real shared_mem_used = 0.0;
867 for( std::set<IVariable*>::const_iterator i = imodvar->second.begin();
868 i!=imodvar->second.end(); ++i ){
869 IVariable* var = *i;
870 Real mem_used2 = var->allocatedMemory();
871 bool is_private = var->nbReference()==1;
872 if (is_private)
874 else
876 if (is_verbose)
877 ostr << "Var: <" << var->name() << "> Kind=" << itemKindName(var->itemKind())
878 << " Mem=" << mem_used << " private?=" << is_private << '\n';
879 }
880 String module_name = "None";
881 if (module)
882 module_name = module->name();
885 << Trace::Width(7) << imodvar->second.size()
886 << Trace::Width(12) << String::fromNumber(private_mem_used / 1e6,3)
887 << Trace::Width(12) << String::fromNumber(shared_mem_used / 1e6,3)
888 << Trace::Width(12) << String::fromNumber(module_mem_used / 1e6,3)
889 << Trace::Width(7) << String::fromNumber(100.0 * module_mem_used / total_mem_used,1) << "%"
890 << Trace::Width(12) << String::fromNumber(module_mem_used / ((Real)nb_cell * 1000.0) ,2)
891 << '\n';
892 }
893 ostr << '\n';
894 ostr << Trace::Width(30) << "TOTAL"
896 << Trace::Width(12) << ""
897 << Trace::Width(12) << ""
898 << Trace::Width(12) << String::fromNumber(total_mem_used/ 1e6,3)
899 << Trace::Width(7) << " "
900 << Trace::Width(13) << String::fromNumber(total_mem_used / ((Real)nb_cell * 1000.0) ,2)
901 << '\n';
902
903 if (is_verbose){
904 for( Integer i=0; i<NB_ITEM_KIND; ++i ){
905 ostr << "Variable " << itemKindName((eItemKind)i) << " N=" << nb_var[i]
906 << " Mémoire=" << mem_used[i] << '\n';
907 }
908 ostr << "Variable Particle N=" << nb_var_particle
909 << " Mémoire=" << mem_used_particle << '\n';
910 ostr << "Variable Link N=" << nb_var_link
911 << " Mémoire=" << mem_used_link << '\n';
912 ostr << "Variable Array N=" << nb_var_array
913 << " Mémoire=" << mem_used_array << '\n';
914 ostr << "Variable Total N=" << total_nb_var
915 << " Mémoire=" << total_mem_used << '\n';
916 }
917
918 std::sort(std::begin(memory_sorted_variables),std::end(memory_sorted_variables),
920
921
923 if (!is_verbose)
925 ostr << "\nBiggest variables (D=Dump, E=Exchange R=Restore):\n";
926 ostr << Trace::Width(45) << "Variable"
927 << Trace::Width(10) << "Kind"
928 << Trace::Width(16) << "Memory (Ko)"
929 << Trace::Width(14) << "per cell (o)"
930 << Trace::Width(7) << "D E R"
931 << "\n\n";
932 for( Integer i=0; i<nb_var_to_display; ++i ){
934 Real mem_used2 = var->allocatedMemory();
935 //ostr << "Var: <" << var->name() << "> Kind=" << itemKindName(var->itemKind())
936 //<< " Mem=" <<var->allocatedMemory() << '\n';
937
938 StringBuilder properties;
939 int var_property = var->property();
941 if (var->itemKind()==IK_Unknown)
942 // Seules les variables du maillage peuvent s'échanger
943 is_no_exchange = true;
944 properties += (var_property & IVariable::PNoDump) ? pr_false : pr_true;
945 properties += (is_no_exchange) ? pr_false : pr_true;
947 ostr << Trace::Width(45) << var->name()
948 << Trace::Width(10) << itemKindName(var->itemKind())
949 << Trace::Width(14) << String::fromNumber(mem_used2 / 1e3,3)
950 << Trace::Width(12) << String::fromNumber(mem_used2 / ((Real)nb_cell),1)
951 << Trace::Width(12) << properties.toString()
952 << '\n';
953 }
954}
955
956/*---------------------------------------------------------------------------*/
957/*---------------------------------------------------------------------------*/
958
961{
962 writer.writeKey("Variables");
963 writer.beginArray();
964 for( const auto& i : m_full_name_variable_map ){
965 IVariable* var = i.second;
966 if (var->dimension()==0)
967 continue;
968 {
970 writer.write("Used",var->isUsed());
971 Real mem = var->allocatedMemory();
972 writer.write("Name",var->name());
973 writer.write("DataType",dataTypeName(var->dataType()));
974 writer.write("Dimension",(Int64)var->dimension());
975 writer.write("NbElement",(Int64)var->nbElement());
976 writer.write("ItemFamily",var->itemFamilyName());
977 writer.write("Mesh",var->meshName());
978 writer.write("Group",var->itemGroupName());
979 writer.write("Property",(Int64)var->property());
980 writer.write("AllocatedMemory",mem);
981 }
982 }
983 writer.endArray();
984}
985
986/*---------------------------------------------------------------------------*/
987/*---------------------------------------------------------------------------*/
988
989} // End namespace Arcane
990
991/*---------------------------------------------------------------------------*/
992/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
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.
Integer count() const
Nombre d'éléments de la collection.
Definition Collection.h:70
Classe utilitaire pour la destruction des objets alloués par new.
Definition Deleter.h:31
Data * lookup(KeyTypeConstRef id)
Recherche la valeur correspondant à la clé id.
void remove(KeyTypeConstRef id)
Supprime la valeur associée à la clé id.
bool add(KeyTypeConstRef id, const ValueType &value)
Ajoute la valeur value correspondant à la clé id.
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 String name() const =0
Nom du maillage.
virtual Properties * properties()=0
Propriétés associées à ce maillage.
Interface d'un module.
Definition IModule.h:39
Interface d'un observable.
virtual void detachAllObservers()=0
Détache tous les observeurs associés à cette instance.
virtual ITimeStats * timeStats() const =0
Gestionnaire de statistiques associé (peut être nul)
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.
Interface d'une fabrique de variables.
Fonctor d'un filtre applicable sur des variables.
Interface du gestionnaire de synchronisation des variables.
Interface d'une variable.
Definition IVariable.h:54
virtual Real allocatedMemory() const =0
Taille mémoire (en Koctet) utilisée par la variable.
virtual void setUsed(bool v)=0
Positionne l'état d'utilisation de la variable.
virtual String fullName() const =0
Nom complet de la variable (avec le préfixe de la famille)
virtual Integer nbReference() const =0
Nombre de références sur cette variable.
virtual ItemGroup itemGroup() const =0
Groupe du maillage associé.
@ PNoExchange
Indique que la variable ne doit pas être échangée.
Definition IVariable.h:143
@ PTemporary
Indique que la variable est temporaire.
Definition IVariable.h:126
@ PNoRestore
Indique que la variable ne doit pas être restaurée.
Definition IVariable.h:133
@ PNoDump
Indique que la variable ne doit pas être sauvegardée.
Definition IVariable.h:72
Groupe d'entités de maillage.
Definition ItemGroup.h:49
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
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Function each(Function f)
Applique le fonctor f à tous les éléments du tableau.
Definition List.h:303
Flot de sortie lié à une String.
Paramètres nécessaires à la construction d'une variable.
Collection de variables.
Enregistreur d'une fabrique de variables.
Gestion de la lecture pour les variables.
Gestion de l'écriture pour les variables.
void writeVariables(IDataWriter *writer, const VariableCollection &vars, bool use_hash)
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)
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.
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.
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.
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
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.
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:304
TraceMessage pwarning() const
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
Formattage du flot en longueur.
ARCCORE_HOST_DEVICE Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
Definition MathUtils.h:336
-*- 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:151
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é.
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Definition DataTypes.cc:70