Arcane  v3.15.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
core/RunQueue.h
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/* RunQueue.h (C) 2000-2024 */
9/* */
10/* Gestion d'une file d'exécution sur accélérateur. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_ACCELERATOR_CORE_RUNQUEUE_H
13#define ARCANE_ACCELERATOR_CORE_RUNQUEUE_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/AutoRef.h"
18
19#include "arcane/accelerator/core/RunCommand.h"
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
24namespace Arcane::Accelerator
25{
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29/*!
30 * \brief File d'exécution pour un accélérateur.
31 *
32 * Cette classe utilise une sémantique par référence. La file d'exécution est
33 * détruite lorsque la dernière référence dessus est détruite.
34 *
35 * Une file est attachée à une instance de Runner et permet d'exécuter
36 * des commandes (RunCommand) sur un accélérateur ou sur le CPU. La méthode
37 * executionPolicy() permet de savoir où s'exécutera les commandes issues
38 * de la file.
39 *
40 * Les instances de cette classe sont créées par l'appel à makeQueue(Runner).
41 * On peut ensuite créer des noyaux de calcul (RunCommand) via l'appel
42 * à makeCommand().
43 *
44 * Le constructeur par défaut construit Une file nulle qui ne peut pas être
45 * utilisée pour lancer des commandes. Les seules opérations autorisées sur
46 * la file nulle sont isNull(), executionPolicy(), isAcceleratorPolicy(),
47 * barrier(), allocationOptions() et memoryRessource().
48 *
49 * Les méthodes de cette classe ne sont pas thread-safe pour une même instance.
50 */
51class ARCANE_ACCELERATOR_CORE_EXPORT RunQueue
52{
53 friend RunCommand;
54 friend ProfileRegion;
55 friend Runner;
56 friend ViewBuildInfo;
57 friend class impl::RunCommandLaunchInfo;
58 friend RunCommand makeCommand(const RunQueue& run_queue);
59 friend RunCommand makeCommand(const RunQueue* run_queue);
60 // Pour _internalNativeStream()
61 friend class impl::CudaUtils;
62 friend class impl::HipUtils;
63 friend class impl::SyclUtils;
64
65 public:
66
67 //! Permet de modifier l'asynchronisme de la file pendant la durée de vie de l'instance
69 {
70 public:
71
72 explicit ScopedAsync(RunQueue* queue)
73 : m_queue(queue)
74 {
75 // Rend la file asynchrone
76 if (m_queue) {
77 m_is_async = m_queue->isAsync();
78 m_queue->setAsync(true);
79 }
80 }
81 ~ScopedAsync() noexcept(false)
82 {
83 // Remet la file dans l'état d'origine lors de l'appel au constructeur
84 if (m_queue)
85 m_queue->setAsync(m_is_async);
86 }
87
88 private:
89
90 RunQueue* m_queue = nullptr;
91 bool m_is_async = false;
92 };
93
94 public:
95
96 //! Créé une file nulle.
97 RunQueue();
98 ~RunQueue();
99
100 public:
101
102 //! Créé une file associée à \a runner avec les paramètres par défaut
103 ARCANE_DEPRECATED_REASON("Y2024: Use makeQueue(runner) instead")
104 explicit RunQueue(const Runner& runner);
105 //! Créé une file associée à \a runner avec les paramètres \a bi
106 ARCANE_DEPRECATED_REASON("Y2024: Use makeQueue(runner,bi) instead")
107 RunQueue(const Runner& runner, const RunQueueBuildInfo& bi);
108
109 public:
110
111 RunQueue(const RunQueue&);
112 RunQueue& operator=(const RunQueue&);
113 RunQueue(RunQueue&&) noexcept;
114 RunQueue& operator=(RunQueue&&) noexcept;
115
116 public:
117
118 //! Indique si la RunQueue est nulle
119 bool isNull() const { return !m_p; }
120
121 //! Politique d'exécution de la file.
122 eExecutionPolicy executionPolicy() const;
123 //! Indique si l'instance est associée à un accélérateur
124 bool isAcceleratorPolicy() const;
125
126 /*!
127 * \brief Positionne l'asynchronisme de l'instance.
128 *
129 * Si l'instance est asynchrone, les différentes commandes
130 * associées ne sont pas bloquantes et il faut appeler explicitement barrier()
131 * pour attendre la fin de l'exécution des commandes.
132 *
133 * \pre !isNull()
134 */
135 void setAsync(bool v);
136 //! Indique si la file d'exécution est asynchrone.
137 bool isAsync() const;
138
139 /*!
140 * \brief Positionne l'asynchronisme de l'instance.
141 *
142 * Retourne l'instance.
143 *
144 * \pre !isNull()
145 * \sa setAsync().
146 */
147 const RunQueue& addAsync(bool is_async) const;
148
149 //! Bloque tant que toutes les commandes associées à la file ne sont pas terminées.
150 void barrier() const;
151
152 //! Copie des informations entre deux zones mémoires
153 void copyMemory(const MemoryCopyArgs& args) const;
154 //! Effectue un préfetching de la mémoire
155 void prefetchMemory(const MemoryPrefetchArgs& args) const;
156
157 /*!
158 * \name Gestion des évènements
159 * \pre !isNull()
160 */
161 //!@{
162 //! Enregistre l'état de l'instance dans \a event.
163 void recordEvent(RunQueueEvent& event);
164 //! Enregistre l'état de l'instance dans \a event.
165 void recordEvent(Ref<RunQueueEvent>& event);
166 //! Bloque l'exécution sur l'instance tant que les jobs enregistrés dans \a event ne sont pas terminés
167 void waitEvent(RunQueueEvent& event);
168 //! Bloque l'exécution sur l'instance tant que les jobs enregistrés dans \a event ne sont pas terminés
169 void waitEvent(Ref<RunQueueEvent>& event);
170 //!@}
171
172 //! \name Gestion mémoire
173 //!@{
174 /*!
175 * \brief Options d'allocation associée à cette file.
176 *
177 * Il est possible de changer la ressource mémoire et donc l'allocateur utilisé
178 * via setMemoryRessource().
179 */
180 MemoryAllocationOptions allocationOptions() const;
181
182 /*!
183 * \brief Positionne la ressource mémoire utilisée pour les allocations avec cette instance.
184 *
185 * La valeur par défaut est eMemoryRessource::UnifiedMemory
186 * si isAcceleratorPolicy()==true et eMemoryRessource::Host sinon.
187 *
188 * \sa memoryRessource()
189 * \sa allocationOptions()
190 *
191 * \pre !isNull()
192 */
193 void setMemoryRessource(eMemoryRessource mem);
194
195 //! Ressource mémoire utilisée pour les allocations avec cette instance.
196 eMemoryRessource memoryRessource() const;
197 //!@}
198
199 public:
200
201 /*!
202 * \brief Indique si on autorise la création de RunCommand pour cette instance
203 * depuis plusieurs threads.
204 *
205 * Cela nécessite d'utiliser un verrou (comme std::mutex) et peut dégrader les
206 * performances. Le défaut est \a false.
207 *
208 * Cette méthode n'est pas supportée pour les files qui sont associées
209 * à des accélérateurs (isAcceleratorPolicy()==true)
210 */
211 void setConcurrentCommandCreation(bool v);
212 //! Indique si la création concurrente de plusieurs RunCommand est autorisée
213 bool isConcurrentCommandCreation() const;
214
215 public:
216
217 /*!
218 * \brief Pointeur sur la structure interne dépendante de l'implémentation.
219 *
220 * Cette méthode est réservée à un usage avancée.
221 * La file retournée ne doit pas être conservée au delà de la vie de l'instance.
222 *
223 * Avec CUDA, le pointeur retourné est un 'cudaStream_t*'. Avec HIP, il
224 * s'agit d'un 'hipStream_t*'.
225 *
226 * \deprecated Utiliser toCudaNativeStream(), toHipNativeStream()
227 * ou toSyclNativeStream() à la place
228 */
229 ARCANE_DEPRECATED_REASON("Y2024: Use toCudaNativeStream(), toHipNativeStream() or toSyclNativeStream() instead")
230 void* platformStream() const;
231
232 public:
233
234 friend bool operator==(const RunQueue& q1, const RunQueue& q2)
235 {
236 return q1.m_p.get() == q2.m_p.get();
237 }
238 friend bool operator!=(const RunQueue& q1, const RunQueue& q2)
239 {
240 return q1.m_p.get() != q2.m_p.get();
241 }
242
243 public:
244
245 impl::RunQueueImpl* _internalImpl() const;
246
247 private:
248
249 // Les méthodes de création sont réservée à Runner.
250 // On ajoute un argument supplémentaire non utilisé pour ne pas utiliser
251 // le constructeur obsolète.
252 RunQueue(const Runner& runner, bool);
253 //! Créé une file associée à \a runner avec les paramètres \a bi
254 RunQueue(const Runner& runner, const RunQueueBuildInfo& bi, bool);
255 explicit RunQueue(impl::RunQueueImpl* p);
256
257 private:
258
259 impl::IRunnerRuntime* _internalRuntime() const;
260 impl::IRunQueueStream* _internalStream() const;
261 impl::RunCommandImpl* _getCommandImpl() const;
262 impl::NativeStream _internalNativeStream() const;
263 void _checkNotNull() const;
264
265 // Pour VariableViewBase
266 friend class VariableViewBase;
267 friend class NumArrayViewBase;
268
269 private:
270
271 AutoRef2<impl::RunQueueImpl> m_p;
272};
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279/*!
280 * \brief Créé une commande associée à la file \a run_queue.
281 */
282inline RunCommand
283makeCommand(const RunQueue& run_queue)
284{
285 run_queue._checkNotNull();
286 return RunCommand(run_queue);
287}
288
289/*!
290 * \brief Créé une commande associée à la file \a run_queue.
291 */
292inline RunCommand
293makeCommand(const RunQueue* run_queue)
294{
295 ARCANE_CHECK_POINTER(run_queue);
296 run_queue->_checkNotNull();
297 return RunCommand(*run_queue);
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
303} // End namespace Arcane::Accelerator
304
305/*---------------------------------------------------------------------------*/
306/*---------------------------------------------------------------------------*/
307
308#endif
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
Arguments pour la copie mémoire.
Definition Memory.h:63
Arguments pour le préfetching mémoire.
Definition Memory.h:125
Région pour le profiling.
Gestion d'une commande sur accélérateur.
Informations pour créer une RunQueue.
Evènement pour une file d'exécution.
Permet de modifier l'asynchronisme de la file pendant la durée de vie de l'instance.
File d'exécution pour un accélérateur.
Gestionnaire d'exécution pour accélérateur.
Definition core/Runner.h:68
Informations pour construire une vue pour les données sur accélérateur.
T * get() const
Retourne l'objet référé par l'instance.
Definition AutoRef.h:189
Options pour configurer les allocations.
Espace de nom pour l'utilisation des accélérateurs.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
eExecutionPolicy
Politique d'exécution pour un Runner.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indique si exec_policy correspond à un accélérateur.
eMemoryResource
Liste des ressources mémoire disponibles.