Arcane  v4.1.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
RunCommandEnumerate.h
Aller à la documentation de ce fichier.
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/* RunCommandEnumerate.h (C) 2000-2025 */
9/* */
10/* Macros pour exécuter une boucle sur une liste d'entités. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_ACCELERATOR_RUNCOMMANDENUMERATE_H
13#define ARCANE_ACCELERATOR_RUNCOMMANDENUMERATE_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/accelerator/RunCommand.h"
18#include "arcane/accelerator/KernelLauncher.h"
19
21#include "arcane/core/ItemGroup.h"
23
24#include <concepts>
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
33{
34};
35
39template <typename T>
40class IteratorWithIndex
42{
43 public:
44
45 constexpr ARCCORE_HOST_DEVICE IteratorWithIndex(Int32 i, T v)
46 : m_index(i)
47 , m_value(v)
48 {}
49
50 public:
51
52 constexpr ARCCORE_HOST_DEVICE Int32 index() const { return m_index; }
53 constexpr ARCCORE_HOST_DEVICE T value() const { return m_value; }
54
55 private:
56
57 Int32 m_index;
58 T m_value;
59};
60
61} // namespace Arcane
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66namespace Arcane::impl
67{
68
69template <typename T>
71{
72 public:
73
74 using ValueType = T;
75
76 public:
77
78 constexpr ARCCORE_HOST_DEVICE static IteratorWithIndex<T> create(Int32 index, T value)
79 {
80 return IteratorWithIndex<T>(index, value);
81 }
82};
83
84template <typename T>
86{
87 public:
88
89 using ValueType = T;
90
91 public:
92
93 constexpr ARCCORE_HOST_DEVICE static T create(Int32, T value)
94 {
95 return value;
96 }
97};
98
99} // namespace Arcane::impl
100
101/*---------------------------------------------------------------------------*/
102/*---------------------------------------------------------------------------*/
103
104namespace Arcane::Accelerator::impl
105{
106
107/*---------------------------------------------------------------------------*/
108/*---------------------------------------------------------------------------*/
115template <typename T>
116concept RunCommandEnumerateIteratorConcept = std::derived_from<T, Item>
117 || std::derived_from<T, ItemLocalId>
118 || std::derived_from<T, IteratorWithIndexBase>;
119
121template <typename T>
123{
124 public:
125
126 using ItemType = T;
127 using ValueType = typename ItemTraitsT<ItemType>::LocalIdType;
129};
130
132template <typename T>
134{
135 public:
136
137 using ItemType = typename ItemLocalIdT<T>::ItemType;
138 using ValueType = ItemLocalIdT<T>;
140};
141
143template <typename T>
144requires std::derived_from<T, ItemLocalId> class RunCommandItemEnumeratorSubTraitsT<IteratorWithIndex<T>>
145{
146 public:
147
148 using ItemType = typename T::ItemType;
149 using ValueType = IteratorWithIndex<T>;
150 using BuilderType = Arcane::impl::IterBuilderWithIndex<T>;
151};
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
165template <typename ItemType>
166class RunCommandItemContainer
167{
168 public:
169
170 explicit RunCommandItemContainer(const ItemGroupT<ItemType>& group)
171 : m_item_group(group)
172 , m_unpadded_vector_view(group._unpaddedView())
173 {}
174 explicit RunCommandItemContainer(const ItemVectorViewT<ItemType>& item_vector_view)
175 : m_item_vector_view(item_vector_view)
176 , m_unpadded_vector_view(item_vector_view)
177 {
178 }
179
180 public:
181
182 Int32 size() const { return m_unpadded_vector_view.size(); }
183 SmallSpan<const Int32> localIds() const { return m_unpadded_vector_view.localIds(); }
184 ItemVectorView paddedView() const
185 {
186 if (!m_item_group.null())
187 return m_item_group._paddedView();
188 return m_item_vector_view;
189 }
190
191 private:
192
193 ItemVectorViewT<ItemType> m_item_vector_view;
194 ItemGroupT<ItemType> m_item_group;
195 ItemVectorViewT<ItemType> m_unpadded_vector_view;
196};
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
209template <RunCommandEnumerateIteratorConcept IteratorValueType_>
210class RunCommandItemEnumeratorTraitsT
211{
212 public:
213
215 using ItemType = typename SubTraitsType::ItemType;
216 using LocalIdType = typename ItemTraitsT<ItemType>::LocalIdType;
217 using ValueType = typename SubTraitsType::ValueType;
218 using ContainerType = RunCommandItemContainer<ItemType>;
219 using BuilderType = typename SubTraitsType::BuilderType;
220
221 public:
222
223 explicit RunCommandItemEnumeratorTraitsT(const ItemGroupT<ItemType>& group)
224 : m_item_container(group)
225 {}
226 explicit RunCommandItemEnumeratorTraitsT(const ItemVectorViewT<ItemType>& vector_view)
227 : m_item_container(vector_view)
228 {
229 }
230
231 public:
232
233 RunCommandItemContainer<ItemType> m_item_container;
234};
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
239template <typename TraitsType, typename ContainerType, typename Lambda, typename... ReducerArgs>
240void _doItemsLambda(Int32 base_index, ContainerType sub_items, const Lambda& func, ReducerArgs... reducer_args)
241{
242 using ItemType = typename TraitsType::ItemType;
243 using BuilderType = typename TraitsType::BuilderType;
244 using LocalIdType = typename BuilderType::ValueType;
245 auto privatizer = privatize(func);
246 auto& body = privatizer.privateCopy();
247
248 ENUMERATE_NO_TRACE_ (ItemType, iitem, sub_items) {
249 body(BuilderType::create(iitem.index() + base_index, LocalIdType(iitem.itemLocalId())), reducer_args...);
250 }
252}
253
254/*---------------------------------------------------------------------------*/
255/*---------------------------------------------------------------------------*/
259template <typename TraitsType, typename Lambda, typename... ReducerArgs> void
260_applyItems(RunCommand& command, typename TraitsType::ContainerType items,
261 const Lambda& func, const ReducerArgs&... reducer_args)
262{
263 // TODO: fusionner la partie commune avec 'applyLoop'
264 Integer vsize = items.size();
265 if (vsize == 0)
266 return;
267 using ItemType = typename TraitsType::ItemType;
268 impl::RunCommandLaunchInfo launch_info(command, vsize);
269 const eExecutionPolicy exec_policy = launch_info.executionPolicy();
270 launch_info.beginExecute();
271 SmallSpan<const Int32> ids = items.localIds();
272 switch (exec_policy) {
274 _applyKernelCUDA(launch_info, ARCANE_KERNEL_CUDA_FUNC(doIndirectGPULambda2) < TraitsType, Lambda, ReducerArgs... >, func, ids, reducer_args...);
275 break;
277 _applyKernelHIP(launch_info, ARCANE_KERNEL_HIP_FUNC(doIndirectGPULambda2) < TraitsType, Lambda, ReducerArgs... >, func, ids, reducer_args...);
278 break;
280 _applyKernelSYCL(launch_info, ARCANE_KERNEL_SYCL_FUNC(impl::DoIndirectSYCLLambda) < TraitsType, Lambda, ReducerArgs... > {}, func, ids, reducer_args...);
281 break;
283 impl::_doItemsLambda<TraitsType>(0, items.paddedView(), func, reducer_args...);
284 break;
286 arcaneParallelForeach(items.paddedView(), launch_info.loopRunInfo(),
287 [&](ItemVectorViewT<ItemType> sub_items, Int32 base_index) {
288 impl::_doItemsLambda<TraitsType>(base_index, sub_items, func, reducer_args...);
289 });
290 break;
291 default:
292 ARCANE_FATAL("Invalid execution policy '{0}'", exec_policy);
293 }
294 launch_info.endExecute();
295}
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
300template <typename TraitsType, typename... ReducerArgs>
301class ItemRunCommandArgs
302{
303 public:
304
305 ItemRunCommandArgs(const TraitsType& traits, const ReducerArgs&... reducer_args)
306 : m_traits(traits)
307 , m_reducer_args(reducer_args...)
308 {
309 }
310
311 public:
312
313 TraitsType m_traits;
314 std::tuple<ReducerArgs...> m_reducer_args;
315};
316
317/*---------------------------------------------------------------------------*/
318/*---------------------------------------------------------------------------*/
319
320} // namespace Arcane::Accelerator::impl
321
322namespace Arcane::Accelerator
323{
324
325/*---------------------------------------------------------------------------*/
326/*---------------------------------------------------------------------------*/
327
328template <typename TraitsType, typename Lambda> void
329run(RunCommand& command, const TraitsType& traits, const Lambda& func)
330{
331 impl::_applyItems<TraitsType>(command, traits.m_item_container, func);
332}
333
334/*---------------------------------------------------------------------------*/
335/*---------------------------------------------------------------------------*/
336
337template <typename TraitsType, typename... ReducerArgs>
338class ItemRunCommand
339{
340 public:
341
342 ItemRunCommand(RunCommand& command, const TraitsType& traits)
343 : m_command(command)
344 , m_traits(traits)
345 {
346 }
347
348 ItemRunCommand(RunCommand& command, const TraitsType& traits, const std::tuple<ReducerArgs...>& reducer_args)
349 : m_command(command)
350 , m_traits(traits)
351 , m_reducer_args(reducer_args)
352 {
353 }
354
355 public:
356
357 RunCommand& m_command;
358 TraitsType m_traits;
359 std::tuple<ReducerArgs...> m_reducer_args;
360};
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
365template <typename ItemType> auto
367{
369 return ItemRunCommand<TraitsType>(command, traits);
370}
371
372/*---------------------------------------------------------------------------*/
373/*---------------------------------------------------------------------------*/
374// Cette méthode est conservée pour compatibilité avec l'existant.
375// A rendre obsolète mi-2024
376template <typename ItemType> auto
377operator<<(RunCommand& command, const ItemVectorViewT<ItemType>& items)
378{
379 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
380 return ItemRunCommand<TraitsType>(command, TraitsType(items));
381}
382
383// Cette méthode est conservée pour compatibilité avec l'existant.
384// A rendre obsolète mi-2024
385template <typename ItemType> auto
386operator<<(RunCommand& command, const ItemGroupT<ItemType>& items)
387{
388 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
389 return ItemRunCommand<TraitsType>(command, TraitsType(items));
390}
391
392template <typename TraitsType, typename Lambda>
393void operator<<(ItemRunCommand<TraitsType>& nr, const Lambda& f)
394{
395 run(nr.m_command, nr.m_traits, f);
396}
397
398template <typename TraitsType, typename... ReducerArgs> auto
400{
401 return ItemRunCommand<TraitsType, ReducerArgs...>(command, args.m_traits, args.m_reducer_args);
402}
403
404template <typename TraitsType, typename Lambda, typename... ReducerArgs>
406{
407 if constexpr (sizeof...(ReducerArgs) > 0) {
408 std::apply([&](auto... vs) { impl::_applyItems<TraitsType>(nr.m_command, nr.m_traits.m_item_container, f, vs...); }, nr.m_reducer_args);
409 }
410 else
411 run(nr.m_command, nr.m_traits, f);
412}
413
414/*---------------------------------------------------------------------------*/
415/*---------------------------------------------------------------------------*/
416
417} // namespace Arcane::Accelerator
418
419namespace Arcane::Accelerator::impl
420{
421
422/*---------------------------------------------------------------------------*/
423/*---------------------------------------------------------------------------*/
424
425template <typename ItemTypeName, typename ItemContainerType, typename... ReducerArgs> auto
426makeExtendedItemEnumeratorLoop(const ItemContainerType& container_type,
427 const ReducerArgs&... reducer_args)
428{
430 return ItemRunCommandArgs<TraitsType, ReducerArgs...>(TraitsType(container_type), reducer_args...);
431}
432
433/*---------------------------------------------------------------------------*/
434/*---------------------------------------------------------------------------*/
435
436} // namespace Arcane::Accelerator::impl
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
459#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group, ...) \
460 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedItemEnumeratorLoop<ItemTypeName>(item_group __VA_OPT__(, __VA_ARGS__)) \
461 << [=] ARCCORE_HOST_DEVICE(::Arcane::Accelerator::impl::RunCommandItemEnumeratorTraitsT<ItemTypeName>::ValueType iter_name \
462 __VA_OPT__(ARCANE_RUNCOMMAND_REDUCER_FOR_EACH(__VA_ARGS__)))
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
467#endif
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Classes, Types et macros pour gérer la concurrence.
#define ENUMERATE_NO_TRACE_(type, name, group)
Enumérateur générique d'un groupe d'entité
Déclarations de types sur les entités.
void _applyItems(RunCommand &command, typename TraitsType::ContainerType items, const Lambda &func, const ReducerArgs &... reducer_args)
Applique l'enumération func sur la liste d'entité items.
Gestion d'une commande sur accélérateur.
Template pour connaitre le type d'entité associé à T.
Caractéristiques d'un énumérateur d'une commande sur les entités.
Object temporaire pour conserver les informations d'exécution d'une commande et regrouper les tests.
void beginExecute()
Indique qu'on commence l'exécution de la commande.
void endExecute()
Signale la fin de l'exécution.
const ForLoopRunInfo & loopRunInfo() const
Informations d'exécution de la boucle.
Référence à un groupe d'un genre donné.
Definition ItemGroup.h:413
ItemVectorView _unpaddedView() const
Vue sur les entités du groupe sans padding pour la vectorisation.
Definition ItemGroup.cc:601
Index d'une entité ItemType dans une variable.
Definition ItemLocalId.h:90
Caractéristiques des éléments du maillage.
Definition ItemTypes.h:621
Vue sur un tableau typé d'entités.
Vue sur un vecteur d'entités.
Classe de base pour un itérateur permettant de conserver l'index de l'itération.
Vue d'un tableau d'éléments de type T.
Definition Span.h:774
static void applyReducerArgs(ReducerArgs &... reducer_args)
Applique les fonctors des arguments additionnels.
Concept pour contraintre les valeurs dans RUNCOMMAND_ENUMERATE.
void arcaneParallelForeach(const ItemVectorView &items_view, const ForLoopRunInfo &run_info, InstanceType *instance, void(InstanceType::*function)(ItemVectorViewT< ItemType > items))
Applique en concurrence la méthode function de l'instance instance sur la vue items_view avec les opt...
Definition Concurrency.h:56
Espace de nom pour l'utilisation des accélérateurs.
std::ostream & operator<<(std::ostream &o, eExecutionPolicy exec_policy)
Affiche le nom de la politique d'exécution.
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.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
std::int32_t Int32
Type entier signé sur 32 bits.