12#ifndef ARCANE_ACCELERATOR_RUNCOMMANDENUMERATE_H
13#define ARCANE_ACCELERATOR_RUNCOMMANDENUMERATE_H
17#include "arccore/common/accelerator/RunCommand.h"
18#include "arcane/accelerator/KernelLauncher.h"
21#include "arcane/core/ItemGroup.h"
24#include "arccore/common/HostKernelRemainingArgsHelper.h"
28#if defined(ARCCORE_EXPERIMENTAL_GRID_STRIDE)
29#include "arccore/common/StridedLoopRanges.h"
35namespace Arcane::Accelerator::Impl
43template <
typename TraitsType_>
44class ItemLocalIdsLoopRanges
48 using TraitsType = TraitsType_;
49 using BuilderType = TraitsType::BuilderType;
55 constexpr Int64 nbElement()
const {
return m_ids.size(); }
65#if defined(ARCCORE_COMPILING_CUDA_OR_HIP)
67template <
typename LoopBoundsType,
typename Lambda,
typename... RemainingArgs> __global__
void
68doIndirectGPULambda2(LoopBoundsType bounds, Lambda func, RemainingArgs... remaining_args)
71 auto privatizer = privatize(func);
72 auto& body = privatizer.privateCopy();
74 Int32 i = blockDim.x * blockIdx.x + threadIdx.x;
78 if constexpr (
requires { bounds.nbStride(); }) {
81 using BuilderType = LoopBoundsType::LoopBoundType::BuilderType;
83 Int32 nb_grid_stride = bounds.nbStride();
84 Int32 offset = blockDim.x * gridDim.x;
85 Int64 nb_item = bounds.nbOriginalElement();
88 for (
Int32 k = 0; k < nb_grid_stride; ++k) {
89 Int32 true_i = i + (offset * k);
90 if (true_i < nb_item) {
92 body(BuilderType::create(true_i, lid), remaining_args...);
97 using BuilderType = LoopBoundsType::BuilderType;
100 SmallSpan<const Int32> ids = bounds.ids();
101 if (i < ids.size()) {
103 body(BuilderType::create(i, lid), remaining_args...);
118#if defined(ARCCORE_COMPILING_SYCL)
121template <
typename TraitsType,
typename Lambda,
typename... RemainingArgs>
122class DoIndirectSYCLLambda
126 void operator()(sycl::nd_item<1> x, SmallSpan<std::byte> shared_memory,
127 SmallSpan<const Int32> ids, Lambda func,
128 RemainingArgs... remaining_args)
const
130 using BuilderType = TraitsType::BuilderType;
132 auto privatizer = privatize(func);
133 auto& body = privatizer.privateCopy();
135 Int32 i =
static_cast<Int32
>(x.get_global_id(0));
136 SyclKernelRemainingArgsHelper::applyAtBegin(x, shared_memory, remaining_args...);
137 if (i < ids.size()) {
139 body(BuilderType::create(i, lid), remaining_args...);
141 SyclKernelRemainingArgsHelper::applyAtEnd(x, shared_memory, remaining_args...);
143 void operator()(sycl::id<1> x, SmallSpan<const Int32> ids, Lambda func)
const
145 using BuilderType = TraitsType::BuilderType;
147 auto privatizer = privatize(func);
148 auto& body = privatizer.privateCopy();
150 Int32 i =
static_cast<Int32
>(x);
151 if (i < ids.size()) {
153 body(BuilderType::create(i, lid));
182class IteratorWithIndex
187 constexpr ARCCORE_HOST_DEVICE IteratorWithIndex(
Int32 i, T v)
194 constexpr ARCCORE_HOST_DEVICE
Int32 index()
const {
return m_index; }
195 constexpr ARCCORE_HOST_DEVICE T value()
const {
return m_value; }
208namespace Arcane::impl
235 constexpr ARCCORE_HOST_DEVICE
static T create(
Int32, T value)
246namespace Arcane::Accelerator::impl
259 || std::derived_from<T, ItemLocalId>
260 || std::derived_from<T, IteratorWithIndexBase>;
279 using ItemType =
typename ItemLocalIdT<T>::ItemType;
290 using ItemType =
typename T::ItemType;
307template <
typename ItemType>
308class RunCommandItemContainer
313 : m_item_group(group)
317 : m_item_vector_view(item_vector_view)
318 , m_unpadded_vector_view(item_vector_view)
324 Int32 size()
const {
return m_unpadded_vector_view.size(); }
328 if (!m_item_group.null())
329 return m_item_group._paddedView();
330 return m_item_vector_view;
351template <RunCommandEnumerateIteratorConcept IteratorValueType_>
352class RunCommandItemEnumeratorTraitsT
357 using ItemType =
typename SubTraitsType::ItemType;
359 using ValueType =
typename SubTraitsType::ValueType;
361 using BuilderType =
typename SubTraitsType::BuilderType;
366 : m_item_container(group)
369 : m_item_container(vector_view)
381template <
typename TraitsType,
typename ContainerType,
typename Lambda,
typename... RemainingArgs>
382void _doItemsLambda(
Int32 base_index,
ContainerType sub_items,
const Lambda& func, RemainingArgs... remaining_args)
384 using ItemType = TraitsType::ItemType;
385 using BuilderType = TraitsType::BuilderType;
387 auto privatizer = Impl::privatize(func);
388 auto& body = privatizer.privateCopy();
392 body(BuilderType::create(iitem.index() + base_index,
LocalIdType(iitem.itemLocalId())), remaining_args...);
402template <
typename TraitsType,
typename Lambda,
typename... RemainingArgs>
void
404 const Lambda& func,
const RemainingArgs&... remaining_args)
410 using ItemType =
typename TraitsType::ItemType;
413 [[maybe_unused]] LoopBoundType bounds(ids);
415#if defined(ARCCORE_EXPERIMENTAL_GRID_STRIDE) && defined(ARCCORE_COMPILING_CUDA_OR_HIP)
417 TrueLoopBoundType bounds2(command.
nbStride(), bounds);
420 using TrueLoopBoundType = LoopBoundType;
421 [[maybe_unused]]
const TrueLoopBoundType& bounds2 = bounds;
428 switch (exec_policy) {
430 ARCCORE_KERNEL_CUDA_FUNC((Impl::doIndirectGPULambda2<TrueLoopBoundType, Lambda, RemainingArgs...>),
431 launch_info, func, bounds2, remaining_args...);
434 ARCCORE_KERNEL_HIP_FUNC((Impl::doIndirectGPULambda2<TrueLoopBoundType, Lambda, RemainingArgs...>),
435 launch_info, func, bounds2, remaining_args...);
438 ARCCORE_KERNEL_SYCL_FUNC((Impl::DoIndirectSYCLLambda<TraitsType, Lambda, RemainingArgs...>{}),
439 launch_info, func, ids, remaining_args...);
442 impl::_doItemsLambda<TraitsType>(0, items.paddedView(), func, remaining_args...);
447 impl::_doItemsLambda<TraitsType>(base_index, sub_items, func, remaining_args...);
451 ARCCORE_FATAL(
"Invalid execution policy '{0}'", exec_policy);
459template <
typename TraitsType,
typename... RemainingArgs>
460class ItemRunCommandArgs
464 ItemRunCommandArgs(
const TraitsType& traits,
const RemainingArgs&... remaining_args)
466 , m_remaining_args(remaining_args...)
473 std::tuple<RemainingArgs...> m_remaining_args;
487template <
typename TraitsType,
typename Lambda>
void
488run(
RunCommand& command,
const TraitsType& traits,
const Lambda& func)
496template <
typename TraitsType,
typename... RemainingArgs>
501 ItemRunCommand(
RunCommand& command,
const TraitsType& traits)
507 ItemRunCommand(
RunCommand& command,
const TraitsType& traits,
const std::tuple<RemainingArgs...>& remaining_args)
510 , m_remaining_args(remaining_args)
518 std::tuple<RemainingArgs...> m_remaining_args;
524template <
typename ItemType>
auto
535template <
typename ItemType>
auto
538 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
544template <
typename ItemType>
auto
545operator<<(RunCommand& command,
const ItemGroupT<ItemType>& items)
547 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
548 return ItemRunCommand<TraitsType>(command, TraitsType(items));
551template <
typename TraitsType,
typename Lambda>
554 run(nr.m_command, nr.m_traits, f);
557template <
typename TraitsType,
typename... RemainingArgs>
auto
560 return ItemRunCommand<TraitsType, RemainingArgs...>(command, args.m_traits, args.m_remaining_args);
563template <
typename TraitsType,
typename Lambda,
typename... RemainingArgs>
566 if constexpr (
sizeof...(RemainingArgs) > 0) {
570 run(nr.m_command, nr.m_traits, f);
578namespace Arcane::Accelerator::impl
584template <
typename ItemTypeName,
typename ItemContainerType,
typename... RemainingArgs>
auto
585makeExtendedItemEnumeratorLoop(
const ItemContainerType& container_type,
586 const RemainingArgs&... remaining_args)
589 return ItemRunCommandArgs<TraitsType, RemainingArgs...>(TraitsType(container_type), remaining_args...);
618#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group, ...) \
619 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedItemEnumeratorLoop<ItemTypeName>(item_group __VA_OPT__(, __VA_ARGS__)) \
620 << [=] ARCCORE_HOST_DEVICE(::Arcane::Accelerator::impl::RunCommandItemEnumeratorTraitsT<ItemTypeName>::ValueType iter_name \
621 __VA_OPT__(ARCCORE_RUNCOMMAND_REMAINING_FOR_EACH(__VA_ARGS__)))
#define ARCCORE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Classes, Types et macros pour gérer la concurrence.
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.
static ARCCORE_DEVICE void applyAtEnd(Int32 index, RemainingArgs &... remaining_args)
Applique les fonctors des arguments additionnels en fin de kernel.
static ARCCORE_DEVICE void applyAtBegin(Int32 index, RemainingArgs &... remaining_args)
Applique les fonctors des arguments additionnels en début de kernel.
Informations pour la boucle accélérateur 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.
Classe pour gérer la décomposition d'une boucle en plusieurs parties.
Gestion d'une commande sur accélérateur.
Int32 nbStride() const
Nombre de pas de décomposition de la boucle.
Conteneur pour RunCommandEnumerate.
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é.
ItemVectorView _unpaddedView() const
Vue sur les entités du groupe sans padding pour la vectorisation.
Index d'une entité ItemType dans une variable.
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.
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...
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 -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
Int32 LocalIdType
Type des entiers utilisés pour stocker les identifiants locaux des entités.
std::int32_t Int32
Type entier signé sur 32 bits.