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/RunCommand.h"
21#include "arcane/accelerator/KernelLauncher.h"
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26namespace Arcane::Accelerator::impl
27{
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
38template <int N, template <int T, typename> class LoopBoundType, typename Lambda, typename... RemainingArgs> void
39_applyGenericLoop(RunCommand& command, LoopBoundType<N, Int32> bounds,
40 const Lambda& func, const RemainingArgs&... other_args)
41{
42 Int64 vsize = bounds.nbElement();
43 if (vsize == 0)
44 return;
45 impl::RunCommandLaunchInfo launch_info(command, vsize);
46 const eExecutionPolicy exec_policy = launch_info.executionPolicy();
47 launch_info.beginExecute();
48 switch (exec_policy) {
50 _applyKernelCUDA(launch_info, ARCANE_KERNEL_CUDA_FUNC(impl::doDirectGPULambdaArrayBounds2) < LoopBoundType<N, Int32>, Lambda, RemainingArgs... >, func, bounds, other_args...);
51 break;
53 _applyKernelHIP(launch_info, ARCANE_KERNEL_HIP_FUNC(impl::doDirectGPULambdaArrayBounds2) < LoopBoundType<N, Int32>, Lambda, RemainingArgs... >, func, bounds, other_args...);
54 break;
56 _applyKernelSYCL(launch_info, ARCANE_KERNEL_SYCL_FUNC(impl::DoDirectSYCLLambdaArrayBounds) < LoopBoundType<N, Int32>, Lambda, RemainingArgs... > {}, func, bounds, other_args...);
57 break;
59 arcaneSequentialFor(bounds, func, other_args...);
60 break;
62 arccoreParallelFor(bounds, launch_info.loopRunInfo(), func, other_args...);
63 break;
64 default:
65 ARCANE_FATAL("Invalid execution policy '{0}'", exec_policy);
66 }
67 launch_info.endExecute();
68}
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73template <typename LoopBoundType, typename... RemainingArgs>
74class ExtendedArrayBoundLoop
75{
76 public:
77
78 ExtendedArrayBoundLoop(const LoopBoundType& bounds, RemainingArgs... args)
79 : m_bounds(bounds)
80 , m_remaining_args(args...)
81 {
82 }
83 LoopBoundType m_bounds;
84 std::tuple<RemainingArgs...> m_remaining_args;
85};
86
87template <typename ExtentType, typename... RemainingArgs> auto
88makeExtendedArrayBoundLoop(const ArrayBounds<ExtentType>& bounds, RemainingArgs... args)
90{
91 return ExtendedArrayBoundLoop<ArrayBounds<ExtentType>, RemainingArgs...>(bounds, args...);
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
97} // namespace Arcane::Accelerator::impl
98
99namespace Arcane::Accelerator
100{
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
106template <typename ExtentType, typename Lambda> void
107run(RunCommand& command, ArrayBounds<ExtentType> bounds, const Lambda& func)
108{
109 impl::_applyGenericLoop(command, SimpleForLoopRanges<ExtentType::rank()>(bounds), func);
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
116template <int N, typename Lambda> void
117run(RunCommand& command, SimpleForLoopRanges<N, Int32> bounds, const Lambda& func)
118{
119 impl::_applyGenericLoop(command, bounds, func);
120}
121
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
126template <int N, typename Lambda> void
127run(RunCommand& command, ComplexForLoopRanges<N, Int32> bounds, const Lambda& func)
128{
129 impl::_applyGenericLoop(command, bounds, func);
130}
131
133template <int N, template <int T, typename> class LoopBoundType, typename Lambda, typename... RemainingArgs> void
134runExtended(RunCommand& command, LoopBoundType<N, Int32> bounds,
135 const Lambda& func, const std::tuple<RemainingArgs...>& other_args)
136{
137 std::apply([&](auto... vs) { impl::_applyGenericLoop(command, bounds, func, vs...); }, other_args);
138}
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
143template <int N, typename LoopBoundType, typename... RemainingArgs>
144class ArrayBoundRunCommand
145{
146 public:
147
148 ArrayBoundRunCommand(RunCommand& command, const LoopBoundType& bounds)
149 : m_command(command)
150 , m_bounds(bounds)
151 {
152 }
153 ArrayBoundRunCommand(RunCommand& command, const LoopBoundType& bounds, const std::tuple<RemainingArgs...>& args)
154 : m_command(command)
155 , m_bounds(bounds)
156 , m_remaining_args(args)
157 {
158 }
159 RunCommand& m_command;
160 LoopBoundType m_bounds;
161 std::tuple<RemainingArgs...> m_remaining_args;
162};
163
164template <typename ExtentType> auto
165operator<<(RunCommand& command, const ArrayBounds<ExtentType>& bounds)
166-> ArrayBoundRunCommand<ExtentType::rank(), SimpleForLoopRanges<ExtentType::rank(), Int32>>
167{
168 return { command, bounds };
169}
170
171template <typename ExtentType, typename... RemainingArgs> auto
172operator<<(RunCommand& command, const impl::ExtendedArrayBoundLoop<ExtentType, RemainingArgs...>& ex_loop)
173-> ArrayBoundRunCommand<1, SimpleForLoopRanges<1, Int32>, RemainingArgs...>
174{
175 return { command, ex_loop.m_bounds, ex_loop.m_remaining_args };
176}
177
179operator<<(RunCommand& command, const SimpleForLoopRanges<N, Int32>& bounds)
180{
181 return { command, bounds };
182}
183
185operator<<(RunCommand& command, const ComplexForLoopRanges<N, Int32>& bounds)
186{
187 return { command, bounds };
188}
189
190template <int N, template <int, typename> class ForLoopBoundType, typename Lambda, typename... RemainingArgs>
191void operator<<(ArrayBoundRunCommand<N, ForLoopBoundType<N, Int32>, RemainingArgs...>&& nr, const Lambda& f)
192{
193 if constexpr (sizeof...(RemainingArgs) > 0) {
194 runExtended(nr.m_command, nr.m_bounds, f, nr.m_remaining_args);
195 }
196 else {
197 run(nr.m_command, nr.m_bounds, f);
198 }
199}
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
203
204} // End namespace Arcane::Accelerator
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
208
210#define RUNCOMMAND_LOOP(iter_name, bounds) \
211 A_FUNCINFO << bounds << [=] ARCCORE_HOST_DEVICE(typename decltype(bounds)::IndexType iter_name)
212
214#define RUNCOMMAND_LOOPN(iter_name, N, ...) \
215 A_FUNCINFO << Arcane::ArrayBounds<typename Arcane::MDDimType<N>::DimType>(__VA_ARGS__) << [=] ARCCORE_HOST_DEVICE(Arcane::ArrayIndex<N> iter_name)
216
218#define RUNCOMMAND_LOOP2(iter_name, x1, x2) \
219 A_FUNCINFO << Arcane::ArrayBounds<MDDim2>(x1, x2) << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<2> iter_name)
220
222#define RUNCOMMAND_LOOP3(iter_name, x1, x2, x3) \
223 A_FUNCINFO << Arcane::ArrayBounds<MDDim3>(x1, x2, x3) << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<3> iter_name)
224
226#define RUNCOMMAND_LOOP4(iter_name, x1, x2, x3, x4) \
227 A_FUNCINFO << Arcane::ArrayBounds<MDDim4>(x1, x2, x3, x4) << [=] ARCCORE_HOST_DEVICE(Arcane::MDIndex<4> iter_name)
228
236#define RUNCOMMAND_LOOP1(iter_name, x1, ...) \
237 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedArrayBoundLoop(Arcane::ArrayBounds<MDDim1>(x1) __VA_OPT__(, __VA_ARGS__)) \
238 << [=] ARCCORE_HOST_DEVICE(Arcane::ArrayIndex<1> iter_name __VA_OPT__(ARCANE_RUNCOMMAND_REDUCER_FOR_EACH(__VA_ARGS__)))
239
243#define RUNCOMMAND_SINGLE(...) \
244 A_FUNCINFO << ::Arcane::Accelerator::impl::makeExtendedArrayBoundLoop(Arcane::ArrayBounds<MDDim1>(1) __VA_OPT__(, __VA_ARGS__)) \
245 << [=] ARCCORE_HOST_DEVICE(Arcane::ArrayIndex<1> __VA_OPT__(ARCANE_RUNCOMMAND_REDUCER_FOR_EACH(__VA_ARGS__)))
246
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251/*---------------------------------------------------------------------------*/
252/*---------------------------------------------------------------------------*/
253
254#endif
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Classes, Types et macros pour gérer la concurrence.
void _applyGenericLoop(RunCommand &command, LoopBoundType< N, Int32 > bounds, const Lambda &func, const RemainingArgs &... other_args)
Applique la lambda func sur une boucle bounds.
Gestion d'une commande sur accélérateur.
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.
Espace de nom pour l'utilisation des accélérateurs.
void runExtended(RunCommand &command, LoopBoundType< N, Int32 > bounds, const Lambda &func, const std::tuple< RemainingArgs... > &other_args)
Applique la lambda func sur l'intervalle d'itération donnée par bounds.
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.
std::int64_t Int64
Type entier signé sur 64 bits.
void arcaneSequentialFor(LoopBoundType< 1, IndexType > bounds, const Lambda &func, ReducerArgs... reducer_args)
Applique le fonctor func sur une boucle 1D.
void arccoreParallelFor(const ComplexForLoopRanges< RankValue > &loop_ranges, const ForLoopRunInfo &run_info, const LambdaType &lambda_function, const ReducerArgs &... reducer_args)
Applique en concurrence la fonction lambda lambda_function sur l'intervalle d'itération donné par loo...
Definition ParallelFor.h:85
std::int32_t Int32
Type entier signé sur 32 bits.