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();
87 for (
Int32 k = 0; k < nb_grid_stride; ++k) {
88 Int32 true_i = i + (offset * k);
89 if (true_i < nb_item) {
91 body(BuilderType::create(true_i, lid), remaining_args...);
96 using BuilderType = LoopBoundsType::BuilderType;
99 SmallSpan<const Int32> ids = bounds.ids();
100 if (i < ids.size()) {
102 body(BuilderType::create(i, lid), remaining_args...);
117#if defined(ARCCORE_COMPILING_SYCL)
120template <
typename TraitsType,
typename Lambda,
typename... RemainingArgs>
121class DoIndirectSYCLLambda
125 void operator()(sycl::nd_item<1> x, SmallSpan<std::byte> shared_memory,
126 SmallSpan<const Int32> ids, Lambda func,
127 RemainingArgs... remaining_args)
const
129 using BuilderType = TraitsType::BuilderType;
131 auto privatizer = privatize(func);
132 auto& body = privatizer.privateCopy();
134 Int32 i =
static_cast<Int32
>(x.get_global_id(0));
135 SyclKernelRemainingArgsHelper::applyAtBegin(x, shared_memory, remaining_args...);
136 if (i < ids.size()) {
138 body(BuilderType::create(i, lid), remaining_args...);
140 SyclKernelRemainingArgsHelper::applyAtEnd(x, shared_memory, remaining_args...);
142 void operator()(sycl::id<1> x, SmallSpan<const Int32> ids, Lambda func)
const
144 using BuilderType = TraitsType::BuilderType;
146 auto privatizer = privatize(func);
147 auto& body = privatizer.privateCopy();
149 Int32 i =
static_cast<Int32
>(x);
150 if (i < ids.size()) {
152 body(BuilderType::create(i, lid));
181class IteratorWithIndex
186 constexpr ARCCORE_HOST_DEVICE IteratorWithIndex(
Int32 i, T v)
193 constexpr ARCCORE_HOST_DEVICE
Int32 index()
const {
return m_index; }
194 constexpr ARCCORE_HOST_DEVICE T value()
const {
return m_value; }
207namespace Arcane::impl
234 constexpr ARCCORE_HOST_DEVICE
static T create(
Int32, T value)
245namespace Arcane::Accelerator::impl
258 || std::derived_from<T, ItemLocalId>
259 || std::derived_from<T, IteratorWithIndexBase>;
278 using ItemType =
typename ItemLocalIdT<T>::ItemType;
289 using ItemType =
typename T::ItemType;
306template <
typename ItemType>
307class RunCommandItemContainer
312 : m_item_group(group)
316 : m_item_vector_view(item_vector_view)
317 , m_unpadded_vector_view(item_vector_view)
323 Int32 size()
const {
return m_unpadded_vector_view.size(); }
327 if (!m_item_group.null())
328 return m_item_group._paddedView();
329 return m_item_vector_view;
350template <RunCommandEnumerateIteratorConcept IteratorValueType_>
351class RunCommandItemEnumeratorTraitsT
356 using ItemType =
typename SubTraitsType::ItemType;
358 using ValueType =
typename SubTraitsType::ValueType;
360 using BuilderType =
typename SubTraitsType::BuilderType;
365 : m_item_container(group)
368 : m_item_container(vector_view)
380template <
typename TraitsType,
typename ContainerType,
typename Lambda,
typename... RemainingArgs>
381void _doItemsLambda(
Int32 base_index,
ContainerType sub_items,
const Lambda& func, RemainingArgs... remaining_args)
383 using ItemType = TraitsType::ItemType;
384 using BuilderType = TraitsType::BuilderType;
386 auto privatizer = Impl::privatize(func);
387 auto& body = privatizer.privateCopy();
391 body(BuilderType::create(iitem.index() + base_index,
LocalIdType(iitem.itemLocalId())), remaining_args...);
401template <
typename TraitsType,
typename Lambda,
typename... RemainingArgs>
void
403 const Lambda& func,
const RemainingArgs&... remaining_args)
409 using ItemType =
typename TraitsType::ItemType;
412 [[maybe_unused]] LoopBoundType bounds(ids);
414#if defined(ARCCORE_EXPERIMENTAL_GRID_STRIDE) && defined(ARCCORE_COMPILING_CUDA_OR_HIP)
416 TrueLoopBoundType bounds2(command.
nbStride(), bounds);
419 using TrueLoopBoundType = LoopBoundType;
420 [[maybe_unused]]
const TrueLoopBoundType& bounds2 = bounds;
427 switch (exec_policy) {
429 ARCCORE_KERNEL_CUDA_FUNC((Impl::doIndirectGPULambda2<TrueLoopBoundType, Lambda, RemainingArgs...>),
430 launch_info, func, bounds2, remaining_args...);
433 ARCCORE_KERNEL_HIP_FUNC((Impl::doIndirectGPULambda2<TrueLoopBoundType, Lambda, RemainingArgs...>),
434 launch_info, func, bounds2, remaining_args...);
437 ARCCORE_KERNEL_SYCL_FUNC((Impl::DoIndirectSYCLLambda<TraitsType, Lambda, RemainingArgs...>{}),
438 launch_info, func, ids, remaining_args...);
441 impl::_doItemsLambda<TraitsType>(0, items.paddedView(), func, remaining_args...);
446 impl::_doItemsLambda<TraitsType>(base_index, sub_items, func, remaining_args...);
450 ARCCORE_FATAL(
"Invalid execution policy '{0}'", exec_policy);
458template <
typename TraitsType,
typename... RemainingArgs>
459class ItemRunCommandArgs
463 ItemRunCommandArgs(
const TraitsType& traits,
const RemainingArgs&... remaining_args)
465 , m_remaining_args(remaining_args...)
472 std::tuple<RemainingArgs...> m_remaining_args;
486template <
typename TraitsType,
typename Lambda>
void
487run(
RunCommand& command,
const TraitsType& traits,
const Lambda& func)
495template <
typename TraitsType,
typename... RemainingArgs>
500 ItemRunCommand(
RunCommand& command,
const TraitsType& traits)
506 ItemRunCommand(
RunCommand& command,
const TraitsType& traits,
const std::tuple<RemainingArgs...>& remaining_args)
509 , m_remaining_args(remaining_args)
517 std::tuple<RemainingArgs...> m_remaining_args;
523template <
typename ItemType>
auto
534template <
typename ItemType>
auto
537 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
543template <
typename ItemType>
auto
544operator<<(RunCommand& command,
const ItemGroupT<ItemType>& items)
546 using TraitsType = impl::RunCommandItemEnumeratorTraitsT<ItemType>;
547 return ItemRunCommand<TraitsType>(command, TraitsType(items));
550template <
typename TraitsType,
typename Lambda>
553 run(nr.m_command, nr.m_traits, f);
556template <
typename TraitsType,
typename... RemainingArgs>
auto
559 return ItemRunCommand<TraitsType, RemainingArgs...>(command, args.m_traits, args.m_remaining_args);
562template <
typename TraitsType,
typename Lambda,
typename... RemainingArgs>
565 if constexpr (
sizeof...(RemainingArgs) > 0) {
569 run(nr.m_command, nr.m_traits, f);
577namespace Arcane::Accelerator::impl
583template <
typename ItemTypeName,
typename ItemContainerType,
typename... RemainingArgs>
auto
584makeExtendedItemEnumeratorLoop(
const ItemContainerType& container_type,
585 const RemainingArgs&... remaining_args)
588 return ItemRunCommandArgs<TraitsType, RemainingArgs...>(TraitsType(container_type), remaining_args...);
617#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group, ...) \
618 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedItemEnumeratorLoop<ItemTypeName>(item_group __VA_OPT__(, __VA_ARGS__)) \
619 << [=] ARCCORE_HOST_DEVICE(::Arcane::Accelerator::impl::RunCommandItemEnumeratorTraitsT<ItemTypeName>::ValueType iter_name \
620 __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.