Skip to content

Commit 6b2635e

Browse files
authored
[SYCL][CUDA][libclc] Add remaining atomics (#5192)
Adds implementations for atomic operations that do not have direct PTX equivalents. Sub is implemented by using add. Floating point min and max use compare exchange loops. I pushed the tests for this into: intel/llvm-test-suite#534
1 parent f139bfc commit 6b2635e

File tree

5 files changed

+152
-1
lines changed

5 files changed

+152
-1
lines changed

libclc/ptx-nvidiacl/libspirv/SOURCES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ atomic/atomic_dec.cl
9595
atomic/atomic_inc.cl
9696
atomic/atomic_max.cl
9797
atomic/atomic_min.cl
98+
atomic/atomic_sub.cl
9899
atomic/atomic_xchg.cl
99100
atomic/atomic_or.cl
100101
atomic/atomic_xor.cl

libclc/ptx-nvidiacl/libspirv/atomic/atomic_inc_dec_helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
volatile ADDR_SPACE TYPE *pointer, enum Scope scope, \
2424
enum MemorySemanticsMask semantics) { \
2525
return _Z21__spirv_AtomicIAddEXTPU3##ADDR_SPACE_MANGLED##TYPE_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE##TYPE_MANGLED( \
26-
pointer, scope, semantics, 1); \
26+
pointer, scope, semantics, VAL); \
2727
}
2828

2929
#define __CLC_NVVM_ATOMIC_INCDEC(TYPE, TYPE_MANGLED, OP_MANGLED, VAL) \

libclc/ptx-nvidiacl/libspirv/atomic/atomic_max.cl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,60 @@ __CLC_NVVM_ATOMIC(unsigned long, m, unsigned long, ul, max,
2020
#undef __CLC_NVVM_ATOMIC_TYPES
2121
#undef __CLC_NVVM_ATOMIC
2222
#undef __CLC_NVVM_ATOMIC_IMPL
23+
24+
#define __CLC_NVVM_ATOMIC_MAX_IMPL(TYPE, TYPE_MANGLED, TYPE_INT, \
25+
TYPE_INT_MANGLED, OP_MANGLED, ADDR_SPACE, \
26+
ADDR_SPACE_MANGLED) \
27+
TYPE_INT \
28+
_Z18__spirv_AtomicLoadPU3##ADDR_SPACE_MANGLED##K##TYPE_INT_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE( \
29+
volatile ADDR_SPACE const TYPE_INT *, enum Scope, \
30+
enum MemorySemanticsMask); \
31+
TYPE_INT \
32+
_Z29__spirv_AtomicCompareExchange##PU3##ADDR_SPACE_MANGLED##TYPE_INT_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagES5_##TYPE_INT_MANGLED##TYPE_INT_MANGLED( \
33+
volatile ADDR_SPACE TYPE_INT *, enum Scope, enum MemorySemanticsMask, \
34+
enum MemorySemanticsMask, TYPE_INT, TYPE_INT); \
35+
_CLC_DECL TYPE \
36+
_Z21__spirv_Atomic##OP_MANGLED##PU3##ADDR_SPACE_MANGLED##TYPE_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE##TYPE_MANGLED( \
37+
volatile ADDR_SPACE TYPE *pointer, enum Scope scope, \
38+
enum MemorySemanticsMask semantics, TYPE val) { \
39+
enum MemorySemanticsMask load_order; \
40+
switch (semantics) { \
41+
case SequentiallyConsistent: \
42+
load_order = SequentiallyConsistent; \
43+
break; \
44+
case Acquire: \
45+
case AcquireRelease: \
46+
load_order = Acquire; \
47+
break; \
48+
default: \
49+
load_order = None; \
50+
} \
51+
volatile ADDR_SPACE TYPE_INT *pointer_int = \
52+
(volatile ADDR_SPACE TYPE_INT *)pointer; \
53+
TYPE_INT val_int = *(TYPE_INT *)&val; \
54+
TYPE_INT old_int = \
55+
_Z18__spirv_AtomicLoadPU3##ADDR_SPACE_MANGLED##K##TYPE_INT_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE( \
56+
pointer_int, scope, load_order); \
57+
TYPE old = *(TYPE *)&old_int; \
58+
while (val > old) { \
59+
TYPE_INT tmp_int = \
60+
_Z29__spirv_AtomicCompareExchange##PU3##ADDR_SPACE_MANGLED##TYPE_INT_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagES5_##TYPE_INT_MANGLED##TYPE_INT_MANGLED( \
61+
pointer_int, scope, semantics, semantics, val_int, old_int); \
62+
if (old_int == tmp_int) { \
63+
return *(TYPE *)&tmp_int; \
64+
} \
65+
old_int = tmp_int; \
66+
old = *(TYPE *)&old_int; \
67+
} \
68+
return old; \
69+
}
70+
71+
#define __CLC_NVVM_ATOMIC_MAX(TYPE, TYPE_MANGLED, TYPE_INT, TYPE_INT_MANGLED, \
72+
OP_MANGLED) \
73+
__CLC_NVVM_ATOMIC_MAX_IMPL(TYPE, TYPE_MANGLED, TYPE_INT, TYPE_INT_MANGLED, \
74+
OP_MANGLED, __global, AS1) \
75+
__CLC_NVVM_ATOMIC_MAX_IMPL(TYPE, TYPE_MANGLED, TYPE_INT, TYPE_INT_MANGLED, \
76+
OP_MANGLED, __local, AS3)
77+
78+
__CLC_NVVM_ATOMIC_MAX(float, f, int, i, FMaxEXT)
79+
__CLC_NVVM_ATOMIC_MAX(double, d, long, l, FMaxEXT)

libclc/ptx-nvidiacl/libspirv/atomic/atomic_min.cl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,60 @@ __CLC_NVVM_ATOMIC(ulong, m, ulong, ul, min, _Z18__spirv_AtomicUMin)
1818
#undef __CLC_NVVM_ATOMIC_TYPES
1919
#undef __CLC_NVVM_ATOMIC
2020
#undef __CLC_NVVM_ATOMIC_IMPL
21+
22+
#define __CLC_NVVM_ATOMIC_MIN_IMPL(TYPE, TYPE_MANGLED, TYPE_INT, \
23+
TYPE_INT_MANGLED, OP_MANGLED, ADDR_SPACE, \
24+
ADDR_SPACE_MANGLED) \
25+
TYPE_INT \
26+
_Z18__spirv_AtomicLoadPU3##ADDR_SPACE_MANGLED##K##TYPE_INT_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE( \
27+
volatile ADDR_SPACE const TYPE_INT *, enum Scope, \
28+
enum MemorySemanticsMask); \
29+
TYPE_INT \
30+
_Z29__spirv_AtomicCompareExchange##PU3##ADDR_SPACE_MANGLED##TYPE_INT_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagES5_##TYPE_INT_MANGLED##TYPE_INT_MANGLED( \
31+
volatile ADDR_SPACE TYPE_INT *, enum Scope, enum MemorySemanticsMask, \
32+
enum MemorySemanticsMask, TYPE_INT, TYPE_INT); \
33+
_CLC_DECL TYPE \
34+
_Z21__spirv_Atomic##OP_MANGLED##PU3##ADDR_SPACE_MANGLED##TYPE_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE##TYPE_MANGLED( \
35+
volatile ADDR_SPACE TYPE *pointer, enum Scope scope, \
36+
enum MemorySemanticsMask semantics, TYPE val) { \
37+
enum MemorySemanticsMask load_order; \
38+
switch (semantics) { \
39+
case SequentiallyConsistent: \
40+
load_order = SequentiallyConsistent; \
41+
break; \
42+
case Acquire: \
43+
case AcquireRelease: \
44+
load_order = Acquire; \
45+
break; \
46+
default: \
47+
load_order = None; \
48+
} \
49+
volatile ADDR_SPACE TYPE_INT *pointer_int = \
50+
(volatile ADDR_SPACE TYPE_INT *)pointer; \
51+
TYPE_INT val_int = *(TYPE_INT *)&val; \
52+
TYPE_INT old_int = \
53+
_Z18__spirv_AtomicLoadPU3##ADDR_SPACE_MANGLED##K##TYPE_INT_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE( \
54+
pointer_int, scope, load_order); \
55+
TYPE old = *(TYPE *)&old_int; \
56+
while (val < old) { \
57+
TYPE_INT tmp_int = \
58+
_Z29__spirv_AtomicCompareExchange##PU3##ADDR_SPACE_MANGLED##TYPE_INT_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagES5_##TYPE_INT_MANGLED##TYPE_INT_MANGLED( \
59+
pointer_int, scope, semantics, semantics, val_int, old_int); \
60+
if (old_int == tmp_int) { \
61+
return *(TYPE *)&tmp_int; \
62+
} \
63+
old_int = tmp_int; \
64+
old = *(TYPE *)&old_int; \
65+
} \
66+
return old; \
67+
}
68+
69+
#define __CLC_NVVM_ATOMIC_MIN(TYPE, TYPE_MANGLED, TYPE_INT, TYPE_INT_MANGLED, \
70+
OP_MANGLED) \
71+
__CLC_NVVM_ATOMIC_MIN_IMPL(TYPE, TYPE_MANGLED, TYPE_INT, TYPE_INT_MANGLED, \
72+
OP_MANGLED, __global, AS1) \
73+
__CLC_NVVM_ATOMIC_MIN_IMPL(TYPE, TYPE_MANGLED, TYPE_INT, TYPE_INT_MANGLED, \
74+
OP_MANGLED, __local, AS3)
75+
76+
__CLC_NVVM_ATOMIC_MIN(float, f, int, i, FMinEXT)
77+
__CLC_NVVM_ATOMIC_MIN(double, d, long, l, FMinEXT)

0 commit comments

Comments
 (0)