Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
HybridParallelSuperMng.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/* HybridParallelSuperMng.cc (C) 2000-2026 */
9/* */
10/* Parallelism manager using MPI and shared memory. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ApplicationInfo.h"
15#include "arcane/utils/NullThreadMng.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/PlatformUtils.h"
19#include "arcane/utils/ValueConvert.h"
20#include "arcane/utils/TraceClassConfig.h"
21#include "arcane/utils/ArgumentException.h"
22#include "arcane/utils/CommandLineArguments.h"
23
24#include "arcane/parallel/IStat.h"
25
26#include "arcane/parallel/mpi/MpiParallelMng.h"
27#include "arcane/parallel/mpi/MpiParallelDispatch.h"
28#include "arcane/parallel/mpi/MpiErrorHandler.h"
29
30#include "arccore/message_passing_mpi/internal/MpiAdapter.h"
31#include "arccore/message_passing_mpi/internal/MpiLock.h"
32
33#include "arcane/parallel/thread/SharedMemoryMessageQueue.h"
34#include "arcane/parallel/thread/SharedMemoryParallelMng.h"
35#include "arcane/parallel/thread/SharedMemoryParallelSuperMng.h"
36#include "arcane/parallel/thread/internal/SharedMemoryThreadMng.h"
37
38#include "arcane/parallel/mpithread/HybridParallelMng.h"
39#include "arcane/parallel/mpithread/HybridParallelDispatch.h"
40#include "arcane/parallel/mpithread/internal/HybridMachineShMemWinBaseInternalCreator.h"
41
42#include "arcane/core/FactoryService.h"
43#include "arcane/core/AbstractService.h"
44#include "arcane/core/IApplication.h"
45#include "arcane/core/ParallelSuperMngDispatcher.h"
46#include "arcane/core/ApplicationBuildInfo.h"
47#include "arcane/core/ServiceBuilder.h"
48
49#include "arcane/core/IMainFactory.h"
50
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
57{
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
65class HybridParallelMngContainer
67{
68 public:
69
70 HybridParallelMngContainer(IApplication* app, Int32 nb_local_rank,
71 MP::Communicator mpi_comm, MP::Communicator mpi_machine_comm,
73 Parallel::IStat* stat, MpiLock* mpi_lock);
74 ~HybridParallelMngContainer() override;
75
76 public:
77
78 void build();
79 Ref<IParallelMng> _createParallelMng(Int32 local_rank, ITraceMng* tm) override;
80
81 public:
82
84 Parallel::IStat* m_stat = nullptr;
86 MpiLock* m_mpi_lock = nullptr;
87 ISharedMemoryMessageQueue* m_message_queue = nullptr;
88 IThreadBarrier* m_thread_barrier = nullptr;
89 Int32 m_local_nb_rank = -1;
90 MpiThreadAllDispatcher* m_all_dispatchers = nullptr;
91 // This object is shared by all HybridParallelMngs.
92 UniqueArray<HybridParallelMng*>* m_parallel_mng_list = nullptr;
93 Mutex* m_internal_create_mutex = nullptr;
94 IParallelMngContainerFactory* m_sub_builder_factory = nullptr;
95 HybridMachineShMemWinBaseInternalCreator* m_window_creator = nullptr;
96
97 private:
98
103
104 private:
105
106 void _setMPICommunicator();
107};
108
109/*---------------------------------------------------------------------------*/
110/*---------------------------------------------------------------------------*/
111
112HybridParallelMngContainer::
113HybridParallelMngContainer(IApplication* app, Int32 nb_local_rank,
114 MP::Communicator mpi_comm, MP::Communicator mpi_machine_comm,
116 Parallel::IStat* stat, MpiLock* mpi_lock)
117: m_application(app)
118, m_stat(stat)
119, m_thread_mng(new SharedMemoryThreadMng())
120, m_mpi_lock(mpi_lock)
121, m_local_nb_rank(nb_local_rank)
122, m_parallel_mng_list(new UniqueArray<HybridParallelMng*>())
123, m_sub_builder_factory(factory)
124, m_mpi_communicator(mpi_comm)
125, m_mpi_machine_communicator(mpi_machine_comm)
126{
127 _setMPICommunicator();
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
133HybridParallelMngContainer::
134~HybridParallelMngContainer()
135{
136 // TODO: check if the communicator needs to be destroyed
137 m_thread_barrier->destroy();
138 delete m_message_queue;
139 delete m_thread_mng;
140 delete m_all_dispatchers;
141 delete m_parallel_mng_list;
142 delete m_internal_create_mutex;
143 delete m_window_creator;
144}
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
149void HybridParallelMngContainer::
150build()
151{
152 m_internal_create_mutex = new Mutex();
153
154 m_all_dispatchers = new MpiThreadAllDispatcher();
155 m_all_dispatchers->resize(m_local_nb_rank);
156
157 m_parallel_mng_list->resize(m_local_nb_rank);
158 m_parallel_mng_list->fill(nullptr);
159
160 m_message_queue = new SharedMemoryMessageQueue();
161 m_message_queue->init(m_local_nb_rank);
162
163 m_thread_barrier = platform::getThreadImplementationService()->createBarrier();
164 m_thread_barrier->init(m_local_nb_rank);
165
166 m_window_creator = new HybridMachineShMemWinBaseInternalCreator(m_local_nb_rank, m_thread_barrier);
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
172void HybridParallelMngContainer::
173_setMPICommunicator()
174{
175 MPI_Comm comm = static_cast<MPI_Comm>(m_mpi_communicator);
176
177 if (comm == MPI_COMM_NULL)
178 ARCANE_THROW(ArgumentException, "Null MPI Communicator");
179 m_mpi_communicator = comm;
180
181 int rank = 0;
182 MPI_Comm_rank(m_mpi_communicator, &rank);
183 int size = 0;
184 MPI_Comm_size(m_mpi_communicator, &size);
185
186 m_mpi_comm_rank = rank;
187 m_mpi_comm_size = size;
188}
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
194_createParallelMng(Int32 local_rank, ITraceMng* tm)
195{
196 if (local_rank < 0 || local_rank >= m_local_nb_rank)
197 ARCANE_THROW(ArgumentException, "Bad value '{0}' for local_rank (max={1})",
198 local_rank, m_local_nb_rank);
199
200 // This method is not reentrant.
201 Mutex::ScopedLock sl(m_internal_create_mutex);
202
203 Int32 nb_process = m_mpi_comm_size;
204 bool is_parallel = nb_process > 1;
205
206 // The communicator passed as an argument remains our property.
208 bi.is_parallel = is_parallel;
209 bi.stat = m_stat;
210 bi.trace_mng = tm;
211 bi.thread_mng = m_thread_mng;
212 bi.is_mpi_comm_owned = false;
213 bi.mpi_lock = m_mpi_lock;
214
215 if (m_mpi_lock)
216 tm->info() << "MPI implementation need serialized threads : using locks";
217
218 MpiParallelMng* mpi_pm = new MpiParallelMng(bi);
219
220 mpi_pm->build();
221 mpi_pm->initialize();
222 mpi_pm->adapter()->enableDebugRequest(false);
223
225 build_info.local_rank = local_rank;
226 build_info.local_nb_rank = m_local_nb_rank;
227 build_info.mpi_parallel_mng = mpi_pm;
228 build_info.trace_mng = tm;
229 build_info.thread_mng = m_thread_mng;
230 build_info.message_queue = m_message_queue;
231 build_info.thread_barrier = m_thread_barrier;
232 build_info.parallel_mng_list = m_parallel_mng_list;
233 build_info.all_dispatchers = m_all_dispatchers;
234 build_info.sub_builder_factory = m_sub_builder_factory;
235 build_info.container = makeRef<IParallelMngContainer>(this);
236 build_info.window_creator = m_window_creator;
237
238 // NOTE: This instance will be destroyed by the caller of this method
239 HybridParallelMng* pm = new HybridParallelMng(build_info);
240 pm->build();
241 (*m_parallel_mng_list)[local_rank] = pm;
242
243 return makeRef<IParallelMng>(pm);
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
252class HybridParallelMngContainerFactory
253: public AbstractService
255{
256 public:
257
258 HybridParallelMngContainerFactory(const ServiceBuildInfo& sbi)
259 : AbstractService(sbi)
260 , m_application(sbi.application())
261 {}
262
263 public:
264
266 _createParallelMngBuilder(Int32 nb_rank, MP::Communicator mpi_communicator,
267 MP::Communicator mpi_machine_communicator) override
268 {
269 auto x = new HybridParallelMngContainer(m_application, nb_rank, mpi_communicator,
270 mpi_machine_communicator,
271 this, m_stat, m_mpi_lock);
272 x->build();
274 }
275
276 private:
277
278 IApplication* m_application;
279
280 public:
281
282 MpiLock* m_mpi_lock = nullptr;
283 Parallel::IStat* m_stat = nullptr;
284};
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
288
290 ServiceProperty("HybridParallelMngContainerFactory", ST_Application),
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
298
302class HybridParallelSuperMng
303: public ParallelSuperMngDispatcher
304{
305 public:
306
307 explicit HybridParallelSuperMng(const ServiceBuildInfo& sbi);
308 ~HybridParallelSuperMng() override;
309
310 void initialize() override;
311 void build() override;
312
313 IApplication* application() const override { return m_application; }
314 IThreadMng* threadMng() const override { return m_container->m_thread_mng; }
315 bool isParallel() const override { return true; }
316 Int32 commRank() const override { return m_mpi_comm_rank; }
317 Int32 commSize() const override { return m_mpi_comm_size; }
318 Int32 traceRank() const override { return m_mpi_comm_rank * m_container->m_local_nb_rank; }
319 void* getMPICommunicator() override { return &m_mpi_communicator; }
320 MP::Communicator communicator() const override { return m_communicator; }
322 void tryAbort() override;
323 bool isMasterIO() const override { return commRank() == 0; }
324 Integer masterIORank() const override { return 0; }
325 Integer nbLocalSubDomain() override { return m_container->m_local_nb_rank; }
326 void barrier() override;
327
328 public:
329
330 HybridParallelMngContainer* m_container = nullptr;
331 Ref<IParallelMngContainerFactory> m_builder_factory;
332 Ref<IParallelMngContainer> m_main_builder;
333
335 Parallel::IStat* m_stat;
338 MPI_Comm m_mpi_communicator;
339 MP::Communicator m_communicator;
340 MP::Communicator m_machine_communicator;
341 Int32 m_local_nb_rank = A_NULL_RANK;
342 MpiLock* m_mpi_lock;
343 MpiAdapter* m_mpi_adapter;
344 MpiDatatypeList* m_datatype_list;
345 MpiErrorHandler m_error_handler;
346};
347
348/*---------------------------------------------------------------------------*/
349/*---------------------------------------------------------------------------*/
350
351HybridParallelSuperMng::
352HybridParallelSuperMng(const ServiceBuildInfo& sbi)
353: m_application(sbi.application())
354, m_stat(nullptr)
355, m_mpi_comm_size(0)
356, m_mpi_communicator(MPI_COMM_NULL)
357, m_local_nb_rank(A_NULL_RANK)
358, m_mpi_lock(nullptr)
359, m_mpi_adapter(nullptr)
360, m_datatype_list(nullptr)
361{
363}
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
368HybridParallelSuperMng::
369~HybridParallelSuperMng()
370{
371 m_error_handler.removeHandler();
372 _finalize();
373 delete m_datatype_list;
374 if (m_mpi_adapter)
375 arcaneCallFunctionAndTerminateIfThrow([&]() { m_mpi_adapter->destroy(); });
376 delete m_mpi_lock;
377 delete m_stat;
378 MPI_Barrier(m_mpi_communicator);
379 MPI_Comm_free(&m_mpi_communicator);
380 m_mpi_communicator = MPI_COMM_NULL;
381 MPI_Comm_free(static_cast<MPI_Comm*>(m_machine_communicator.communicatorAddress()));
383}
384
385/*---------------------------------------------------------------------------*/
386/*---------------------------------------------------------------------------*/
387
392
393/*---------------------------------------------------------------------------*/
394/*---------------------------------------------------------------------------*/
395
397build()
398{
399 if (!arcaneHasThread())
400 ARCANE_FATAL("Can not create HybridParallelSuperMng because threads are disabled");
401
402 Request::setNullRequest(Request(0, nullptr, MPI_REQUEST_NULL));
403 Communicator::setNullCommunicator(Communicator(MPI_COMM_NULL));
404
405 int rank, size;
406 int* argc = nullptr;
407 char*** argv = nullptr;
408
409 const ApplicationInfo& app_info = m_application->applicationInfo();
410 const CommandLineArguments& cmd_line_args = app_info.commandLineArguments();
411 argc = cmd_line_args.commandLineArgc();
412 argv = cmd_line_args.commandLineArgv();
413
414 bool need_serialize = false;
415
416 // Try with MPI_THREAD_MULTIPLE
417 // which allows calling MPI from multiple threads simultaneously
418 // If this level is not available, at least the
419 // MPI_THREAD_SERIALIZED level is required, which allows calling MPI from multiple
420 // threads but only one at a time. Therefore, in this case, locks
421 // must be used around MPI calls. In our case, locks
422 // are only used for point-to-point communications because
423 // for collective operations, only one thread performs them
424 // at a time.
425 int thread_wanted = MPI_THREAD_MULTIPLE;
426 int thread_provided = 0;
427
428 Real start_time = platform::getRealTime();
429 arcaneInitializeMPI(argc, argv, thread_wanted);
430 Real end_time = platform::getRealTime();
431 MPI_Query_thread(&thread_provided);
432
433 if (thread_provided < MPI_THREAD_MULTIPLE) {
434 if (thread_provided >= MPI_THREAD_SERIALIZED)
435 need_serialize = true;
436 else {
437 // The required thread level is not available.
438 // Launch a fatal error but only on a single processor.
439 int my_rank = 0;
440 MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
441 if (my_rank != 0)
442 ARCANE_FATAL("MPI thread level provided!=wanted ({0}!={1})",
443 thread_provided, thread_wanted);
444 }
445 }
446
447 // Uncomment to force the use of locks for testing.
448 // need_serialize = true;
449
450 if (need_serialize)
451 m_mpi_lock = new MpiLock();
452
453 MPI_Comm_dup(MPI_COMM_WORLD, &m_mpi_communicator);
454 m_communicator = Communicator(m_mpi_communicator);
455 MPI_Comm_rank(m_mpi_communicator, &rank);
456 MPI_Comm_size(m_mpi_communicator, &size);
457
458 m_mpi_comm_rank = rank;
459 m_mpi_comm_size = size;
460
461 MPI_Comm mpi_machine_communicator = MPI_COMM_NULL;
462 MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, m_mpi_comm_rank, MPI_INFO_NULL, &mpi_machine_communicator);
463 m_machine_communicator = Communicator(mpi_machine_communicator);
464
466
467 m_error_handler.registerHandler(m_mpi_communicator);
468
469 Integer n = app->applicationBuildInfo().nbSharedMemorySubDomain();
470 if (n == 0)
471 ARCANE_FATAL("Number of shared memory sub-domains is not defined");
472 m_local_nb_rank = n;
473
474 if (rank == 0) {
475 ITraceMng* tm = app->traceMng();
476 tm->info() << "MPI has non blocking collective";
477 tm->info() << "MPI: sizeof(MPI_Count)=" << sizeof(MPI_Count);
478 tm->info() << "MPI: is Cuda Aware?=" << arcaneIsCudaAwareMPI();
479 tm->info() << "MPI: init_time (seconds)=" << (end_time - start_time);
480 }
481
482 /*cout << "ThreadSuperParallelMng: nb_sub_domain=" << m_local_nb_rank
483 << " env=" << s
484 << " mpi_rank=" << m_mpi_comm_rank << "/" << m_mpi_comm_size
485 << " first_rank=" << m_current_rank << '\n';*/
486
487 ITraceMng* tm = app->traceMng();
488 m_datatype_list = new MpiDatatypeList(false);
489 auto* adapter = new MpiAdapter(tm, m_stat->toArccoreStat(), m_communicator, nullptr);
490 m_mpi_adapter = adapter;
491 auto c = createBuiltInDispatcher<Byte>(tm, nullptr, m_mpi_adapter, m_datatype_list);
492 auto i32 = createBuiltInDispatcher<Int32>(tm, nullptr, m_mpi_adapter, m_datatype_list);
493 auto i64 = createBuiltInDispatcher<Int64>(tm, nullptr, m_mpi_adapter, m_datatype_list);
494 auto r = createBuiltInDispatcher<Real>(tm, nullptr, m_mpi_adapter, m_datatype_list);
495 _setDispatchers(c, i32, i64, r);
496
498 String service_name = "HybridParallelMngContainerFactory";
499 m_builder_factory = sb.createReference(service_name);
500 auto* true_builder = dynamic_cast<HybridParallelMngContainerFactory*>(m_builder_factory.get());
501 ARCANE_CHECK_POINTER(true_builder);
502 true_builder->m_stat = m_stat;
503 true_builder->m_mpi_lock = m_mpi_lock;
504
505 Ref<IParallelMngContainer> x = m_builder_factory->_createParallelMngBuilder(n, m_communicator, m_machine_communicator);
506 m_main_builder = x;
507 m_container = dynamic_cast<HybridParallelMngContainer*>(x.get());
508 ARCANE_CHECK_POINTER(m_container);
509}
510
511/*---------------------------------------------------------------------------*/
512/*---------------------------------------------------------------------------*/
513
516{
517 if (local_rank < 0 || local_rank >= m_local_nb_rank)
518 throw ArgumentException(A_FUNCINFO, "Bad value for local_rank");
519
520 Int32 current_global_rank = local_rank + m_local_nb_rank * commRank();
521 ITraceMng* app_tm = m_application->traceMng();
522 app_tm->info() << "Create SharedMemoryParallelMng rank=" << current_global_rank;
523
524 ITraceMng* tm = nullptr;
525 if (local_rank == 0) {
526 // The first created subdomain uses the default traceMng().
527 tm = app_tm;
528 }
529 else {
530 tm = m_application->createAndInitializeTraceMng(app_tm, String::fromNumber(current_global_rank));
531 }
532
533 Ref<IParallelMng> pm = m_container->_createParallelMng(local_rank, tm);
534 return pm;
535}
536
537/*---------------------------------------------------------------------------*/
538/*---------------------------------------------------------------------------*/
539
541tryAbort()
542{
543 m_application->traceMng()->flush();
544 MPI_Abort(m_communicator, 2);
545}
546
547/*---------------------------------------------------------------------------*/
548/*---------------------------------------------------------------------------*/
549
551barrier()
552{
553 MPI_Barrier(m_communicator);
554}
555
556/*---------------------------------------------------------------------------*/
557/*---------------------------------------------------------------------------*/
558
560 ServiceProperty("HybridParallelSuperMng", ST_Application),
562
563// Old name
565 ServiceProperty("MpiThreadParallelSuperMng", ST_Application),
567
568/*---------------------------------------------------------------------------*/
569/*---------------------------------------------------------------------------*/
570
571/*---------------------------------------------------------------------------*/
572/*---------------------------------------------------------------------------*/
573
580class MpiSharedMemoryParallelSuperMng
581: public SharedMemoryParallelSuperMng
582{
583 public:
584
585 explicit MpiSharedMemoryParallelSuperMng(const ServiceBuildInfo& sbi)
586 : SharedMemoryParallelSuperMng(sbi, Parallel::Communicator(MPI_COMM_WORLD), true)
587 {
588 Request::setNullRequest(Request(0, nullptr, MPI_REQUEST_NULL));
589 Communicator::setNullCommunicator(Communicator(MPI_COMM_NULL));
590 }
591
592 ~MpiSharedMemoryParallelSuperMng() override
593 {
594 //arcaneFinalizeMPI();
595 }
596
597 void build() override
598 {
600 }
601};
602
603/*---------------------------------------------------------------------------*/
604/*---------------------------------------------------------------------------*/
605
607 ServiceProperty("MpiSharedMemoryParallelSuperMng", ST_Application),
609
610/*---------------------------------------------------------------------------*/
611/*---------------------------------------------------------------------------*/
612
613} // End namespace Arcane::MessagePassing
614
615/*---------------------------------------------------------------------------*/
616/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
AbstractService(const ServiceBuildInfo &)
Constructor from a ServiceBuildInfo.
Application information.
const CommandLineArguments & commandLineArguments() const
Command line arguments.
Application interface.
virtual const ApplicationBuildInfo & applicationBuildInfo() const =0
Instance build parameter information.
virtual ITraceMng * traceMng() const =0
Trace manager.
Interface for an 'IParallelMng' container factory.
Abstract class of the parallelism supervisor.
virtual void destroy()=0
Destroys the barrier.
virtual void init(Integer nb_thread)=0
Initializes the barrier for nb_thread.
Interface of a thread manager.
Definition IThreadMng.h:32
virtual TraceMessage info()=0
Stream for an information message.
Communicator for message exchange.
Container of information for the hybrid mode message manager.
Ref< IParallelMng > _createParallelMng(Int32 local_rank, ITraceMng *tm) override
Creates the IParallelMng for the local rank local_rank.
Thread-based parallelism manager.
void build() override
Constructs the instance.
Supervisor of parallelism using MPI and Threads.
Int32 commRank() const override
Returns the process number (between 0 and nbProcess()-1).
MP::Communicator communicator() const override
MPI communicator associated with this manager.
void build() override
Constructs the instance members.
void * getMPICommunicator() override
Address of the MPI communicator associated with this manager.
IThreadMng * threadMng() const override
Thread manager.
IApplication * application() const override
Returns the main manager.
void barrier() override
Parallelism manager for all allocated resources.
Ref< IParallelMng > internalCreateWorldParallelMng(Int32 local_rank) override
Creates a parallelism manager for all allocated cores.
Integer masterIORank() const override
Rank of the instance managing input/output (for which isMasterIO() is true).
void initialize() override
Initializes the instance.
Integer nbLocalSubDomain() override
Number of subdomains to create locally.
bool isMasterIO() const override
Returns true if the instance is a master I/O manager.
Int32 commSize() const override
Returns the total number of processes used.
bool isParallel() const override
Returns true if the execution is parallel.
Int32 traceRank() const override
Rank of this instance for traces.
Shared memory supervisor with MPI initialization.
void build() override
Constructs the instance members.
void destroy()
Destroys the instance. It should no longer be used afterward.
void build() override
Constructs the instance members.
Manages the MPI_Datatypes associated with Arcane types.
Message interface for the Type.
Parallelism manager using MPI.
void build() override
Constructs the instance.
void initialize() override
Initializes the parallelism manager.
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
IApplication * application() const
Access to the associated IApplication.
Structure containing the information to create a service.
Utility class for instantiating a service of a given interface.
Ref< InterfaceType > createReference(const String &name, eServiceBuilderProperties properties=SB_None)
Creates an instance implementing the InterfaceType interface.
Service creation properties.
1D data vector with value semantics (STL style).
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
Declarations of types and methods used by message exchange mechanisms.
IStat * createDefaultStat()
Creates a default instance.
Real getRealTime()
Real time used in seconds.
IThreadImplementation * getThreadImplementationService()
Service used to manage threads.
ARCANE_MPI_EXPORT void arcaneInitializeMPI(int *argc, char ***argv, int wanted_thread_level)
Definition ArcaneMpi.cc:226
bool arcaneHasThread()
True if arcane is compiled with thread support AND they are active.
Definition Misc.cc:88
ARCANE_MPI_EXPORT bool arcaneIsCudaAwareMPI()
Indicates if the current MPI runtime supports CUDA.
Definition ArcaneMpi.cc:40
Int32 Integer
Type representing an integer.
@ ST_Application
The service is used at the application level.
void arcaneCallFunctionAndTerminateIfThrow(std::function< void()> function)
Calls the function function and calls std::terminate() if an exception occurs.
double Real
Type representing a real number.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
ARCANE_MPI_EXPORT void arcaneFinalizeMPI()
Definition ArcaneMpi.cc:232
std::int32_t Int32
Signed integer type of 32 bits.
Info for constructing a HybridParallelMng.
Info to construct an MpiParallelMng.