Fermat
atomics.h
1 /*
2  * cugar
3  * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the NVIDIA CORPORATION nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #pragma once
29 
30 #include <cugar/basic/types.h>
31 
32 #if defined(__CUDACC__)
33 #include <cuda_runtime.h>
34 #endif
35 
36 #ifndef WIN32
37 #ifdef __INTEL_COMPILER
38 #include <ia32intrin.h> // ia32intrin.h
39 #else
40 //#warning atomics.h BROKEN on GCC!
41 // Intrinsics docs at http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Atomic-Builtins.html
42 #endif
43 #endif
44 
45 namespace cugar {
46 
64 
67 
71 
72 CUGAR_API void host_release_fence();
73 CUGAR_API void host_acquire_fence();
74 
75 CUGAR_API int32 host_atomic_add( int32* value, const int32 op);
76 CUGAR_API uint32 host_atomic_add(uint32* value, const uint32 op);
77 CUGAR_API int64 host_atomic_add( int64* value, const int64 op);
78 CUGAR_API uint64 host_atomic_add(uint64* value, const uint64 op);
79 
80 CUGAR_API int32 host_atomic_sub( int32* value, const int32 op);
81 CUGAR_API uint32 host_atomic_sub(uint32* value, const uint32 op);
82 CUGAR_API int64 host_atomic_sub( int64* value, const int64 op);
83 CUGAR_API uint64 host_atomic_sub(uint64* value, const uint64 op);
84 
85 CUGAR_API uint32 host_atomic_or(uint32* value, const uint32 op);
86 CUGAR_API uint64 host_atomic_or(uint64* value, const uint64 op);
87 
88 CUGAR_API int32 host_atomic_increment(int32* value);
89 CUGAR_API int64 host_atomic_increment(int64* value);
90 
91 CUGAR_API int32 host_atomic_decrement(int32* value);
92 CUGAR_API int64 host_atomic_decrement(int64* value);
93 
94 CUGAR_API float host_atomic_add(float* value, const float op);
95 
96 
99 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
100 float atomic_add(float* value, const float op)
101 {
102 #if defined(CUGAR_DEVICE_COMPILATION)
103  return atomicAdd(value, op);
104 #else
105  return host_atomic_add(value, op);
106 #endif
107 }
108 
111 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
112 int32 atomic_add(int32* value, const int32 op)
113 {
114  #if defined(CUGAR_DEVICE_COMPILATION)
115  return atomicAdd( value, op );
116  #else
117  return host_atomic_add( value, op );
118  #endif
119 }
120 
123 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
124 uint32 atomic_add(uint32* value, const uint32 op)
125 {
126  #if defined(CUGAR_DEVICE_COMPILATION)
127  return atomicAdd( value, op );
128  #else
129  return host_atomic_add( value, op );
130  #endif
131 }
132 
135 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
136 uint64 atomic_add(uint64* value, const uint64 op)
137 {
138  #if defined(CUGAR_DEVICE_COMPILATION)
139  return atomicAdd( (unsigned long long int*)value, (unsigned long long int)op );
140  #else
141  return host_atomic_add( value, op );
142  #endif
143 }
144 
147 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
148 int32 atomic_sub(int32* value, const int32 op)
149 {
150  #if defined(CUGAR_DEVICE_COMPILATION)
151  return atomicSub( value, op );
152  #else
153  return host_atomic_sub( value, op );
154  #endif
155 }
156 
159 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
160 uint32 atomic_sub(uint32* value, const uint32 op)
161 {
162  #if defined(CUGAR_DEVICE_COMPILATION)
163  return atomicSub( value, op );
164  #else
165  return host_atomic_sub( value, op );
166  #endif
167 }
168 
171 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
172 uint32 atomic_or(uint32* value, const uint32 op)
173 {
174  #if defined(CUGAR_DEVICE_COMPILATION)
175  return atomicOr( value, op );
176  #else
177  return host_atomic_or( value, op );
178  #endif
179 }
180 
183 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
184 uint64 atomic_or(uint64* value, const uint64 op)
185 {
186  #if defined(CUGAR_DEVICE_COMPILATION)
187  return atomicOr( (unsigned long long int*)value, (unsigned long long int)op );
188  #else
189  return host_atomic_or( value, op );
190  #endif
191 }
192 
195 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
196 int32 atomic_increment(int32* value)
197 {
198  #if defined(CUGAR_DEVICE_COMPILATION)
199  return atomicAdd( value, int32(1) );
200  #else
201  return host_atomic_increment( value );
202  #endif
203 }
206 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
207 int64 atomic_increment(int64* value)
208 {
209  #if defined(CUGAR_DEVICE_COMPILATION)
210  return (int64)atomicAdd( (unsigned long long int*)value, (unsigned long long int)(1) );
211  #else
212  return host_atomic_increment( value );
213  #endif
214 }
215 
218 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
219 int32 atomic_decrement(int32* value)
220 {
221  #if defined(CUGAR_DEVICE_COMPILATION)
222  return atomicSub( value, int32(1) );
223  #else
224  return host_atomic_decrement( value );
225  #endif
226 }
229 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
230 int64 atomic_decrement(int64* value)
231 {
232  #if defined(CUGAR_DEVICE_COMPILATION)
233  return (int64)atomicAdd( (unsigned long long int*)value, (unsigned long long int)(-1) );
234  #else
235  return host_atomic_decrement( value );
236  #endif
237 }
238 
241 template<typename intT>
242 struct AtomicInt
243 {
245  AtomicInt() : m_value(0) {}
246 
248  AtomicInt(const intT value) : m_value(value) {}
249 
251  intT increment()
252  {
253  return atomic_increment( (intT*)&m_value );
254  }
255 
257  intT decrement()
258  {
259  return atomic_decrement( (intT*)&m_value );
260  }
261 
263  intT operator++(int) { return increment(); }
264 
266  intT operator--(int) { return decrement(); }
267 
269  intT operator++() { return increment()+intT(1); }
270 
272  intT operator--() { return decrement()-intT(1); }
273 
275  intT operator+=(const intT v) { return atomic_add( (intT*)&m_value, v ) + v; }
277  intT operator-=(const intT v) { return atomic_sub( (intT*)&m_value, v ) - v; }
278 
280  bool operator==(const intT value) { return m_value == value; }
281  bool operator!=(const intT value) { return m_value != value; }
282  bool operator>=(const intT value) { return m_value >= value; }
283  bool operator<=(const intT value) { return m_value <= value; }
284  bool operator>(const intT value) { return m_value > value; }
285  bool operator<(const intT value) { return m_value < value; }
286 
287  volatile intT m_value;
288 };
289 
292 
295 
296 } // namespace cugar
bool operator==(const intT value)
compare
Definition: atomics.h:280
intT operator-=(const intT v)
decrement by v
Definition: atomics.h:277
intT operator++()
increment by one
Definition: atomics.h:269
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE int32 atomic_increment(int32 *value)
Definition: atomics.h:196
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float atomic_add(float *value, const float op)
Definition: atomics.h:100
AtomicInt()
constructor
Definition: atomics.h:245
intT increment()
increment by one
Definition: atomics.h:251
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE int32 atomic_sub(int32 *value, const int32 op)
Definition: atomics.h:148
Definition: atomics.h:242
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
intT operator++(int)
increment by one
Definition: atomics.h:263
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 atomic_or(uint32 *value, const uint32 op)
Definition: atomics.h:172
AtomicInt(const intT value)
destructor
Definition: atomics.h:248
intT operator+=(const intT v)
increment by v
Definition: atomics.h:275
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE int32 atomic_decrement(int32 *value)
Definition: atomics.h:219
intT operator--()
decrement by one
Definition: atomics.h:272
intT operator--(int)
decrement by one
Definition: atomics.h:266
intT decrement()
decrement by one
Definition: atomics.h:257