Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
SharedMemoryParallelSuperMng.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/* SharedMemoryParallelSuperMng.cc (C) 2000-2024 */
9/* */
10/* Gestionnaire de messages utilisant uniquement la mémoire partagée. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/parallel/thread/SharedMemoryParallelSuperMng.h"
15
16#include "arcane/utils/ApplicationInfo.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/NotImplementedException.h"
19#include "arcane/utils/FatalErrorException.h"
20#include "arcane/utils/ArgumentException.h"
21#include "arcane/utils/ValueConvert.h"
22#include "arcane/utils/IThreadMng.h"
23#include "arcane/utils/TraceClassConfig.h"
24#include "arcane/utils/ITraceMng.h"
25#include "arcane/utils/IThreadImplementation.h"
26#include "arcane/utils/Mutex.h"
27
28#include "arcane/parallel/IStat.h"
29
30#include "arcane/parallel/thread/SharedMemoryParallelMng.h"
31#include "arcane/parallel/thread/SharedMemoryParallelDispatch.h"
32#include "arcane/parallel/thread/SharedMemoryMessageQueue.h"
33#include "arcane/parallel/thread/internal/SharedMemoryThreadMng.h"
34
35#include "arcane/core/FactoryService.h"
36#include "arcane/core/IApplication.h"
37#include "arcane/core/ParallelSuperMngDispatcher.h"
38#include "arcane/core/ApplicationBuildInfo.h"
39#include "arcane/core/AbstractService.h"
40#include "arcane/core/ServiceBuilder.h"
41
42#include "arcane/core/IMainFactory.h"
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
48{
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
55class SharedMemoryParallelMngContainer
57{
58 public:
59 SharedMemoryParallelMngContainer(IApplication* app,Int32 nb_local_rank,
60 MP::Communicator mpi_comm,
62 ~SharedMemoryParallelMngContainer() override;
63
64 public:
65
66 void build();
67 Ref<IParallelMng> _createParallelMng(Int32 local_rank,ITraceMng* tm) override;
68
69 public:
70
72 Int32 m_nb_local_rank;
73 SharedMemoryThreadMng* m_thread_mng;
74 ISharedMemoryMessageQueue* m_message_queue = nullptr;
75 Mutex* m_internal_create_mutex = nullptr;
76 IThreadBarrier* m_thread_barrier = nullptr;
77 SharedMemoryAllDispatcher* m_all_dispatchers = nullptr;
78 IParallelMngContainerFactory* m_sub_factory_builder = nullptr;
79
80 private:
81
82 MP::Communicator m_communicator;
83};
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88SharedMemoryParallelMngContainer::
89SharedMemoryParallelMngContainer(IApplication* app,Int32 nb_local_rank,
90 MP::Communicator mpi_comm,
92: m_application(app), m_nb_local_rank(nb_local_rank)
93, m_thread_mng(new SharedMemoryThreadMng())
94, m_sub_factory_builder(factory)
95, m_communicator(mpi_comm)
96{
97}
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
102SharedMemoryParallelMngContainer::
103~SharedMemoryParallelMngContainer()
104{
105 if (m_thread_barrier)
106 m_thread_barrier->destroy();
107 delete m_message_queue;
108 delete m_thread_mng;
109 delete m_all_dispatchers;
110 delete m_internal_create_mutex;
111}
112
113/*---------------------------------------------------------------------------*/
114/*---------------------------------------------------------------------------*/
115
116void SharedMemoryParallelMngContainer::
117build()
118{
119 m_message_queue = new SharedMemoryMessageQueue();
120 m_message_queue->init(m_nb_local_rank);
121
122 m_thread_barrier = platform::getThreadImplementationService()->createBarrier();
123 m_thread_barrier->init(m_nb_local_rank);
124
125 m_all_dispatchers = new SharedMemoryAllDispatcher();
126 m_all_dispatchers->resize(m_nb_local_rank);
127
128 m_internal_create_mutex = new Mutex();
129}
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
133
135_createParallelMng(Int32 local_rank,ITraceMng* tm)
136{
137 if (local_rank<0 || local_rank>=m_nb_local_rank)
138 ARCANE_THROW(ArgumentException,"Bad value '{0}' for local_rank (max={1})",
139 local_rank,m_nb_local_rank);
140
141 // Cette méthode n'est pas réentrante.
142 Mutex::ScopedLock sl(m_internal_create_mutex);
143
144 IParallelSuperMng* sm = m_application->sequentialParallelSuperMng();
146 build_info.rank = local_rank;
147 build_info.nb_rank = m_nb_local_rank;
148 build_info.trace_mng = tm;
149 build_info.thread_mng = m_thread_mng;
150 build_info.sequential_parallel_mng = sm->internalCreateWorldParallelMng(0);
151 build_info.world_parallel_mng = nullptr;
152 build_info.message_queue = m_message_queue;
153 build_info.thread_barrier = m_thread_barrier;
154 build_info.all_dispatchers = m_all_dispatchers;
155 build_info.sub_builder_factory = m_sub_factory_builder;
156 build_info.container = makeRef<IParallelMngContainer>(this);
157 // Seul le rang 0 positionne l'éventuel communicateur sinon tous les PE
158 // vont se retrouver avec le même rang MPI
159 if (local_rank==0)
160 build_info.communicator = m_communicator;
161
162 IParallelMng* pm = new SharedMemoryParallelMng(build_info);
163 pm->build();
164
165 return makeRef(pm);
166}
167
168/*---------------------------------------------------------------------------*/
169/*---------------------------------------------------------------------------*/
170
171class SharedMemoryParallelMngContainerFactory
172: public AbstractService
174{
175 public:
176 SharedMemoryParallelMngContainerFactory(const ServiceBuildInfo& sbi)
177 : AbstractService(sbi), m_application(sbi.application()){}
178 public:
179 Ref<IParallelMngContainer> _createParallelMngBuilder(Int32 nb_rank,MP::Communicator comm) override
180 {
181 auto x = new SharedMemoryParallelMngContainer(m_application,nb_rank,comm,this);
182 x->build();
184 }
185 private:
186 IApplication* m_application;
187};
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
193 ServiceProperty("SharedMemoryParallelMngContainerFactory",ST_Application),
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198
199SharedMemoryParallelSuperMng::
200SharedMemoryParallelSuperMng(const ServiceBuildInfo& sbi)
202{
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208SharedMemoryParallelSuperMng::
209SharedMemoryParallelSuperMng(const ServiceBuildInfo& sbi,MP::Communicator comm,
210 bool has_mpi_init)
211: m_application(sbi.application())
212, m_stat(nullptr)
213, m_is_parallel(false)
214, m_communicator(comm)
215{
217 m_has_mpi_init = has_mpi_init;
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
223SharedMemoryParallelSuperMng::
224~SharedMemoryParallelSuperMng()
225{
226 delete m_stat;
227}
228
229/*---------------------------------------------------------------------------*/
230/*---------------------------------------------------------------------------*/
231
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
241build()
242{
243 if (!arcaneHasThread())
244 ARCANE_FATAL("Can not create SharedMemoryParallelSuperMng because threads are disabled");
245
246 // Si on a été initialisé avec MPI, alors les requêtes nulles et le communicateur
247 // nul ont déjà été positionnés.
248 if (!m_has_mpi_init){
249 Request::setNullRequest(Request(0,nullptr,0));
250 Parallel::Communicator::setNullCommunicator(Parallel::Communicator((void*)nullptr));
251 }
252
253 m_is_parallel = true;
254 Int32 n = m_application->applicationBuildInfo().nbSharedMemorySubDomain();
255 if (n==0)
256 ARCANE_FATAL("Number of shared memory sub-domains is not defined");
257
258 ITraceMng* app_tm = m_application->traceMng();
259 app_tm->info() << "SharedMemoryParallelSuperMng: nb_local_sub_domain=" << n;
260 app_tm->info() << "SharedMemoryParallelSuperMng: mpi_communicator=" << getMPICommunicator();
262 String service_name = "SharedMemoryParallelMngContainerFactory";
263 m_builder_factory = sb.createReference(service_name);
264 Ref<IParallelMngContainer> x = m_builder_factory->_createParallelMngBuilder(n,communicator());
265 m_main_builder = x;
266 m_container = dynamic_cast<SharedMemoryParallelMngContainer*>(x.get());
267 ARCANE_CHECK_POINTER(m_container);
268}
269
270/*---------------------------------------------------------------------------*/
271/*---------------------------------------------------------------------------*/
272
275{
276 Int32 max_rank = nbLocalSubDomain();
277 if (local_rank<0 || local_rank>=max_rank)
278 ARCANE_THROW(ArgumentException,"Bad value '{0}' for local_rank (max={1})",
279 local_rank,max_rank);
280
281 ITraceMng* tm = nullptr;
282 ITraceMng* app_tm = m_application->traceMng();
283 if (local_rank==0){
284 // Le premier sous-domaine créé utilise le traceMng() par défaut.
285 tm = app_tm;
286 }
287 else{
288 tm = m_application->createAndInitializeTraceMng(app_tm,String::fromNumber(local_rank));
289 }
290
291 Ref<IParallelMng> pm = m_container->_createParallelMng(local_rank,tm);
292 return pm;
293}
294
295/*---------------------------------------------------------------------------*/
296/*---------------------------------------------------------------------------*/
297
299tryAbort()
300{
301 m_application->traceMng()->flush();
302 ::abort();
303}
304
305/*---------------------------------------------------------------------------*/
306/*---------------------------------------------------------------------------*/
307
309broadcast(ByteArrayView send_buf,Int32 process_id)
310{
311 ARCANE_UNUSED(send_buf);
312 ARCANE_UNUSED(process_id);
313}
314
315/*---------------------------------------------------------------------------*/
316/*---------------------------------------------------------------------------*/
317
319broadcast(Int32ArrayView send_buf,Int32 process_id)
320{
321 ARCANE_UNUSED(send_buf);
322 ARCANE_UNUSED(process_id);
323}
324
325/*---------------------------------------------------------------------------*/
326/*---------------------------------------------------------------------------*/
327
329broadcast(Int64ArrayView send_buf,Int32 process_id)
330{
331 ARCANE_UNUSED(send_buf);
332 ARCANE_UNUSED(process_id);
333}
334
335/*---------------------------------------------------------------------------*/
336/*---------------------------------------------------------------------------*/
337
339broadcast(RealArrayView send_buf,Int32 process_id)
340{
341 ARCANE_UNUSED(send_buf);
342 ARCANE_UNUSED(process_id);
343}
344
345/*---------------------------------------------------------------------------*/
346/*---------------------------------------------------------------------------*/
347
349threadMng() const
350{
351 return m_container->m_thread_mng;
352}
353
354/*---------------------------------------------------------------------------*/
355/*---------------------------------------------------------------------------*/
356
359{
360 return m_container->m_nb_local_rank;
361}
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
367 ServiceProperty("SharedMemoryParallelSuperMng",ST_Application),
369
370// Ancien nom
372 ServiceProperty("ThreadParallelSuperMng",ST_Application),
374
375/*---------------------------------------------------------------------------*/
376/*---------------------------------------------------------------------------*/
377
378} // End namespace Arcane::MessagePassing
379
380/*---------------------------------------------------------------------------*/
381/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
AbstractService(const ServiceBuildInfo &)
Constructeur à partir d'un ServiceBuildInfo.
Exception lorsqu'un argument est invalide.
Interface de l'application.
Interface d'une fabrique de conteneur de 'IParallelMng'.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual void build()=0
Construit l'instance.
Classe abstraite du superviseur de parallélisme.
virtual Ref< IParallelMng > internalCreateWorldParallelMng(Int32 local_rank)=0
Créé un gestionnaire de parallélisme pour l'ensemble des coeurs alloués.
virtual void destroy()=0
Détruit la barrière.
virtual void init(Integer nb_thread)=0
Initialise la barrière pour nb_thread.
Interface d'un gestionnaire de thread.
Definition IThreadMng.h:30
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
Communicateur pour l'échange de message.
Interface d'une file de messages avec les threads.
Conteneur des informations du gestionnaire de message en mémoire partagée.
Ref< IParallelMng > _createParallelMng(Int32 local_rank, ITraceMng *tm) override
Créé le IParallelMng pour le rang local local_rank.
Gestionnaire du parallélisme utilisant les threads.
Superviseur du parallélisme utilisant les threads.
Ref< IParallelMng > internalCreateWorldParallelMng(Int32 local_rank) override
Créé un gestionnaire de parallélisme pour l'ensemble des coeurs alloués.
void build() override
Construit les membres l'instance.
void broadcast(ByteArrayView send_buf, Int32 rank) override
Envoie un tableau de valeurs sur tous les processus Cette opération synchronise le tableau de valeur ...
void * getMPICommunicator() override
Adresse du communicateur MPI associé à ce gestionnaire.
Parallel::Communicator communicator() const override
Communicateur MPI associé à ce gestionnaire.
Int32 nbLocalSubDomain() override
Nombre de sous-domaines à créér localement.
IThreadMng * threadMng() const override
Gestionnaire de thread.
Référence à une instance.
InstanceType * get() const
Instance associée ou nullptr si aucune.
IApplication * application() const
Accès à l'application IApplication associé.
Structure contenant les informations pour créer un service.
Classe utilitaire pour instantier un service d'une interface donnée.
Ref< InterfaceType > createReference(const String &name, eServiceBuilderProperties properties=SB_None)
Créé une instance implémentant l'interface InterfaceType.
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.
Déclarations des types et méthodes utilisés par les mécanismes d'échange de messages.
Definition Parallel.h:50
IStat * createDefaultStat()
Créé une instance par défaut.
IThreadImplementation * getThreadImplementationService()
Service utilisé pour gérer les threads.
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:538
bool arcaneHasThread()
Vrai si arcane est compilé avec le support des threads ET qu'ils sont actifs.
Definition Misc.cc:99
ArrayView< Byte > ByteArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:534
@ ST_Application
Le service s'utilise au niveau de l'application.
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:540
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
ArrayView< Real > RealArrayView
Equivalent C d'un tableau à une dimension de réels.
Definition UtilsTypes.h:546
std::int32_t Int32
Type entier signé sur 32 bits.
Infos pour construire un SharedMemoryParallelMng.