Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Runner.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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-2024 */
9/* */
10/* Gestion d'une file d'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/IDeviceInfoList.h"
28#include "arcane/accelerator/core/PointerAttribute.h"
29#include "arcane/accelerator/core/internal/IRunnerRuntime.h"
30#include "arcane/accelerator/core/internal/AcceleratorCoreGlobalInternal.h"
31#include "arcane/accelerator/core/internal/RunQueueImpl.h"
32#include "arcane/accelerator/core/internal/RunnerImpl.h"
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arcane::Accelerator
38{
39
40namespace
41{
42 inline impl::IRunnerRuntime*
43 _getRuntimeNoCheck(eExecutionPolicy p)
44 {
45 impl::IRunnerRuntime* runtime = nullptr;
46 switch (p) {
48 ARCANE_FATAL("No runtime for eExecutionPolicy::None");
50 return impl::getSYCLRunQueueRuntime();
52 return impl::getHIPRunQueueRuntime();
54 return impl::getCUDARunQueueRuntime();
56 return impl::getSequentialRunQueueRuntime();
58 return impl::getThreadRunQueueRuntime();
59 }
60 return runtime;
61 }
62
63 inline impl::IRunnerRuntime*
64 _getRuntime(eExecutionPolicy p)
65 {
66 auto* x = _getRuntimeNoCheck(p);
67 if (!x)
68 ARCANE_FATAL("No runtime is available for execution policy '{0}'", p);
69 return x;
70 }
71
72 inline void
73 _stopProfiling(eExecutionPolicy p)
74 {
75 auto* x = _getRuntimeNoCheck(p);
76 if (x)
77 x->stopProfiling();
78 }
79 inline void
80 _finalize(eExecutionPolicy p, ITraceMng* tm)
81 {
82 auto* x = _getRuntimeNoCheck(p);
83 if (x) {
84 x->stopProfiling();
85 x->finalize(tm);
86 }
87 }
88} // namespace
89
90} // namespace Arcane::Accelerator
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
94
95namespace Arcane::Accelerator::impl
96{
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101void RunnerImpl::
102initialize(Runner* runner, eExecutionPolicy v, DeviceId device)
103{
104 if (m_is_init)
105 ARCANE_FATAL("Runner is already initialized");
106 if (v == eExecutionPolicy::None)
107 ARCANE_THROW(ArgumentException, "executionPolicy should not be eExecutionPolicy::None");
108 if (device.isHost() || device.isNull())
109 ARCANE_THROW(ArgumentException, "device should not be Device::hostDevice() or Device::nullDevice()");
110
111 m_execution_policy = v;
112 m_device_id = device;
113 m_runtime = _getRuntime(v);
114 m_is_init = true;
115 m_is_auto_prefetch_command = false;
116
117 // Pour test
118 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACCELERATOR_PREFETCH_COMMAND", true))
119 m_is_auto_prefetch_command = (v.value() != 0);
120
121 // Il faut initialiser le pool à la fin car il a besoin d'accéder à \a m_runtime
122 m_run_queue_pool.initialize(runner->_impl());
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
128void RunnerImpl::
129_checkIsInit() const
130{
131 if (!m_is_init)
132 ARCANE_FATAL("Runner is not initialized. Call method initialize() before");
133}
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
138void RunnerImpl::
139_freePool()
140{
141 RunQueueImplStack& s = m_run_queue_pool;
142 while (!s.empty()) {
143 delete s.top();
144 s.pop();
145 }
146}
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150
151RunQueueImplStack* RunnerImpl::
152getPool()
153{
154 return &m_run_queue_pool;
155}
156
157/*---------------------------------------------------------------------------*/
158/*---------------------------------------------------------------------------*/
159
160void RunnerImpl::
161_internalPutRunQueueImplInPool(RunQueueImpl* p)
162{
163 RunnerImpl::Lock my_lock(this);
164 getPool()->push(p);
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
170impl::RunQueueImpl* RunnerImpl::
171_internalCreateOrGetRunQueueImpl()
172{
173 _checkIsInit();
174
175 auto pool = getPool();
176
177 {
178 impl::RunnerImpl::Lock my_lock(this);
179 if (!pool->empty()) {
180 impl::RunQueueImpl* p = pool->top();
181 pool->pop();
182 return p;
183 }
184 }
185
186 return pool->createRunQueue(RunQueueBuildInfo{});
187}
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
192impl::RunQueueImpl* RunnerImpl::
193_internalCreateOrGetRunQueueImpl(const RunQueueBuildInfo& bi)
194{
195 _checkIsInit();
196 // Si on utilise les paramètres par défaut, on peut utilier une RunQueueImpl
197 // issue du pool.
198 if (bi.isDefault())
199 return _internalCreateOrGetRunQueueImpl();
200 impl::IRunnerRuntime* runtime = m_runtime;
201 ARCANE_CHECK_POINTER(runtime);
202 auto* queue = new impl::RunQueueImpl(this, 0, bi);
203 return queue;
204}
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
208
209RunQueueImpl* RunQueueImplStack::
210createRunQueue(const RunQueueBuildInfo& bi)
211{
212 if (!m_runner_impl)
213 ARCANE_FATAL("RunQueueImplStack is not initialized");
214 Int32 x = ++m_nb_created;
215 auto* q = new impl::RunQueueImpl(m_runner_impl, x, bi);
216 q->m_is_in_pool = true;
217 return q;
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
223IRunQueueEventImpl* RunnerImpl::
224_createEvent()
225{
226 _checkIsInit();
227 return m_runtime->createEventImpl();
228}
229
230/*---------------------------------------------------------------------------*/
231/*---------------------------------------------------------------------------*/
232
233IRunQueueEventImpl* RunnerImpl::
234_createEventWithTimer()
235{
236 _checkIsInit();
237 return m_runtime->createEventImplWithTimer();
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
243} // namespace Arcane::Accelerator::impl
244
245/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247
248namespace Arcane::Accelerator
249{
250
251/*---------------------------------------------------------------------------*/
252/*---------------------------------------------------------------------------*/
253
254/*---------------------------------------------------------------------------*/
255/*---------------------------------------------------------------------------*/
256
258Runner()
259: m_p(std::make_shared<impl::RunnerImpl>())
260{
261}
262
263/*---------------------------------------------------------------------------*/
264/*---------------------------------------------------------------------------*/
265
268: Runner()
269{
270 initialize(p);
271}
272
273/*---------------------------------------------------------------------------*/
274/*---------------------------------------------------------------------------*/
275
277Runner(eExecutionPolicy p, DeviceId device_id)
278: Runner()
279{
280 initialize(p, device_id);
281}
282
283/*---------------------------------------------------------------------------*/
284/*---------------------------------------------------------------------------*/
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
288
289impl::IRunnerRuntime* Runner::
290_internalRuntime() const
291{
292 _checkIsInit();
293 return m_p->runtime();
294}
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
298
300executionPolicy() const
301{
302 return m_p->executionPolicy();
303}
304
305/*---------------------------------------------------------------------------*/
306/*---------------------------------------------------------------------------*/
307
309isInitialized() const
310{
311 return m_p->isInit();
312}
313
314/*---------------------------------------------------------------------------*/
315/*---------------------------------------------------------------------------*/
316
319{
320 m_p->setConcurrentQueueCreation(v);
321}
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
328{
329 return m_p->isConcurrentQueueCreation();
330}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
337{
338 m_p->m_reduce_policy = v;
339}
340
341/*---------------------------------------------------------------------------*/
342/*---------------------------------------------------------------------------*/
343
345deviceReducePolicy() const
346{
347 return m_p->m_reduce_policy;
348}
349
350/*---------------------------------------------------------------------------*/
351/*---------------------------------------------------------------------------*/
352
355{
356 m_p->initialize(this, v, DeviceId());
357}
358
359/*---------------------------------------------------------------------------*/
360/*---------------------------------------------------------------------------*/
361
364{
365 m_p->initialize(this, v, device_id);
366}
367
368/*---------------------------------------------------------------------------*/
369/*---------------------------------------------------------------------------*/
370
371void Runner::
372_checkIsInit() const
373{
374 if (!m_p->m_is_init)
375 ARCANE_FATAL("Runner is not initialized. Call method initialize() before");
376}
377
378/*---------------------------------------------------------------------------*/
379/*---------------------------------------------------------------------------*/
380
383{
384 return m_p->cumulativeCommandTime();
385}
386
387/*---------------------------------------------------------------------------*/
388/*---------------------------------------------------------------------------*/
389
391setMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
392{
393 _checkIsInit();
394 m_p->runtime()->setMemoryAdvice(buffer, advice, m_p->m_device_id);
395}
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
399
401unsetMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
402{
403 _checkIsInit();
404 m_p->runtime()->unsetMemoryAdvice(buffer, advice, m_p->m_device_id);
405}
406
407/*---------------------------------------------------------------------------*/
408/*---------------------------------------------------------------------------*/
409
412{
413 _checkIsInit();
414 m_p->runtime()->setCurrentDevice(m_p->m_device_id);
415}
416
417/*---------------------------------------------------------------------------*/
418/*---------------------------------------------------------------------------*/
419
421deviceId() const
422{
423 return m_p->m_device_id;
424}
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
430deviceInfo() const
431{
432 _checkIsInit();
434 Int32 nb_device = dlist->nbDevice();
435 if (nb_device == 0)
436 ARCANE_FATAL("Internal error: no device available");
437 Int32 device_id = deviceId().asInt32();
438 if (device_id >= nb_device)
439 device_id = 0;
440 return dlist->deviceInfo(device_id);
441}
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
448{
449 if (policy == eExecutionPolicy::None)
450 return nullptr;
451 impl::IRunnerRuntime* r = _getRuntime(policy);
452 return r->deviceInfoList();
453}
454
455/*---------------------------------------------------------------------------*/
456/*---------------------------------------------------------------------------*/
457
459fillPointerAttribute(PointerAttribute& attr, const void* ptr)
460{
461 _checkIsInit();
462 m_p->runtime()->getPointerAttribute(attr, ptr);
463}
464
465
466/*---------------------------------------------------------------------------*/
467/*---------------------------------------------------------------------------*/
468
469bool Runner::
470_isAutoPrefetchCommand() const
471{
472 return m_p->isAutoPrefetchCommand();
473}
474
475/*---------------------------------------------------------------------------*/
476/*---------------------------------------------------------------------------*/
477
478RunnerInternal* Runner::
480{
481 return m_p->_internalApi();
482}
483
484/*---------------------------------------------------------------------------*/
485/*---------------------------------------------------------------------------*/
486/*!
487 * \brief Arrête tout les profiling en cours de tout les runtime.
488 *
489 * En général on utilise cela en fin de calcul.
490 */
491void RunnerInternal::
492stopAllProfiling()
493{
494 _stopProfiling(eExecutionPolicy::CUDA);
495 _stopProfiling(eExecutionPolicy::HIP);
496 _stopProfiling(eExecutionPolicy::Sequential);
497 _stopProfiling(eExecutionPolicy::Thread);
498}
499
500/*---------------------------------------------------------------------------*/
501/*---------------------------------------------------------------------------*/
502
503void RunnerInternal::
504finalize(ITraceMng* tm)
505{
506 _finalize(eExecutionPolicy::CUDA, tm);
507 _finalize(eExecutionPolicy::HIP, tm);
508 _finalize(eExecutionPolicy::Sequential, tm);
509 _finalize(eExecutionPolicy::Thread, tm);
510}
511
512/*---------------------------------------------------------------------------*/
513/*---------------------------------------------------------------------------*/
514
515void RunnerInternal::
516startProfiling()
517{
518 m_runner_impl->runtime()->startProfiling();
519}
520
521/*---------------------------------------------------------------------------*/
522/*---------------------------------------------------------------------------*/
523
524void RunnerInternal::
525stopProfiling()
526{
527 m_runner_impl->runtime()->stopProfiling();
528}
529
530/*---------------------------------------------------------------------------*/
531/*---------------------------------------------------------------------------*/
532
533bool RunnerInternal::
534isProfilingActive()
535{
536 return m_runner_impl->runtime()->isProfilingActive();
537}
538
539/*---------------------------------------------------------------------------*/
540/*---------------------------------------------------------------------------*/
541
542void RunnerInternal::
543printProfilingInfos(std::ostream& o)
544{
545 bool is_active = isProfilingActive();
546 if (is_active)
547 stopProfiling();
548
549 {
550 // Affiche les statistiques de profiling.
551 using Arcane::impl::AcceleratorStatInfoList;
552 auto f = [&](const AcceleratorStatInfoList& stat_list) {
553 stat_list.print(o);
554 };
555 ProfilingRegistry::visitAcceleratorStat(f);
556 }
557
558 if (is_active)
559 startProfiling();
560}
561
562/*---------------------------------------------------------------------------*/
563/*---------------------------------------------------------------------------*/
564
565extern "C++" ePointerAccessibility
566getPointerAccessibility(Runner* runner, const void* ptr, PointerAttribute* ptr_attr)
567{
568 if (!runner)
570 return impl::RuntimeStaticInfo::getPointerAccessibility(runner->executionPolicy(), ptr, ptr_attr);
571}
572
573extern "C++" void impl::
574arcaneCheckPointerIsAccessible(const Runner* runner, const void* ptr,
575 const char* name, const TraceInfo& ti)
576{
577 if (!runner)
578 return;
579 return impl::RuntimeStaticInfo::checkPointerIsAcccessible(runner->executionPolicy(), ptr, name, ti);
580}
581
582/*---------------------------------------------------------------------------*/
583/*---------------------------------------------------------------------------*/
584
585/*---------------------------------------------------------------------------*/
586/*---------------------------------------------------------------------------*/
587
588void impl::IRunnerRuntime::
589_fillPointerAttribute(PointerAttribute& attribute,
590 ePointerMemoryType mem_type,
591 int device, const void* pointer, const void* device_pointer,
592 const void* host_pointer)
593{
594 attribute = PointerAttribute(mem_type, device, pointer, device_pointer, host_pointer);
595}
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
600void impl::IRunnerRuntime::
601_fillPointerAttribute(PointerAttribute& attribute, const void* pointer)
602{
603 attribute = PointerAttribute(pointer);
604}
605
606/*---------------------------------------------------------------------------*/
607/*---------------------------------------------------------------------------*/
608
609} // namespace Arcane::Accelerator
610
611/*---------------------------------------------------------------------------*/
612/*---------------------------------------------------------------------------*/
#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
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.
Gestionnaire d'exécution pour accélérateur.
Definition core/Runner.h:53
void fillPointerAttribute(PointerAttribute &attr, const void *ptr)
Remplit attr avec les informations concernant la zone mémoire pointée par ptr.
Definition Runner.cc:459
void setConcurrentQueueCreation(bool v)
Indique si on autorise la création de RunQueue depuis plusieurs threads.
Definition Runner.cc:318
static const IDeviceInfoList * deviceInfoList(eExecutionPolicy policy)
Liste des devices pour la politique d'exécution policy.
Definition Runner.cc:447
bool isInitialized() const
Indique si l'instance a été initialisée.
Definition Runner.cc:309
Runner()
Créé un gestionnaire d'exécution non initialisé.
Definition Runner.cc:258
RunnerInternal * _internalApi()
API interne à Arcane.
Definition Runner.cc:479
double cumulativeCommandTime() const
Temps total passé dans les commandes associées à cette instance.
Definition Runner.cc:382
bool isConcurrentQueueCreation() const
Indique si la création concurrent de plusieurs RunQueue est autorisé
Definition Runner.cc:327
DeviceId deviceId() const
Device associé à cette instance.
Definition Runner.cc:421
void setDeviceReducePolicy(eDeviceReducePolicy v)
Positionne la politique d'exécution des réductions.
Definition Runner.cc:336
const DeviceInfo & deviceInfo() const
Information sur le device associé à cette instance.
Definition Runner.cc:430
void initialize(eExecutionPolicy v)
Initialise l'instance. Cette méthode ne doit être appelée qu'une seule fois.
Definition Runner.cc:354
void setAsCurrentDevice()
Positionne le device associé à cette instance comme le device par défaut du contexte.
Definition Runner.cc:411
eDeviceReducePolicy deviceReducePolicy() const
politique d'exécution des réductions
Definition Runner.cc:345
void setMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
Positionne un conseil sur la gestion d'une zone mémoire.
Definition Runner.cc:391
void unsetMemoryAdvice(ConstMemoryView buffer, eMemoryAdvice advice)
Supprime un conseil sur la gestion d'une zone mémoire.
Definition Runner.cc:401
eExecutionPolicy executionPolicy() const
Politique d'exécution associée.
Definition Runner.cc:300
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.
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.