Arcane  v4.1.7.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ExecutionStatsDumper.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/* ExecutionStatsDumper.cc (C) 2000-2026 */
9/* */
10/* Ecriture des statistiques d'exécution. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/ExecutionStatsDumper.h"
15
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/OStringStream.h"
18#include "arcane/utils/IMemoryInfo.h"
19#include "arcane/utils/Profiling.h"
20#include "arcane/utils/ITraceMng.h"
21#include "arcane/utils/JSONWriter.h"
22#include "arcane/utils/FloatingPointExceptionSentry.h"
23
24#include "arccore/base/internal/ProfilingInternal.h"
25
26#include "arcane/core/ISubDomain.h"
27#include "arcane/core/IVariableMng.h"
28#include "arcane/core/IVariableSynchronizerMng.h"
29#include "arcane/core/IPropertyMng.h"
30#include "arcane/core/ITimeLoopMng.h"
31#include "arcane/core/IMesh.h"
32#include "arcane/core/ITimeStats.h"
33#include "arcane/core/Directory.h"
34#include "arcane/core/IParallelMng.h"
35#include "arcane/core/ServiceBuilder.h"
36#include "arcane/core/ISimpleTableOutput.h"
37
38#include <iostream>
39#include <iomanip>
40#include <fstream>
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45namespace Arcane
46{
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51void ExecutionStatsDumper::
52_dumpProfilingJSON(JSONWriter& json_writer)
53{
54 json_writer.write("Version", "1");
55 auto f = [&](const Impl::ForLoopStatInfoList& stat_list) {
56 JSONWriter::Object jo(json_writer);
57 json_writer.writeKey("Loops");
58 json_writer.beginArray();
59 for (const auto& x : stat_list._internalImpl()->m_stat_map) {
60 JSONWriter::Object jo2(json_writer);
61 const auto& s = x.second;
62 json_writer.write("Name", x.first);
63 json_writer.write("TotalTime", s.execTime());
64 json_writer.write("NbLoop", s.nbCall());
65 json_writer.write("NbChunk", s.nbChunk());
66 }
67 json_writer.endArray();
68 };
69
70 json_writer.writeKey("AllLoops");
71 json_writer.beginArray();
73 json_writer.endArray();
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79void ExecutionStatsDumper::
80_dumpProfilingJSON(const String& filename)
81{
82 JSONWriter json_writer;
83 {
84 JSONWriter::Object jo(json_writer);
85 _dumpProfilingJSON(json_writer);
86 }
87 {
88 ofstream ofile(filename.localstr());
89 ofile << json_writer.getBuffer();
90 }
91}
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96void ExecutionStatsDumper::
97_dumpProfilingTable(ISimpleTableOutput* table)
98{
99 table->init("Profiling");
100
101 table->addColumn("TotalTime");
102 table->addColumn("NbLoop");
103 table->addColumn("NbChunk");
104
105 Integer list_index = 0;
106 auto f = [&](const Impl::ForLoopStatInfoList& stat_list) {
107 for (const auto& x : stat_list._internalImpl()->m_stat_map) {
108 const auto& s = x.second;
109 String row_name = x.first;
110 if (list_index > 0)
111 row_name = String::format("{0}_{1}", x.first, list_index);
112 Integer row = table->addRow(row_name);
113 table->addElementInRow(row, static_cast<Real>(s.execTime()));
114 table->addElementInRow(row, static_cast<Real>(s.nbCall()));
115 table->addElementInRow(row, static_cast<Real>(s.nbChunk()));
116 }
117 ++list_index;
118 };
119
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126void ExecutionStatsDumper::
127_dumpProfiling(std::ostream& o)
128{
129 Impl::dumpProfilingStatistics(o);
130}
131
132/*---------------------------------------------------------------------------*/
133/*---------------------------------------------------------------------------*/
134
135void ExecutionStatsDumper::
136dumpStats(ISubDomain* sd, ITimeStats* time_stat)
137{
138 FloatingPointExceptionSentry fp_sentry(false);
139 {
140 // Statistiques sur la mémoire
141 double mem = platform::getMemoryUsed();
142 info() << "Memory consumption (Mo): " << mem / 1.e6;
143 }
144 if (sd) {
145 {
146 // Affiche les valeurs des propriétés
147 OStringStream postr;
148 postr() << "Properties:\n";
149 sd->propertyMng()->print(postr());
150 plog() << postr.str();
151 }
152 IVariableMng* vm = sd->variableMng();
153 // Affiche les statistiques sur les synchronisations
154 IVariableSynchronizerMng* vsm = vm->synchronizerMng();
155 OStringStream ostr_vsm;
156 vsm->dumpStats(ostr_vsm());
157 info() << ostr_vsm.str();
158 // Affiche les statistiques sur les variables
159 OStringStream ostr_full;
160 vm->dumpStats(ostr_full(), true);
161 OStringStream ostr;
162 vm->dumpStats(ostr(), false);
163 plog() << ostr_full.str();
164 info() << ostr.str();
165 }
166 {
167 // Affiche les statistiques sur les variables
168 IMemoryInfo* mem_info = arcaneGlobalMemoryInfo();
169 OStringStream ostr;
170 mem_info->printInfos(ostr());
171 info() << ostr.str();
172 }
173 // Affiche les statistiques sur les temps d'exécution
174 Integer nb_loop = 1;
175 Integer nb_cell = 1;
176 if (sd) {
177 nb_loop = sd->timeLoopMng()->nbLoop();
178 if (sd->defaultMesh())
179 nb_cell = sd->defaultMesh()->nbCell();
180 }
181 Real n = ((Real)nb_cell);
182 info() << "NB_CELL=" << nb_cell << " nb_loop=" << nb_loop;
183
184 // Informations de profiling des boucles
185 {
186 OStringStream ostr;
187 _dumpProfiling(ostr());
188 String str = ostr.str();
189 if (!str.empty()) {
190 info() << "LoopStatistics:\n"
191 << str;
192 if (sd) {
193 Directory dir = sd->listingDirectory();
194 Int32 rank = sd->parallelMng()->commRank();
195 {
196 String filename = String::format("loop_profiling.{0}.json", rank);
197 String full_filename(dir.file(filename));
198 _dumpProfilingJSON(full_filename);
199 }
200 {
201 ServiceBuilder<ISimpleTableOutput> sb(sd);
202 Ref<ISimpleTableOutput> table(sb.createReference("SimpleCsvOutput"));
203 _dumpProfilingTable(table.get());
204 table->writeFile(0);
205 }
206 }
207 else
208 _dumpProfilingJSON("loop_profiling.json");
209 }
210 }
211 {
212 bool use_elapsed_time = true;
213 if (!platform::getEnvironmentVariable("ARCANE_USE_REAL_TIMER").null())
214 use_elapsed_time = true;
215 if (!platform::getEnvironmentVariable("ARCANE_USE_VIRTUAL_TIMER").null())
216 use_elapsed_time = false;
217 OStringStream ostr_full;
218 time_stat->dumpStats(ostr_full(), true, n, "cell", use_elapsed_time);
219 OStringStream ostr;
220 time_stat->dumpStats(ostr(), false, n, "cell", use_elapsed_time);
221 info() << ostr.str();
222 plog() << ostr_full.str();
223 traceMng()->flush();
224 }
225}
226
227/*---------------------------------------------------------------------------*/
228/*---------------------------------------------------------------------------*/
229
230} // End namespace Arcane
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
Interface représentant une sortie de tableau simple.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Interface gérant les statistiques sur les temps d'exécution.
Definition ITimeStats.h:43
virtual void flush()=0
Flush tous les flots.
static void visitLoopStat(const std::function< void(const Impl::ForLoopStatInfoList &)> &f)
Visite la liste des statistiques des boucles.
Definition Profiling.cc:291
Chaîne de caractères unicode.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage plog() const
Flot pour un message de log.
ITraceMng * traceMng() const
Gestionnaire de trace.
ARCCORE_BASE_EXPORT double getMemoryUsed()
Mémoire utilisée em octets.
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 -*-
Int32 Integer
Type représentant un entier.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.