Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Otf2MessagePassingProfilingService.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/* Otf2MessagePassingProfilingService.cc (C) 2000-2020 */
9/* */
10/* Informations de performances du "message passing" au format Otf2 */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/Otf2MessagePassingProfilingService.h"
15
16#include "arcane/ServiceFactory.h"
17#include "arcane/CommonVariables.h"
18#include "arcane/IMesh.h"
19#include "arcane/IItemFamily.h"
20#include "arcane/IVariableSynchronizer.h"
21#include "arcane/ITimeLoopMng.h"
22#include "arcane/IParallelMng.h"
23#include "arcane/IEntryPoint.h"
24#include "arcane/utils/ITraceMng.h"
25#include "arcane/parallel/IStat.h"
26
27#include "arccore/message_passing/IMessagePassingMng.h"
28#include "arccore/message_passing/IDispatchers.h"
29#include "arccore/message_passing/IControlDispatcher.h"
30
31#include <algorithm>
32#include <string>
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arcane
38{
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
43ARCANE_REGISTER_SERVICE(Otf2MessagePassingProfilingService,
44 ServiceProperty("Otf2MessagePassingProfiling",ST_SubDomain),
45 ARCANE_SERVICE_INTERFACE(IMessagePassingProfilingService));
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
49
50Otf2MessagePassingProfilingService::
51Otf2MessagePassingProfilingService(const ServiceBuildInfo& sbi)
52: AbstractService(sbi)
53, m_sub_domain(sbi.subDomain())
54, m_otf2_wrapper(sbi.subDomain())
55, m_otf2_prof(&m_otf2_wrapper)
56, m_prof_backup(nullptr)
57, m_impl_name("Otf2MessagePassingProfiling")
58{
59}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64Otf2MessagePassingProfilingService::
65~Otf2MessagePassingProfilingService() noexcept
66{
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72void Otf2MessagePassingProfilingService::
73startProfiling()
74{
75 // DBG
76 //info() << "========== OTF2 PROFILING SERVICE ! ==========";
77
78 // On initialise la lib otf2
79 m_otf2_wrapper.init(m_sub_domain->application()->applicationName());
80
81 IMessagePassingMng* mp_mng = m_sub_domain->parallelMng()->messagePassingMng();
82 IControlDispatcher* cd = mp_mng->dispatchers()->controlDispatcher();
83 m_control_dispatcher = cd;
84
85 // On sauvegarde l'ancien service de profiling MPI pour le repositionner
86 m_prof_backup = cd->profiler();
87
88 // On positionne le decorateur OTF2 pour les appels MPI
89 cd->setProfiler(&m_otf2_prof);
90
91 // Lorsqu'on lance le profiling on commence l'observation des evts du timeLoopMng
92 // Evt de debut de point d'entree
93 m_observer.addObserver(this, &Otf2MessagePassingProfilingService::_updateFromBeginEntryPointEvt,
94 m_sub_domain->timeLoopMng()->observable(eTimeLoopEventType::BeginEntryPoint));
95
96 // Evt de fin de point d'entree
97 m_observer.addObserver(this, &Otf2MessagePassingProfilingService::_updateFromEndEntryPointEvt,
98 m_sub_domain->timeLoopMng()->observable(eTimeLoopEventType::EndEntryPoint));
99
100 // C'est la meme fct pour tous les evts de synchronize
101 auto sync_evt_handler = std::function<void(const Arcane::VariableSynchronizerEventArgs&)>(
102 std::bind(&Otf2MessagePassingProfilingService::_updateFromSynchronizeEvt, this, std::placeholders::_1));
103
104 // Evt de synchro sur les variables aux mailles
105 m_sub_domain->defaultMesh()->cellFamily()->allItemsSynchronizer()->onSynchronized().attach(m_observer_pool,
107 // Evt de synchro sur les variables aux noeuds
108 m_sub_domain->defaultMesh()->nodeFamily()->allItemsSynchronizer()->onSynchronized().attach(m_observer_pool,
110 // Evt de synchro sur les variables aux arretes
111 m_sub_domain->defaultMesh()->edgeFamily()->allItemsSynchronizer()->onSynchronized().attach(m_observer_pool,
113 // Evt de synchro sur les variables aux faces
114 m_sub_domain->defaultMesh()->faceFamily()->allItemsSynchronizer()->onSynchronized().attach(m_observer_pool,
116 // TODO: le faire pour les variables materiaux
117
118 // On commence le profiling du programme
119 OTF2_EvtWriter_ProgramBegin(m_otf2_wrapper.getEventWriter(), NULL, Otf2LibWrapper::getTime(),
120 m_otf2_wrapper.getApplicationNameId(), 0, NULL);
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126void Otf2MessagePassingProfilingService::
127stopProfiling()
128{
129 // On enleve le decorateur OTF2 des appels MPI
130 if (m_control_dispatcher)
131 m_control_dispatcher->setProfiler(m_prof_backup);
132
133 // On termine le profiling du programme
134 OTF2_EvtWriter_ProgramEnd(m_otf2_wrapper.getEventWriter(), NULL, Otf2LibWrapper::getTime(), 0);
135 m_otf2_wrapper.finalize();
136
137 // Arret des observations
138 m_observer.detachAll();
139}
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
143void Otf2MessagePassingProfilingService::
144printInfos(std::ostream& output)
145{
146 ARCANE_UNUSED(output);
147 // TODO: fait on qqch ici ?
148}
149
150/*---------------------------------------------------------------------------*/
151/*---------------------------------------------------------------------------*/
152String Otf2MessagePassingProfilingService::
153implName()
154{
155 return m_impl_name;
156}
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
161void Otf2MessagePassingProfilingService::
162_updateFromBeginEntryPointEvt()
163{
164 // Recuperation du nom du pt d'entree
165 const String& ep_name(m_sub_domain->timeLoopMng()->currentEntryPoint()->fullName());
166
167 OTF2_EvtWriter_Enter(m_otf2_wrapper.getEventWriter(), NULL, Otf2LibWrapper::getTime(),
168 m_otf2_wrapper.getEntryPointId(ep_name));
169}
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
173
174void Otf2MessagePassingProfilingService::
175_updateFromEndEntryPointEvt()
176{
177 // Recuperation du nom du pt d'entree
178 const String& ep_name(m_sub_domain->timeLoopMng()->currentEntryPoint()->fullName());
179
180 OTF2_EvtWriter_Leave(m_otf2_wrapper.getEventWriter(), NULL, Otf2LibWrapper::getTime(),
181 m_otf2_wrapper.getEntryPointId(ep_name));
182}
183
184/*---------------------------------------------------------------------------*/
185/*---------------------------------------------------------------------------*/
186
187void Otf2MessagePassingProfilingService::
188_updateFromSynchronizeEvt(const VariableSynchronizerEventArgs& arg)
189{
190 if (arg.state() == VariableSynchronizerEventArgs::State::BeginSynchronize)
191 OTF2_EvtWriter_Enter(m_otf2_wrapper.getEventWriter(), NULL, Otf2LibWrapper::getTime(),
192 m_otf2_wrapper.getSynchronizeId());
193 else
194 OTF2_EvtWriter_Leave(m_otf2_wrapper.getEventWriter(), NULL, Otf2LibWrapper::getTime(),
195 m_otf2_wrapper.getSynchronizeId());
196}
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201} // namespace Arcane
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Manage control streams for parallel messages.
Interface du gestionnaire des échanges de messages.
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.