Arcane  v4.1.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-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 "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/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38namespace Arcane::Accelerator
39{
40
41namespace
42{
44 _getRuntimeNoCheck(eExecutionPolicy p)
45 {
46 impl::IRunnerRuntime* runtime = nullptr;
47 switch (p) {
49 ARCCORE_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 ARCCORE_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 ARCCORE_FATAL("Runner is already initialized");
107 if (v == eExecutionPolicy::None)
108 ARCCORE_THROW(ArgumentException, "executionPolicy should not be eExecutionPolicy::None");
109 if (device.isHost() || device.isNull())
110 ARCCORE_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 ARCCORE_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 ARCCORE_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 ARCCORE_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 ARCCORE_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 ARCCORE_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 Impl::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/*---------------------------------------------------------------------------*/
virtual const DeviceInfo & deviceInfo(Int32 i) const =0
Informations du i-ème device.
virtual Int32 nbDevice() const =0
Nombre de device de la liste.
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.
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.
bool m_is_auto_prefetch_command
Indique si on pré-copie les données avant une commande de cette RunQueue.
Definition RunnerImpl.h:154
Vue constante sur une zone mémoire contigue contenant des éléments de taille fixe.
static ARCCORE_BASE_EXPORT 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 Impl::AcceleratorStatInfoList &)> &f)
Visite la liste des statistiques sur accélérateur.
Definition Profiling.cc:221
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.