Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
CommonUtils.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/* CommonUtils.h (C) 2000-2024 */
9/* */
10/* Fonctions/Classes utilitaires communes à tout les runtimes. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_ACCELERATOR_COMMONUTILS_H
13#define ARCANE_ACCELERATOR_COMMONUTILS_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/Array.h"
18
19#include "arcane/accelerator/AcceleratorGlobal.h"
20#include "arcane/accelerator/core/RunQueue.h"
21#include "arcane/accelerator/AcceleratorUtils.h"
22
23#if defined(ARCANE_COMPILING_HIP)
24#include "arcane/accelerator/hip/HipAccelerator.h"
25#include <hip/hip_runtime.h>
26#include <rocprim/rocprim.hpp>
27#endif
28#if defined(ARCANE_COMPILING_CUDA)
29#include "arcane/accelerator/cuda/CudaAccelerator.h"
30#include <cub/cub.cuh>
31#endif
32#if defined(ARCANE_COMPILING_SYCL) && defined(__INTEL_LLVM_COMPILER)
33#include <oneapi/dpl/execution>
34#include <oneapi/dpl/algorithm>
35#endif
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane::Accelerator::impl
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45/*!
46 * \internal
47 * \brief Gère l'allocation interne sur le device.
48 */
49class ARCANE_ACCELERATOR_EXPORT GenericDeviceStorage
50{
51 public:
52
55 {
56 deallocate();
57 }
58
59 public:
60
61 void* address() { return m_storage.data(); }
62 size_t size() const { return m_storage.largeSize(); }
63 void* allocate(size_t new_size)
64 {
65 m_storage.resize(new_size);
66 return m_storage.data();
67 }
68
69 void deallocate()
70 {
71 m_storage.clear();
72 }
73
74 Span<const std::byte> bytes() const
75 {
76 return m_storage.span();
77 }
78
79 private:
80
81 UniqueArray<std::byte> m_storage;
82};
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86/*!
87 * \internal
88 * \brief Gère l'allocation interne sur le device.
89 */
90class ARCANE_ACCELERATOR_EXPORT DeviceStorageBase
91{
92 protected:
93
94 GenericDeviceStorage m_storage;
95
96 protected:
97
98 //! Copie l'instance dans \a dest_ptr
99 void _copyToAsync(Span<std::byte> destination, Span<const std::byte> source, const RunQueue& queue);
100};
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104/*!
105 * \internal
106 * \brief Gère l'allocation interne sur le device pour un type donné.
107 */
108template <typename DataType, Int32 N = 1>
110: public DeviceStorageBase
111{
112 public:
113
114 DataType* address() { return reinterpret_cast<DataType*>(m_storage.address()); }
115 size_t size() const { return m_storage.size(); }
116 DataType* allocate()
117 {
118 m_storage.allocate(sizeof(DataType) * N);
119 return address();
120 }
121 void deallocate() { m_storage.deallocate(); }
122
123 //! Copie l'instance dans \a dest_ptr
124 void copyToAsync(SmallSpan<DataType> dest_ptr, const RunQueue& queue)
125 {
126 _copyToAsync(asWritableBytes(dest_ptr), m_storage.bytes(), queue);
127 }
128};
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132/*!
133 * \brief Itérateur sur un index.
134 *
135 * Permet d'itérer entre deux entiers.
136 */
138{
139 public:
140
141 using value_type = Int32;
142 using iterator_category = std::random_access_iterator_tag;
143 using reference = value_type&;
144 using difference_type = ptrdiff_t;
145 using pointer = void;
146
147 using ThatClass = IndexIterator;
148
149 public:
150
151 IndexIterator() = default;
152 ARCCORE_HOST_DEVICE explicit IndexIterator(Int32 v)
153 : m_value(v)
154 {}
155
156 public:
157
158 ARCCORE_HOST_DEVICE IndexIterator& operator++()
159 {
160 ++m_value;
161 return (*this);
162 }
163 ARCCORE_HOST_DEVICE IndexIterator operator+(Int32 x) const
164 {
165 return IndexIterator(m_value + x);
166 }
167 ARCCORE_HOST_DEVICE friend ThatClass operator+(Int32 x, const ThatClass& iter)
168 {
169 return ThatClass(iter.m_value + x);
170 }
171 ARCCORE_HOST_DEVICE IndexIterator operator-(Int32 x) const
172 {
173 return IndexIterator(m_value - x);
174 }
175 ARCCORE_HOST_DEVICE Int32 operator-(const ThatClass& x) const
176 {
177 return m_value - x.m_value;
178 }
179 ARCCORE_HOST_DEVICE Int32 operator*() const { return m_value; }
180 ARCCORE_HOST_DEVICE Int32 operator[](Int32 x) const { return m_value + x; }
181 ARCCORE_HOST_DEVICE friend bool operator==(const ThatClass& a, const ThatClass& b)
182 {
183 return a.m_value == b.m_value;
184 }
185 ARCCORE_HOST_DEVICE friend bool operator<(const ThatClass& iter1, const ThatClass& iter2)
186 {
187 return iter1.m_value < iter2.m_value;
188 }
189
190 private:
191
192 Int32 m_value = 0;
193};
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
198//! Opérateur de Scan/Reduce pour les sommes
199template <typename DataType>
201{
202 public:
203
204 constexpr ARCCORE_HOST_DEVICE DataType operator()(const DataType& a, const DataType& b) const
205 {
206 return a + b;
207 }
208 static DataType defaultValue() { return {}; }
209#if defined(ARCANE_COMPILING_SYCL)
210 static sycl::plus<DataType> syclFunctor() { return {}; }
211#endif
212};
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217//! Opérateur de Scan/Reduce pour le minimum
218template <typename DataType>
220{
221 public:
222
223 constexpr ARCCORE_HOST_DEVICE DataType operator()(const DataType& a, const DataType& b) const
224 {
225 return (a < b) ? a : b;
226 }
227 static DataType defaultValue() { return std::numeric_limits<DataType>::max(); }
228#if defined(ARCANE_COMPILING_SYCL)
229 static sycl::minimum<DataType> syclFunctor() { return {}; }
230#endif
231};
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
236//! Opérateur de Scan/Reduce pour le maximum
237template <typename DataType>
239{
240 public:
241
242 constexpr ARCCORE_HOST_DEVICE DataType operator()(const DataType& a, const DataType& b) const
243 {
244 return (a < b) ? b : a;
245 }
246 static DataType defaultValue() { return std::numeric_limits<DataType>::lowest(); }
247#if defined(ARCANE_COMPILING_SYCL)
248 static sycl::maximum<DataType> syclFunctor() { return {}; }
249#endif
250};
251
252/*---------------------------------------------------------------------------*/
253/*---------------------------------------------------------------------------*/
254/*!
255 * \brief Itérateur sur une lambda pour récupérer une valeur via un index.
256 */
257template <typename DataType, typename GetterLambda>
259{
260 public:
261
262 using value_type = DataType;
263 using iterator_category = std::random_access_iterator_tag;
264 using reference = DataType&;
265 using difference_type = ptrdiff_t;
266 using pointer = void;
268
269 public:
270
271 ARCCORE_HOST_DEVICE GetterLambdaIterator(const GetterLambda& s)
272 : m_lambda(s)
273 {}
274 ARCCORE_HOST_DEVICE explicit GetterLambdaIterator(const GetterLambda& s, Int32 v)
275 : m_index(v)
276 , m_lambda(s)
277 {}
278
279 public:
280
281 ARCCORE_HOST_DEVICE ThatClass& operator++()
282 {
283 ++m_index;
284 return (*this);
285 }
286 ARCCORE_HOST_DEVICE ThatClass& operator+=(Int32 x)
287 {
288 m_index += x;
289 return (*this);
290 }
291 ARCCORE_HOST_DEVICE friend ThatClass operator+(const ThatClass& iter, Int32 x)
292 {
293 return ThatClass(iter.m_lambda, iter.m_index + x);
294 }
295 ARCCORE_HOST_DEVICE friend ThatClass operator+(Int32 x, const ThatClass& iter)
296 {
297 return ThatClass(iter.m_lambda, iter.m_index + x);
298 }
299 ARCCORE_HOST_DEVICE friend bool operator<(const ThatClass& iter1, const ThatClass& iter2)
300 {
301 return iter1.m_index < iter2.m_index;
302 }
303
304 ARCCORE_HOST_DEVICE ThatClass operator-(Int32 x) const
305 {
306 return ThatClass(m_lambda, m_index - x);
307 }
308 ARCCORE_HOST_DEVICE Int32 operator-(const ThatClass& x) const
309 {
310 return m_index - x.m_index;
311 }
312 ARCCORE_HOST_DEVICE value_type operator*() const
313 {
314 return m_lambda(m_index);
315 }
316 ARCCORE_HOST_DEVICE value_type operator[](Int32 x) const { return m_lambda(m_index + x); }
317 ARCCORE_HOST_DEVICE friend bool operator!=(const ThatClass& a, const ThatClass& b)
318 {
319 return a.m_index != b.m_index;
320 }
321 ARCCORE_HOST_DEVICE friend bool operator==(const ThatClass& a, const ThatClass& b)
322 {
323 return a.m_index == b.m_index;
324 }
325
326 private:
327
328 Int32 m_index = 0;
329 GetterLambda m_lambda;
330};
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334/*!
335 * \brief Itérateur sur une lambda pour positionner une valeur via un index.
336 *
337 * Le positionnement se fait via Setter::operator=().
338 */
339template <typename SetterLambda>
341{
342 public:
343
344 //! Permet de positionner un élément de l'itérateur de sortie
345 class Setter
346 {
347 public:
348
349 ARCCORE_HOST_DEVICE explicit Setter(const SetterLambda& s, Int32 output_index)
350 : m_output_index(output_index)
351 , m_lambda(s)
352 {}
353 ARCCORE_HOST_DEVICE void operator=(Int32 input_index)
354 {
355 m_lambda(input_index, m_output_index);
356 }
357 Int32 m_output_index = 0;
358 SetterLambda m_lambda;
359 };
360
361 using value_type = Int32;
362 using iterator_category = std::random_access_iterator_tag;
363 using reference = Setter;
364 using difference_type = ptrdiff_t;
365 using pointer = void;
366
367 using ThatClass = SetterLambdaIterator<SetterLambda>;
368
369 public:
370
371 ARCCORE_HOST_DEVICE SetterLambdaIterator(const SetterLambda& s)
372 : m_lambda(s)
373 {}
374 ARCCORE_HOST_DEVICE explicit SetterLambdaIterator(const SetterLambda& s, Int32 v)
375 : m_index(v)
376 , m_lambda(s)
377 {}
378
379 public:
380
381 ARCCORE_HOST_DEVICE SetterLambdaIterator<SetterLambda>& operator++()
382 {
383 ++m_index;
384 return (*this);
385 }
386 ARCCORE_HOST_DEVICE SetterLambdaIterator<SetterLambda>& operator--()
387 {
388 --m_index;
389 return (*this);
390 }
391 ARCCORE_HOST_DEVICE reference operator*() const
392 {
393 return Setter(m_lambda, m_index);
394 }
395 ARCCORE_HOST_DEVICE reference operator[](Int32 x) const { return Setter(m_lambda, m_index + x); }
396 ARCCORE_HOST_DEVICE friend ThatClass operator+(Int32 x, const ThatClass& iter)
397 {
398 return ThatClass(iter.m_lambda, iter.m_index + x);
399 }
400 ARCCORE_HOST_DEVICE friend ThatClass operator+(const ThatClass& iter, Int32 x)
401 {
402 return ThatClass(iter.m_lambda, iter.m_index + x);
403 }
404 ARCCORE_HOST_DEVICE Int32 operator-(const ThatClass& x) const
405 {
406 return m_index - x.m_index;
407 }
408 ARCCORE_HOST_DEVICE friend bool operator<(const ThatClass& iter1, const ThatClass& iter2)
409 {
410 return iter1.m_index < iter2.m_index;
411 }
412
413 private:
414
415 Int32 m_index = 0;
416 SetterLambda m_lambda;
417};
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
421
422} // namespace Arcane::Accelerator::impl
423
424/*---------------------------------------------------------------------------*/
425/*---------------------------------------------------------------------------*/
426
427namespace Arcane::Accelerator
428{
429
430/*---------------------------------------------------------------------------*/
431/*---------------------------------------------------------------------------*/
432
433template <typename DataType> using ScannerSumOperator = impl::SumOperator<DataType>;
434template <typename DataType> using ScannerMaxOperator = impl::MaxOperator<DataType>;
435template <typename DataType> using ScannerMinOperator = impl::MinOperator<DataType>;
436
437/*---------------------------------------------------------------------------*/
438/*---------------------------------------------------------------------------*/
439
440} // namespace Arcane::Accelerator
441
442/*---------------------------------------------------------------------------*/
443/*---------------------------------------------------------------------------*/
444
445#endif
446
447/*---------------------------------------------------------------------------*/
448/*---------------------------------------------------------------------------*/
File d'exécution pour un accélérateur.
void _copyToAsync(Span< std::byte > destination, Span< const std::byte > source, const RunQueue &queue)
Copie l'instance dans dest_ptr.
void copyToAsync(SmallSpan< DataType > dest_ptr, const RunQueue &queue)
Copie l'instance dans dest_ptr.
Itérateur sur une lambda pour récupérer une valeur via un index.
Opérateur de Scan/Reduce pour le maximum.
Opérateur de Scan/Reduce pour le minimum.
Permet de positionner un élément de l'itérateur de sortie.
Itérateur sur une lambda pour positionner une valeur via un index.
Opérateur de Scan/Reduce pour les sommes.
Vue d'un tableau d'éléments de type T.
Definition Span.h:670
Vue d'un tableau d'éléments de type T.
Definition Span.h:510
Vecteur 1D de données avec sémantique par valeur (style STL).
Espace de nom pour l'utilisation des accélérateurs.
detail::SpanTypeFromSize< std::byte, SizeType >::SpanType asWritableBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets modifiables.
Definition Span.h:916
std::int32_t Int32
Type entier signé sur 32 bits.