Skip to content

Commit c22708b

Browse files
committed
Add atomic implementation in OpenCL
1 parent 6d6d0ad commit c22708b

File tree

6 files changed

+159
-1
lines changed

6 files changed

+159
-1
lines changed

conda-recipe/build.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,16 @@ export OpenCL_LIBDIR=${DPCPP_ROOT}/lib
4141
export DPPL_ONEAPI_INTERFACE_LIBDIR=${PREFIX}/lib
4242
export DPPL_ONEAPI_INTERFACE_INCLDIR=${PREFIX}/include
4343

44+
4445
# FIXME: How to pass this using setup.py? This flags is needed when
4546
# dpcpp compiles the generated cpp file.
4647
export CFLAGS="-fPIC -O3 ${CFLAGS}"
4748
export LDFLAGS="-L OpenCL_LIBDIR ${LDFLAGS}"
4849
${PYTHON} setup.py clean --all
4950
${PYTHON} setup.py build
50-
${PYTHON} setup.py install
51+
${PYTHON} setup.py install --old-and-unmanageable
52+
53+
54+
$CC -flto -target spir64-unknown-unknown -c -x cl -emit-llvm -cl-std=CL2.0 -Xclang -finclude-default-header oneapi_wrapper/source/atomics/atomic_ops.cl -o oneapi_wrapper/source/atomics/atomic_ops.bc
55+
llvm-spirv -o dppl/atomic_ops.spir oneapi_wrapper/source/atomics/atomic_ops.bc
56+
cp dppl/atomic_ops.spir ${SP_DIR}/dppl/

conda-recipe/meta.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ requirements:
2424
- python
2525
- make
2626
- numpy >=1.17
27+
- llvm-spirv
2728
run:
2829
- python
2930
- numpy >=1.17

dppl/ocldrv.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@
6363
_logger.addHandler(_ch)
6464

6565

66+
import os
67+
atomic_spirv_path = os.path.join(os.path.dirname(__file__), 'atomic_ops.spir')
68+
69+
def read_atomic_spirv_object():
70+
""" This function returns the spirv module containing Atomic operations
71+
"""
72+
with open(atomic_spirv_path, 'rb') as fin:
73+
spirv = fin.read()
74+
75+
return spirv
76+
77+
6678
##########################################################################
6779
# Exception classes
6880
##########################################################################
5.19 KB
Binary file not shown.
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#ifdef cl_khr_int64_base_atomics
2+
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics: enable
3+
4+
long numba_dppl_atomic_add_i64(volatile __generic long *p, long val, int type) {
5+
long found = *p;
6+
long expected;
7+
do {
8+
expected = found;
9+
if (type == 1) { /* The address qualifier should be __local */
10+
found = atom_cmpxchg((volatile __local ulong *)p, expected, expected + val);
11+
} else {
12+
found = atom_cmpxchg((volatile __global ulong *)p, expected, expected + val);
13+
}
14+
} while (found != expected);
15+
return found;
16+
}
17+
18+
long numba_dppl_atomic_sub_i64(volatile __generic long *p, long val, int type) {
19+
long found = *p;
20+
long expected;
21+
do {
22+
expected = found;
23+
if (type == 1) { /* The address qualifier should be __local */
24+
found = atom_cmpxchg((volatile __local ulong *)p, expected, expected - val);
25+
} else {
26+
found = atom_cmpxchg((volatile __global ulong *)p, expected, expected - val);
27+
}
28+
} while (found != expected);
29+
return found;
30+
}
31+
32+
#ifdef cl_khr_fp64
33+
#pragma OPENCL EXTENSION cl_khr_fp64: enable
34+
35+
double numba_dppl_atomic_cmpxchg_f64(volatile __generic double *p, double cmp, double val, int type) {
36+
union {
37+
ulong u64;
38+
double f64;
39+
} cmp_union, val_union, old_union;
40+
41+
cmp_union.f64 = cmp;
42+
val_union.f64 = val;
43+
if (type == 1) { /* The address qualifier should be __local */
44+
old_union.u64 = atom_cmpxchg((volatile __local ulong *) p, cmp_union.u64, val_union.u64);
45+
} else {
46+
old_union.u64 = atom_cmpxchg((volatile __global ulong *) p, cmp_union.u64, val_union.u64);
47+
}
48+
return old_union.f64;
49+
}
50+
51+
double numba_dppl_atomic_add_f64(volatile __generic double *p, double val, int type) {
52+
double found = *p;
53+
double expected;
54+
do {
55+
expected = found;
56+
found = numba_dppl_atomic_cmpxchg_f64(p, expected, expected + val, type);
57+
} while (found != expected);
58+
return found;
59+
}
60+
61+
double numba_dppl_atomic_sub_f64(volatile __generic double *p, double val, int type) {
62+
double found = *p;
63+
double expected;
64+
do {
65+
expected = found;
66+
found = numba_dppl_atomic_cmpxchg_f64(p, expected, expected - val, type);
67+
} while (found != expected);
68+
return found;
69+
}
70+
#endif
71+
#endif
72+
73+
float numba_dppl_atomic_cmpxchg_f32(volatile __generic float *p, float cmp, float val, int type) {
74+
union {
75+
unsigned int u32;
76+
float f32;
77+
} cmp_union, val_union, old_union;
78+
79+
cmp_union.f32 = cmp;
80+
val_union.f32 = val;
81+
if (type == 1) { /* The address qualifier should be __local */
82+
old_union.u32 = atomic_cmpxchg((volatile __local unsigned int *) p, cmp_union.u32, val_union.u32);
83+
} else {
84+
old_union.u32 = atomic_cmpxchg((volatile __global unsigned int *) p, cmp_union.u32, val_union.u32);
85+
}
86+
return old_union.f32;
87+
}
88+
89+
float numba_dppl_atomic_add_f32(volatile __generic float *p, float val, int type) {
90+
float found = *p;
91+
float expected;
92+
do {
93+
expected = found;
94+
found = numba_dppl_atomic_cmpxchg_f32(p, expected, expected + val, type);
95+
} while (found != expected);
96+
return found;
97+
}
98+
99+
int numba_dppl_atomic_add_i32(volatile __generic int *p, int val, int type) {
100+
int found = *p;
101+
int expected;
102+
do {
103+
expected = found;
104+
if (type == 1) { /* The address qualifier should be __local */
105+
found = atomic_cmpxchg((volatile __local unsigned int *)p, expected, expected + val);
106+
} else {
107+
found = atomic_cmpxchg((volatile __global unsigned int *)p, expected, expected + val);
108+
}
109+
} while (found != expected);
110+
return found;
111+
}
112+
113+
float numba_dppl_atomic_sub_f32(volatile __generic float *p, float val, int type) {
114+
float found = *p;
115+
float expected;
116+
do {
117+
expected = found;
118+
found = numba_dppl_atomic_cmpxchg_f32(p, expected, expected - val, type);
119+
} while (found != expected);
120+
return found;
121+
}
122+
123+
int numba_dppl_atomic_sub_i32(volatile __generic int *p, int val, int type) {
124+
int found = *p;
125+
int expected;
126+
do {
127+
expected = found;
128+
if (type == 1) { /* The address qualifier should be __local */
129+
found = atomic_cmpxchg((volatile __local unsigned int *)p, expected, expected - val);
130+
} else {
131+
found = atomic_cmpxchg((volatile __global unsigned int *)p, expected, expected - val);
132+
}
133+
} while (found != expected);
134+
return found;
135+
}

scripts/build_for_develop.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@ export CFLAGS=-fPIC
4141
python setup.py clean --all
4242
python setup.py build_ext --inplace
4343
python setup.py develop
44+
45+
46+
$CC -flto -target spir64-unknown-unknown -c -x cl -emit-llvm -cl-std=CL2.0 -Xclang -finclude-default-header oneapi_wrapper/source/atomics/atomic_ops.cl -o oneapi_wrapper/source/atomics/atomic_ops.bc
47+
llvm-spirv -o dppl/atomic_ops.spir oneapi_wrapper/source/atomics/atomic_ops.bc

0 commit comments

Comments
 (0)