Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
JsonMessagePassingProfilingService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* JsonMessagePassingProfilingService.cc (C) 2000-2022 */
9/* */
10/* Informations de performances du "message passing" au format JSON */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/JsonMessagePassingProfilingService.h"
15#include <algorithm>
16#include <string>
17#include "arcane/ServiceFactory.h"
18#include "arcane/CommonVariables.h"
19#include "arcane/ITimeLoopMng.h"
20#include "arcane/IParallelMng.h"
21#include "arcane/IEntryPoint.h"
22#include "arcane/parallel/IStat.h"
23#include "arcane/utils/JSONWriter.h"
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28namespace Arcane
29{
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34ARCANE_REGISTER_SERVICE(JsonMessagePassingProfilingService,
35 ServiceProperty("JsonMessagePassingProfiling",ST_SubDomain),
36 ARCANE_SERVICE_INTERFACE(IMessagePassingProfilingService));
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41JsonMessagePassingProfilingService::
42JsonMessagePassingProfilingService(const ServiceBuildInfo& sbi)
43: AbstractService(sbi)
44, m_sub_domain(sbi.subDomain())
45, m_json_writer(nullptr)
46, m_impl_name("JsonMessagePassingProfiling")
47{
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53JsonMessagePassingProfilingService::
54~JsonMessagePassingProfilingService()
55{
56 if (m_json_writer)
57 delete m_json_writer;
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63void JsonMessagePassingProfilingService::
64startProfiling()
65{
66 // creation du json writer
67 if (!m_json_writer) {
68 m_json_writer = new JSONWriter(JSONWriter::FormatFlags::None);
69 m_json_writer->beginObject();
70 }
71
72 // Lorsqu'on lance le profiling on commence l'observation des evts du timeLoopMng
73 m_observer.addObserver(this, &JsonMessagePassingProfilingService::_updateFromBeginEntryPointEvt,
74 m_sub_domain->timeLoopMng()->observable(eTimeLoopEventType::BeginEntryPoint));
75 m_observer.addObserver(this, &JsonMessagePassingProfilingService::_updateFromEndEntryPointEvt,
76 m_sub_domain->timeLoopMng()->observable(eTimeLoopEventType::EndEntryPoint));
77 m_observer.addObserver(this, &JsonMessagePassingProfilingService::_updateFromBeginIterationEvt,
78 m_sub_domain->timeLoopMng()->observable(eTimeLoopEventType::BeginIteration));
79 m_observer.addObserver(this, &JsonMessagePassingProfilingService::_updateFromEndIterationEvt,
80 m_sub_domain->timeLoopMng()->observable(eTimeLoopEventType::EndIteration));
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86void JsonMessagePassingProfilingService::
87stopProfiling()
88{
89 // Arret des observations
90 m_observer.detachAll();
91 // On flush les infos
92 if (m_json_writer){
93 _dumpCurrentIterationInJSON();
94 m_json_writer->endObject();
95 }
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100void JsonMessagePassingProfilingService::
101printInfos(std::ostream& output)
102{
103 output << m_json_writer->getBuffer();
104}
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108String JsonMessagePassingProfilingService::
109implName()
110{
111 return m_impl_name;
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
117void JsonMessagePassingProfilingService::
118_dumpCurrentIterationInJSON()
119{
120 if (m_ep_mpstat_col.empty())
121 return;
122
123 // Numero d'iteration (decale d'un car le compteur s'incremente avant la notification)
124 JSONWriter::Object obj_it(*m_json_writer,
125 String::fromNumber(m_sub_domain->commonVariables().globalIteration() - 1));
126 // Par point d'entree
127 for (const auto &ep_mpstat : m_ep_mpstat_col) {
128 // Alias sur les stats de msg passing pour ce pt d'entree
129 const auto& stats_(ep_mpstat.second.stats());
130 // On ecrit le pt d'entree que s'il existe une stat de msg passing non nulle
131 if (std::any_of(stats_.cbegin(), stats_.cend(), [&](const Arccore::MessagePassing::OneStat& os)
132 {return static_cast<bool>(os.nbMessage());})) {
133 // Nom du point d'entree
134 JSONWriter::Object obj_ep(*m_json_writer, ep_mpstat.first);
135 // Par stat msg passing
136 for (const auto &mpstat : stats_) {
137 // Stats message passing s'il y en a
138 if (mpstat.nbMessage())
139 Parallel::dumpJSON(*m_json_writer, mpstat, false);
140 }
141 }
142 }
143}
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
148void JsonMessagePassingProfilingService::
149_updateFromBeginEntryPointEvt()
150{
151 // On arrive dans le pt d'entree, on s'assure que les stats sont remises a zero
152 m_sub_domain->parallelMng()->stat()->toArccoreStat()->resetCurrentStat();
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
158void JsonMessagePassingProfilingService::
159_updateFromEndEntryPointEvt()
160{
161 // On recupere le nom du pt d'entree
162 const String& ep_name(m_sub_domain->timeLoopMng()->currentEntryPoint()->name());
163 auto pos(m_ep_mpstat_col.find(ep_name));
164 // S'il n'y a pas encore de stats pour ce pt d'entree, on les crees
165 Arccore::MessagePassing::StatData stat_data(m_sub_domain->parallelMng()->stat()->toArccoreStat()->stats());
166 if (pos == m_ep_mpstat_col.end())
167 m_ep_mpstat_col.emplace(ep_name, stat_data);
168 else // sinon, on merge les stats
169 pos->second.mergeAllData(stat_data);
170}
171
172/*---------------------------------------------------------------------------*/
173/*---------------------------------------------------------------------------*/
174
175void JsonMessagePassingProfilingService::
176_updateFromBeginIterationEvt()
177{
178 // On commence avec une structure vide, puisqu'elle est dumpee a chq fin d'iteration
179 m_ep_mpstat_col.clear();
180}
181
182/*---------------------------------------------------------------------------*/
183/*---------------------------------------------------------------------------*/
184
185void JsonMessagePassingProfilingService::
186_updateFromEndIterationEvt()
187{
188 // On dump tout ce qu'on a enregistre pour cette iteration
189 if (m_json_writer)
190 _dumpCurrentIterationInJSON();
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
196} // End namespace Arcane
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Ecrivain au format JSON.
Definition JSONWriter.h:33
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Ensemble de données statistiques pour le profiling.
Definition Stat.h:36
Chaîne de caractères unicode.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
@ ST_SubDomain
Le service s'utilise au niveau du sous-domaine.