Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
ForLoopRanges.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* ForLoopRanges.h (C) 2000-2024 */
9/* */
10/* Intervalles d'itérations pour les boucles. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_FORLOOPRANGES_H
13#define ARCANE_UTILS_FORLOOPRANGES_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/ArrayBounds.h"
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21
22namespace Arcane::impl
23{
24/*!
25 * \brief Classe pour appliquer la finalisation des réductions.
26 */
28{
29 public:
30
31 //! Applique les fonctors des arguments additionnels.
32 template <typename... ReducerArgs> static inline void
33 applyReducerArgs(ReducerArgs&... reducer_args)
34 {
35 // Applique les réductions
36 (reducer_args._internalReduceHost(), ...);
37 }
38};
39}
40
41namespace Arcane
42{
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46/*!
47 * \brief Intervalle d'itération pour une boucle.
48 */
50{
51 public:
52
53 //! Créé un interval entre *[lower_bound,lower_bound+size[*
54 ForLoopRange(Int32 lower_bound, Int32 size)
55 : m_lower_bound(lower_bound)
56 , m_size(size)
57 {}
58 //! Créé un interval entre *[0,size[*
59 ForLoopRange(Int32 size)
60 : m_lower_bound(0)
61 , m_size(size)
62 {}
63
64 public:
65
66 constexpr Int32 lowerBound() const { return m_lower_bound; }
67 constexpr Int32 size() const { return m_size; }
68 constexpr Int32 upperBound() const { return m_lower_bound + m_size; }
69
70 private:
71
72 Int32 m_lower_bound;
73 Int32 m_size;
74};
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78/*!
79 * \brief Interval d'itération simple.
80 *
81 * Les indices de début pour chaque dimension commencent à 0.
82 */
83template <int N, typename IndexType_>
85{
86 friend class ComplexForLoopRanges<N>;
87
88 public:
89
91 using ArrayIndexType = typename ArrayBoundsType::IndexType;
92 using IndexType = ArrayIndexType;
93
94 public:
95
96 explicit SimpleForLoopRanges(std::array<Int32, N> b)
97 : m_bounds(b)
98 {}
100 : m_bounds(b)
101 {}
102
103 public:
104
105 template <Int32 I> constexpr Int32 lowerBound() const { return 0; }
106 template <Int32 I> constexpr Int32 upperBound() const { return m_bounds.template constExtent<I>(); }
107 constexpr Int64 nbElement() const { return m_bounds.nbElement(); }
108 constexpr ArrayIndexType getIndices(Int32 i) const { return m_bounds.getIndices(i); }
109
110 private:
111
112 ArrayBoundsType m_bounds;
113};
114
115/*---------------------------------------------------------------------------*/
116/*---------------------------------------------------------------------------*/
117/*!
118 * \internal
119 * \brief Interval d'itération complexe.
120 *
121 * Les indices de début pour chaque dimension sont spécifiés \a lower et
122 * le nombre d'éléments dans chaque dimension par \a extents.
123 */
124template <int N, typename IndexType_>
126{
127 public:
128
130 using ArrayIndexType = typename ArrayBoundsType::IndexType;
131 using IndexType = ArrayIndexType;
132
133 public:
134
136 : m_lower_bounds(lower.asStdArray())
137 , m_extents(extents)
138 {}
140 : m_extents(bounds.m_bounds)
141 {}
142
143 public:
144
145 template <Int32 I> constexpr Int32 lowerBound() const { return m_lower_bounds[I]; }
146 template <Int32 I> constexpr Int32 upperBound() const { return m_lower_bounds[I] + m_extents.template constExtent<I>(); }
147 constexpr Int64 nbElement() const { return m_extents.nbElement(); }
148 constexpr ArrayIndexType getIndices(Int32 i) const
149 {
150 auto x = m_extents.getIndices(i);
151 x.add(m_lower_bounds);
152 return x;
153 }
154
155 private:
156
157 ArrayIndexType m_lower_bounds;
158 ArrayBoundsType m_extents;
159};
160
161/*---------------------------------------------------------------------------*/
162/*---------------------------------------------------------------------------*/
163//! Créé un intervalle d'itération [0,n1[
166{
168 using ArrayExtentType = typename BoundsType::ArrayExtentType;
169
170 return BoundsType(ArrayExtentType(n1));
171}
172
173//! Créé un intervalle d'itération [0,n1[,[0,n2[
174inline SimpleForLoopRanges<2>
175makeLoopRanges(Int32 n1, Int32 n2)
176{
178 using ArrayExtentType = typename BoundsType::ArrayExtentType;
179
180 return BoundsType(ArrayExtentType(n1, n2));
181}
182
183//! Créé un intervalle d'itération [0,n1[,[0,n2[,[0,n3[
184inline SimpleForLoopRanges<3>
185makeLoopRanges(Int32 n1, Int32 n2, Int32 n3)
186{
188 using ArrayExtentType = typename BoundsType::ArrayExtentType;
189
190 return BoundsType(ArrayExtentType(n1, n2, n3));
191}
192
193//! Créé un intervalle d'itération [0,n1[,[0,n2[,[0,n3[,[0,n4[
194inline SimpleForLoopRanges<4>
195makeLoopRanges(Int32 n1, Int32 n2, Int32 n3, Int32 n4)
196{
198 using ArrayExtentType = typename BoundsType::ArrayExtentType;
199
200 return BoundsType(ArrayExtentType(n1, n2, n3, n4));
201}
202
203//! Créé un intervalle d'itération dans ℕ.
204inline ComplexForLoopRanges<1>
206{
208 using ArrayExtentType = typename BoundsType::ArrayExtentType;
209
210 BoundsType lower_bounds(ArrayExtentType(n1.lowerBound()));
211 BoundsType sizes(ArrayExtentType(n1.size()));
212 return { lower_bounds, sizes };
213}
214
215//! Créé un intervalle d'itération dans ℕ².
216inline ComplexForLoopRanges<2>
218{
220 using ArrayExtentType = typename BoundsType::ArrayExtentType;
221
222 BoundsType lower_bounds(ArrayExtentType(n1.lowerBound(), n2.lowerBound()));
223 BoundsType sizes(ArrayExtentType(n1.size(), n2.size()));
224 return { lower_bounds, sizes };
225}
226
227//! Créé un intervalle d'itération dans ℕ³.
228inline ComplexForLoopRanges<3>
230{
232 using ArrayExtentType = typename BoundsType::ArrayExtentType;
233
234 BoundsType lower_bounds(ArrayExtentType(n1.lowerBound(), n2.lowerBound(), n3.lowerBound()));
235 BoundsType sizes(ArrayExtentType(n1.size(), n2.size(), n3.size()));
236 return { lower_bounds, sizes };
237}
238
239//! Créé un intervalle d'itération dans ℕ⁴.
240inline ComplexForLoopRanges<4>
242{
244 using ArrayExtentType = typename BoundsType::ArrayExtentType;
245
246 BoundsType lower_bounds(ArrayExtentType(n1.lowerBound(), n2.lowerBound(), n3.lowerBound(), n4.lowerBound()));
247 BoundsType sizes(ArrayExtentType(n1.size(), n2.size(), n3.size(), n4.size()));
248 return { lower_bounds, sizes };
249}
250
251/*---------------------------------------------------------------------------*/
252/*---------------------------------------------------------------------------*/
253//! Applique le fonctor \a func sur une boucle 1D.
254template <typename IndexType, template <int T, typename> class LoopBoundType,
255 typename Lambda, typename... ReducerArgs>
256inline void
257arcaneSequentialFor(LoopBoundType<1, IndexType> bounds, const Lambda& func, ReducerArgs... reducer_args)
258{
259 for (Int32 i0 = bounds.template lowerBound<0>(); i0 < bounds.template upperBound<0>(); ++i0)
260 func(MDIndex<1>(i0), reducer_args...);
262}
263
264//! Applique le fonctor \a func sur une boucle 2D.
265template <typename IndexType, template <int T, typename> class LoopBoundType, typename Lambda> inline void
266arcaneSequentialFor(LoopBoundType<2, IndexType> bounds, const Lambda& func)
267{
268 for (Int32 i0 = bounds.template lowerBound<0>(); i0 < bounds.template upperBound<0>(); ++i0)
269 for (Int32 i1 = bounds.template lowerBound<1>(); i1 < bounds.template upperBound<1>(); ++i1)
270 func(MDIndex<2>(i0, i1));
271}
272
273//! Applique le fonctor \a func sur une boucle 3D.
274template <typename IndexType, template <int T, typename> class LoopBoundType, typename Lambda> inline void
275arcaneSequentialFor(LoopBoundType<3, IndexType> bounds, const Lambda& func)
276{
277 for (Int32 i0 = bounds.template lowerBound<0>(); i0 < bounds.template upperBound<0>(); ++i0)
278 for (Int32 i1 = bounds.template lowerBound<1>(); i1 < bounds.template upperBound<1>(); ++i1)
279 for (Int32 i2 = bounds.template lowerBound<2>(); i2 < bounds.template upperBound<2>(); ++i2)
280 func(MDIndex<3>(i0, i1, i2));
281}
282
283//! Applique le fonctor \a func sur une boucle 4D.
284template <typename IndexType, template <int, typename> class LoopBoundType, typename Lambda> inline void
285arcaneSequentialFor(LoopBoundType<4, IndexType> bounds, const Lambda& func)
286{
287 for (Int32 i0 = bounds.template lowerBound<0>(); i0 < bounds.template upperBound<0>(); ++i0)
288 for (Int32 i1 = bounds.template lowerBound<1>(); i1 < bounds.template upperBound<1>(); ++i1)
289 for (Int32 i2 = bounds.template lowerBound<2>(); i2 < bounds.template upperBound<2>(); ++i2)
290 for (Int32 i3 = bounds.template lowerBound<3>(); i3 < bounds.template upperBound<3>(); ++i3)
291 func(MDIndex<4>(i0, i1, i2, i3));
292}
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297} // End namespace Arcane
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
302#endif
Intervalle d'itération pour une boucle.
ForLoopRange(Int32 size)
Créé un interval entre *[0,size[*.
ForLoopRange(Int32 lower_bound, Int32 size)
Créé un interval entre *[lower_bound,lower_bound+size[*.
Interval d'itération simple.
Classe pour appliquer la finalisation des réductions.
static void applyReducerArgs(ReducerArgs &... reducer_args)
Applique les fonctors des arguments additionnels.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
void arcaneSequentialFor(LoopBoundType< 1, IndexType > bounds, const Lambda &func, ReducerArgs... reducer_args)
Applique le fonctor func sur une boucle 1D.
SimpleForLoopRanges< 1 > makeLoopRanges(Int32 n1)
Créé un intervalle d'itération [0,n1[.