Arcane  v4.1.1.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
AcceleratorCore.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* AcceleratorCore.cc (C) 2000-2025 */
9/* */
10/* Déclarations générales pour le support des accélérateurs. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/base/FatalErrorException.h"
15
16#include "arccore/common/accelerator/internal/AcceleratorCoreGlobalInternal.h"
17#include "arccore/common/accelerator/internal/IRunnerRuntime.h"
18
19#include "arccore/common/accelerator/DeviceInfoList.h"
20#include "arccore/common/accelerator/PointerAttribute.h"
21#include "arccore/common/accelerator/ViewBuildInfo.h"
22#include "arccore/common/accelerator/RunCommand.h"
23#include "arccore/common/accelerator/RunQueue.h"
24
25// Pas utilisé mais nécessaire pour les exports de symboles.
26#include "arccore/common/accelerator/IAcceleratorMng.h"
27
28#include <iostream>
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33/*!
34 * \namespace Arcane::Accelerator
35 *
36 * \brief Espace de nom pour l'utilisation des accélérateurs.
37 *
38 * Toutes les classes et types utilisés pour la gestion des accélérateurs
39 * sont dans ce namespace.
40 */
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45namespace Arcane::Accelerator
46{
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51namespace
52{
53 bool global_is_using_cuda_runtime = false;
54 impl::IRunnerRuntime* global_cuda_runqueue_runtime = nullptr;
55 bool global_is_using_hip_runtime = false;
56 impl::IRunnerRuntime* global_hip_runqueue_runtime = nullptr;
57 bool global_is_using_sycl_runtime = false;
58 impl::IRunnerRuntime* global_sycl_runqueue_runtime = nullptr;
59} // namespace
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64extern "C++" ARCCORE_COMMON_EXPORT bool impl::
65isUsingCUDARuntime()
66{
67 return global_is_using_cuda_runtime;
68}
69
70extern "C++" ARCCORE_COMMON_EXPORT void impl::
71setUsingCUDARuntime(bool v)
72{
73 global_is_using_cuda_runtime = v;
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79//! Récupère l'implémentation CUDA de RunQueue
80extern "C++" ARCCORE_COMMON_EXPORT impl::IRunnerRuntime* impl::
81getCUDARunQueueRuntime()
82{
83 return global_cuda_runqueue_runtime;
84}
85
86//! Positionne l'implémentation CUDA de RunQueue.
87extern "C++" ARCCORE_COMMON_EXPORT void impl::
88setCUDARunQueueRuntime(IRunnerRuntime* v)
89{
90 global_cuda_runqueue_runtime = v;
91}
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96extern "C++" ARCCORE_COMMON_EXPORT bool impl::
97isUsingHIPRuntime()
98{
99 return global_is_using_hip_runtime;
100}
101
102extern "C++" ARCCORE_COMMON_EXPORT void impl::
103setUsingHIPRuntime(bool v)
104{
105 global_is_using_hip_runtime = v;
106}
107
108/*---------------------------------------------------------------------------*/
109/*---------------------------------------------------------------------------*/
110
111//! Récupère l'implémentation HIP de RunQueue
112extern "C++" ARCCORE_COMMON_EXPORT impl::IRunnerRuntime* impl::
113getHIPRunQueueRuntime()
114{
115 return global_hip_runqueue_runtime;
116}
117
118//! Positionne l'implémentation HIP de RunQueue.
119extern "C++" ARCCORE_COMMON_EXPORT void impl::
120setHIPRunQueueRuntime(impl::IRunnerRuntime* v)
121{
122 global_hip_runqueue_runtime = v;
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
128extern "C++" ARCCORE_COMMON_EXPORT bool impl::
129isUsingSYCLRuntime()
130{
131 return global_is_using_sycl_runtime;
132}
133
134extern "C++" ARCCORE_COMMON_EXPORT void impl::
135setUsingSYCLRuntime(bool v)
136{
137 global_is_using_sycl_runtime = v;
138}
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
143extern "C++" ARCCORE_COMMON_EXPORT impl::IRunnerRuntime* impl::
144getSYCLRunQueueRuntime()
145{
146 return global_hip_runqueue_runtime;
147}
148
149extern "C++" ARCCORE_COMMON_EXPORT void impl::
150setSYCLRunQueueRuntime(impl::IRunnerRuntime* v)
151{
152 global_hip_runqueue_runtime = v;
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
158//! Affiche le nom de la politique d'exécution
159extern "C++" ARCCORE_COMMON_EXPORT
160std::ostream&
161operator<<(std::ostream& o, eExecutionPolicy exec_policy)
162{
163 switch (exec_policy) {
165 o << "None";
166 break;
168 o << "Sequential";
169 break;
171 o << "Thread";
172 break;
174 o << "CUDA";
175 break;
177 o << "HIP";
178 break;
180 o << "SYCL";
181 break;
182 }
183 return o;
184}
185
186/*---------------------------------------------------------------------------*/
187/*---------------------------------------------------------------------------*/
188
189std::ostream& operator<<(std::ostream& o, const DeviceId& device_id)
190{
191 o << device_id.asInt32();
192 return o;
193}
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
198std::ostream&
199operator<<(std::ostream& o, ePointerMemoryType mem_type)
200{
201 switch (mem_type) {
202 case ePointerMemoryType::Unregistered:
203 o << "Unregistered";
204 break;
205 case ePointerMemoryType::Host:
206 o << "Host";
207 break;
208 case ePointerMemoryType::Device:
209 o << "Device";
210 break;
211 case ePointerMemoryType::Managed:
212 o << "Managed";
213 break;
214 }
215 return o;
216}
217
218/*---------------------------------------------------------------------------*/
219/*---------------------------------------------------------------------------*/
220
221extern "C++" impl::IRunnerRuntime* impl::
222getAcceleratorRunnerRuntime()
223{
224 if (isUsingCUDARuntime())
225 return getCUDARunQueueRuntime();
226 if (isUsingHIPRuntime())
227 return getHIPRunQueueRuntime();
228 if (isUsingSYCLRuntime())
229 return getSYCLRunQueueRuntime();
230 return nullptr;
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
236ePointerAccessibility impl::RuntimeStaticInfo::
237getPointerAccessibility(eExecutionPolicy policy, const void* ptr, PointerAttribute* ptr_attr)
238{
239 // Regarde si le pointeur est accessible pour la politique d'exécution donnée.
240 // Le seul cas où on peut le savoir exactement est si on a un runtime
241 // accélérateur et que la valeur retournée par getPointeAttribute() est valide.
242 if (policy == eExecutionPolicy::None)
244 IRunnerRuntime* r = getAcceleratorRunnerRuntime();
245 if (!r)
247 PointerAttribute attr;
248 r->getPointerAttribute(attr, ptr);
249 if (ptr_attr) {
250 *ptr_attr = attr;
251 }
252 if (attr.isValid()) {
253 if (isAcceleratorPolicy(policy))
254 return attr.devicePointer() ? ePointerAccessibility::Yes : ePointerAccessibility::No;
255 else {
256 if (attr.memoryType() == ePointerMemoryType::Unregistered)
258 return attr.hostPointer() ? ePointerAccessibility::Yes : ePointerAccessibility::No;
259 }
260 }
262}
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
267void impl::RuntimeStaticInfo::
268checkPointerIsAcccessible(eExecutionPolicy policy, const void* ptr,
269 const char* name, const TraceInfo& ti)
270{
271 // Le pointeur nul est toujours accessible.
272 if (!ptr)
273 return;
274 PointerAttribute ptr_attr;
275 ePointerAccessibility a = getPointerAccessibility(policy, ptr, &ptr_attr);
276 if (a == ePointerAccessibility::No) {
277 auto s = String::format("Pointer 'addr={0}' ({1}) is not accessible "
278 "for this execution policy ({2}).\n PointerInfo: {3}",
279 ptr, name, policy, ptr_attr);
280
281 throw FatalErrorException(ti, s);
282 }
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288extern "C++" ePointerAccessibility
290{
291 return impl::RuntimeStaticInfo::getPointerAccessibility(policy, ptr, ptr_attr);
292}
293
294void impl::
295arcaneCheckPointerIsAccessible(eExecutionPolicy policy, const void* ptr,
296 const char* name, const TraceInfo& ti)
297{
298 return impl::RuntimeStaticInfo::checkPointerIsAcccessible(policy, ptr, name, ti);
299}
300
301/*---------------------------------------------------------------------------*/
302/*---------------------------------------------------------------------------*/
303
304void impl::
305printUUID(std::ostream& o, char bytes[16])
306{
307 static const char hexa_chars[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
308
309 for (int i = 0; i < 16; ++i) {
310 o << hexa_chars[(bytes[i] >> 4) & 0xf];
311 o << hexa_chars[bytes[i] & 0xf];
312 if (i == 4 || i == 6 || i == 8 || i == 10)
313 o << '-';
314 }
315}
316
317/*---------------------------------------------------------------------------*/
318/*---------------------------------------------------------------------------*/
319
320std::ostream&
321operator<<(std::ostream& o, const PointerAttribute& a)
322{
323 o << "(mem_type=" << a.memoryType() << ", ptr=" << a.originalPointer()
324 << ", host_ptr=" << a.hostPointer()
325 << ", device_ptr=" << a.devicePointer() << " device=" << a.device() << ")";
326 return o;
327}
328
329/*---------------------------------------------------------------------------*/
330/*---------------------------------------------------------------------------*/
331
333ViewBuildInfo(const RunQueue& queue)
334: m_queue_impl(queue._internalImpl())
335{}
336
337/*---------------------------------------------------------------------------*/
338/*---------------------------------------------------------------------------*/
339
341ViewBuildInfo(const RunQueue* queue)
342: m_queue_impl(queue->_internalImpl())
343{}
344
345/*---------------------------------------------------------------------------*/
346/*---------------------------------------------------------------------------*/
347
350: m_queue_impl(command._internalQueueImpl())
351{
352}
353
354/*---------------------------------------------------------------------------*/
355/*---------------------------------------------------------------------------*/
356
357} // namespace Arcane::Accelerator
358
359/*---------------------------------------------------------------------------*/
360/*---------------------------------------------------------------------------*/
ViewBuildInfo(const RunQueue &queue)
Créé instance associée a la file queue.
Espace de nom pour l'utilisation des accélérateurs.
ePointerAccessibility getPointerAccessibility(eExecutionPolicy policy, const void *ptr, PointerAttribute *ptr_attr)
Accessibilité de l'adresse ptr pour une politique d'exécutionpolicy.
ePointerAccessibility
Informations d'accessibilité d'une adresse mémoire.
ePointerMemoryType
Type de mémoire pour un pointeur.
eExecutionPolicy
Politique d'exécution pour un Runner.
@ SYCL
Politique d'exécution utilisant l'environnement SYCL.
@ HIP
Politique d'exécution utilisant l'environnement HIP.
@ CUDA
Politique d'exécution utilisant l'environnement CUDA.
@ Sequential
Politique d'exécution séquentielle.
@ Thread
Politique d'exécution multi-thread.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indique si exec_policy correspond à un accélérateur.
std::ostream & operator<<(std::ostream &ostr, eItemKind item_kind)
Opérateur de sortie sur un flot.