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 "arccore/common/accelerator/RunCommand.h"
18#include "arcane/accelerator/KernelLauncher.h"
19
21#include "arcane/core/ItemGroup.h"
23
24#include "arccore/common/HostKernelRemainingArgsHelper.h"
25
26#include <concepts>
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31namespace Arcane
32{
33
35{
36};
37
41template <typename T>
42class IteratorWithIndex
44{
45 public:
46
47 constexpr ARCCORE_HOST_DEVICE IteratorWithIndex(Int32 i, T v)
48 : m_index(i)
49 , m_value(v)
50 {}
51
52 public:
53
54 constexpr ARCCORE_HOST_DEVICE Int32 index() const { return m_index; }
55 constexpr ARCCORE_HOST_DEVICE T value() const { return m_value; }
56
57 private:
58
59 Int32 m_index;
60 T m_value;
61};
62
63} // namespace Arcane
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
68namespace Arcane::impl
69{
70
71template <typename T>
73{
74 public:
75
76 using ValueType = T;
77
78 public:
79
80 constexpr ARCCORE_HOST_DEVICE static IteratorWithIndex<T> create(Int32 index, T value)
81 {
82 return IteratorWithIndex<T>(index, value);
83 }
84};
85
86template <typename T>
88{
89 public:
90
91 using ValueType = T;
92
93 public:
94
95 constexpr ARCCORE_HOST_DEVICE static T create(Int32, T value)
96 {
97 return value;
98 }
99};
100
101} // namespace Arcane::impl
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
106namespace Arcane::Accelerator::impl
107{
108
109/*---------------------------------------------------------------------------*/
110/*---------------------------------------------------------------------------*/
117template <typename T>
118concept RunCommandEnumerateIteratorConcept = std::derived_from<T, Item>
119 || std::derived_from<T, ItemLocalId>
120 || std::derived_from<T, IteratorWithIndexBase>;
121
123template <typename T>
125{
126 public:
127
128 using ItemType = T;
129 using ValueType = typename ItemTraitsT<ItemType>::LocalIdType;
131};
132
134template <typename T>
136{
137 public:
138
139 using ItemType = typename ItemLocalIdT<T>::ItemType;
140 using ValueType = ItemLocalIdT<T>;
142};
143
145template <typename T>
146requires std::derived_from<T, ItemLocalId> class RunCommandItemEnumeratorSubTraitsT<IteratorWithIndex<T>>
147{
148 public:
149
150 using ItemType = typename T::ItemType;
151 using ValueType = IteratorWithIndex<T>;
152 using BuilderType = Arcane::impl::IterBuilderWithIndex<T>;
153};
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
167template <typename ItemType>
168class RunCommandItemContainer
169{
170 public:
171
172 explicit RunCommandItemContainer(const ItemGroupT<ItemType>& group)
173 : m_item_group(group)
174 , m_unpadded_vector_view(group._unpaddedView())
175 {}
176 explicit RunCommandItemContainer(const ItemVectorViewT<ItemType>& item_vector_view)
177 : m_item_vector_view(item_vector_view)
178 , m_unpadded_vector_view(item_vector_view)
179 {
180 }
181
182 public:
183
184 Int32 size() const { return m_unpadded_vector_view.size(); }
185 SmallSpan<const Int32> localIds() const { return m_unpadded_vector_view.localIds(); }
186 ItemVectorView paddedView() const
187 {
188 if (!m_item_group.null())
189 return m_item_group._paddedView();
190 return m_item_vector_view;
191 }
192
193 private:
194
195 ItemVectorViewT<ItemType> m_item_vector_view;
196 ItemGroupT<ItemType> m_item_group;
197 ItemVectorViewT<ItemType> m_unpadded_vector_view;
198};
199
200/*---------------------------------------------------------------------------*/
201/*---------------------------------------------------------------------------*/
211template <RunCommandEnumerateIteratorConcept IteratorValueType_>
212class RunCommandItemEnumeratorTraitsT
213{
214 public:
215
217 using ItemType = typename SubTraitsType::ItemType;
218 using LocalIdType = typename ItemTraitsT<ItemType>::LocalIdType;
219 using ValueType = typename SubTraitsType::ValueType;
220 using ContainerType = RunCommandItemContainer<ItemType>;
221 using BuilderType = typename SubTraitsType::BuilderType;
222
223 public:
224
225 explicit RunCommandItemEnumeratorTraitsT(const ItemGroupT<ItemType>& group)
226 : m_item_container(group)
227 {}
228 explicit RunCommandItemEnumeratorTraitsT(const ItemVectorViewT<ItemType>& vector_view)
229 : m_item_container(vector_view)
230 {
231 }
232
233 public:
234
235 RunCommandItemContainer<ItemType> m_item_container;
236};
237
238/*---------------------------------------------------------------------------*/
239/*---------------------------------------------------------------------------*/
240
241template <typename TraitsType, typename ContainerType, typename Lambda, typename... RemainingArgs>
242void _doItemsLambda(Int32 base_index, ContainerType sub_items, const Lambda& func, RemainingArgs... remaining_args)
243{
244 using ItemType = TraitsType::ItemType;
245 using BuilderType = TraitsType::BuilderType;
246 using LocalIdType = BuilderType::ValueType;
247 auto privatizer = Impl::privatize(func);
248 auto& body = privatizer.privateCopy();
249
251 ENUMERATE_NO_TRACE_ (ItemType, iitem, sub_items) {
252 body(BuilderType::create(iitem.index() + base_index, LocalIdType(iitem.itemLocalId())), remaining_args...);
253 }
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
262template <typename TraitsType, typename Lambda, typename... RemainingArgs> void
263_applyItems(RunCommand& command, typename TraitsType::ContainerType items,
264 const Lambda& func, const RemainingArgs&... remaining_args)
265{
266 // TODO: fusionner la partie commune avec 'applyLoop'
267 Integer vsize = items.size();
268 if (vsize == 0)
269 return;
270 using ItemType = typename TraitsType::ItemType;
271 Impl::RunCommandLaunchInfo launch_info(command, vsize);
272 const eExecutionPolicy exec_policy = launch_info.executionPolicy();
273 launch_info.beginExecute();
274 [[maybe_unused]] SmallSpan<const Int32> ids = items.localIds();
275 switch (exec_policy) {
277 ARCCORE_KERNEL_CUDA_FUNC((Impl::doIndirectGPULambda2 < TraitsType, Lambda, RemainingArgs... >),
278 launch_info, func, ids, remaining_args...);
279 break;
281 ARCCORE_KERNEL_HIP_FUNC((Impl::doIndirectGPULambda2 < TraitsType, Lambda, RemainingArgs... >),
282 launch_info, func, ids, remaining_args...);
283 break;
285 ARCCORE_KERNEL_SYCL_FUNC((Impl::DoIndirectSYCLLambda < TraitsType, Lambda, RemainingArgs... > {}),
286 launch_info, func, ids, remaining_args...);
287 break;
289 impl::_doItemsLambda<TraitsType>(0, items.paddedView(), func, remaining_args...);
290 break;
292 arcaneParallelForeach(items.paddedView(), launch_info.loopRunInfo(),
293 [&](ItemVectorViewT<ItemType> sub_items, Int32 base_index) {
294 impl::_doItemsLambda<TraitsType>(base_index, sub_items, func, remaining_args...);
295 });
296 break;
297 default:
298 ARCCORE_FATAL("Invalid execution policy '{0}'", exec_policy);
299 }
300 launch_info.endExecute();
301}
302
303/*---------------------------------------------------------------------------*/
304/*---------------------------------------------------------------------------*/
305
306template <typename TraitsType, typename... RemainingArgs>
307class ItemRunCommandArgs
308{
309 public:
310
311 ItemRunCommandArgs(const TraitsType& traits, const RemainingArgs&... remaining_args)
312 : m_traits(traits)
313 , m_remaining_args(remaining_args...)
314 {
315 }
316
317 public:
318
319 TraitsType m_traits;
320 std::tuple<RemainingArgs...> m_remaining_args;
321};
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
326} // namespace Arcane::Accelerator::impl
327
328namespace Arcane::Accelerator
329{
330
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
333
334template <typename TraitsType, typename Lambda> void
335run(RunCommand& command, const TraitsType& traits, const Lambda& func)
336{
337 impl::_applyItems<TraitsType>(command, traits.m_item_container, func);
338}
339
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
342
343template <typename TraitsType, typename... RemainingArgs>
344class ItemRunCommand
345{
346 public:
347
348 ItemRunCommand(RunCommand& command, const TraitsType& traits)
349 : m_command(command)
350 , m_traits(traits)
351 {
352 }
353
354 ItemRunCommand(RunCommand& command, const TraitsType& traits, const std::tuple<RemainingArgs...>& remaining_args)
355 : m_command(command)
356 , m_traits(traits)
357 , m_remaining_args(remaining_args)
358 {
359 }
360
361 public:
362
363 RunCommand& m_command;
364 TraitsType m_traits;
365 std::tuple<RemainingArgs...> m_remaining_args;
366};
367
368/*---------------------------------------------------------------------------*/
369/*---------------------------------------------------------------------------*/
370
371template <typename ItemType> auto
372operator<<(RunCommand& command, const impl::RunCommandItemEnumeratorTraitsT<ItemType>& traits)
373{
375 return ItemRunCommand<TraitsType>(command, traits);
376}
377
378/*---------------------------------------------------------------------------*/
379/*---------------------------------------------------------------------------*/
380// Cette méthode est conservée pour compatibilité avec l'existant.
381// A rendre obsolète mi-2024
382template <typename ItemType> auto
383operator<<(RunCommand& command, const ItemVectorViewT<ItemType>& items)
384{
385 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
386 return ItemRunCommand<TraitsType>(command, TraitsType(items));
387}
388
389// Cette méthode est conservée pour compatibilité avec l'existant.
390// A rendre obsolète mi-2024
391template <typename ItemType> auto
392operator<<(RunCommand& command, const ItemGroupT<ItemType>& items)
393{
394 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
395 return ItemRunCommand<TraitsType>(command, TraitsType(items));
396}
397
398template <typename TraitsType, typename Lambda>
399void operator<<(ItemRunCommand<TraitsType>& nr, const Lambda& f)
400{
401 run(nr.m_command, nr.m_traits, f);
402}
403
404template <typename TraitsType, typename... RemainingArgs> auto
406{
407 return ItemRunCommand<TraitsType, RemainingArgs...>(command, args.m_traits, args.m_remaining_args);
408}
409
410template <typename TraitsType, typename Lambda, typename... RemainingArgs>
411void operator<<(ItemRunCommand<TraitsType, RemainingArgs...>&& nr, const Lambda& f)
412{
413 if constexpr (sizeof...(RemainingArgs) > 0) {
414 std::apply([&](auto... vs) { impl::_applyItems<TraitsType>(nr.m_command, nr.m_traits.m_item_container, f, vs...); }, nr.m_remaining_args);
415 }
416 else
417 run(nr.m_command, nr.m_traits, f);
418}
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422
423} // namespace Arcane::Accelerator
424
425namespace Arcane::Accelerator::impl
426{
427
428/*---------------------------------------------------------------------------*/
429/*---------------------------------------------------------------------------*/
430
431template <typename ItemTypeName, typename ItemContainerType, typename... RemainingArgs> auto
432makeExtendedItemEnumeratorLoop(const ItemContainerType& container_type,
433 const RemainingArgs&... remaining_args)
434{
436 return ItemRunCommandArgs<TraitsType, RemainingArgs...>(TraitsType(container_type), remaining_args...);
437}
438
439/*---------------------------------------------------------------------------*/
440/*---------------------------------------------------------------------------*/
441
442} // namespace Arcane::Accelerator::impl
443
444/*---------------------------------------------------------------------------*/
445/*---------------------------------------------------------------------------*/
465#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group, ...) \
466 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedItemEnumeratorLoop<ItemTypeName>(item_group __VA_OPT__(, __VA_ARGS__)) \
467 << [=] ARCCORE_HOST_DEVICE(::Arcane::Accelerator::impl::RunCommandItemEnumeratorTraitsT<ItemTypeName>::ValueType iter_name \
468 __VA_OPT__(ARCCORE_RUNCOMMAND_REMAINING_FOR_EACH(__VA_ARGS__)))
469
470/*---------------------------------------------------------------------------*/
471/*---------------------------------------------------------------------------*/
472
473#endif
#define ARCCORE_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 RemainingArgs &... remaining_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.
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.