14#include "arcane/utils/Collection.h"
15#include "arcane/utils/Enumerator.h"
16#include "arcane/utils/ScopedPtr.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/TimeoutException.h"
19#include "arcane/utils/NotImplementedException.h"
20#include "arcane/utils/ArgumentException.h"
21#include "arcane/utils/ITraceMng.h"
22#include "arcane/utils/ValueConvert.h"
23#include "arcane/utils/Exception.h"
24#include "arcane/utils/HPReal.h"
26#include "arcane/core/IIOMng.h"
27#include "arcane/core/Timer.h"
28#include "arcane/core/IItemFamily.h"
29#include "arcane/core/IParallelTopology.h"
30#include "arcane/core/parallel/IStat.h"
31#include "arcane/core/internal/SerializeMessage.h"
32#include "arcane/core/internal/ParallelMngInternal.h"
33#include "arcane/core/internal/MachineShMemWinMemoryAllocator.h"
35#include "arcane/parallel/mpi/MpiParallelMng.h"
36#include "arcane/parallel/mpi/MpiParallelDispatch.h"
37#include "arcane/parallel/mpi/MpiTimerMng.h"
38#include "arcane/parallel/mpi/MpiSerializeMessage.h"
39#include "arcane/parallel/mpi/MpiParallelNonBlockingCollective.h"
40#include "arcane/parallel/mpi/MpiDatatype.h"
41#include "arcane/parallel/mpi/IVariableSynchronizerMpiCommunicator.h"
43#include "arcane/impl/ParallelReplication.h"
44#include "arcane/impl/SequentialParallelMng.h"
45#include "arcane/impl/internal/ParallelMngUtilsFactoryBase.h"
46#include "arcane/impl/internal/VariableSynchronizer.h"
48#include "arccore/message_passing_mpi/MpiMessagePassingMng.h"
49#include "arccore/message_passing_mpi/internal/MpiSerializeDispatcher.h"
50#include "arccore/message_passing_mpi/internal/MpiRequestList.h"
51#include "arccore/message_passing_mpi/internal/MpiAdapter.h"
52#include "arccore/message_passing_mpi/internal/MpiLock.h"
53#include "arccore/message_passing_mpi/internal/MpiMachineShMemWinBaseInternalCreator.h"
54#include "arccore/message_passing_mpi/internal/MpiContigMachineShMemWinBaseInternal.h"
55#include "arccore/message_passing_mpi/internal/MpiMachineShMemWinBaseInternal.h"
56#include "arccore/message_passing/Dispatchers.h"
58#include "arccore/message_passing/internal/SerializeMessageList.h"
60#include "arcane_packages.h"
70using namespace Arcane::MessagePassing::Mpi;
79#if defined(ARCANE_HAS_MPI_NEIGHBOR)
82arcaneCreateMpiNeighborVariableSynchronizerFactory(
MpiParallelMng* mpi_pm,
90arcaneCreateMpiDirectSendrecvVariableSynchronizerFactory(
MpiParallelMng* mpi_pm);
92arcaneCreateMpiLegacyVariableSynchronizerFactory(
MpiParallelMng* mpi_pm);
93#if defined(ARCANE_HAS_PACKAGE_NCCL)
95arcaneCreateNCCLVariableSynchronizerFactory(
IParallelMng* mpi_pm);
101MpiParallelMngBuildInfo::
102MpiParallelMngBuildInfo(MPI_Comm comm, MPI_Comm machine_comm)
111, mpi_machine_comm(machine_comm)
112, is_mpi_comm_owned(true)
115 ::MPI_Comm_rank(comm, &comm_rank);
116 ::MPI_Comm_size(comm, &comm_nb_rank);
119 MP::Mpi::MpiMessagePassingMng::BuildInfo bi(comm_rank, comm_nb_rank, m_dispatchers_ref.get(), mpi_comm);
132class VariableSynchronizerMpiCommunicator
138 : m_mpi_parallel_mng(pm)
140 ~VariableSynchronizerMpiCommunicator()
override
142 _checkFreeCommunicator();
146 return m_topology_communicator;
151 const Int32 nb_message = comm_ranks.
size();
158 for (
Integer i = 0; i < nb_message; ++i) {
159 destinations[i] = comm_ranks[i];
162 _checkFreeCommunicator();
164 int r = MPI_Dist_graph_create_adjacent(old_comm, nb_message, destinations.
data(), MPI_UNWEIGHTED,
165 nb_message, destinations.
data(), MPI_UNWEIGHTED,
166 MPI_INFO_NULL, 0, &m_topology_communicator);
168 if (r != MPI_SUCCESS)
169 ARCANE_FATAL(
"Error '{0}' in MPI_Dist_graph_create", r);
177 MPI_Dist_graph_neighbors_count(m_topology_communicator, &indegree, &outdegree, &weighted);
179 if (indegree != nb_message)
180 ARCANE_FATAL(
"Bad value '{0}' for 'indegree' (expected={1})", indegree, nb_message);
181 if (outdegree != nb_message)
182 ARCANE_FATAL(
"Bad value '{0}' for 'outdegree' (expected={1})", outdegree, nb_message);
187 MPI_Dist_graph_neighbors(m_topology_communicator, indegree, srcs.
data(), MPI_UNWEIGHTED, outdegree, dsts.
data(), MPI_UNWEIGHTED);
189 for (
int k = 0; k < outdegree; ++k) {
191 if (x != comm_ranks[k])
192 ARCANE_FATAL(
"Invalid destination rank order k={0} v={1} expected={2}", k, x, comm_ranks[k]);
195 for (
int k = 0; k < indegree; ++k) {
197 if (x != comm_ranks[k])
198 ARCANE_FATAL(
"Invalid source rank order k={0} v={1} expected={2}", k, x, comm_ranks[k]);
206 MPI_Comm m_topology_communicator = MPI_COMM_NULL;
210 void _checkFreeCommunicator()
212 if (m_topology_communicator != MPI_COMM_NULL)
213 MPI_Comm_free(&m_topology_communicator);
214 m_topology_communicator = MPI_COMM_NULL;
226class MpiVariableSynchronizer
227:
public VariableSynchronizer
234 : VariableSynchronizer(pm, group, implementation_factory)
235 , m_topology_info(topology_info)
245 if (m_topology_info.get())
246 m_topology_info->compute(
this);
257class MpiParallelMngUtilsFactory
262 MpiParallelMngUtilsFactory()
263 : m_synchronizer_version(2)
266 m_synchronizer_version = 1;
268 m_synchronizer_version = 2;
270 m_synchronizer_version = 3;
272 m_synchronizer_version = 4;
275 Int32 block_size = 0;
276 if (!builtInGetValue(block_size, v))
277 m_synchronize_block_size = block_size;
278 m_synchronize_block_size = std::clamp(m_synchronize_block_size, 0, 1000000000);
282 Int32 nb_sequence = 0;
283 if (!builtInGetValue(nb_sequence, v))
284 m_synchronize_nb_sequence = nb_sequence;
285 m_synchronize_nb_sequence = std::clamp(m_synchronize_nb_sequence, 1, 1024 * 1024);
289 m_synchronizer_version = 5;
291 m_synchronizer_version = 6;
298 return _createSynchronizer(pm, family->
allItems());
303 return _createSynchronizer(pm, group);
317 if (m_synchronizer_version == 2) {
319 tm->
info() <<
"Using MpiSynchronizer V2";
320 generic_factory = arcaneCreateMpiVariableSynchronizerFactory(mpi_pm);
322 else if (m_synchronizer_version == 3) {
324 tm->
info() <<
"Using MpiSynchronizer V3";
325 generic_factory = arcaneCreateMpiDirectSendrecvVariableSynchronizerFactory(mpi_pm);
327 else if (m_synchronizer_version == 4) {
329 tm->
info() <<
"Using MpiSynchronizer V4 block_size=" << m_synchronize_block_size
330 <<
" nb_sequence=" << m_synchronize_nb_sequence;
331 generic_factory = arcaneCreateMpiBlockVariableSynchronizerFactory(mpi_pm, m_synchronize_block_size, m_synchronize_nb_sequence);
333 else if (m_synchronizer_version == 5) {
335 tm->
info() <<
"Using MpiSynchronizer V5";
336 topology_info = createRef<VariableSynchronizerMpiCommunicator>(mpi_pm);
337#if defined(ARCANE_HAS_MPI_NEIGHBOR)
338 generic_factory = arcaneCreateMpiNeighborVariableSynchronizerFactory(mpi_pm, topology_info);
340 throw NotSupportedException(A_FUNCINFO,
"Synchronize implementation V5 is not supported with this version of MPI");
343#if defined(ARCANE_HAS_PACKAGE_NCCL)
344 else if (m_synchronizer_version == 6) {
346 tm->
info() <<
"Using NCCLSynchronizer";
347 generic_factory = arcaneCreateNCCLVariableSynchronizerFactory(mpi_pm);
352 tm->
info() <<
"Using MpiSynchronizer V1";
353 generic_factory = arcaneCreateMpiLegacyVariableSynchronizerFactory(mpi_pm);
355 if (!generic_factory.
get())
357 return createRef<MpiVariableSynchronizer>(pm, group, generic_factory, topology_info);
362 Integer m_synchronizer_version = 1;
363 Int32 m_synchronize_block_size = 32000;
364 Int32 m_synchronize_nb_sequence = 1;
374:
public ParallelMngInternal
378 explicit Impl(MpiParallelMng* pm)
379 : ParallelMngInternal(pm)
384 ~Impl()
override =
default;
393 m_parallel_mng->traceMng()->info() <<
"initializeWindowCreator() MPI";
394 m_parallel_mng->adapter()->initializeWindowCreator(m_parallel_mng->machineCommunicator());
399 if (m_shmem_available == 1) {
403 if (m_shmem_available == 0) {
405 if (topo->machineRanks().size() == m_parallel_mng->adapter()->windowCreator()->machineRanks().size()) {
406 m_shmem_available = 1;
410 m_shmem_available = 2;
419 return makeRef(m_parallel_mng->adapter()->windowCreator()->createWindow(sizeof_segment, sizeof_type));
424 return makeRef(m_parallel_mng->adapter()->windowCreator()->createDynamicWindow(sizeof_segment, sizeof_type));
434 return m_parallel_mng->adapter()->windowCreator()->machineRanks();
439 m_parallel_mng->adapter()->windowCreator()->machineBarrier();
444 MpiParallelMng* m_parallel_mng;
450 Int8 m_shmem_available = 0;
462, m_trace(bi.trace_mng)
463, m_thread_mng(bi.thread_mng)
464, m_world_parallel_mng(bi.world_parallel_mng)
465, m_timer_mng(bi.timer_mng)
467, m_is_parallel(bi.is_parallel)
468, m_comm_rank(bi.commRank())
469, m_comm_size(bi.commSize())
471, m_communicator(bi.mpiComm())
472, m_machine_communicator(bi.mpiMachineComm())
473, m_is_communicator_owned(bi.is_mpi_comm_owned)
474, m_mpi_lock(bi.mpi_lock)
475, m_non_blocking_collective(nullptr)
477, m_parallel_mng_internal(new Impl(this))
479 if (!m_world_parallel_mng) {
480 m_trace->debug() <<
"[MpiParallelMng] No m_world_parallel_mng found, reverting to ourselves!";
481 m_world_parallel_mng =
this;
491 delete m_parallel_mng_internal;
492 delete m_non_blocking_collective;
493 m_sequential_parallel_mng.reset();
494 if (m_is_communicator_owned) {
495 MpiLock::Section ls(m_mpi_lock);
496 MPI_Comm_free(&m_communicator);
497 MPI_Comm_free(&m_machine_communicator);
499 delete m_replication;
501 if (m_is_timer_owned)
504 delete m_datatype_list;
516 class DispatchCreator
520 DispatchCreator(ITraceMng* tm, IMessagePassingMng* mpm, MpiAdapter* adapter, MpiDatatypeList* datatype_list)
524 , m_datatype_list(datatype_list)
529 template <
typename DataType> MpiParallelDispatchT<DataType>*
532 MpiDatatype* dt = m_datatype_list->datatype(DataType());
533 return new MpiParallelDispatchT<DataType>(m_tm, m_mpm, m_adapter, dt);
537 IMessagePassingMng* m_mpm;
538 MpiAdapter* m_adapter;
539 MpiDatatypeList* m_datatype_list;
545 class ControlDispatcherDecorator
546 :
public ParallelMngDispatcher::DefaultControlDispatcher
550 ControlDispatcherDecorator(IParallelMng* pm, MpiAdapter* adapter)
551 : ParallelMngDispatcher::DefaultControlDispatcher(pm)
555 IMessagePassingMng* commSplit(
bool keep)
override
557 return m_adapter->commSplit(keep);
559 MP::IProfiler* profiler()
const override {
return m_adapter->profiler(); }
560 void setProfiler(MP::IProfiler* p)
override { m_adapter->setProfiler(p); }
564 MpiAdapter* m_adapter;
577 m_is_timer_owned =
true;
586 m_sequential_parallel_mng = arcaneCreateSequentialParallelMngRef(bi);
591 bool is_ordered_reduce =
false;
593 is_ordered_reduce =
true;
598 MpiAdapter* adapter =
new MpiAdapter(m_trace, m_stat->toArccoreStat(), m_communicator, m_mpi_lock);
600 auto mpm = _messagePassingMng();
603 auto* control_dispatcher =
new ControlDispatcherDecorator(
this, m_adapter);
604 _setControlDispatcher(control_dispatcher);
608 m_mpi_serialize_dispatcher = serialize_dispatcher;
609 _setSerializeDispatcher(serialize_dispatcher);
611 DispatchCreator creator(m_trace, mpm, m_adapter, m_datatype_list);
612 this->createDispatchers(creator);
614 m_io_mng = arcaneCreateIOMng(
this);
617 m_non_blocking_collective->build();
619 m_trace->info() <<
"Using mpi with locks.";
621 m_parallel_mng_internal->initializeWindowCreator();
635 m_trace->warning() <<
"MpiParallelMng already initialized";
640 m_trace->info() <<
"Initialisation de MpiParallelMng";
641 m_sequential_parallel_mng->initialize();
657 m_mpi_serialize_dispatcher->legacySendSerializer(s, {
MessageRank(rank), mpi_tag, Blocking });
666 return m_utils_factory->createSendSerializeMessage(
this, rank)._release();
678 return m_mpi_serialize_dispatcher->legacySendSerializer(s, {
MessageRank(rank), mpi_tag, NonBlocking });
688 m_mpi_serialize_dispatcher->broadcastSerializer(values,
MessageRank(rank));
700 m_mpi_serialize_dispatcher->legacyReceiveSerializer(values,
MessageRank(rank), mpi_tag);
709 return m_utils_factory->createReceiveSerializeMessage(
this, rank)._release();
718 return m_adapter->probeMessage(message);
727 return m_adapter->legacyProbeMessage(message);
754 for (
Integer i = 0, is = requests.
size(); i < is; ++i)
755 m_adapter->freeRequest(requests[i]);
762_checkFinishedSubRequests()
764 m_mpi_serialize_dispatcher->checkFinishedSubRequests();
771sequentialParallelMngRef()
773 return m_sequential_parallel_mng;
779 return m_sequential_parallel_mng.get();
789 m_stat->print(m_trace);
799 m_adapter->barrier();
808 m_adapter->waitAllRequests(requests);
809 _checkFinishedSubRequests();
818 return _waitSomeRequests(requests,
false);
827 return _waitSomeRequests(requests,
true);
839 m_adapter->waitSomeRequests(requests, done_indexes, is_non_blocking);
840 for (
int i = 0; i < requests.
size(); i++) {
850ISerializeMessageList* MpiParallelMng::
851_createSerializeMessageList()
862 return m_utils_factory->createGetVariablesValuesOperation(
this)._release();
871 return m_utils_factory->createTransferValuesOperation(
this)._release();
880 return m_utils_factory->createExchanger(
this)._release();
889 return m_utils_factory->createSynchronizer(
this, family)._release();
898 return m_utils_factory->createSynchronizer(
this, group)._release();
907 return m_utils_factory->createTopology(
this)._release();
916 return m_replication;
925 delete m_replication;
933_createSubParallelMng(MPI_Comm sub_communicator)
936 if (sub_communicator == MPI_COMM_NULL)
940 MPI_Comm_rank(sub_communicator, &sub_rank);
942 MPI_Comm sub_machine_communicator = MPI_COMM_NULL;
943 MPI_Comm_split_type(sub_communicator, MPI_COMM_TYPE_SHARED, sub_rank, MPI_INFO_NULL, &sub_machine_communicator);
948 bi.timer_mng = m_timer_mng;
949 bi.thread_mng = m_thread_mng;
950 bi.trace_mng = m_trace;
951 bi.world_parallel_mng = m_world_parallel_mng;
952 bi.mpi_lock = m_mpi_lock;
963_createSubParallelMngRef(Int32 color, Int32 key)
966 color = MPI_UNDEFINED;
967 MPI_Comm sub_communicator = MPI_COMM_NULL;
968 MPI_Comm_split(m_communicator, color, key, &sub_communicator);
969 IParallelMng* sub_pm = _createSubParallelMng(sub_communicator);
976IParallelMng* MpiParallelMng::
979 MPI_Group mpi_group = MPI_GROUP_NULL;
980 MPI_Comm_group(m_communicator, &mpi_group);
982 UniqueArray<int> mpi_kept_ranks(nb_sub_rank);
983 for (
Integer i = 0; i < nb_sub_rank; ++i)
984 mpi_kept_ranks[i] = (
int)kept_ranks[i];
986 MPI_Group final_group = MPI_GROUP_NULL;
987 MPI_Group_incl(mpi_group, nb_sub_rank, mpi_kept_ranks.data(), &final_group);
988 MPI_Comm sub_communicator = MPI_COMM_NULL;
990 MPI_Comm_create(m_communicator, final_group, &sub_communicator);
991 MPI_Group_free(&final_group);
992 return _createSubParallelMng(sub_communicator);
1006:
public MpiRequestList
1008 using Base = MpiRequestList;
1012 explicit RequestList(MpiParallelMng* pm)
1013 : Base(pm->m_adapter)
1014 , m_parallel_mng(pm)
1022 m_parallel_mng->_checkFinishedSubRequests();
1027 MpiParallelMng* m_parallel_mng;
1045 return m_utils_factory;
1051bool MpiParallelMng::
1052_isAcceleratorAware()
const
#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_FATAL(...)
Macro throwing a FatalErrorException.
Brief list of message exchange functions.
Modifiable view of an array of type T.
constexpr Integer size() const noexcept
Returns the size of the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
const T * data() const
Access to the root of the array without any protection.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Operations to access variable values from another subdomain.
Interface of the input/output manager.
Interface of an entity family.
virtual ItemGroup allItems() const =0
Group of all entities.
Information exchange between processors.
Interface of the parallelism manager for a subdomain.
virtual ITraceMng * traceMng() const =0
Trace manager.
virtual void build()=0
Constructs the instance.
Brief information on parallel subdomain replication.
Information on the computing core allocation topology.
virtual void flush()=0
Flushes all streams.
virtual TraceMessage info()=0
Stream for an information message.
Sends values across different processors.
Interface of a specific MPI communicator for synchronizations.
Interface of a variable synchronization service.
eItemKind itemKind() const
Group kind. This is the kind of its elements.
bool isAllItems() const
Indicates if the group is that of all entities.
Options to configure allocations.
Interface for a serialization message between IMessagePassingMng.
Information about the source of a message.
void _wait(eWaitType wait_type) override
Performs the wait or test.
Request receiveSerializer(ISerializer *s, const PointToPointMessageInfo &message) override
Receiving message.
Request sendSerializer(const ISerializer *s, const PointToPointMessageInfo &message) override
Sending message.
Information for sending/receiving a point-to-point message.
Serializing message using a BasicSerializer.
static MessageTag defaultTag()
Default tag for serialization messages.
Manages the MPI_Datatypes associated with Arcane types.
Ref< IVariableSynchronizer > createSynchronizer(IParallelMng *pm, IItemFamily *family) override
Returns an interface to synchronize variables on the group of the family family.
Ref< IVariableSynchronizer > createSynchronizer(IParallelMng *pm, const ItemGroup &group) override
Returns an interface to synchronize variables on the group group.
void initializeWindowCreator() override
Method allowing the initialization of the windowCreator specific to the implementation.
Ref< IContigMachineShMemWinBaseInternal > createContigMachineShMemWinBase(Int64 sizeof_segment, Int32 sizeof_type) override
Method allowing the creation of a memory window on the node.
Ref< IMachineShMemWinBaseInternal > createMachineShMemWinBase(Int64 sizeof_segment, Int32 sizeof_type) override
Method allowing the creation of a dynamic memory window on the node.
bool isMachineShMemWinAvailable() override
Method allowing to know if shared memory mode is supported.
ConstArrayView< Int32 > machineRanks() override
Method allowing retrieval of the ranks of the sub-domains of the computing node.
void machineBarrier() override
Method allowing a barrier for the sub-domains of the computing node.
Int32 masterParallelIORank() const override
Int32 nbSendersToMasterParallelIO() const override
MemoryAllocationOptions machineShMemWinMemoryAllocator() override
Method allowing retrieval of a shared memory allocator.
Specialization of MpiRequestList for MpiParallelMng.
void _wait(Parallel::eWaitType wait_type) override
Performs the wait or test.
Parallelism manager using MPI.
IParallelMng * worldParallelMng() const override
Parallelism manager over all allocated resources.
MessageSourceInfo legacyProbe(const PointToPointMessageInfo &message) override
Probes if messages are available.
void barrier() override
Performs a barrier.
UniqueArray< Integer > waitSomeRequests(ArrayView< Request > requests) override
Blocks while waiting for one of the rvalues requests to complete.
void waitAllRequests(ArrayView< Request > requests) override
Blocks while waiting for the rvalues requests to complete.
MessageId probe(const PointToPointMessageInfo &message) override
Probes if messages are available.
void build() override
Constructs the instance.
void printStats() override
Prints statistics related to this parallelism manager.
bool m_is_initialized
true if already initialized
IParallelMng * sequentialParallelMng() override
Returns a sequential parallelism manager.
IThreadMng * threadMng() const override
Thread manager.
ITimerMng * timerMng() const override
Timer manager.
void initialize() override
Initializes the parallelism manager.
IVariableSynchronizer * createSynchronizer(IItemFamily *family) override
Returns an interface for synchronizing variables on the group of the family.
ISerializeMessage * createSendSerializer(Int32 rank) override
Creates a non-blocking message to send serialized data to rank rank.
bool isParallel() const override
Returns true if the execution is parallel.
Ref< IParallelMngUtilsFactory > _internalUtilsFactory() const override
Factory for utility functions.
ITraceMng * traceMng() const override
Trace manager.
IParallelTopology * createTopology() override
Creates an instance containing information about the rank topology of this manager.
Communicator communicator() const override
MPI communicator associated with this manager.
IParallelExchanger * createExchanger() override
Returns an interface for transferring messages between processors.
IParallelReplication * replication() const override
Replication information.
void setReplication(IParallelReplication *v) override
Sets the Replication Information.
Ref< Parallel::IRequestList > createRequestListRef() override
Creates a request list for this manager.
ITransferValuesParallelOperation * createTransferValuesOperation() override
Returns an operation to transfer values between subdomains.
UniqueArray< Integer > testSomeRequests(ArrayView< Request > requests) override
Tests if one of the rvalues requests is complete.
IGetVariablesValuesParallelOperation * createGetVariablesValuesOperation() override
Returns an operation to retrieve the values of a variable on the entities of another subdomain.
ISerializeMessage * createReceiveSerializer(Int32 rank) override
Creates a non-blocking message to receive serialized data from rank rank.
void freeRequests(ArrayView< Parallel::Request > requests) override
Frees the requests.
Parallelism manager using MPI.
Timer manager using the MPI library.
void compute() override
Recalculates the synchronization information.
Redirects the message management of sub-domains according to the argument type.
IMessagePassingMng * messagePassingMng() const override
Associated Arccore message passing manager.
ITimeMetricCollector * timeMetricCollector() const override
Arccore temporal statistics collector (can be null).
ITimeStats * timeStats() const override
Associated statistics manager (can be null).
Base class of a factory for IParallelMng utility functions.
Brief information on parallel subdomain replication.
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
Unicode character string.
bool null() const
Returns true if the string is null.
Positions the phase of the currently executing action.
1D data vector with value semantics (STL style).
MPI_Comm communicator() const override
Retrieves the specific communicator from the topology.
void compute(VariableSynchronizer *var_syncer) override
Calculates the specific communicator.
Interface of a variable synchronization service.
void compute() override
Creation of the list of synchronization elements.
Int32ConstArrayView communicatingRanks() override
Ranks of subdomains with which communication occurs.
Declarations of types and methods used by message exchange mechanisms.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int8_t Int8
Signed integer type of 8 bits.
Ref< TrueType > createRef(Args &&... args)
Creates an instance of type TrueType with arguments Args and returns a reference to it.
ARCANE_MPI_EXPORT bool arcaneIsAcceleratorAwareMPI()
Indicates if the current MPI runtime supports accelerators.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
Array< Byte > ByteArray
Dynamic one-dimensional array of characters.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
@ IK_Cell
Cell mesh entity.
void arcaneCallFunctionAndTerminateIfThrow(std::function< void()> function)
Calls the function function and calls std::terminate() if an exception occurs.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.
Info to construct an MpiParallelMng.
Information to construct a SequentialParallelMng.