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