Arcane  v3.16.9.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/FatalErrorException.h"
17#include "arcane/utils/NotImplementedException.h"
18#include "arcane/utils/ArgumentException.h"
19#include "arcane/utils/MemoryView.h"
20#include "arcane/utils/ValueConvert.h"
21#include "arcane/utils/Profiling.h"
22#include "arcane/utils/internal/ProfilingInternal.h"
23
24#include "arcane/accelerator/core/RunQueueBuildInfo.h"
25#include "arcane/accelerator/core/DeviceId.h"
26#include "arcane/accelerator/core/DeviceMemoryInfo.h"
27#include "arcane/accelerator/core/IDeviceInfoList.h"
28#include "arcane/accelerator/core/PointerAttribute.h"
29#include "arcane/accelerator/core/KernelLaunchArgs.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{
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
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_device_info = m_runtime->deviceInfoList()->deviceInfo(m_device_id.asInt32());
116 m_is_init = true;
118
119 // Pour test
120 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACCELERATOR_PREFETCH_COMMAND", true))
121 m_is_auto_prefetch_command = (v.value() != 0);
122
123 // Il faut initialiser le pool à la fin car il a besoin d'accéder à \a m_runtime
124 m_run_queue_pool.initialize(runner->_impl());
125}
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
130void RunnerImpl::
131_checkIsInit() const
132{
133 if (!m_is_init)
134 ARCANE_FATAL("Runner is not initialized. Call method initialize() before");
135}
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
140void RunnerImpl::
141_freePool()
142{
143 RunQueueImplStack& s = m_run_queue_pool;
144 while (!s.empty()) {
145 RunQueueImpl* q = s.top();
146 RunQueueImpl::_destroy(q);
147 s.pop();
148 }
149}
150
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
153
154RunQueueImplStack* RunnerImpl::
155getPool()
156{
157 return &m_run_queue_pool;
158}
159
160/*---------------------------------------------------------------------------*/
161/*---------------------------------------------------------------------------*/
162
163void RunnerImpl::
164_internalPutRunQueueImplInPool(RunQueueImpl* p)
165{
166 RunnerImpl::Lock my_lock(this);
167 getPool()->push(p);
168}
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
173impl::RunQueueImpl* RunnerImpl::
174_internalCreateOrGetRunQueueImpl()
175{
176 _checkIsInit();
177
178 auto pool = getPool();
179
180 {
181 impl::RunnerImpl::Lock my_lock(this);
182 if (!pool->empty()) {
183 impl::RunQueueImpl* p = pool->top();
184 pool->pop();
185 return p;
186 }
187 }
188
189 return pool->createRunQueue(RunQueueBuildInfo{});
190}
191
192/*---------------------------------------------------------------------------*/
193/*---------------------------------------------------------------------------*/
194
195impl::RunQueueImpl* RunnerImpl::
196_internalCreateOrGetRunQueueImpl(const RunQueueBuildInfo& bi)
197{
198 _checkIsInit();
199 // Si on utilise les paramètres par défaut, on peut utilier une RunQueueImpl
200 // issue du pool.
201 if (bi.isDefault())
202 return _internalCreateOrGetRunQueueImpl();
203 impl::IRunnerRuntime* runtime = m_runtime;
204 ARCANE_CHECK_POINTER(runtime);
205 auto* queue = new impl::RunQueueImpl(this, 0, bi);
206 return queue;
207}
208
209/*---------------------------------------------------------------------------*/
210/*---------------------------------------------------------------------------*/
211
212RunQueueImpl* RunQueueImplStack::
213createRunQueue(const RunQueueBuildInfo& bi)
214{
215 if (!m_runner_impl)
216 ARCANE_FATAL("RunQueueImplStack is not initialized");
217 Int32 x = ++m_nb_created;
218 auto* q = new impl::RunQueueImpl(m_runner_impl, x, bi);
219 q->m_is_in_pool = true;
220 return q;
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
226IRunQueueEventImpl* RunnerImpl::
227_createEvent()
228{
229 _checkIsInit();
230 return m_runtime->createEventImpl();
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
236IRunQueueEventImpl* RunnerImpl::
237_createEventWithTimer()
238{
239 _checkIsInit();
240 return m_runtime->createEventImplWithTimer();
241}
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
246} // namespace Arcane::Accelerator::impl
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251namespace Arcane::Accelerator
252{
253
254/*---------------------------------------------------------------------------*/
255/*---------------------------------------------------------------------------*/
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
261Runner()
262: m_p(std::make_shared<impl::RunnerImpl>())
263{
264}
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
268
271: Runner()
272{
273 initialize(p);
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278
280Runner(eExecutionPolicy p, DeviceId device_id)
281: Runner()
282{
283 initialize(p, device_id);
284}
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
288
289/*---------------------------------------------------------------------------*/
290/*---------------------------------------------------------------------------*/
291
292impl::IRunnerRuntime* Runner::
293_internalRuntime() const
294{
295 _checkIsInit();
296 return m_p->runtime();
297}
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
303executionPolicy() const
304{
305 return m_p->executionPolicy();
306}
307
308/*---------------------------------------------------------------------------*/
309/*---------------------------------------------------------------------------*/
310
312isInitialized() const
313{
314 return m_p->isInit();
315}
316
317/*---------------------------------------------------------------------------*/
318/*---------------------------------------------------------------------------*/
319
322{
323 // Toujours thread-safe;
324}
325
326/*---------------------------------------------------------------------------*/
327/*---------------------------------------------------------------------------*/
328
331{
332 return true;
333}
334
335/*---------------------------------------------------------------------------*/
336/*---------------------------------------------------------------------------*/
337
340{
342 std::cout << "Warning: Runner::setDeviceReducePolicy(): only 'eDeviceReducePolicy::Grid' is supported\n";
343}
344
345/*---------------------------------------------------------------------------*/
346/*---------------------------------------------------------------------------*/
347
349deviceReducePolicy() const
350{
351 return m_p->m_reduce_policy;
352}
353
354/*---------------------------------------------------------------------------*/
355/*---------------------------------------------------------------------------*/
356
359{
360 m_p->initialize(this, v, DeviceId());
361}
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
368{
369 m_p->initialize(this, v, device_id);
370}
371
372/*---------------------------------------------------------------------------*/
373/*---------------------------------------------------------------------------*/
374
375void Runner::
376_checkIsInit() const
377{
378 if (!m_p->m_is_init)
379 ARCANE_FATAL("Runner is not initialized. Call method initialize() before");
380}
381
382/*---------------------------------------------------------------------------*/
383/*---------------------------------------------------------------------------*/
384
387{
388 return m_p->cumulativeCommandTime();
389}
390
391/*---------------------------------------------------------------------------*/
392/*---------------------------------------------------------------------------*/
393
396{
397 _checkIsInit();
398 m_p->runtime()->setMemoryAdvice(buffer, advice, m_p->m_device_id);
399}
400
401/*---------------------------------------------------------------------------*/
402/*---------------------------------------------------------------------------*/
403
406{
407 _checkIsInit();
408 m_p->runtime()->unsetMemoryAdvice(buffer, advice, m_p->m_device_id);
409}
410
411/*---------------------------------------------------------------------------*/
412/*---------------------------------------------------------------------------*/
413
416{
417 _checkIsInit();
418 m_p->runtime()->setCurrentDevice(m_p->m_device_id);
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
425deviceId() const
426{
427 return m_p->m_device_id;
428}
429
430/*---------------------------------------------------------------------------*/
431/*---------------------------------------------------------------------------*/
432
434deviceInfo() const
435{
436 _checkIsInit();
438 Int32 nb_device = dlist->nbDevice();
439 if (nb_device == 0)
440 ARCANE_FATAL("Internal error: no device available");
441 Int32 device_id = deviceId().asInt32();
442 if (device_id >= nb_device)
443 device_id = 0;
444 return dlist->deviceInfo(device_id);
445}
446
447/*---------------------------------------------------------------------------*/
448/*---------------------------------------------------------------------------*/
449
452{
453 if (policy == eExecutionPolicy::None)
454 return nullptr;
455 impl::IRunnerRuntime* r = _getRuntime(policy);
456 return r->deviceInfoList();
457}
458
459/*---------------------------------------------------------------------------*/
460/*---------------------------------------------------------------------------*/
461
463deviceMemoryInfo() const
464{
465 _checkIsInit();
466 return m_p->runtime()->getDeviceMemoryInfo(deviceId());
467}
468
469/*---------------------------------------------------------------------------*/
470/*---------------------------------------------------------------------------*/
471
473fillPointerAttribute(PointerAttribute& attr, const void* ptr)
474{
475 _checkIsInit();
476 m_p->runtime()->getPointerAttribute(attr, ptr);
477}
478
479/*---------------------------------------------------------------------------*/
480/*---------------------------------------------------------------------------*/
481
482bool Runner::
483_isAutoPrefetchCommand() const
484{
485 return m_p->isAutoPrefetchCommand();
486}
487
488/*---------------------------------------------------------------------------*/
489/*---------------------------------------------------------------------------*/
490
493{
494 return m_p->_internalApi();
495}
496
497/*---------------------------------------------------------------------------*/
498/*---------------------------------------------------------------------------*/
506{
507 _stopProfiling(eExecutionPolicy::CUDA);
508 _stopProfiling(eExecutionPolicy::HIP);
509 _stopProfiling(eExecutionPolicy::Sequential);
510 _stopProfiling(eExecutionPolicy::Thread);
511}
512
513/*---------------------------------------------------------------------------*/
514/*---------------------------------------------------------------------------*/
515
518{
519 _finalize(eExecutionPolicy::CUDA, tm);
520 _finalize(eExecutionPolicy::HIP, tm);
521 _finalize(eExecutionPolicy::Sequential, tm);
522 _finalize(eExecutionPolicy::Thread, tm);
523}
524
525/*---------------------------------------------------------------------------*/
526/*---------------------------------------------------------------------------*/
527
530{
531 m_runner_impl->runtime()->startProfiling();
532}
533
534/*---------------------------------------------------------------------------*/
535/*---------------------------------------------------------------------------*/
536
539{
540 m_runner_impl->runtime()->stopProfiling();
541}
542
543/*---------------------------------------------------------------------------*/
544/*---------------------------------------------------------------------------*/
545
548{
549 return m_runner_impl->runtime()->isProfilingActive();
550}
551
552/*---------------------------------------------------------------------------*/
553/*---------------------------------------------------------------------------*/
554
556printProfilingInfos(std::ostream& o)
557{
558 bool is_active = isProfilingActive();
559 if (is_active)
561
562 {
563 // Affiche les statistiques de profiling.
565 auto f = [&](const AcceleratorStatInfoList& stat_list) {
566 stat_list.print(o);
567 };
569 }
570
571 if (is_active)
573}
574
575/*---------------------------------------------------------------------------*/
576/*---------------------------------------------------------------------------*/
577
578extern "C++" ePointerAccessibility
579getPointerAccessibility(Runner* runner, const void* ptr, PointerAttribute* ptr_attr)
580{
581 if (!runner)
583 return impl::RuntimeStaticInfo::getPointerAccessibility(runner->executionPolicy(), ptr, ptr_attr);
584}
585
586extern "C++" void impl::
587arcaneCheckPointerIsAccessible(const Runner* runner, const void* ptr,
588 const char* name, const TraceInfo& ti)
589{
590 if (!runner)
591 return;
592 return impl::RuntimeStaticInfo::checkPointerIsAcccessible(runner->executionPolicy(), ptr, name, ti);
593}
594
595/*---------------------------------------------------------------------------*/
596/*---------------------------------------------------------------------------*/
597
598/*---------------------------------------------------------------------------*/
599/*---------------------------------------------------------------------------*/
600
601void impl::IRunnerRuntime::
602_fillPointerAttribute(PointerAttribute& attribute,
603 ePointerMemoryType mem_type,
604 int device, const void* pointer, const void* device_pointer,
605 const void* host_pointer)
606{
607 attribute = PointerAttribute(mem_type, device, pointer, device_pointer, host_pointer);
608}
609
610/*---------------------------------------------------------------------------*/
611/*---------------------------------------------------------------------------*/
612
613void impl::IRunnerRuntime::
614_fillPointerAttribute(PointerAttribute& attribute, const void* pointer)
615{
616 attribute = PointerAttribute(pointer);
617}
618
619/*---------------------------------------------------------------------------*/
620/*---------------------------------------------------------------------------*/
621
622impl::KernelLaunchArgs impl::IRunnerRuntime::
623computeKernalLaunchArgs(const KernelLaunchArgs& orig_args,
624 [[maybe_unused]] const void* kernel_ptr,
625 [[maybe_unused]] Int64 total_loop_size,
626 [[maybe_unused]] Int32 wanted_shared_memory)
627{
628 return orig_args;
629}
630
631/*---------------------------------------------------------------------------*/
632/*---------------------------------------------------------------------------*/
633
634} // namespace Arcane::Accelerator
635
636/*---------------------------------------------------------------------------*/
637/*---------------------------------------------------------------------------*/
#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.
virtual const DeviceInfo & deviceInfo(Int32 i) const =0
Informations du i-ème device.
virtual Int32 nbDevice() const =0
Nombre de device de la liste.
Informations sur une adresse mémoire.
static void finalize(ITraceMng *tm)
Finalise l'exécution.
Definition Runner.cc:517
void startProfiling()
Démarre le profiling pour le runtime associé
Definition Runner.cc:529
bool isProfilingActive()
Indique si le profiling est actif pour le runtime associé
Definition Runner.cc:547
static void stopAllProfiling()
Stoppe toutes les activités de profiling.
Definition Runner.cc:505
void stopProfiling()
Stoppe le profiling pour le runtime associé
Definition Runner.cc:538
void printProfilingInfos(std::ostream &o)
Affiche les informations de profiling.
Definition Runner.cc:556
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:473
void setConcurrentQueueCreation(bool v)
Indique si on autorise la création de RunQueue depuis plusieurs threads.
Definition Runner.cc:321
static const IDeviceInfoList * deviceInfoList(eExecutionPolicy policy)
Liste des devices pour la politique d'exécution policy.
Definition Runner.cc:451
bool isInitialized() const
Indique si l'instance a été initialisée.
Definition Runner.cc:312
Runner()
Créé un gestionnaire d'exécution non initialisé.
Definition Runner.cc:261
RunnerInternal * _internalApi()
API interne à Arcane.
Definition Runner.cc:492
double cumulativeCommandTime() const
Temps total passé dans les commandes associées à cette instance.
Definition Runner.cc:386
bool isConcurrentQueueCreation() const
Indique si la création concurrent de plusieurs RunQueue est autorisé
Definition Runner.cc:330
DeviceId deviceId() const
Device associé à cette instance.
Definition Runner.cc:425
void setDeviceReducePolicy(eDeviceReducePolicy v)
Positionne la politique d'exécution des réductions.
Definition Runner.cc:339
const DeviceInfo & deviceInfo() const
Information sur le device associé à cette instance.
Definition Runner.cc:434
DeviceMemoryInfo deviceMemoryInfo() const
Information sur le device associé à cette instance.
Definition Runner.cc:463
void initialize(eExecutionPolicy v)
Initialise l'instance. Cette méthode ne doit être appelée qu'une seule fois.
Definition Runner.cc:358
void setAsCurrentDevice()
Positionne le device associé à cette instance comme le device par défaut du contexte.
Definition Runner.cc:415
eDeviceReducePolicy deviceReducePolicy() const
politique d'exécution des réductions
Definition Runner.cc:349
void setMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
Positionne un conseil sur la gestion d'une zone mémoire.
Definition Runner.cc:395
void unsetMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
Supprime un conseil sur la gestion d'une zone mémoire.
Definition Runner.cc:405
eExecutionPolicy executionPolicy() const
Politique d'exécution associée.
Definition Runner.cc:303
Interface de l'implémentation d'un évènement.
Interface du runtime associé à un accélérateur.
File d'exécution pour 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:156
Vue constante sur une zone mémoire contigue contenant des éléments de taille fixe.
Definition MemoryView.h:38
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Definition Convert.cc:122
Interface du gestionnaire de traces.
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.
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.
std::int32_t Int32
Type entier signé sur 32 bits.