Arcane  v4.1.4.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArcaneMpi.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/* ArcaneMpi.cc (C) 2000-2026 */
9/* */
10/* Déclarations globales pour la partie MPI de Arcane. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/parallel/mpi/ArcaneMpi.h"
15
16#include "arcane/utils/String.h"
17#include "arcane/impl/ArcaneMain.h"
18#include "arcane/ApplicationBuildInfo.h"
19
20#include <iostream>
21
22// Ce fichier est utilisé par OpenMpi pour définir des extensions
23// La page https://www.open-mpi.org/faq/?category=runcuda
24// indique comment détecter si on est CUDA-AWARE.
25
26#if __has_include(<mpi-ext.h>)
27#include <mpi-ext.h>
28#endif
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39extern "C++" ARCANE_MPI_EXPORT bool
41{
42 bool is_aware = false;
43 // OpenMPI définit MPIX_CUDA_AWARE_SUPPORT et mpich définit MPIX_GPU_SUPPORT_CUDA
44 // pour indiquer que MPIX_Query_cuda_support() est disponible.
45#if defined(ARCANE_OS_LINUX)
46#if defined(MPIX_CUDA_AWARE_SUPPORT) || defined(MPIX_GPU_SUPPORT_CUDA)
47 is_aware = (MPIX_Query_cuda_support()==1);
48#endif
49#endif
50 return is_aware;
51}
52
53extern "C++" ARCANE_MPI_EXPORT bool
54arcaneIsHipAwareMPI()
55{
56 bool is_aware = false;
57 // OpenMPI définit MPIX_HIP_AWARE_SUPPORT et mpich définit MPIX_GPU_SUPPORT_HIP
58 // pour indiquer que MPIX_Query_hip_support() est disponible.
59
60 // MPICH
61#if defined(ARCANE_OS_LINUX)
62#if defined(MPIX_GPU_SUPPORT_HIP)
63 // CRAY MPICH
64# if defined(CRAY_MPICH_VERSION)
65 int is_supported = 0;
66 MPIX_GPU_query_support(MPIX_GPU_SUPPORT_HIP,&is_supported);
67 is_aware = (is_supported!=0);
68# else
69 is_aware = (MPIX_Query_hip_support()==1);
70# endif
71#endif
72
73 // OpenMPI:
74#if defined(MPIX_ROCM_AWARE_SUPPORT)
75 is_aware = (MPIX_Query_rocm_support()==1);
76#endif
77#endif
78 return is_aware;
79}
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
84extern "C++" ARCANE_MPI_EXPORT bool
86{
87 return arcaneIsCudaAwareMPI() || arcaneIsHipAwareMPI();
88}
89
90/*---------------------------------------------------------------------------*/
91/*---------------------------------------------------------------------------*/
97class MpiAutoInit
98{
99 public:
100
101 MpiAutoInit() = default;
102
103 public:
104
105 void initialize(int* argc,char*** argv,int wanted_thread_level)
106 {
107 int is_init = 0;
108 MPI_Initialized(&is_init);
109
110 if (is_init!=0)
111 return;
112
113 int thread_provided = 0;
114 MPI_Init_thread(argc, argv, wanted_thread_level, &thread_provided);
115 m_need_finalize = true;
116 }
117
118 void finalize()
119 {
120 if (m_need_finalize){
121 MPI_Finalize();
122 m_need_finalize = false;
123 }
124 }
125
126 private:
127
128 bool m_need_finalize = false;
129};
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
133
136{
137 public:
138 void visit(ApplicationBuildInfo& app_build_info) override;
139};
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
157visit(ApplicationBuildInfo& app_build_info)
158{
159 String message_passing_service = app_build_info.messagePassingService();
160 bool need_init = message_passing_service != "SequentialParallelSuperMng";
161 bool has_shared_memory_message_passing = app_build_info.nbSharedMemorySubDomain()>0;
162
163 // Si MPI n'a pas été initialisé, on le fait ici.
164 // On choisit le niveau de thread en fonction du nombre de
165 // sous-domaines en mémoire partagée spécifié. Si pas de mémoire
166 // partagée, prend MPI_THREAD_SERIALIZED.
167 int thread_wanted = MPI_THREAD_SERIALIZED;
168 if (has_shared_memory_message_passing)
169 thread_wanted = MPI_THREAD_MULTIPLE;
170
171 int comm_size = 0;
172
173 // On ne fait pas l'initialisation si le service demandé est 'Sequential'.
174 if (need_init){
175 // TODO: utiliser les bons arguments.
176 int* argc = nullptr;
177 char*** argv = nullptr;
178 arcaneInitializeMPI(argc,argv,thread_wanted);
179
180 MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
181 }
182
183 // Positionne le service d'échange par défaut.
184 // A noter que ce ne sera pas utilisé si l'utilisateur
185 // a lui même spécifié un service
186 message_passing_service = "Sequential";
187 if (comm_size>1){
188 if (has_shared_memory_message_passing)
189 message_passing_service = "Hybrid";
190 else
191 message_passing_service = "Mpi";
192 }
193 else{
194 if (has_shared_memory_message_passing)
195 message_passing_service = "MpiSharedMemory";
196 else
197 message_passing_service = "MpiSequential";
198 }
199 message_passing_service = message_passing_service + "ParallelSuperMng";
200 // Change le service par défaut.
201 app_build_info.internalSetDefaultMessagePassingService(message_passing_service);
202}
203
204/*---------------------------------------------------------------------------*/
205/*---------------------------------------------------------------------------*/
206
207namespace
208{
209MpiAutoInit global_mpi_auto_init;
210AutoDetecterMPI global_autodetecter_mpi;
211bool global_already_added = false;
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217extern "C" ARCANE_MPI_EXPORT void
219{
220 if (!global_already_added)
221 ArcaneMain::addApplicationBuildInfoVisitor(&global_autodetecter_mpi);
222 global_already_added = true;
223}
224
225extern "C++" ARCANE_MPI_EXPORT void
226arcaneInitializeMPI(int* argc,char*** argv,int wanted_thread_level)
227{
228 global_mpi_auto_init.initialize(argc,argv,wanted_thread_level);
229}
230
231extern "C++" ARCANE_MPI_EXPORT void
233{
234 global_mpi_auto_init.finalize();
235}
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
240} // End namespace Arcane.
241
242/*---------------------------------------------------------------------------*/
243/*---------------------------------------------------------------------------*/
Informations pour construire une instance de IApplication.
void internalSetDefaultMessagePassingService(const String &name)
Nom du gestionnaire de message par défaut. Ne doit être modifié que par Arcane.
static void addApplicationBuildInfoVisitor(IApplicationBuildInfoVisitor *visitor)
Ajoute un visiteur pour remplir ApplicationBuildInfo.
void visit(ApplicationBuildInfo &app_build_info) override
Remplit les valeurs par défaut pour les services d'échange de message.
Definition ArcaneMpi.cc:157
Classe singleton pour appeler automatiquement MPI_Init et MPI_Finalize si besoin. On appelle MPI_Fina...
Definition ArcaneMpi.cc:98
Chaîne de caractères unicode.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ARCANE_MPI_EXPORT void arcaneInitializeMPI(int *argc, char ***argv, int wanted_thread_level)
Definition ArcaneMpi.cc:226
ARCANE_MPI_EXPORT bool arcaneIsAcceleratorAwareMPI()
Indique si le runtime actuel de MPI a le support des accélérateurs.
Definition ArcaneMpi.cc:85
ARCANE_MPI_EXPORT bool arcaneIsCudaAwareMPI()
Indique si le runtime actuel de MPI a le support de CUDA.
Definition ArcaneMpi.cc:40
ARCANE_MPI_EXPORT void arcaneAutoDetectMessagePassingServiceMPI()
Mécanisme pour initialiser automatiquement MPI et les services d'échange de messages de Arcane en fon...
Definition ArcaneMpi.cc:218
ARCANE_MPI_EXPORT void arcaneFinalizeMPI()
Definition ArcaneMpi.cc:232