Arcane  v3.14.10.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 // TODO: Rendre obsolète mi-2024
85 using IndexType = ArrayIndex<1>;
86
87 ArrayExtentsValue() = default;
88
89 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int32 constExtent() const
90 {
91 static_assert(I == 0, "Invalid value for i (i==0)");
92 return m_extent0.v;
93 }
94
95 constexpr ARCCORE_HOST_DEVICE std::array<Int32, 1> asStdArray() const
96 {
97 return std::array<Int32, 1>{ m_extent0.v };
98 }
99
100 constexpr ARCCORE_HOST_DEVICE Int64 totalNbElement() const
101 {
102 return m_extent0.v;
103 }
104
105 constexpr ARCCORE_HOST_DEVICE IndexType getIndices(Int32 i) const
106 {
107 return { i };
108 }
109
110 constexpr ARCCORE_HOST_DEVICE Int32 extent0() const { return m_extent0.v; };
111
112 //! Liste des dimensions dynamiques
113 constexpr DynamicDimsType dynamicExtents() const
114 {
115 std::array<Int32, ExtentsType::nb_dynamic> x = {};
116 Int32 i = 0;
117 if constexpr (X0 == DynExtent)
118 x[i++] = m_extent0.v;
119 return DynamicDimsType(x);
120 }
121
122 protected:
123
124 explicit ARCCORE_HOST_DEVICE ArrayExtentsValue(SmallSpan<const Int32> extents)
125 {
126 if constexpr (X0 == DynExtent)
127 m_extent0.v = extents[0];
128 }
129
130 //! Construit une instance avec les N valeurs dynamiques.
131 constexpr ARCCORE_HOST_DEVICE ArrayExtentsValue(DynamicDimsType dims)
132 {
133 ARCANE_UNUSED(dims);
134 Int32 i = 0;
135 if constexpr (X0 == DynExtent)
136 m_extent0.v = dims[i++];
137 }
138
139 constexpr std::array<Int32, 0> _removeFirstExtent() const
140 {
141 return {};
142 }
143
144 ARCCORE_HOST_DEVICE void _checkIndex(IndexType idx) const
145 {
146 ARCANE_UNUSED(idx);
147 ARCCORE_CHECK_AT(idx.id0(), m_extent0.v);
148 }
149
150 protected:
151
152 impl::ExtentValue<X0> m_extent0;
153};
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157/*!
158 * \brief Spécialisation pour contenir les dimensions d'un tableau à 2 dimensions.
159 */
160template <typename IndexType_, Int32 X0, Int32 X1>
161class ArrayExtentsValue<IndexType_, X0, X1>
162{
163 public:
164
166 using MDIndexType = MDIndex<2>;
167 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
168
169 // TODO: Rendre obsolète mi-2024
170 using IndexType = ArrayIndex<2>;
171
172 public:
173
174 ArrayExtentsValue() = default;
175
176 public:
177
178 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int32 constExtent() const
179 {
180 static_assert(I >= 0 && I < 2, "Invalid value for I (0<=I<2)");
181 if (I == 0)
182 return m_extent0.v;
183 return m_extent1.v;
184 }
185
186 constexpr ARCCORE_HOST_DEVICE std::array<Int32, 2> asStdArray() const
187 {
188 return { m_extent0.v, m_extent1.v };
189 }
190
191 constexpr ARCCORE_HOST_DEVICE Int64 totalNbElement() const
192 {
193 return m_extent0.size() * m_extent1.size();
194 }
195
196 constexpr ARCCORE_HOST_DEVICE IndexType getIndices(Int32 i) const
197 {
198 Int32 i1 = impl::fastmod(i, m_extent1.v);
199 Int32 i0 = i / m_extent1.v;
200 return { i0, i1 };
201 }
202
203 constexpr ARCCORE_HOST_DEVICE Int32 extent0() const { return m_extent0.v; };
204 constexpr ARCCORE_HOST_DEVICE Int32 extent1() const { return m_extent1.v; };
205
206 //! Liste des dimensions dynamiques
207 constexpr DynamicDimsType dynamicExtents() const
208 {
209 std::array<Int32, ExtentsType::nb_dynamic> x = {};
210 Int32 i = 0;
211 if constexpr (X0 == DynExtent)
212 x[i++] = m_extent0.v;
213 if constexpr (X1 == DynExtent)
214 x[i++] = m_extent1.v;
215 return DynamicDimsType(x);
216 }
217
218 protected:
219
220 explicit ARCCORE_HOST_DEVICE ArrayExtentsValue(SmallSpan<const Int32> extents)
221 {
222 if constexpr (X0 == DynExtent)
223 m_extent0.v = extents[0];
224 if constexpr (X1 == DynExtent)
225 m_extent1.v = extents[1];
226 }
227
228 //! Construit une instance avec les N valeurs dynamiques.
229 constexpr ARCCORE_HOST_DEVICE ArrayExtentsValue(DynamicDimsType dims)
230 {
231 ARCANE_UNUSED(dims);
232 Int32 i = 0;
233 if constexpr (X0 == DynExtent)
234 m_extent0.v = dims[i++];
235 if constexpr (X1 == DynExtent)
236 m_extent1.v = dims[i++];
237 }
238
239 constexpr std::array<Int32, 1> _removeFirstExtent() const
240 {
241 return std::array<Int32, 1>{ m_extent1.v };
242 }
243
244 ARCCORE_HOST_DEVICE void _checkIndex(IndexType idx) const
245 {
246 ARCANE_UNUSED(idx);
247 ARCCORE_CHECK_AT(idx.id0(), m_extent0.v);
248 ARCCORE_CHECK_AT(idx.id1(), m_extent1.v);
249 }
250
251 protected:
252
253 impl::ExtentValue<X0> m_extent0;
254 impl::ExtentValue<X1> m_extent1;
255};
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259/*!
260 * \brief Spécialisation pour contenir les dimensions d'un tableau à 3 dimensions.
261 */
262template <typename IndexType_, Int32 X0, Int32 X1, Int32 X2>
263class ArrayExtentsValue<IndexType_, X0, X1, X2>
264{
265 public:
266
268 using MDIndexType = MDIndex<3>;
269 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
270
271 // TODO: Rendre obsolète mi-2024
272 using IndexType = ArrayIndex<3>;
273
274 public:
275
276 ArrayExtentsValue() = default;
277
278 public:
279
280 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int32 constExtent() const
281 {
282 static_assert(I >= 0 && I < 3, "Invalid value for I (0<=I<3)");
283 if (I == 0)
284 return m_extent0.v;
285 if (I == 1)
286 return m_extent1.v;
287 return m_extent2.v;
288 }
289
290 constexpr ARCCORE_HOST_DEVICE std::array<Int32, 3> asStdArray() const
291 {
292 return { m_extent0.v, m_extent1.v, m_extent2.v };
293 }
294
295 constexpr ARCCORE_HOST_DEVICE Int64 totalNbElement() const
296 {
297 return m_extent0.size() * m_extent1.size() * m_extent2.size();
298 }
299
300 constexpr ARCCORE_HOST_DEVICE IndexType getIndices(Int32 i) const
301 {
302 Int32 i2 = impl::fastmod(i, m_extent2.v);
303 Int32 fac = m_extent2.v;
304 Int32 i1 = impl::fastmod(i / fac, m_extent1.v);
305 fac *= m_extent1.v;
306 Int32 i0 = i / fac;
307 return { i0, i1, i2 };
308 }
309
310 constexpr ARCCORE_HOST_DEVICE Int32 extent0() const { return m_extent0.v; };
311 constexpr ARCCORE_HOST_DEVICE Int32 extent1() const { return m_extent1.v; };
312 constexpr ARCCORE_HOST_DEVICE Int32 extent2() const { return m_extent2.v; };
313
314 //! Liste des dimensions dynamiques
315 constexpr DynamicDimsType dynamicExtents() const
316 {
317 std::array<Int32, ExtentsType::nb_dynamic> x = {};
318 Int32 i = 0;
319 if constexpr (X0 == DynExtent)
320 x[i++] = m_extent0.v;
321 if constexpr (X1 == DynExtent)
322 x[i++] = m_extent1.v;
323 if constexpr (X2 == DynExtent)
324 x[i++] = m_extent2.v;
325 return DynamicDimsType(x);
326 }
327
328 protected:
329
330 explicit ARCCORE_HOST_DEVICE ArrayExtentsValue(SmallSpan<const Int32> extents)
331 {
332 if constexpr (X0 == DynExtent)
333 m_extent0.v = extents[0];
334 if constexpr (X1 == DynExtent)
335 m_extent1.v = extents[1];
336 if constexpr (X2 == DynExtent)
337 m_extent2.v = extents[2];
338 }
339
340 //! Construit une instance avec les N valeurs dynamiques.
341 constexpr ARCCORE_HOST_DEVICE ArrayExtentsValue(DynamicDimsType dims)
342 {
343 ARCANE_UNUSED(dims);
344 Int32 i = 0;
345 if constexpr (X0 == DynExtent)
346 m_extent0.v = dims[i++];
347 if constexpr (X1 == DynExtent)
348 m_extent1.v = dims[i++];
349 if constexpr (X2 == DynExtent)
350 m_extent2.v = dims[i++];
351 }
352
353 constexpr std::array<Int32, 2> _removeFirstExtent() const
354 {
355 return { m_extent1.v, m_extent2.v };
356 }
357
358 ARCCORE_HOST_DEVICE void _checkIndex(IndexType idx) const
359 {
360 ARCANE_UNUSED(idx);
361 ARCCORE_CHECK_AT(idx.id0(), m_extent0.v);
362 ARCCORE_CHECK_AT(idx.id1(), m_extent1.v);
363 ARCCORE_CHECK_AT(idx.id2(), m_extent2.v);
364 }
365
366 protected:
367
368 impl::ExtentValue<X0> m_extent0;
369 impl::ExtentValue<X1> m_extent1;
370 impl::ExtentValue<X2> m_extent2;
371};
372
373/*---------------------------------------------------------------------------*/
374/*---------------------------------------------------------------------------*/
375/*!
376 * \brief Spécialisation pour contenir les dimensions d'un tableau à 4 dimensions.
377 */
378template <typename IndexType_, Int32 X0, Int32 X1, Int32 X2, Int32 X3>
379class ArrayExtentsValue<IndexType_, X0, X1, X2, X3>
380{
381 public:
382
384 using MDIndexType = MDIndex<4>;
385 using DynamicDimsType = typename ExtentsType::DynamicDimsType;
386
387 // TODO: Rendre obsolète mi-2024
388 using IndexType = ArrayIndex<4>;
389
390 public:
391
392 ArrayExtentsValue() = default;
393
394 public:
395
396 template <Int32 I> constexpr ARCCORE_HOST_DEVICE Int32 constExtent() const
397 {
398 static_assert(I >= 0 && I < 4, "Invalid value for I (0<=I<4)");
399 if (I == 0)
400 return m_extent0.v;
401 if (I == 1)
402 return m_extent1.v;
403 if (I == 2)
404 return m_extent2.v;
405 return m_extent3.v;
406 }
407
408 constexpr ARCCORE_HOST_DEVICE std::array<Int32, 4> asStdArray() const
409 {
410 return { m_extent0.v, m_extent1.v, m_extent2.v, m_extent3.v };
411 }
412
413 constexpr ARCCORE_HOST_DEVICE Int64 totalNbElement() const
414 {
415 return m_extent0.size() * m_extent1.size() * m_extent2.size() * m_extent3.size();
416 }
417
418 constexpr ARCCORE_HOST_DEVICE IndexType getIndices(Int32 i) const
419 {
420 // Compute base indices
421 Int32 i3 = impl::fastmod(i, m_extent3.v);
422 Int32 fac = m_extent3.v;
423 Int32 i2 = impl::fastmod(i / fac, m_extent2.v);
424 fac *= m_extent2.v;
425 Int32 i1 = impl::fastmod(i / fac, m_extent1.v);
426 fac *= m_extent1.v;
427 Int32 i0 = i / fac;
428 return { i0, i1, i2, i3 };
429 }
430
431 constexpr ARCCORE_HOST_DEVICE Int32 extent0() const { return m_extent0.v; };
432 constexpr ARCCORE_HOST_DEVICE Int32 extent1() const { return m_extent1.v; };
433 constexpr ARCCORE_HOST_DEVICE Int32 extent2() const { return m_extent2.v; };
434 constexpr ARCCORE_HOST_DEVICE Int32 extent3() const { return m_extent3.v; };
435
436 //! Liste des dimensions dynamiques
437 constexpr DynamicDimsType dynamicExtents() const
438 {
439 std::array<Int32, ExtentsType::nb_dynamic> x = {};
440 Int32 i = 0;
441 if constexpr (X0 == DynExtent)
442 x[i++] = m_extent0.v;
443 if constexpr (X1 == DynExtent)
444 x[i++] = m_extent1.v;
445 if constexpr (X2 == DynExtent)
446 x[i++] = m_extent2.v;
447 if constexpr (X3 == DynExtent)
448 x[i++] = m_extent3.v;
449 return DynamicDimsType(x);
450 }
451
452 protected:
453
454 explicit ARCCORE_HOST_DEVICE ArrayExtentsValue(SmallSpan<const Int32> extents)
455 {
456 if constexpr (X0 == DynExtent)
457 m_extent0.v = extents[0];
458 if constexpr (X1 == DynExtent)
459 m_extent1.v = extents[1];
460 if constexpr (X2 == DynExtent)
461 m_extent2.v = extents[2];
462 if constexpr (X3 == DynExtent)
463 m_extent3.v = extents[3];
464 }
465
466 //! Construit une instance avec les N valeurs dynamiques.
467 ARCCORE_HOST_DEVICE ArrayExtentsValue(DynamicDimsType dims)
468 {
469 ARCANE_UNUSED(dims);
470 Int32 i = 0;
471 if constexpr (X0 == DynExtent)
472 m_extent0.v = dims[i++];
473 if constexpr (X1 == DynExtent)
474 m_extent1.v = dims[i++];
475 if constexpr (X2 == DynExtent)
476 m_extent2.v = dims[i++];
477 if constexpr (X3 == DynExtent)
478 m_extent3.v = dims[i++];
479 }
480
481 constexpr std::array<Int32, 3> _removeFirstExtent() const
482 {
483 return { m_extent1.v, m_extent2.v, m_extent3.v };
484 }
485
486 ARCCORE_HOST_DEVICE void _checkIndex(IndexType idx) const
487 {
488 ARCANE_UNUSED(idx);
489 ARCCORE_CHECK_AT(idx.id0(), m_extent0.v);
490 ARCCORE_CHECK_AT(idx.id1(), m_extent1.v);
491 ARCCORE_CHECK_AT(idx.id2(), m_extent2.v);
492 ARCCORE_CHECK_AT(idx.id3(), m_extent3.v);
493 }
494
495 protected:
496
497 impl::ExtentValue<X0> m_extent0;
498 impl::ExtentValue<X1> m_extent1;
499 impl::ExtentValue<X2> m_extent2;
500 impl::ExtentValue<X3> m_extent3;
501};
502
503/*---------------------------------------------------------------------------*/
504/*---------------------------------------------------------------------------*/
505
506} // End namespace Arcane::impl
507
508/*---------------------------------------------------------------------------*/
509/*---------------------------------------------------------------------------*/
510
511#endif
Spécialisation pour les dimensions des tableaux à 4 dimensions.
Definition MDDim.h:150
Spécialisation pour les dimensions des tableaux à 3 dimensions.
Definition MDDim.h:126
Spécialisation pour les dimensions des tableaux à 2 dimensions.
Definition MDDim.h:101
Spécialisation pour les dimensions des tableaux à 1 dimension.
Definition MDDim.h:75
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:255