14#include "arcane/parallel/thread/SharedMemoryParallelMng.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/NotSupportedException.h"
18#include "arcane/utils/PlatformUtils.h"
19#include "arcane/utils/TraceInfo.h"
20#include "arcane/utils/NumericTypes.h"
21#include "arcane/utils/ArgumentException.h"
22#include "arcane/utils/FatalErrorException.h"
23#include "arcane/utils/ITraceMng.h"
24#include "arcane/utils/SmallArray.h"
26#include "arcane/parallel/IStat.h"
28#include "arcane/parallel/thread/SharedMemoryParallelDispatch.h"
29#include "arcane/parallel/thread/ISharedMemoryMessageQueue.h"
30#include "arcane/parallel/thread/internal/SharedMemoryMachineShMemWinBaseInternalCreator.h"
31#include "arcane/parallel/thread/internal/SharedMemoryContigMachineShMemWinBaseInternal.h"
32#include "arcane/parallel/thread/internal/SharedMemoryMachineShMemWinBaseInternal.h"
34#include "arcane/core/Timer.h"
35#include "arcane/core/IIOMng.h"
36#include "arcane/core/ISerializeMessageList.h"
37#include "arcane/core/IItemFamily.h"
38#include "arcane/core/internal/SerializeMessage.h"
39#include "arcane/core/internal/ParallelMngInternal.h"
40#include "arcane/core/internal/MachineShMemWinMemoryAllocator.h"
42#include "arcane/impl/TimerMng.h"
43#include "arcane/impl/ParallelReplication.h"
44#include "arcane/impl/internal/ParallelMngUtilsFactoryBase.h"
46#include "arccore/message_passing/RequestListBase.h"
47#include "arccore/message_passing/internal/SerializeMessageList.h"
49#include "arcane/parallel/thread/SharedMemoryMessageQueue.h"
58extern "C++" ARCANE_IMPL_EXPORT
IIOMng*
76 explicit RequestList(SharedMemoryParallelMng* pm)
77 : m_parallel_mng(pm), m_message_queue(pm->m_message_queue),
78 m_local_rank(m_parallel_mng->commRank()){}
83 case Parallel::WaitAll:
84 m_message_queue->waitAll(m_local_rank, _requests());
87 m_message_queue->waitSome(m_local_rank, _requests(), _requestsDone(),
false);
90 m_message_queue->waitSome(m_local_rank, _requests(), _requestsDone(),
true);
97 SharedMemoryParallelMng* m_parallel_mng;
106:
public ParallelMngInternal
111 : ParallelMngInternal(pm)
113 , m_window_creator(window_creator)
117 ~Impl()
override =
default;
133 return makeRef(m_window_creator->createWindow(m_parallel_mng->commRank(), sizeof_segment, sizeof_type));
138 return makeRef(m_window_creator->createDynamicWindow(m_parallel_mng->commRank(), sizeof_segment, sizeof_type));
148 return m_window_creator->machineRanks();
153 m_window_creator->machineBarrier();
158 SharedMemoryParallelMng* m_parallel_mng;
166SharedMemoryParallelMng::
169, m_trace(build_info.trace_mng)
170, m_thread_mng(build_info.thread_mng)
171, m_sequential_parallel_mng(build_info.sequential_parallel_mng)
172, m_timer_mng(nullptr)
174, m_world_parallel_mng(build_info.world_parallel_mng)
176, m_message_queue(build_info.message_queue)
177, m_is_parallel(build_info.nb_rank!=1)
178, m_rank(build_info.rank)
179, m_nb_rank(build_info.nb_rank)
180, m_is_initialized(false)
181, m_stat(
Parallel::createDefaultStat())
182, m_thread_barrier(build_info.thread_barrier)
183, m_all_dispatchers(build_info.all_dispatchers)
184, m_sub_builder_factory(build_info.sub_builder_factory)
185, m_parent_container_ref(build_info.container)
186, m_mpi_communicator(build_info.communicator)
188, m_parallel_mng_internal(new Impl(this, build_info.window_creator))
190 if (!m_world_parallel_mng)
191 m_world_parallel_mng =
this;
197SharedMemoryParallelMng::
198~SharedMemoryParallelMng()
200 delete m_parallel_mng_internal;
201 delete m_replication;
202 m_sequential_parallel_mng.reset();
217 DispatchCreator(ITraceMng* tm,SharedMemoryParallelMng* mpm,
218 ISharedMemoryMessageQueue* message_queue,
219 SharedMemoryAllDispatcher* all_dispatchers)
220 : m_tm(tm), m_mpm(mpm), m_message_queue(message_queue),
221 m_all_dispatchers(all_dispatchers){}
223 template<
typename DataType> SharedMemoryParallelDispatch<DataType>*
226 ISharedMemoryMessageQueue* tmq = m_message_queue;
227 SharedMemoryAllDispatcher* ad = m_all_dispatchers;
228 auto& field = ad->instance((DataType*)
nullptr);
229 return new SharedMemoryParallelDispatch<DataType>(m_tm,m_mpm,tmq,field);
233 SharedMemoryParallelMng* m_mpm;
234 ISharedMemoryMessageQueue* m_message_queue;
235 SharedMemoryAllDispatcher* m_all_dispatchers;
248 DispatchCreator creator(m_trace.get(),
this,m_message_queue,m_all_dispatchers);
249 this->createDispatchers(creator);
251 m_io_mng = arcaneCreateIOMng(
this);
262 m_trace->warning() <<
"SharedMemoryParallelMng already initialized";
275 return m_utils_factory->createGetVariablesValuesOperation(
this)._release();
281 return m_utils_factory->createTransferValuesOperation(
this)._release();
287 return m_utils_factory->createExchanger(
this)._release();
296void SharedMemoryParallelMng::
299 auto p2p_message =
buildMessage(dest_rank, Parallel::Blocking);
310 ARCANE_UNUSED(bytes);
320 return m_utils_factory->createSendSerializeMessage(
this, rank)._release();
326void SharedMemoryParallelMng::
338 m_message_queue->waitAll(
m_rank, requests);
341 recvSerializer(values,rank);
348void SharedMemoryParallelMng::
349recvSerializer(ISerializer* values,
Int32 rank)
351 auto p2p_message =
buildMessage(rank, Parallel::Blocking);
352 Request r = m_message_queue->addReceive(p2p_message, ReceiveBufferInfo(values));
353 m_message_queue->waitAll(
m_rank, ArrayView<Request>(1, &r));
362 return m_utils_factory->createReceiveSerializeMessage(
this, rank)._release();
371 ARCANE_UNUSED(requests);
382 m_stat->print(m_trace.get());
391 m_thread_barrier->wait();
401 m_message_queue->waitAll(
m_rank, requests);
403 m_stat->add(
"WaitAll",(end_time-begin_time),0);
410_createSerializeMessageList()
423 return m_message_queue->probe(p2p_message);
434 return m_message_queue->legacyProbe(p2p_message);
440auto SharedMemoryParallelMng::
444 return m_message_queue->addSend(p2p_message,
SendBufferInfo(values));
450auto SharedMemoryParallelMng::
463 return m_utils_factory->createSynchronizer(
this,family)._release();
472 return m_utils_factory->createSynchronizer(
this,group)._release();
481 return m_utils_factory->createTopology(
this)._release();
490 return m_replication;
499 delete m_replication;
509 ARCANE_UNUSED(kept_ranks);
522 if (kept_ranks.
empty())
531 Int32 my_new_rank = (-1);
532 for(
Integer i=0; i<nb_rank; ++i )
533 if (kept_ranks[i]==
m_rank){
541 builder = m_sub_builder_factory->_createParallelMngBuilder(nb_rank, m_mpi_communicator, m_mpi_communicator);
543 m_all_dispatchers->m_create_sub_parallel_mng_info.m_builder = builder;
547 builder = m_all_dispatchers->m_create_sub_parallel_mng_info.m_builder;
552 new_parallel_mng = builder->_createParallelMng(my_new_rank,
traceMng());
563 m_all_dispatchers->m_create_sub_parallel_mng_info.m_builder.reset();
567 return new_parallel_mng;
584sequentialParallelMngRef()
586 return m_sequential_parallel_mng;
592 return m_sequential_parallel_mng.get();
621 return m_utils_factory;
#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.
Vue modifiable d'un tableau d'un type T.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr bool empty() const noexcept
true si le tableau est vide (size()==0)
Opérations pour accéder aux valeurs de variables d'un autre sous-domaine.
Interface du gestionnaire des entrées sorties.
Interface d'une famille d'entités.
Échange d'informations entre processeurs.
Interface du gestionnaire de parallélisme pour un sous-domaine.
Informations sur la réplication des sous-domaines en parallèle.
Informations sur la topologie d'allocation des coeurs de calcul.
Interface d'un sérialiseur.
Envoie de valeurs sur différents processeurs.
Interface d'un service de synchronisation de variable.
Groupe d'entités de maillage.
Options pour configurer les allocations.
Liste de requête de messages.
Interface d'une liste de messages de sérialisation.
Interface d'un message de sérialisation entre IMessagePassingMng.
Interface d'une file de messages avec les threads.
Informations sur la source d'un message.
Informations pour envoyer/recevoir un message point à point.
void setEmiterRank(MessageRank rank)
Positionne le rang de l'émetteur du message.
Informations des buffers de réception.
Informations des buffers d'envoie.
Int32 masterParallelIORank() const override
bool isMachineShMemWinAvailable() override
Méthode permettant de savoir si le mode mémoire partagée est supporté.
MemoryAllocationOptions machineShMemWinMemoryAllocator() override
Méthode permettant de récupérer un allocateur en mémoire partagée.
void initializeWindowCreator() override
Méthode permettant d'initialiser le windowCreator spécifique à l'implémentation.
Ref< IMachineShMemWinBaseInternal > createMachineShMemWinBase(Int64 sizeof_segment, Int32 sizeof_type) override
Méthode permettant de créer une fenêtre mémoire dynamique sur le noeud.
ConstArrayView< Int32 > machineRanks() override
Méthode permettant de récupérer les rangs des sous-domaines du noeud de calcul.
Int32 nbSendersToMasterParallelIO() const override
Ref< IContigMachineShMemWinBaseInternal > createContigMachineShMemWinBase(Int64 sizeof_segment, Int32 sizeof_type) override
Méthode permettant de créer une fenêtre mémoire sur le noeud.
void machineBarrier() override
Méthode permettant de faire une barrière pour les sous-domaines du noeud de calcul.
Implémentation de IRequestList pour SharedMemoryParallelMng.
void _wait(Parallel::eWaitType wait_type) override
Effectue l'attente ou le test.
IParallelTopology * createTopology() override
Créé une instance contenant les infos sur la topologie des rangs de ce gestionnnaire.
IGetVariablesValuesParallelOperation * createGetVariablesValuesOperation() override
Retourne une opération pour récupérer les valeurs d'une variable sur les entités d'un autre sous-doma...
Ref< Parallel::IRequestList > createRequestListRef() override
Créé une liste de requêtes pour ce gestionnaire.
void build() override
Construit l'instance.
Int32 m_nb_rank
Nombre de rangs.
bool m_is_initialized
true si déjà initialisé
void printStats() override
Affiche des statistiques liées à ce gestionnaire du parallélisme.
void initialize() override
Initialise le gestionnaire du parallélisme.
void barrier() override
Effectue une barière.
void setReplication(IParallelReplication *v) override
Positionne les Informations sur la réplication.
PointToPointMessageInfo buildMessage(Int32 dest, MP::eBlockingType is_blocking)
Construit un message avec pour destinataire dest.
void waitAllRequests(ArrayView< Request > requests) override
Bloque en attendant que les requêtes rvalues soient terminées.
Ref< IParallelMngUtilsFactory > _internalUtilsFactory() const override
Fabrique des fonctions utilitaires.
IVariableSynchronizer * createSynchronizer(IItemFamily *family) override
Retourne une interface pour synchroniser des variables sur le groupe de la famille family.
MessageId probe(const PointToPointMessageInfo &message) override
Sonde si des messages sont disponibles.
ISerializeMessage * createSendSerializer(Int32 rank) override
Créé un message non bloquant pour envoyer des données sérialisées au rang rank.
ITraceMng * traceMng() const override
Gestionnaire de trace associé à cette instance.
IParallelMng * sequentialParallelMng() override
Retourne un gestionnaire de parallélisme séquentiel.
Int32 m_rank
Rang de l'instance.
IParallelExchanger * createExchanger() override
Retourne une interface pour transférer des messages entre processeurs.
void freeRequests(ArrayView< Parallel::Request > requests) override
Libère les requêtes.
ISerializeMessage * createReceiveSerializer(Int32 rank) override
Créé un message non bloquant pour recevoir des données sérialisées du rang rank.
Ref< IParallelMng > createSubParallelMngRef(Int32ConstArrayView kept_ranks) override
Créé un nouveau gestionnaire de parallélisme pour un sous-ensemble des rangs.
ITransferValuesParallelOperation * createTransferValuesOperation() override
Retourne une opération pour transférer des valeurs entre sous-domaine.
MessageSourceInfo legacyProbe(const PointToPointMessageInfo &message) override
Sonde si des messages sont disponibles.
IParallelReplication * replication() const override
Informations sur la réplication.
Classe de base d'une liste de requêtes.
Exception lorsqu'une fonction n'est pas implémentée.
Exception lorsqu'une opération n'est pas supportée.
Redirige la gestion des messages des sous-domaines suivant le type de l'argument.
IMessagePassingMng * messagePassingMng() const override
Gestionnaire de message de Arccore associé
Classe de base d'une fabrique pour les fonctions utilitaires de IParallelMng.
Informations sur la réplication des sous-domaines en parallèle.
InstanceType * get() const
Instance associée ou nullptr si aucune.
Référence à une instance.
Positionne une classe de message.
Vecteur 1D de données avec sémantique par valeur (style STL).
Déclarations des types et méthodes utilisés par les mécanismes d'échange de messages.
@ WaitSome
Attend que tous les messages de la liste soient traités.
eBlockingType
Type indiquant si un message est bloquant ou non.
Implémentation de la concurrence.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Ref< TrueType > createRef(Args &&... args)
Créé une instance de type TrueType avec les arguments Args et retourne une référence dessus.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
Array< Byte > ByteArray
Tableau dynamique à une dimension de caractères.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
double Real
Type représentant un réel.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.
Infos pour construire un SharedMemoryParallelMng.