alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
Op.hpp
Go to the documentation of this file.
1/* Copyright 2020 Benjamin Worpitz, Bernhard Manfred Gruber
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
9
10#include <algorithm>
11#include <type_traits>
12
13namespace alpaka
14{
15 //! The addition function object.
16 struct AtomicAdd
17 {
18 //! \return The old value of addr.
20 template<typename T>
21 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
22 {
23 auto const old = *addr;
24 auto& ref = *addr;
25#if BOOST_COMP_GNUC
26# pragma GCC diagnostic push
27# pragma GCC diagnostic ignored "-Wconversion"
28#endif
29 ref += value;
30 return old;
31#if BOOST_COMP_GNUC
32# pragma GCC diagnostic pop
33#endif
34 }
35 };
36
37 //! The subtraction function object.
38 struct AtomicSub
39 {
40 //! \return The old value of addr.
42 template<typename T>
43 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
44 {
45 auto const old = *addr;
46 auto& ref = *addr;
47#if BOOST_COMP_GNUC
48# pragma GCC diagnostic push
49# pragma GCC diagnostic ignored "-Wconversion"
50#endif
51 ref -= value;
52#if BOOST_COMP_GNUC
53# pragma GCC diagnostic pop
54#endif
55 return old;
56 }
57 };
58
59 //! The minimum function object.
60 struct AtomicMin
61 {
62 //! \return The old value of addr.
64 template<typename T>
65 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
66 {
67 auto const old = *addr;
68 auto& ref = *addr;
69 ref = std::min(ref, value);
70 return old;
71 }
72 };
73
74 //! The maximum function object.
75 struct AtomicMax
76 {
77 //! \return The old value of addr.
79 template<typename T>
80 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
81 {
82 auto const old = *addr;
83 auto& ref = *addr;
84 ref = std::max(ref, value);
85 return old;
86 }
87 };
88
89 //! The exchange function object.
91 {
92 //! \return The old value of addr.
94 template<typename T>
95 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
96 {
97 auto const old = *addr;
98 auto& ref = *addr;
99 ref = value;
100 return old;
101 }
102 };
103
104 //! The increment function object.
106 {
107 //! Increments up to value, then reset to 0.
108 //!
109 //! \return The old value of addr.
111 template<typename T>
112 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
113 {
114 auto const old = *addr;
115 auto& ref = *addr;
116 ref = ((old >= value) ? static_cast<T>(0) : static_cast<T>(old + static_cast<T>(1)));
117 return old;
118 }
119 };
120
121 //! The decrement function object.
123 {
124 //! Decrement down to 0, then reset to value.
125 //!
126 //! \return The old value of addr.
128 template<typename T>
129 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
130 {
131 auto const old = *addr;
132 auto& ref = *addr;
133 ref = (((old == static_cast<T>(0)) || (old > value)) ? value : static_cast<T>(old - static_cast<T>(1)));
134 return old;
135 }
136 };
137
138 //! The and function object.
140 {
141 //! \return The old value of addr.
143 template<typename T>
144 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
145 {
146 auto const old = *addr;
147 auto& ref = *addr;
148 ref &= value;
149 return old;
150 }
151 };
152
153 //! The or function object.
154 struct AtomicOr
155 {
156 //! \return The old value of addr.
158 template<typename T>
159 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
160 {
161 auto const old = *addr;
162 auto& ref = *addr;
163 ref |= value;
164 return old;
165 }
166 };
167
168 //! The exclusive or function object.
170 {
171 //! \return The old value of addr.
173 template<typename T>
174 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
175 {
176 auto const old = *addr;
177 auto& ref = *addr;
178 ref ^= value;
179 return old;
180 }
181 };
182
183 //! The compare and swap function object.
185 {
186 //! AtomicCas for non floating point values
187 // \return The old value of addr.
189 template<typename T, std::enable_if_t<!std::is_floating_point_v<T>, bool> = true>
190 ALPAKA_FN_HOST_ACC auto operator()(T* addr, T const& compare, T const& value) const -> T
191 {
192 auto const old = *addr;
193 auto& ref = *addr;
194
195// gcc-7.4.0 assumes for an optimization that a signed overflow does not occur here.
196// That's fine, so ignore that warning.
197#if BOOST_COMP_GNUC && (BOOST_COMP_GNUC == BOOST_VERSION_NUMBER(7, 4, 0))
198# pragma GCC diagnostic push
199# pragma GCC diagnostic ignored "-Wstrict-overflow"
200#endif
201 // check if values are bit-wise equal
202 ref = ((old == compare) ? value : old);
203#if BOOST_COMP_GNUC && (BOOST_COMP_GNUC == BOOST_VERSION_NUMBER(7, 4, 0))
204# pragma GCC diagnostic pop
205#endif
206 return old;
207 }
208
209 //! AtomicCas for floating point values
210 // \return The old value of addr.
212 template<typename T, std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
213 ALPAKA_FN_HOST_ACC auto operator()(T* addr, T const& compare, T const& value) const -> T
214 {
215 static_assert(sizeof(T) == 4u || sizeof(T) == 8u, "AtomicCas is supporting only 32bit and 64bit values!");
216 // Type to reinterpret too to perform the bit comparison
217 using BitType = std::conditional_t<sizeof(T) == 4u, unsigned int, unsigned long long>;
218
219 // type used to have a safe way to reinterprete the data into another type
220 // std::variant can not be used because clang8 has issues to compile std::variant
221 struct BitUnion
222 {
223 union
224 {
225 T value;
226 BitType r;
227 };
228 };
229
230 auto const old = *addr;
231 auto& ref = *addr;
232
233// gcc-7.4.0 assumes for an optimization that a signed overflow does not occur here.
234// That's fine, so ignore that warning.
235#if BOOST_COMP_GNUC && (BOOST_COMP_GNUC == BOOST_VERSION_NUMBER(7, 4, 0))
236# pragma GCC diagnostic push
237# pragma GCC diagnostic ignored "-Wstrict-overflow"
238#endif
239 BitUnion o{old};
240 BitUnion c{compare};
241
242 ref = ((o.r == c.r) ? value : old);
243#if BOOST_COMP_GNUC && (BOOST_COMP_GNUC == BOOST_VERSION_NUMBER(7, 4, 0))
244# pragma GCC diagnostic pop
245#endif
246 return old;
247 }
248 };
249} // namespace alpaka
#define ALPAKA_FN_HOST_ACC
Definition Common.hpp:39
#define ALPAKA_NO_HOST_ACC_WARNING
Disable nvcc warning: 'calling a host function from host device function.' Usage: ALPAKA_NO_HOST_ACC_...
Definition Common.hpp:82
The alpaka accelerator library.
The addition function object.
Definition Op.hpp:17
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition Op.hpp:21
The and function object.
Definition Op.hpp:140
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition Op.hpp:144
The compare and swap function object.
Definition Op.hpp:185
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *addr, T const &compare, T const &value) const -> T
AtomicCas for non floating point values.
Definition Op.hpp:190
The decrement function object.
Definition Op.hpp:123
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Decrement down to 0, then reset to value.
Definition Op.hpp:129
The exchange function object.
Definition Op.hpp:91
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition Op.hpp:95
The increment function object.
Definition Op.hpp:106
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Increments up to value, then reset to 0.
Definition Op.hpp:112
The maximum function object.
Definition Op.hpp:76
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition Op.hpp:80
The minimum function object.
Definition Op.hpp:61
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition Op.hpp:65
The or function object.
Definition Op.hpp:155
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition Op.hpp:159
The subtraction function object.
Definition Op.hpp:39
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition Op.hpp:43
The exclusive or function object.
Definition Op.hpp:170
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition Op.hpp:174