alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
operation.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
13/** Contains functors with operation following the atomic operation semantics.
14 *
15 * @attention The operations itself are not atomic, only the argument interface follows corresponding atomic
16 * operations. The argument updated is always hand in as pointer.
17 *
18 */
20{
21 //! The addition function object.
22 struct Add
23 {
24 //! \return The old value of addr.
25 template<typename T>
26 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
27 {
28 auto const old = *addr;
29 auto& ref = *addr;
30#if ALPAKA_COMP_GNUC
31# pragma GCC diagnostic push
32# pragma GCC diagnostic ignored "-Wconversion"
33#endif
34 ref += value;
35 return old;
36#if ALPAKA_COMP_GNUC
37# pragma GCC diagnostic pop
38#endif
39 }
40 };
41
42 //! The subtraction function object.
43 struct Sub
44 {
45 //! \return The old value of addr.
47 template<typename T>
48 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
49 {
50 auto const old = *addr;
51 auto& ref = *addr;
52#if ALPAKA_COMP_GNUC
53# pragma GCC diagnostic push
54# pragma GCC diagnostic ignored "-Wconversion"
55#endif
56 ref -= value;
57#if ALPAKA_COMP_GNUC
58# pragma GCC diagnostic pop
59#endif
60 return old;
61 }
62 };
63
64 //! The minimum function object.
65 struct Min
66 {
67 //! \return The old value of addr.
69 template<typename T>
70 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
71 {
72 auto const old = *addr;
73 auto& ref = *addr;
74 ref = std::min(ref, value);
75 return old;
76 }
77 };
78
79 //! The maximum function object.
80 struct Max
81 {
82 //! \return The old value of addr.
84 template<typename T>
85 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
86 {
87 auto const old = *addr;
88 auto& ref = *addr;
89 ref = std::max(ref, value);
90 return old;
91 }
92 };
93
94 //! The exchange function object.
95 struct Exch
96 {
97 //! \return The old value of addr.
99 template<typename T>
100 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
101 {
102 auto const old = *addr;
103 auto& ref = *addr;
104 ref = value;
105 return old;
106 }
107 };
108
109 //! The increment function object.
110 struct Inc
111 {
112 //! Increments up to value, then reset to 0.
113 //!
114 //! \return The old value of addr.
116 template<typename T>
117 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
118 {
119 auto const old = *addr;
120 auto& ref = *addr;
121 ref = ((old >= value) ? static_cast<T>(0) : static_cast<T>(old + static_cast<T>(1)));
122 return old;
123 }
124 };
125
126 //! The decrement function object.
127 struct Dec
128 {
129 //! Decrement down to 0, then reset to value.
130 //!
131 //! \return The old value of addr.
133 template<typename T>
134 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
135 {
136 auto const old = *addr;
137 auto& ref = *addr;
138 ref = (((old == static_cast<T>(0)) || (old > value)) ? value : static_cast<T>(old - static_cast<T>(1)));
139 return old;
140 }
141 };
142
143 //! The and function object.
144 struct And
145 {
146 //! \return The old value of addr.
148 template<typename T>
149 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
150 {
151 auto const old = *addr;
152 auto& ref = *addr;
153 ref &= value;
154 return old;
155 }
156 };
157
158 //! The or function object.
159 struct Or
160 {
161 //! \return The old value of addr.
163 template<typename T>
164 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
165 {
166 auto const old = *addr;
167 auto& ref = *addr;
168 ref |= value;
169 return old;
170 }
171 };
172
173 //! The exclusive or function object.
174 struct Xor
175 {
176 //! \return The old value of addr.
178 template<typename T>
179 ALPAKA_FN_HOST_ACC auto operator()(T* const addr, T const& value) const -> T
180 {
181 auto const old = *addr;
182 auto& ref = *addr;
183 ref ^= value;
184 return old;
185 }
186 };
187
188 //! The compare and swap function object.
189 struct Cas
190 {
191 //! Cas for non floating point values
192 // \return The old value of addr.
194 template<typename T, std::enable_if_t<!std::is_floating_point_v<T>, bool> = true>
195 ALPAKA_FN_HOST_ACC auto operator()(T* addr, T const& compare, T const& value) const -> T
196 {
197 auto const old = *addr;
198 auto& ref = *addr;
199
200 // check if values are bit-wise equal
201 ref = ((old == compare) ? value : old);
202 return old;
203 }
204
205 //! Cas for floating point values
206 // \return The old value of addr.
208 template<typename T, std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
209 ALPAKA_FN_HOST_ACC auto operator()(T* addr, T const& compare, T const& value) const -> T
210 {
211 static_assert(sizeof(T) == 4u || sizeof(T) == 8u, "Cas is supporting only 32bit and 64bit values!");
212 // Type to reinterpret too to perform the bit comparison
213 using BitType = std::conditional_t<sizeof(T) == 4u, unsigned int, unsigned long long>;
214
215 // type used to have a safe way to reinterprete the data into another type
216 // std::variant can not be used because clang8 has issues to compile std::variant
217 struct BitUnion
218 {
219 union
220 {
221 T value;
222 BitType r;
223 };
224 };
225
226 auto const old = *addr;
227 auto& ref = *addr;
228
229
230 BitUnion o{old};
231 BitUnion c{compare};
232
233 ref = ((o.r == c.r) ? value : old);
234 return old;
235 }
236 };
237} // namespace alpaka::operation
#define ALPAKA_FN_HOST_ACC
All functions that can be used on an accelerator have to be attributed with ALPAKA_FN_ACC or ALPAKA_F...
Definition common.hpp:31
#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:74
Contains functors with operation following the atomic operation semantics.
Definition operation.hpp:20
The addition function object.
Definition operation.hpp:23
ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition operation.hpp:26
The and function object.
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
The compare and swap function object.
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *addr, T const &compare, T const &value) const -> T
Cas for non floating point values.
The decrement function object.
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.
The exchange function object.
Definition operation.hpp:96
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
The increment function object.
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.
The maximum function object.
Definition operation.hpp:81
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition operation.hpp:85
The minimum function object.
Definition operation.hpp:66
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition operation.hpp:70
The or function object.
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
The subtraction function object.
Definition operation.hpp:44
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T
Definition operation.hpp:48
The exclusive or function object.
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto operator()(T *const addr, T const &value) const -> T