Arcane  v4.1.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
RunCommandLoop.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/* RunCommandLoop.h (C) 2000-2025 */
9/* */
10/* Macros pour exécuter une boucle sur une commande. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_ACCELERATOR_RUNCOMMANDLOOP_H
13#define ARCANE_ACCELERATOR_RUNCOMMANDLOOP_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17// Pour compatibilité avec l'existant
19
20#include "arcane/accelerator/core/RunCommand.h"
21#include "arcane/accelerator/KernelLauncher.h"
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26namespace Arcane::Accelerator::impl
27{
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
44template <typename LoopBoundType, typename Lambda, typename... RemainingArgs> void
45_applyGenericLoop(RunCommand& command, LoopBoundType bounds,
46 const Lambda& func, const RemainingArgs&... other_args)
47{
48 Int64 vsize = bounds.nbElement();
49 if (vsize == 0)
50 return;
51 Impl::RunCommandLaunchInfo launch_info(command, vsize);
52 const eExecutionPolicy exec_policy = launch_info.executionPolicy();
53 launch_info.beginExecute();
54 switch (exec_policy) {
56 _applyKernelCUDA(launch_info, ARCANE_KERNEL_CUDA_FUNC(Impl::doDirectGPULambdaArrayBounds2) < LoopBoundType, Lambda, RemainingArgs... >, func, bounds, other_args...);
57 break;
59 _applyKernelHIP(launch_info, ARCANE_KERNEL_HIP_FUNC(Impl::doDirectGPULambdaArrayBounds2) < LoopBoundType, Lambda, RemainingArgs... >, func, bounds, other_args...);
60 break;
62 _applyKernelSYCL(launch_info, ARCANE_KERNEL_SYCL_FUNC(Impl::DoDirectSYCLLambdaArrayBounds) < LoopBoundType, Lambda, RemainingArgs... > {}, func, bounds, other_args...);
63 break;
65 arcaneSequentialFor(bounds, func, other_args...);
66 break;
68 arccoreParallelFor(bounds, launch_info.loopRunInfo(), func, other_args...);
69 break;
70 default:
71 ARCANE_FATAL("Invalid execution policy '{0}'", exec_policy);
72 }
73 launch_info.endExecute();
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
84template <typename LoopBoundType, typename... RemainingArgs>
85class ArrayBoundRunCommand
86{
87 public:
88
89 ArrayBoundRunCommand(RunCommand& command, const LoopBoundType& bounds)
90 : m_command(command)
91 , m_bounds(bounds)
92 {
93 }
94 ArrayBoundRunCommand(RunCommand& command, const LoopBoundType& bounds, const std::tuple<RemainingArgs...>& args)
95 : m_command(command)
96 , m_bounds(bounds)
97 , m_remaining_args(args)
98 {
99 }
100 RunCommand& m_command;
101 LoopBoundType m_bounds;
102 std::tuple<RemainingArgs...> m_remaining_args;
103};
104
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
110template <typename LoopBoundType, typename... RemainingArgs>
111class ExtendedArrayBoundLoop
112{
113 public:
114
115 ExtendedArrayBoundLoop(const LoopBoundType& bounds, RemainingArgs... args)
116 : m_bounds(bounds)
117 , m_remaining_args(args...)
118 {
119 }
120 LoopBoundType m_bounds;
121 std::tuple<RemainingArgs...> m_remaining_args;
122};
123
124template <typename LoopBoundType, typename... RemainingArgs> auto
125makeExtendedArrayBoundLoop(const LoopBoundType& bounds, RemainingArgs... args)
126-> ExtendedArrayBoundLoop<LoopBoundType, RemainingArgs...>
127{
128 return ExtendedArrayBoundLoop<LoopBoundType, RemainingArgs...>(bounds, args...);
129}
130
131template <typename LoopBoundType, typename... RemainingArgs> auto
132makeExtendedLoop(const LoopBoundType& bounds, RemainingArgs... args)
133-> ExtendedArrayBoundLoop<LoopBoundType, RemainingArgs...>
134{
135 return ExtendedArrayBoundLoop<LoopBoundType, RemainingArgs...>(bounds, args...);
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
146template <typename LoopBoundType, typename Lambda, typename... RemainingArgs> void
147runExtended(RunCommand& command, LoopBoundType bounds,
148 const Lambda& func, const std::tuple<RemainingArgs...>& other_args)
149{
150 std::apply([&](auto... vs) { _applyGenericLoop(command, bounds, func, vs...); }, other_args);
151}
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
155
156} // namespace Arcane::Accelerator::impl
157
158namespace Arcane::Accelerator
159{
160
161/*---------------------------------------------------------------------------*/
162/*---------------------------------------------------------------------------*/
163
165template <typename ExtentType, typename Lambda> void
166run(RunCommand& command, ArrayBounds<ExtentType> bounds, const Lambda& func)
167{
168 impl::_applyGenericLoop(command, SimpleForLoopRanges<ExtentType::rank()>(bounds), func);
169}
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
173
175template <int N, typename Lambda> void
176run(RunCommand& command, SimpleForLoopRanges<N, Int32> bounds, const Lambda& func)
177{
178 impl::_applyGenericLoop(command, bounds, func);
179}
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
185template <int N, typename Lambda> void
186run(RunCommand& command, ComplexForLoopRanges<N, Int32> bounds, const Lambda& func)
187{
188 impl::_applyGenericLoop(command, bounds, func);
189}
190
191/*---------------------------------------------------------------------------*/
192/*---------------------------------------------------------------------------*/
193
194template <typename ExtentType> auto
195operator<<(RunCommand& command, const ArrayBounds<ExtentType>& bounds)
196 -> impl::ArrayBoundRunCommand<SimpleForLoopRanges<ExtentType::rank(), Int32>>
197{
198 return { command, bounds };
199}
200
201template <typename LoopBoundType, typename... RemainingArgs> auto
203 -> impl::ArrayBoundRunCommand<LoopBoundType, RemainingArgs...>
204{
205 return { command, ex_loop.m_bounds, ex_loop.m_remaining_args };
206}
207
209operator<<(RunCommand& command, const SimpleForLoopRanges<N, Int32>& bounds)
210{
211 return { command, bounds };
212}
213
215operator<<(RunCommand& command, const ComplexForLoopRanges<N, Int32>& bounds)
216{
217 return { command, bounds };
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
223} // namespace Arcane::Accelerator
224
225/*---------------------------------------------------------------------------*/
226/*---------------------------------------------------------------------------*/
227
228namespace Arcane::Accelerator::impl
229{
230
231/*---------------------------------------------------------------------------*/
232/*---------------------------------------------------------------------------*/
233
234template <typename LoopBoundType, typename Lambda, typename... RemainingArgs>
235inline void operator<<(ArrayBoundRunCommand<LoopBoundType, RemainingArgs...>&& nr, const Lambda& f)
236{
237 if constexpr (sizeof...(RemainingArgs) > 0) {
238 runExtended(nr.m_command, nr.m_bounds, f, nr.m_remaining_args);
239 }
240 else {
241 run(nr.m_command, nr.m_bounds, f);
242 }
243}
244
245/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247
248} // End namespace Arcane::Accelerator
249
250/*---------------------------------------------------------------------------*/
251/*---------------------------------------------------------------------------*/
252
254#define RUNCOMMAND_LOOP(iter_name, bounds, ...) \
255 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedLoop(bounds __VA_OPT__(, __VA_ARGS__)) \
256 << [=] ARCCORE_HOST_DEVICE(typename decltype(bounds)::LoopIndexType iter_name __VA_OPT__(ARCANE_RUNCOMMAND_REDUCER_FOR_EACH(__VA_ARGS__)))
257
259#define RUNCOMMAND_LOOPN(iter_name, N, ...) \
260 A_FUNCINFO << Arcane::ArrayBounds<typename Arcane::MDDimType<N>::DimType>(__VA_ARGS__) << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<N> iter_name)
261
263#define RUNCOMMAND_LOOP2(iter_name, x1, x2) \
264 A_FUNCINFO << Arcane::ArrayBounds<MDDim2>(x1, x2) << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<2> iter_name)
265
267#define RUNCOMMAND_LOOP3(iter_name, x1, x2, x3) \
268 A_FUNCINFO << Arcane::ArrayBounds<MDDim3>(x1, x2, x3) << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<3> iter_name)
269
271#define RUNCOMMAND_LOOP4(iter_name, x1, x2, x3, x4) \
272 A_FUNCINFO << Arcane::ArrayBounds<MDDim4>(x1, x2, x3, x4) << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<4> iter_name)
273
282#define RUNCOMMAND_LOOP1(iter_name, x1, ...) \
283 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedArrayBoundLoop(::Arcane::SimpleForLoopRanges<1>(x1) __VA_OPT__(, __VA_ARGS__)) \
284 << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<1> iter_name __VA_OPT__(ARCANE_RUNCOMMAND_REDUCER_FOR_EACH(__VA_ARGS__)))
285
289#define RUNCOMMAND_SINGLE(...) \
290 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedArrayBoundLoop(::Arcane::SimpleForLoopRanges<1>(1) __VA_OPT__(, __VA_ARGS__)) \
291 << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<1> __VA_OPT__(ARCANE_RUNCOMMAND_REDUCER_FOR_EACH(__VA_ARGS__)))
292
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
300#endif
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Classes, Types et macros pour gérer la concurrence.
void _applyGenericLoop(RunCommand &command, LoopBoundType bounds, const Lambda &func, const RemainingArgs &... other_args)
Applique la lambda func sur une boucle bounds.
void runExtended(RunCommand &command, LoopBoundType bounds, const Lambda &func, const std::tuple< RemainingArgs... > &other_args)
Applique la lambda func sur l'intervalle d'itération donnée par bounds.
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.
Gestion d'une commande sur accélérateur.
Classe pour conserver les arguments d'une RunCommand.
Classe pour gérer les paramètres supplémentaires des commandes.
Espace de nom pour l'utilisation des accélérateurs.
void arccoreParallelFor(WorkGroupLoopRange bounds, ForLoopRunInfo run_info, const Lambda &func, const RemainingArgs &... remaining_args)
Applique le fonctor func sur une boucle parallèle.
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.
void arcaneSequentialFor(WorkGroupLoopRange bounds, const Lambda &func, const RemainingArgs &... remaining_args)
Applique le fonctor func sur une boucle séqentielle.
std::int64_t Int64
Type entier signé sur 64 bits.
std::int32_t Int32
Type entier signé sur 32 bits.