Arcane  v3.15.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
accelerator/Atomic.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/* Atomic.h (C) 2000-2024 */
9/* */
10/* Opérations atomiques. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_ACCELERATOR_ATOMIC_H
13#define ARCANE_ACCELERATOR_ATOMIC_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/ArcaneCxx20.h"
18
19#if defined(ARCCORE_DEVICE_TARGET_CUDA) || defined(ARCCORE_DEVICE_TARGET_HIP)
20#include "arcane/accelerator/CommonCudaHipAtomicImpl.h"
21#endif
22
23#include <atomic>
24#include <concepts>
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane::Accelerator
30{
31//! Liste des types supportant les opérations atomiques.
32template <typename T>
33concept AcceleratorAtomicConcept = std::same_as<T, Real> || std::same_as<T, Int32> || std::same_as<T, Int64>;
34}
35
36namespace Arcane::Accelerator::impl
37{
38
39template <enum eAtomicOperation Operation>
41template <enum eAtomicOperation Operation>
43
44template <>
46{
47 public:
48
49 template <AcceleratorAtomicConcept DataType> static DataType
50 apply(DataType* ptr, DataType value)
51 {
52 std::atomic_ref<DataType> v(*ptr);
53 return v.fetch_add(value);
54 }
55};
56
57template <>
59{
60 public:
61
62 template <AcceleratorAtomicConcept DataType> static DataType
63 apply(DataType* ptr, DataType value)
64 {
65 std::atomic_ref<DataType> v(*ptr);
66 DataType prev_value = v;
67 while (prev_value < value && !v.compare_exchange_weak(prev_value, value)) {
68 }
69 return prev_value;
70 }
71};
72
73template <>
75{
76 public:
77
78 template <AcceleratorAtomicConcept DataType> static DataType
79 apply(DataType* ptr, DataType value)
80 {
81 std::atomic_ref<DataType> v(*ptr);
82 DataType prev_value = v;
83 while (prev_value > value && !v.compare_exchange_weak(prev_value, value)) {
84 }
85 return prev_value;
86 }
87};
88
89/*---------------------------------------------------------------------------*/
90/*---------------------------------------------------------------------------*/
91
92#if defined(ARCANE_COMPILING_SYCL)
93
94template <>
96{
97 public:
98
99 template <AcceleratorAtomicConcept DataType> static DataType
100 apply(DataType* ptr, DataType value)
101 {
102 sycl::atomic_ref<DataType, sycl::memory_order::relaxed, sycl::memory_scope::device> v(*ptr);
103 return v.fetch_add(value);
104 }
105};
106
107template <>
108class SyclAtomic<eAtomicOperation::Max>
109{
110 public:
111
112 template <AcceleratorAtomicConcept DataType> static DataType
113 apply(DataType* ptr, DataType value)
114 {
115 sycl::atomic_ref<DataType, sycl::memory_order::relaxed, sycl::memory_scope::device> v(*ptr);
116 return v.fetch_max(value);
117 }
118};
119
120template <>
121class SyclAtomic<eAtomicOperation::Min>
122{
123 public:
124
125 template <AcceleratorAtomicConcept DataType> static DataType
126 apply(DataType* ptr, DataType value)
127 {
128 sycl::atomic_ref<DataType, sycl::memory_order::relaxed, sycl::memory_scope::device> v(*ptr);
129 return v.fetch_min(value);
130 }
131};
132
133#endif
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
139{
140 public:
141
142 template <AcceleratorAtomicConcept DataType, enum eAtomicOperation Operation>
143 ARCCORE_HOST_DEVICE static inline DataType
144 doAtomic(DataType* ptr, DataType value)
145 {
146#if defined(ARCCORE_DEVICE_TARGET_CUDA) || defined(ARCCORE_DEVICE_TARGET_HIP)
148#elif defined(ARCCORE_DEVICE_TARGET_SYCL)
149 return SyclAtomic<Operation>::apply(ptr, value);
150#else
151 return HostAtomic<Operation>::apply(ptr, value);
152#endif
153 }
154
155 template <AcceleratorAtomicConcept DataType, enum eAtomicOperation Operation>
156 ARCCORE_HOST_DEVICE static inline DataType
157 doAtomic(const DataViewGetterSetter<DataType>& view, DataType value)
158 {
159 return doAtomic<DataType, Operation>(view._address(), value);
160 }
161};
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
165
166} // namespace Arcane::Accelerator::impl
167
168namespace Arcane::Accelerator
169{
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
173/*!
174 * \brief Applique l'opération atomique \a Operation à la valeur à l'adresse \a ptr avec la valeur \a value.
175 *
176 * \retval l'ancienne valeur avant ajout.
177 */
178template <enum eAtomicOperation Operation, AcceleratorAtomicConcept DataType, typename ValueType>
179ARCCORE_HOST_DEVICE inline DataType
180doAtomic(DataType* ptr, ValueType value)
181requires(std::convertible_to<ValueType, DataType>)
182{
183 DataType v = value;
184 return impl::AtomicImpl::doAtomic<DataType, Operation>(ptr, v);
185}
186
187/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189/*!
190 * \brief Applique l'opération atomique \a Operation à la vue \a view avec la valeur \a value.
191 *
192 * \retval l'ancienne valeur avant ajout.
193 */
194template <enum eAtomicOperation Operation, AcceleratorAtomicConcept DataType, typename ValueType>
195ARCCORE_HOST_DEVICE inline DataType
196doAtomic(const DataViewGetterSetter<DataType>& view, ValueType value)
197requires(std::convertible_to<ValueType, DataType>)
198{
199 DataType v = value;
200 return impl::AtomicImpl::doAtomic<DataType, Operation>(view, v);
201}
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
206} // namespace Arcane::Accelerator
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
210
211#endif
Classe pour accéder à un élément d'une vue en lecture/écriture.
Definition DataView.h:245
Liste des types supportant les opérations atomiques.
Espace de nom pour l'utilisation des accélérateurs.
__host__ __device__ DataType doAtomic(DataType *ptr, ValueType value)
Applique l'opération atomique Operation à la valeur à l'adresse ptr avec la valeur value.
eAtomicOperation
Type d'opération atomique supportée.