Arcane  v3.15.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
ArrayExtentsValue.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/* ArrayExtentsValue.h (C) 2000-2024 */
9/* */
10/* Gestion de valeurs des dimensions des tableaux N-dimensions. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_ARRAYEXTENTSVALUE_H
13#define ARCANE_UTILS_ARRAYEXTENTSVALUE_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/ArrayView.h"
18#include "arcane/utils/ArrayBoundsIndex.h"
19#include "arcane/utils/ArrayLayout.h"
20
21#include "arccore/base/Span.h"
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26namespace Arcane::impl
27{
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32template <class T> constexpr ARCCORE_HOST_DEVICE
33T
34fastmod(T a, T b)
35{
36 return a < b ? a : a - b * (a / b);
37}
38
39/*!
40 * \brief Informations pour une dimension fixe connue à la compilation.
41 *
42 * La valeur de la dimension est donnée en paramètre template
43 */
44template <Int32 Size, typename IndexType_ = Int32>
46{
47 public:
48
49 static constexpr Int64 size() { return Size; };
50 static constexpr Int32 v = Size;
51};
52
53/*!
54 * \brief Spécialisation pour une dimension dynamique.
55 *
56 * La valeur de la dimension est conservée dans \a v.
57 */
58template <typename IndexType_>
59class ExtentValue<DynExtent, IndexType_>
60{
61 public:
62
63 constexpr Int64 size() const { return v; }
64
65 public:
66
67 IndexType_ v = 0;
68};
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72/*!
73 * \brief Spécialisation pour contenir les dimensions d'un tableau à 1 dimension.
74 */
75template <typename IndexType_, Int32 X0>
76class ArrayExtentsValue<IndexType_, X0>
77{
78 public:
79
81 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
82 using MDIndexType = MDIndex<1>;
83
84 using IndexType ARCANE_DEPRECATED_REASON("Use 'MDIndexType' instead") = ArrayIndex<1>;
85
86 ArrayExtentsValue() = default;
87
88 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int32 constExtent() const
89 {
90 static_assert(I == 0, "Invalid value for i (i==0)");
91 return m_extent0.v;
92 }
93
94 constexpr ARCCORE_HOST_DEVICE std::array<Int32, 1> asStdArray() const
95 {
96 return std::array<Int32, 1>{ m_extent0.v };
97 }
98
99 constexpr ARCCORE_HOST_DEVICE Int64 totalNbElement() const
100 {
101 return m_extent0.v;
102 }
103
104 constexpr ARCCORE_HOST_DEVICE MDIndexType getIndices(Int32 i) const
105 {
106 return { i };
107 }
108
109 constexpr ARCCORE_HOST_DEVICE Int32 extent0() const { return m_extent0.v; };
110
111 //! Liste des dimensions dynamiques
112 constexpr DynamicDimsType dynamicExtents() const
113 {
114 std::array<Int32, ExtentsType::nb_dynamic> x = {};
115 Int32 i = 0;
116 if constexpr (X0 == DynExtent)
117 x[i++] = m_extent0.v;
118 return DynamicDimsType(x);
119 }
120
121 protected:
122
123 explicit ARCCORE_HOST_DEVICE ArrayExtentsValue(SmallSpan<const Int32> extents)
124 {
125 if constexpr (X0 == DynExtent)
126 m_extent0.v = extents[0];
127 }
128
129 //! Construit une instance avec les N valeurs dynamiques.
130 constexpr ARCCORE_HOST_DEVICE ArrayExtentsValue(DynamicDimsType dims)
131 {
132 ARCANE_UNUSED(dims);
133 Int32 i = 0;
134 if constexpr (X0 == DynExtent)
135 m_extent0.v = dims[i++];
136 }
137
138 constexpr std::array<Int32, 0> _removeFirstExtent() const
139 {
140 return {};
141 }
142
143 ARCCORE_HOST_DEVICE void _checkIndex(MDIndexType idx) const
144 {
145 ARCANE_UNUSED(idx);
146 ARCCORE_CHECK_AT(idx.id0(), m_extent0.v);
147 }
148
149 protected:
150
151 impl::ExtentValue<X0> m_extent0;
152};
153
154/*---------------------------------------------------------------------------*/
155/*---------------------------------------------------------------------------*/
156/*!
157 * \brief Spécialisation pour contenir les dimensions d'un tableau à 2 dimensions.
158 */
159template <typename IndexType_, Int32 X0, Int32 X1>
160class ArrayExtentsValue<IndexType_, X0, X1>
161{
162 public:
163
165 using MDIndexType = MDIndex<2>;
166 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
167
168 using IndexType ARCANE_DEPRECATED_REASON("Use 'MDIndexType' instead") = ArrayIndex<2>;
169
170 public:
171
172 ArrayExtentsValue() = default;
173
174 public:
175
176 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int32 constExtent() const
177 {
178 static_assert(I >= 0 && I < 2, "Invalid value for I (0<=I<2)");
179 if (I == 0)
180 return m_extent0.v;
181 return m_extent1.v;
182 }
183
184 constexpr ARCCORE_HOST_DEVICE std::array<Int32, 2> asStdArray() const
185 {
186 return { m_extent0.v, m_extent1.v };
187 }
188
189 constexpr ARCCORE_HOST_DEVICE Int64 totalNbElement() const
190 {
191 return m_extent0.size() * m_extent1.size();
192 }
193
194 constexpr ARCCORE_HOST_DEVICE MDIndexType getIndices(Int32 i) const
195 {
196 Int32 i1 = impl::fastmod(i, m_extent1.v);
197 Int32 i0 = i / m_extent1.v;
198 return { i0, i1 };
199 }
200
201 constexpr ARCCORE_HOST_DEVICE Int32 extent0() const { return m_extent0.v; };
202 constexpr ARCCORE_HOST_DEVICE Int32 extent1() const { return m_extent1.v; };
203
204 //! Liste des dimensions dynamiques
205 constexpr DynamicDimsType dynamicExtents() const
206 {
207 std::array<Int32, ExtentsType::nb_dynamic> x = {};
208 Int32 i = 0;
209 if constexpr (X0 == DynExtent)
210 x[i++] = m_extent0.v;
211 if constexpr (X1 == DynExtent)
212 x[i++] = m_extent1.v;
213 return DynamicDimsType(x);
214 }
215
216 protected:
217
218 explicit ARCCORE_HOST_DEVICE ArrayExtentsValue(SmallSpan<const Int32> extents)
219 {
220 if constexpr (X0 == DynExtent)
221 m_extent0.v = extents[0];
222 if constexpr (X1 == DynExtent)
223 m_extent1.v = extents[1];
224 }
225
226 //! Construit une instance avec les N valeurs dynamiques.
227 constexpr ARCCORE_HOST_DEVICE ArrayExtentsValue(DynamicDimsType dims)
228 {
229 ARCANE_UNUSED(dims);
230 Int32 i = 0;
231 if constexpr (X0 == DynExtent)
232 m_extent0.v = dims[i++];
233 if constexpr (X1 == DynExtent)
234 m_extent1.v = dims[i++];
235 }
236
237 constexpr std::array<Int32, 1> _removeFirstExtent() const
238 {
239 return std::array<Int32, 1>{ m_extent1.v };
240 }
241
242 ARCCORE_HOST_DEVICE void _checkIndex(MDIndexType idx) const
243 {
244 ARCANE_UNUSED(idx);
245 ARCCORE_CHECK_AT(idx.id0(), m_extent0.v);
246 ARCCORE_CHECK_AT(idx.id1(), m_extent1.v);
247 }
248
249 protected:
250
251 impl::ExtentValue<X0> m_extent0;
252 impl::ExtentValue<X1> m_extent1;
253};
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257/*!
258 * \brief Spécialisation pour contenir les dimensions d'un tableau à 3 dimensions.
259 */
260template <typename IndexType_, Int32 X0, Int32 X1, Int32 X2>
261class ArrayExtentsValue<IndexType_, X0, X1, X2>
262{
263 public:
264
266 using MDIndexType = MDIndex<3>;
267 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
268
269 using IndexType ARCANE_DEPRECATED_REASON("Use 'MDIndexType' instead") = ArrayIndex<3>;
270
271 public:
272
273 ArrayExtentsValue() = default;
274
275 public:
276
277 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int32 constExtent() const
278 {
279 static_assert(I >= 0 && I < 3, "Invalid value for I (0<=I<3)");
280 if (I == 0)
281 return m_extent0.v;
282 if (I == 1)
283 return m_extent1.v;
284 return m_extent2.v;
285 }
286
287 constexpr ARCCORE_HOST_DEVICE std::array<Int32, 3> asStdArray() const
288 {
289 return { m_extent0.v, m_extent1.v, m_extent2.v };
290 }
291
292 constexpr ARCCORE_HOST_DEVICE Int64 totalNbElement() const
293 {
294 return m_extent0.size() * m_extent1.size() * m_extent2.size();
295 }
296
297 constexpr ARCCORE_HOST_DEVICE MDIndexType getIndices(Int32 i) const
298 {
299 Int32 i2 = impl::fastmod(i, m_extent2.v);
300 Int32 fac = m_extent2.v;
301 Int32 i1 = impl::fastmod(i / fac, m_extent1.v);
302 fac *= m_extent1.v;
303 Int32 i0 = i / fac;
304 return { i0, i1, i2 };
305 }
306
307 constexpr ARCCORE_HOST_DEVICE Int32 extent0() const { return m_extent0.v; };
308 constexpr ARCCORE_HOST_DEVICE Int32 extent1() const { return m_extent1.v; };
309 constexpr ARCCORE_HOST_DEVICE Int32 extent2() const { return m_extent2.v; };
310
311 //! Liste des dimensions dynamiques
312 constexpr DynamicDimsType dynamicExtents() const
313 {
314 std::array<Int32, ExtentsType::nb_dynamic> x = {};
315 Int32 i = 0;
316 if constexpr (X0 == DynExtent)
317 x[i++] = m_extent0.v;
318 if constexpr (X1 == DynExtent)
319 x[i++] = m_extent1.v;
320 if constexpr (X2 == DynExtent)
321 x[i++] = m_extent2.v;
322 return DynamicDimsType(x);
323 }
324
325 protected:
326
327 explicit ARCCORE_HOST_DEVICE ArrayExtentsValue(SmallSpan<const Int32> extents)
328 {
329 if constexpr (X0 == DynExtent)
330 m_extent0.v = extents[0];
331 if constexpr (X1 == DynExtent)
332 m_extent1.v = extents[1];
333 if constexpr (X2 == DynExtent)
334 m_extent2.v = extents[2];
335 }
336
337 //! Construit une instance avec les N valeurs dynamiques.
338 constexpr ARCCORE_HOST_DEVICE ArrayExtentsValue(DynamicDimsType dims)
339 {
340 ARCANE_UNUSED(dims);
341 Int32 i = 0;
342 if constexpr (X0 == DynExtent)
343 m_extent0.v = dims[i++];
344 if constexpr (X1 == DynExtent)
345 m_extent1.v = dims[i++];
346 if constexpr (X2 == DynExtent)
347 m_extent2.v = dims[i++];
348 }
349
350 constexpr std::array<Int32, 2> _removeFirstExtent() const
351 {
352 return { m_extent1.v, m_extent2.v };
353 }
354
355 ARCCORE_HOST_DEVICE void _checkIndex(MDIndexType idx) const
356 {
357 ARCANE_UNUSED(idx);
358 ARCCORE_CHECK_AT(idx.id0(), m_extent0.v);
359 ARCCORE_CHECK_AT(idx.id1(), m_extent1.v);
360 ARCCORE_CHECK_AT(idx.id2(), m_extent2.v);
361 }
362
363 protected:
364
365 impl::ExtentValue<X0> m_extent0;
366 impl::ExtentValue<X1> m_extent1;
367 impl::ExtentValue<X2> m_extent2;
368};
369
370/*---------------------------------------------------------------------------*/
371/*---------------------------------------------------------------------------*/
372/*!
373 * \brief Spécialisation pour contenir les dimensions d'un tableau à 4 dimensions.
374 */
375template <typename IndexType_, Int32 X0, Int32 X1, Int32 X2, Int32 X3>
376class ArrayExtentsValue<IndexType_, X0, X1, X2, X3>
377{
378 public:
379
381 using MDIndexType = MDIndex<4>;
382 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
383
384 using IndexType ARCANE_DEPRECATED_REASON("Use 'MDIndexType' instead") = ArrayIndex<4>;
385
386 public:
387
388 ArrayExtentsValue() = default;
389
390 public:
391
392 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int32 constExtent() const
393 {
394 static_assert(I >= 0 && I < 4, "Invalid value for I (0<=I<4)");
395 if (I == 0)
396 return m_extent0.v;
397 if (I == 1)
398 return m_extent1.v;
399 if (I == 2)
400 return m_extent2.v;
401 return m_extent3.v;
402 }
403
404 constexpr ARCCORE_HOST_DEVICE std::array<Int32, 4> asStdArray() const
405 {
406 return { m_extent0.v, m_extent1.v, m_extent2.v, m_extent3.v };
407 }
408
409 constexpr ARCCORE_HOST_DEVICE Int64 totalNbElement() const
410 {
411 return m_extent0.size() * m_extent1.size() * m_extent2.size() * m_extent3.size();
412 }
413
414 constexpr ARCCORE_HOST_DEVICE MDIndexType getIndices(Int32 i) const
415 {
416 // Compute base indices
417 Int32 i3 = impl::fastmod(i, m_extent3.v);
418 Int32 fac = m_extent3.v;
419 Int32 i2 = impl::fastmod(i / fac, m_extent2.v);
420 fac *= m_extent2.v;
421 Int32 i1 = impl::fastmod(i / fac, m_extent1.v);
422 fac *= m_extent1.v;
423 Int32 i0 = i / fac;
424 return { i0, i1, i2, i3 };
425 }
426
427 constexpr ARCCORE_HOST_DEVICE Int32 extent0() const { return m_extent0.v; };
428 constexpr ARCCORE_HOST_DEVICE Int32 extent1() const { return m_extent1.v; };
429 constexpr ARCCORE_HOST_DEVICE Int32 extent2() const { return m_extent2.v; };
430 constexpr ARCCORE_HOST_DEVICE Int32 extent3() const { return m_extent3.v; };
431
432 //! Liste des dimensions dynamiques
433 constexpr DynamicDimsType dynamicExtents() const
434 {
435 std::array<Int32, ExtentsType::nb_dynamic> x = {};
436 Int32 i = 0;
437 if constexpr (X0 == DynExtent)
438 x[i++] = m_extent0.v;
439 if constexpr (X1 == DynExtent)
440 x[i++] = m_extent1.v;
441 if constexpr (X2 == DynExtent)
442 x[i++] = m_extent2.v;
443 if constexpr (X3 == DynExtent)
444 x[i++] = m_extent3.v;
445 return DynamicDimsType(x);
446 }
447
448 protected:
449
450 explicit ARCCORE_HOST_DEVICE ArrayExtentsValue(SmallSpan<const Int32> extents)
451 {
452 if constexpr (X0 == DynExtent)
453 m_extent0.v = extents[0];
454 if constexpr (X1 == DynExtent)
455 m_extent1.v = extents[1];
456 if constexpr (X2 == DynExtent)
457 m_extent2.v = extents[2];
458 if constexpr (X3 == DynExtent)
459 m_extent3.v = extents[3];
460 }
461
462 //! Construit une instance avec les N valeurs dynamiques.
463 ARCCORE_HOST_DEVICE ArrayExtentsValue(DynamicDimsType dims)
464 {
465 ARCANE_UNUSED(dims);
466 Int32 i = 0;
467 if constexpr (X0 == DynExtent)
468 m_extent0.v = dims[i++];
469 if constexpr (X1 == DynExtent)
470 m_extent1.v = dims[i++];
471 if constexpr (X2 == DynExtent)
472 m_extent2.v = dims[i++];
473 if constexpr (X3 == DynExtent)
474 m_extent3.v = dims[i++];
475 }
476
477 constexpr std::array<Int32, 3> _removeFirstExtent() const
478 {
479 return { m_extent1.v, m_extent2.v, m_extent3.v };
480 }
481
482 ARCCORE_HOST_DEVICE void _checkIndex(MDIndexType idx) const
483 {
484 ARCANE_UNUSED(idx);
485 ARCCORE_CHECK_AT(idx.id0(), m_extent0.v);
486 ARCCORE_CHECK_AT(idx.id1(), m_extent1.v);
487 ARCCORE_CHECK_AT(idx.id2(), m_extent2.v);
488 ARCCORE_CHECK_AT(idx.id3(), m_extent3.v);
489 }
490
491 protected:
492
493 impl::ExtentValue<X0> m_extent0;
494 impl::ExtentValue<X1> m_extent1;
495 impl::ExtentValue<X2> m_extent2;
496 impl::ExtentValue<X3> m_extent3;
497};
498
499/*---------------------------------------------------------------------------*/
500/*---------------------------------------------------------------------------*/
501
502} // End namespace Arcane::impl
503
504/*---------------------------------------------------------------------------*/
505/*---------------------------------------------------------------------------*/
506
507#endif
Spécialisation pour les dimensions des tableaux à 4 dimensions.
Definition ExtentsV.h:145
Spécialisation pour les dimensions des tableaux à 3 dimensions.
Definition ExtentsV.h:121
Spécialisation pour les dimensions des tableaux à 2 dimensions.
Definition ExtentsV.h:96
Spécialisation pour les dimensions des tableaux à 1 dimension.
Definition ExtentsV.h:70
constexpr DynamicDimsType dynamicExtents() const
Liste des dimensions dynamiques.
__host__ __device__ ArrayExtentsValue(DynamicDimsType dims)
Construit une instance avec les N valeurs dynamiques.
constexpr DynamicDimsType dynamicExtents() const
Liste des dimensions dynamiques.
constexpr __host__ __device__ ArrayExtentsValue(DynamicDimsType dims)
Construit une instance avec les N valeurs dynamiques.
constexpr DynamicDimsType dynamicExtents() const
Liste des dimensions dynamiques.
constexpr __host__ __device__ ArrayExtentsValue(DynamicDimsType dims)
Construit une instance avec les N valeurs dynamiques.
constexpr __host__ __device__ ArrayExtentsValue(DynamicDimsType dims)
Construit une instance avec les N valeurs dynamiques.
constexpr DynamicDimsType dynamicExtents() const
Liste des dimensions dynamiques.
Informations pour une dimension fixe connue à la compilation.
Vue d'un tableau d'éléments de type T.
Definition Span.h:670
constexpr Int32 DynExtent
Constante pour indiquer que la dimension d'un tableau est dynamique.
Definition UtilsTypes.h:261