Arcane  v3.16.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
68 class ScopedAsync
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
Gestion d'une commande sur accélérateur.
Informations pour créer une RunQueue.
Evènement pour une file d'exécution.
File d'exécution pour un accélérateur.
friend RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
RunQueue()
Créé une file nulle.
Definition RunQueue.cc:46
bool isNull() const
Indique si la RunQueue est nulle.
T * get() const
Retourne l'objet référé par l'instance.
Definition AutoRef.h:189
Options pour configurer les allocations.
Référence à une instance.
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.
Arcane::eMemoryResource eMemoryRessource
Typedef pour la version Arcane historique (avec 2's')