Arcane  v4.1.2.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
35 ServiceProperty("JsonMessagePassingProfiling",ST_SubDomain),
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.
Classe de base d'un service.
Interface d'un service de profiling dedie au "message passing".
Service de profiling du "message passing" au format JSON.
Ensemble de données statistiques pour le profiling.
Definition Stat.h:36
Structure contenant les informations pour créer un service.
Propriétés de création d'un service.
Chaîne de caractères unicode.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
void dumpJSON(JSONWriter &writer, const Arccore::MessagePassing::OneStat &os, bool cumulative_stat=true)
Free function pour le dump d'une stat de message dans un JSON.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
@ ST_SubDomain
Le service s'utilise au niveau du sous-domaine.