Arcane  v3.15.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Runner.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/* Runner.cc (C) 2000-2025 */
9/* */
10/* Gestion de l'exécution sur accélérateur. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/accelerator/core/Runner.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/NotImplementedException.h"
19#include "arcane/utils/ArgumentException.h"
20#include "arcane/utils/MemoryView.h"
21#include "arcane/utils/ValueConvert.h"
22#include "arcane/utils/Profiling.h"
23#include "arcane/utils/internal/ProfilingInternal.h"
24
25#include "arcane/accelerator/core/RunQueueBuildInfo.h"
26#include "arcane/accelerator/core/DeviceId.h"
27#include "arcane/accelerator/core/DeviceMemoryInfo.h"
28#include "arcane/accelerator/core/IDeviceInfoList.h"
29#include "arcane/accelerator/core/PointerAttribute.h"
30#include "arcane/accelerator/core/internal/IRunnerRuntime.h"
31#include "arcane/accelerator/core/internal/AcceleratorCoreGlobalInternal.h"
32#include "arcane/accelerator/core/internal/RunQueueImpl.h"
33#include "arcane/accelerator/core/internal/RunnerImpl.h"
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38namespace Arcane::Accelerator
39{
40
41namespace
42{
43 inline impl::IRunnerRuntime*
44 _getRuntimeNoCheck(eExecutionPolicy p)
45 {
46 impl::IRunnerRuntime* runtime = nullptr;
47 switch (p) {
49 ARCANE_FATAL("No runtime for eExecutionPolicy::None");
51 return impl::getSYCLRunQueueRuntime();
53 return impl::getHIPRunQueueRuntime();
55 return impl::getCUDARunQueueRuntime();
57 return impl::getSequentialRunQueueRuntime();
59 return impl::getThreadRunQueueRuntime();
60 }
61 return runtime;
62 }
63
64 inline impl::IRunnerRuntime*
65 _getRuntime(eExecutionPolicy p)
66 {
67 auto* x = _getRuntimeNoCheck(p);
68 if (!x)
69 ARCANE_FATAL("No runtime is available for execution policy '{0}'", p);
70 return x;
71 }
72
73 inline void
74 _stopProfiling(eExecutionPolicy p)
75 {
76 auto* x = _getRuntimeNoCheck(p);
77 if (x)
78 x->stopProfiling();
79 }
80 inline void
81 _finalize(eExecutionPolicy p, ITraceMng* tm)
82 {
83 auto* x = _getRuntimeNoCheck(p);
84 if (x) {
85 x->stopProfiling();
86 x->finalize(tm);
87 }
88 }
89} // namespace
90
91} // namespace Arcane::Accelerator
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96namespace Arcane::Accelerator::impl
97{
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
102void RunnerImpl::
103initialize(Runner* runner, eExecutionPolicy v, DeviceId device)
104{
105 if (m_is_init)
106 ARCANE_FATAL("Runner is already initialized");
107 if (v == eExecutionPolicy::None)
108 ARCANE_THROW(ArgumentException, "executionPolicy should not be eExecutionPolicy::None");
109 if (device.isHost() || device.isNull())
110 ARCANE_THROW(ArgumentException, "device should not be Device::hostDevice() or Device::nullDevice()");
111
112 m_execution_policy = v;
113 m_device_id = device;
114 m_runtime = _getRuntime(v);
115 m_is_init = true;
117
118 // Pour test
119 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACCELERATOR_PREFETCH_COMMAND", true))
120 m_is_auto_prefetch_command = (v.value() != 0);
121
122 // Il faut initialiser le pool à la fin car il a besoin d'accéder à \a m_runtime
123 m_run_queue_pool.initialize(runner->_impl());
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
128
129void RunnerImpl::
130_checkIsInit() const
131{
132 if (!m_is_init)
133 ARCANE_FATAL("Runner is not initialized. Call method initialize() before");
134}
135
136/*---------------------------------------------------------------------------*/
137/*---------------------------------------------------------------------------*/
138
139void RunnerImpl::
140_freePool()
141{
142 RunQueueImplStack& s = m_run_queue_pool;
143 while (!s.empty()) {
144 RunQueueImpl* q = s.top();
145 RunQueueImpl::_destroy(q);
146 s.pop();
147 }
148}
149
150/*---------------------------------------------------------------------------*/
151/*---------------------------------------------------------------------------*/
152
153RunQueueImplStack* RunnerImpl::
154getPool()
155{
156 return &m_run_queue_pool;
157}
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
162void RunnerImpl::
163_internalPutRunQueueImplInPool(RunQueueImpl* p)
164{
165 RunnerImpl::Lock my_lock(this);
166 getPool()->push(p);
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
172impl::RunQueueImpl* RunnerImpl::
173_internalCreateOrGetRunQueueImpl()
174{
175 _checkIsInit();
176
177 auto pool = getPool();
178
179 {
180 impl::RunnerImpl::Lock my_lock(this);
181 if (!pool->empty()) {
182 impl::RunQueueImpl* p = pool->top();
183 pool->pop();
184 return p;
185 }
186 }
187
188 return pool->createRunQueue(RunQueueBuildInfo{});
189}
190
191/*---------------------------------------------------------------------------*/
192/*---------------------------------------------------------------------------*/
193
194impl::RunQueueImpl* RunnerImpl::
195_internalCreateOrGetRunQueueImpl(const RunQueueBuildInfo& bi)
196{
197 _checkIsInit();
198 // Si on utilise les paramètres par défaut, on peut utilier une RunQueueImpl
199 // issue du pool.
200 if (bi.isDefault())
201 return _internalCreateOrGetRunQueueImpl();
202 impl::IRunnerRuntime* runtime = m_runtime;
203 ARCANE_CHECK_POINTER(runtime);
204 auto* queue = new impl::RunQueueImpl(this, 0, bi);
205 return queue;
206}
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
210
211RunQueueImpl* RunQueueImplStack::
212createRunQueue(const RunQueueBuildInfo& bi)
213{
214 if (!m_runner_impl)
215 ARCANE_FATAL("RunQueueImplStack is not initialized");
216 Int32 x = ++m_nb_created;
217 auto* q = new impl::RunQueueImpl(m_runner_impl, x, bi);
218 q->m_is_in_pool = true;
219 return q;
220}
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
225IRunQueueEventImpl* RunnerImpl::
226_createEvent()
227{
228 _checkIsInit();
229 return m_runtime->createEventImpl();
230}
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
235IRunQueueEventImpl* RunnerImpl::
236_createEventWithTimer()
237{
238 _checkIsInit();
239 return m_runtime->createEventImplWithTimer();
240}
241
242/*---------------------------------------------------------------------------*/
243/*---------------------------------------------------------------------------*/
244
245} // namespace Arcane::Accelerator::impl
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
250namespace Arcane::Accelerator
251{
252
253/*---------------------------------------------------------------------------*/
254/*---------------------------------------------------------------------------*/
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
260Runner()
261: m_p(std::make_shared<impl::RunnerImpl>())
262{
263}
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
291impl::IRunnerRuntime* Runner::
292_internalRuntime() const
293{
294 _checkIsInit();
295 return m_p->runtime();
296}
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
300
302executionPolicy() const
303{
304 return m_p->executionPolicy();
305}
306
307/*---------------------------------------------------------------------------*/
308/*---------------------------------------------------------------------------*/
309
311isInitialized() const
312{
313 return m_p->isInit();
314}
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
321{
322 // Toujours thread-safe;
323}
324
325/*---------------------------------------------------------------------------*/
326/*---------------------------------------------------------------------------*/
327
330{
331 return true;
332}
333
334/*---------------------------------------------------------------------------*/
335/*---------------------------------------------------------------------------*/
336
339{
341 std::cout << "Warning: Runner::setDeviceReducePolicy(): only 'eDeviceReducePolicy::Grid' is supported\n";
342}
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
348deviceReducePolicy() const
349{
350 return m_p->m_reduce_policy;
351}
352
353/*---------------------------------------------------------------------------*/
354/*---------------------------------------------------------------------------*/
355
358{
359 m_p->initialize(this, v, DeviceId());
360}
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
367{
368 m_p->initialize(this, v, device_id);
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
373
374void Runner::
375_checkIsInit() const
376{
377 if (!m_p->m_is_init)
378 ARCANE_FATAL("Runner is not initialized. Call method initialize() before");
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
386{
387 return m_p->cumulativeCommandTime();
388}
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
394setMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
395{
396 _checkIsInit();
397 m_p->runtime()->setMemoryAdvice(buffer, advice, m_p->m_device_id);
398}
399
400/*---------------------------------------------------------------------------*/
401/*---------------------------------------------------------------------------*/
402
404unsetMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
405{
406 _checkIsInit();
407 m_p->runtime()->unsetMemoryAdvice(buffer, advice, m_p->m_device_id);
408}
409
410/*---------------------------------------------------------------------------*/
411/*---------------------------------------------------------------------------*/
412
415{
416 _checkIsInit();
417 m_p->runtime()->setCurrentDevice(m_p->m_device_id);
418}
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422
424deviceId() const
425{
426 return m_p->m_device_id;
427}
428
429/*---------------------------------------------------------------------------*/
430/*---------------------------------------------------------------------------*/
431
433deviceInfo() const
434{
435 _checkIsInit();
437 Int32 nb_device = dlist->nbDevice();
438 if (nb_device == 0)
439 ARCANE_FATAL("Internal error: no device available");
440 Int32 device_id = deviceId().asInt32();
441 if (device_id >= nb_device)
442 device_id = 0;
443 return dlist->deviceInfo(device_id);
444}
445
446/*---------------------------------------------------------------------------*/
447/*---------------------------------------------------------------------------*/
448
451{
453 return nullptr;
455 return r->deviceInfoList();
456}
457
458/*---------------------------------------------------------------------------*/
459/*---------------------------------------------------------------------------*/
460
462deviceMemoryInfo() const
463{
464 _checkIsInit();
465 return m_p->runtime()->getDeviceMemoryInfo(deviceId());
466}
467
468/*---------------------------------------------------------------------------*/
469/*---------------------------------------------------------------------------*/
470
472fillPointerAttribute(PointerAttribute& attr, const void* ptr)
473{
474 _checkIsInit();
475 m_p->runtime()->getPointerAttribute(attr, ptr);
476}
477
478/*---------------------------------------------------------------------------*/
479/*---------------------------------------------------------------------------*/
480
481bool Runner::
482_isAutoPrefetchCommand() const
483{
484 return m_p->isAutoPrefetchCommand();
485}
486
487/*---------------------------------------------------------------------------*/
488/*---------------------------------------------------------------------------*/
489
492{
493 return m_p->_internalApi();
494}
495
496/*---------------------------------------------------------------------------*/
497/*---------------------------------------------------------------------------*/
511
512/*---------------------------------------------------------------------------*/
513/*---------------------------------------------------------------------------*/
514
517{
518 _finalize(eExecutionPolicy::CUDA, tm);
519 _finalize(eExecutionPolicy::HIP, tm);
521 _finalize(eExecutionPolicy::Thread, tm);
522}
523
524/*---------------------------------------------------------------------------*/
525/*---------------------------------------------------------------------------*/
526
529{
530 m_runner_impl->runtime()->startProfiling();
531}
532
533/*---------------------------------------------------------------------------*/
534/*---------------------------------------------------------------------------*/
535
538{
539 m_runner_impl->runtime()->stopProfiling();
540}
541
542/*---------------------------------------------------------------------------*/
543/*---------------------------------------------------------------------------*/
544
547{
548 return m_runner_impl->runtime()->isProfilingActive();
549}
550
551/*---------------------------------------------------------------------------*/
552/*---------------------------------------------------------------------------*/
553
555printProfilingInfos(std::ostream& o)
556{
558 if (is_active)
560
561 {
562 // Affiche les statistiques de profiling.
564 auto f = [&](const AcceleratorStatInfoList& stat_list) {
565 stat_list.print(o);
566 };
568 }
569
570 if (is_active)
572}
573
574/*---------------------------------------------------------------------------*/
575/*---------------------------------------------------------------------------*/
576
577extern "C++" ePointerAccessibility
579{
580 if (!runner)
582 return impl::RuntimeStaticInfo::getPointerAccessibility(runner->executionPolicy(), ptr, ptr_attr);
583}
584
585extern "C++" void impl::
586arcaneCheckPointerIsAccessible(const Runner* runner, const void* ptr,
587 const char* name, const TraceInfo& ti)
588{
589 if (!runner)
590 return;
591 return impl::RuntimeStaticInfo::checkPointerIsAcccessible(runner->executionPolicy(), ptr, name, ti);
592}
593
594/*---------------------------------------------------------------------------*/
595/*---------------------------------------------------------------------------*/
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
600void impl::IRunnerRuntime::
601_fillPointerAttribute(PointerAttribute& attribute,
603 int device, const void* pointer, const void* device_pointer,
604 const void* host_pointer)
605{
607}
608
609/*---------------------------------------------------------------------------*/
610/*---------------------------------------------------------------------------*/
611
612void impl::IRunnerRuntime::
613_fillPointerAttribute(PointerAttribute& attribute, const void* pointer)
614{
615 attribute = PointerAttribute(pointer);
616}
617
618/*---------------------------------------------------------------------------*/
619/*---------------------------------------------------------------------------*/
620
621} // namespace Arcane::Accelerator
622
623/*---------------------------------------------------------------------------*/
624/*---------------------------------------------------------------------------*/
#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.
Identifiant d'un composant du système.
Definition DeviceId.h:33
Int32 asInt32() const
Valeur numérique du device.
Definition DeviceId.h:69
Information sur un device.
Definition DeviceInfo.h:32
Information mémoire d'un accélérateur.
Interface d'une liste de devices.
Informations sur une adresse mémoire.
static void finalize(ITraceMng *tm)
Finalise l'exécution.
Definition Runner.cc:516
void startProfiling()
Démarre le profiling pour le runtime associé
Definition Runner.cc:528
bool isProfilingActive()
Indique si le profiling est actif pour le runtime associé
Definition Runner.cc:546
static void stopAllProfiling()
Stoppe toutes les activités de profiling.
Definition Runner.cc:504
void stopProfiling()
Stoppe le profiling pour le runtime associé
Definition Runner.cc:537
void printProfilingInfos(std::ostream &o)
Affiche les informations de profiling.
Definition Runner.cc:555
Gestionnaire d'exécution pour accélérateur.
Definition core/Runner.h:68
void fillPointerAttribute(PointerAttribute &attr, const void *ptr)
Remplit attr avec les informations concernant la zone mémoire pointée par ptr.
Definition Runner.cc:472
void setConcurrentQueueCreation(bool v)
Indique si on autorise la création de RunQueue depuis plusieurs threads.
Definition Runner.cc:320
static const IDeviceInfoList * deviceInfoList(eExecutionPolicy policy)
Liste des devices pour la politique d'exécution policy.
Definition Runner.cc:450
bool isInitialized() const
Indique si l'instance a été initialisée.
Definition Runner.cc:311
Runner()
Créé un gestionnaire d'exécution non initialisé.
Definition Runner.cc:260
RunnerInternal * _internalApi()
API interne à Arcane.
Definition Runner.cc:491
double cumulativeCommandTime() const
Temps total passé dans les commandes associées à cette instance.
Definition Runner.cc:385
bool isConcurrentQueueCreation() const
Indique si la création concurrent de plusieurs RunQueue est autorisé
Definition Runner.cc:329
DeviceId deviceId() const
Device associé à cette instance.
Definition Runner.cc:424
void setDeviceReducePolicy(eDeviceReducePolicy v)
Positionne la politique d'exécution des réductions.
Definition Runner.cc:338
const DeviceInfo & deviceInfo() const
Information sur le device associé à cette instance.
Definition Runner.cc:433
DeviceMemoryInfo deviceMemoryInfo() const
Information sur le device associé à cette instance.
Definition Runner.cc:462
void initialize(eExecutionPolicy v)
Initialise l'instance. Cette méthode ne doit être appelée qu'une seule fois.
Definition Runner.cc:357
void setAsCurrentDevice()
Positionne le device associé à cette instance comme le device par défaut du contexte.
Definition Runner.cc:414
eDeviceReducePolicy deviceReducePolicy() const
politique d'exécution des réductions
Definition Runner.cc:348
void setMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
Positionne un conseil sur la gestion d'une zone mémoire.
Definition Runner.cc:394
void unsetMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
Supprime un conseil sur la gestion d'une zone mémoire.
Definition Runner.cc:404
eExecutionPolicy executionPolicy() const
Politique d'exécution associée.
Definition Runner.cc:302
Interface du runtime associé à un accélérateur.
bool m_is_auto_prefetch_command
Indique si on pré-copie les données avant une commande de cette RunQueue.
Definition RunnerImpl.h:154
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
static void visitAcceleratorStat(const std::function< void(const impl::AcceleratorStatInfoList &)> &f)
Visite la liste des statistiques sur accélérateur.
Definition Profiling.cc:221
Statistiques pour les accélérateurs.
Interface du gestionnaire de traces.
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.
eDeviceReducePolicy
Politique des opératations de réduction sur les accélérateurs.
@ Grid
Utilise un noyau de calcul avec une synchronisations entre les blocs.
ePointerAccessibility
Informations d'accessibilité d'une adresse mémoire.
eMemoryAdvice
Conseils pour la gestion mémoire.
Definition Memory.h:36
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.
@ None
Aucune politique d'exécution.
@ CUDA
Politique d'exécution utilisant l'environnement CUDA.
@ Sequential
Politique d'exécution séquentielle.
@ Thread
Politique d'exécution multi-thread.