Arcane  v3.14.10.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 void
50 apply(DataType* ptr, DataType value)
51 {
52 std::atomic_ref<DataType> v(*ptr);
53 v.fetch_add(value);
54 }
55};
56
57template <>
59{
60 public:
61
62 template <AcceleratorAtomicConcept DataType> static void
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 }
70};
71
72template <>
74{
75 public:
76
77 template <AcceleratorAtomicConcept DataType> static void
78 apply(DataType* ptr, DataType value)
79 {
80 std::atomic_ref<DataType> v(*ptr);
81 DataType prev_value = v;
82 while (prev_value > value && !v.compare_exchange_weak(prev_value, value)) {
83 }
84 }
85};
86
87/*---------------------------------------------------------------------------*/
88/*---------------------------------------------------------------------------*/
89
90#if defined(ARCANE_COMPILING_SYCL)
91
92template <>
94{
95 public:
96
97 template <AcceleratorAtomicConcept DataType> static void
98 apply(DataType* ptr, DataType value)
99 {
100 sycl::atomic_ref<DataType, sycl::memory_order::relaxed, sycl::memory_scope::device> v(*ptr);
101 v.fetch_add(value);
102 }
103};
104
105template <>
106class SyclAtomic<eAtomicOperation::Max>
107{
108 public:
109
110 template <AcceleratorAtomicConcept DataType> static void
111 apply(DataType* ptr, DataType value)
112 {
113 sycl::atomic_ref<DataType, sycl::memory_order::relaxed, sycl::memory_scope::device> v(*ptr);
114 v.fetch_max(value);
115 }
116};
117
118template <>
119class SyclAtomic<eAtomicOperation::Min>
120{
121 public:
122
123 template <AcceleratorAtomicConcept DataType> static void
124 apply(DataType* ptr, DataType value)
125 {
126 sycl::atomic_ref<DataType, sycl::memory_order::relaxed, sycl::memory_scope::device> v(*ptr);
127 v.fetch_min(value);
128 }
129};
130
131#endif
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135
137{
138 public:
139
140 template <AcceleratorAtomicConcept DataType, enum eAtomicOperation Operation>
141 ARCCORE_HOST_DEVICE static inline void
142 doAtomic(DataType* ptr, DataType value)
143 {
144#if defined(ARCCORE_DEVICE_TARGET_CUDA) || defined(ARCCORE_DEVICE_TARGET_HIP)
146#elif defined(ARCCORE_DEVICE_TARGET_SYCL)
148#else
150#endif
151 }
152
153 template <AcceleratorAtomicConcept DataType, enum eAtomicOperation Operation>
154 ARCCORE_HOST_DEVICE static inline void
155 doAtomic(const DataViewGetterSetter<DataType>& view, DataType value)
156 {
157 doAtomic<DataType, Operation>(view._address(), value);
158 }
159};
160
161/*---------------------------------------------------------------------------*/
162/*---------------------------------------------------------------------------*/
163
164} // namespace Arcane::Accelerator::impl
165
166namespace Arcane::Accelerator
167{
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
172//! Applique l'opération atomique \a Operation à la valeur à l'adresse \a ptr avec la valeur \a value
173template <enum eAtomicOperation Operation, AcceleratorAtomicConcept DataType, typename ValueType>
174ARCCORE_HOST_DEVICE inline void
175doAtomic(DataType* ptr, ValueType value)
176requires(std::convertible_to<ValueType, DataType>)
177{
178 DataType v = value;
179 impl::AtomicImpl::doAtomic<DataType, Operation>(ptr, v);
180}
181
182//! Applique l'opération atomique \a Operation à la vue \a view avec la valeur \a value
183template <enum eAtomicOperation Operation, AcceleratorAtomicConcept DataType, typename ValueType>
184ARCCORE_HOST_DEVICE inline void
185doAtomic(const DataViewGetterSetter<DataType>& view, ValueType value)
186requires(std::convertible_to<ValueType, DataType>)
187{
188 DataType v = value;
189 impl::AtomicImpl::doAtomic<DataType, Operation>(view, v);
190}
191
192/*---------------------------------------------------------------------------*/
193/*---------------------------------------------------------------------------*/
194
195} // namespace Arcane::Accelerator
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
200#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__ void 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.