Arcane  v4.1.1.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... RemainingArgs>
240void _doItemsLambda(Int32 base_index, ContainerType sub_items, const Lambda& func, RemainingArgs... remaining_args)
241{
242 using ItemType = TraitsType::ItemType;
243 using BuilderType = TraitsType::BuilderType;
244 using LocalIdType = BuilderType::ValueType;
245 auto privatizer = Impl::privatize(func);
246 auto& body = privatizer.privateCopy();
247
249 ENUMERATE_NO_TRACE_ (ItemType, iitem, sub_items) {
250 body(BuilderType::create(iitem.index() + base_index, LocalIdType(iitem.itemLocalId())), remaining_args...);
251 }
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
260template <typename TraitsType, typename Lambda, typename... ReducerArgs> void
261_applyItems(RunCommand& command, typename TraitsType::ContainerType items,
262 const Lambda& func, const ReducerArgs&... reducer_args)
263{
264 // TODO: fusionner la partie commune avec 'applyLoop'
265 Integer vsize = items.size();
266 if (vsize == 0)
267 return;
268 using ItemType = typename TraitsType::ItemType;
269 Impl::RunCommandLaunchInfo launch_info(command, vsize);
270 const eExecutionPolicy exec_policy = launch_info.executionPolicy();
271 launch_info.beginExecute();
272 SmallSpan<const Int32> ids = items.localIds();
273 switch (exec_policy) {
275 _applyKernelCUDA(launch_info, ARCANE_KERNEL_CUDA_FUNC(Impl::doIndirectGPULambda2) < TraitsType, Lambda, ReducerArgs... >, func, ids, reducer_args...);
276 break;
278 _applyKernelHIP(launch_info, ARCANE_KERNEL_HIP_FUNC(Impl::doIndirectGPULambda2) < TraitsType, Lambda, ReducerArgs... >, func, ids, reducer_args...);
279 break;
281 _applyKernelSYCL(launch_info, ARCANE_KERNEL_SYCL_FUNC(Impl::DoIndirectSYCLLambda) < TraitsType, Lambda, ReducerArgs... > {}, func, ids, reducer_args...);
282 break;
284 impl::_doItemsLambda<TraitsType>(0, items.paddedView(), func, reducer_args...);
285 break;
287 arcaneParallelForeach(items.paddedView(), launch_info.loopRunInfo(),
288 [&](ItemVectorViewT<ItemType> sub_items, Int32 base_index) {
289 impl::_doItemsLambda<TraitsType>(base_index, sub_items, func, reducer_args...);
290 });
291 break;
292 default:
293 ARCANE_FATAL("Invalid execution policy '{0}'", exec_policy);
294 }
295 launch_info.endExecute();
296}
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
300
301template <typename TraitsType, typename... ReducerArgs>
302class ItemRunCommandArgs
303{
304 public:
305
306 ItemRunCommandArgs(const TraitsType& traits, const ReducerArgs&... reducer_args)
307 : m_traits(traits)
308 , m_reducer_args(reducer_args...)
309 {
310 }
311
312 public:
313
314 TraitsType m_traits;
315 std::tuple<ReducerArgs...> m_reducer_args;
316};
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321} // namespace Arcane::Accelerator::impl
322
323namespace Arcane::Accelerator
324{
325
326/*---------------------------------------------------------------------------*/
327/*---------------------------------------------------------------------------*/
328
329template <typename TraitsType, typename Lambda> void
330run(RunCommand& command, const TraitsType& traits, const Lambda& func)
331{
332 impl::_applyItems<TraitsType>(command, traits.m_item_container, func);
333}
334
335/*---------------------------------------------------------------------------*/
336/*---------------------------------------------------------------------------*/
337
338template <typename TraitsType, typename... ReducerArgs>
339class ItemRunCommand
340{
341 public:
342
343 ItemRunCommand(RunCommand& command, const TraitsType& traits)
344 : m_command(command)
345 , m_traits(traits)
346 {
347 }
348
349 ItemRunCommand(RunCommand& command, const TraitsType& traits, const std::tuple<ReducerArgs...>& reducer_args)
350 : m_command(command)
351 , m_traits(traits)
352 , m_reducer_args(reducer_args)
353 {
354 }
355
356 public:
357
358 RunCommand& m_command;
359 TraitsType m_traits;
360 std::tuple<ReducerArgs...> m_reducer_args;
361};
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
366template <typename ItemType> auto
367operator<<(RunCommand& command, const impl::RunCommandItemEnumeratorTraitsT<ItemType>& traits)
368{
370 return ItemRunCommand<TraitsType>(command, traits);
371}
372
373/*---------------------------------------------------------------------------*/
374/*---------------------------------------------------------------------------*/
375// Cette méthode est conservée pour compatibilité avec l'existant.
376// A rendre obsolète mi-2024
377template <typename ItemType> auto
378operator<<(RunCommand& command, const ItemVectorViewT<ItemType>& items)
379{
380 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
381 return ItemRunCommand<TraitsType>(command, TraitsType(items));
382}
383
384// Cette méthode est conservée pour compatibilité avec l'existant.
385// A rendre obsolète mi-2024
386template <typename ItemType> auto
387operator<<(RunCommand& command, const ItemGroupT<ItemType>& items)
388{
389 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
390 return ItemRunCommand<TraitsType>(command, TraitsType(items));
391}
392
393template <typename TraitsType, typename Lambda>
394void operator<<(ItemRunCommand<TraitsType>& nr, const Lambda& f)
395{
396 run(nr.m_command, nr.m_traits, f);
397}
398
399template <typename TraitsType, typename... ReducerArgs> auto
401{
402 return ItemRunCommand<TraitsType, ReducerArgs...>(command, args.m_traits, args.m_reducer_args);
403}
404
405template <typename TraitsType, typename Lambda, typename... ReducerArgs>
406void operator<<(ItemRunCommand<TraitsType, ReducerArgs...>&& nr, const Lambda& f)
407{
408 if constexpr (sizeof...(ReducerArgs) > 0) {
409 std::apply([&](auto... vs) { impl::_applyItems<TraitsType>(nr.m_command, nr.m_traits.m_item_container, f, vs...); }, nr.m_reducer_args);
410 }
411 else
412 run(nr.m_command, nr.m_traits, f);
413}
414
415/*---------------------------------------------------------------------------*/
416/*---------------------------------------------------------------------------*/
417
418} // namespace Arcane::Accelerator
419
420namespace Arcane::Accelerator::impl
421{
422
423/*---------------------------------------------------------------------------*/
424/*---------------------------------------------------------------------------*/
425
426template <typename ItemTypeName, typename ItemContainerType, typename... ReducerArgs> auto
427makeExtendedItemEnumeratorLoop(const ItemContainerType& container_type,
428 const ReducerArgs&... reducer_args)
429{
431 return ItemRunCommandArgs<TraitsType, ReducerArgs...>(TraitsType(container_type), reducer_args...);
432}
433
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
437} // namespace Arcane::Accelerator::impl
438
439/*---------------------------------------------------------------------------*/
440/*---------------------------------------------------------------------------*/
460#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group, ...) \
461 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedItemEnumeratorLoop<ItemTypeName>(item_group __VA_OPT__(, __VA_ARGS__)) \
462 << [=] ARCCORE_HOST_DEVICE(::Arcane::Accelerator::impl::RunCommandItemEnumeratorTraitsT<ItemTypeName>::ValueType iter_name \
463 __VA_OPT__(ARCANE_RUNCOMMAND_REDUCER_FOR_EACH(__VA_ARGS__)))
464
465/*---------------------------------------------------------------------------*/
466/*---------------------------------------------------------------------------*/
467
468#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.
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.
Template pour connaitre le type d'entité associé à T.
Caractéristiques d'un énumérateur d'une commande sur les entités.
static void applyAtEnd(RemainingArgs &... remaining_args)
Applique les functors des arguments additionnels à la fin de l'itération.
static void applyAtBegin(RemainingArgs &... remaining_args)
Applique les functors des arguments additionnels au début de l'itération.
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:801
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.
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.