Skip to content

Commit 491adac

Browse files
ZzEeKkAaDiptorup Deb
authored andcommitted
Remove atomics emulation and spirv-tools linking
1 parent a861a50 commit 491adac

File tree

6 files changed

+29
-251
lines changed

6 files changed

+29
-251
lines changed

numba_dpex/config.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ def __getattr__(name):
5353
# Dump offload diagnostics
5454
OFFLOAD_DIAGNOSTICS = _readenv("NUMBA_DPEX_OFFLOAD_DIAGNOSTICS", int, 0)
5555

56-
# Activate Native floating point atomcis support for supported devices.
57-
# Requires llvm-spirv supporting the FP atomics extension
58-
NATIVE_FP_ATOMICS = _readenv("NUMBA_DPEX_ACTIVATE_ATOMICS_FP_NATIVE", int, 0)
5956
# Emit debug info
6057
DEBUG = _readenv("NUMBA_DPEX_DEBUG", int, config.DEBUG)
6158
DEBUGINFO_DEFAULT = _readenv(

numba_dpex/ocl/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
# SPDX-FileCopyrightText: 2020 - 2023 Intel Corporation
22
#
33
# SPDX-License-Identifier: Apache-2.0
4-
5-
from .atomics import atomic_support_present

numba_dpex/ocl/atomics/__init__.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,3 @@
11
# SPDX-FileCopyrightText: 2020 - 2023 Intel Corporation
22
#
33
# SPDX-License-Identifier: Apache-2.0
4-
5-
import os
6-
import os.path
7-
8-
9-
def atomic_support_present():
10-
if os.path.isfile(
11-
os.path.join(os.path.dirname(__file__), "atomic_ops.spir")
12-
):
13-
return True
14-
else:
15-
return False
16-
17-
18-
def get_atomic_spirv_path():
19-
if atomic_support_present():
20-
return os.path.join(os.path.dirname(__file__), "atomic_ops.spir")
21-
else:
22-
return None
23-
24-
25-
def read_atomic_spirv_file():
26-
path = get_atomic_spirv_path()
27-
if path:
28-
with open(path, "rb") as fin:
29-
spirv = fin.read()
30-
return spirv
31-
else:
32-
return None

numba_dpex/ocl/oclimpl.py

Lines changed: 18 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -143,63 +143,6 @@ def sub_group_barrier_impl(context, builder, sig, args):
143143
return _void_value
144144

145145

146-
def insert_and_call_atomic_fn(
147-
context, builder, sig, fn_type, dtype, ptr, val, addrspace
148-
):
149-
ll_p = None
150-
name = ""
151-
if dtype.name == "float32":
152-
ll_val = llvmir.FloatType()
153-
ll_p = ll_val.as_pointer()
154-
if fn_type == "add":
155-
name = "numba_dpex_atomic_add_f32"
156-
elif fn_type == "sub":
157-
name = "numba_dpex_atomic_sub_f32"
158-
else:
159-
raise TypeError("Operation type is not supported %s" % (fn_type))
160-
elif dtype.name == "float64":
161-
if True:
162-
ll_val = llvmir.DoubleType()
163-
ll_p = ll_val.as_pointer()
164-
if fn_type == "add":
165-
name = "numba_dpex_atomic_add_f64"
166-
elif fn_type == "sub":
167-
name = "numba_dpex_atomic_sub_f64"
168-
else:
169-
raise TypeError(
170-
"Operation type is not supported %s" % (fn_type)
171-
)
172-
else:
173-
raise TypeError(
174-
"Atomic operation is not supported for type %s" % (dtype.name)
175-
)
176-
177-
if addrspace == address_space.LOCAL:
178-
name = name + "_local"
179-
else:
180-
name = name + "_global"
181-
182-
assert ll_p is not None
183-
assert name != ""
184-
ll_p.addrspace = address_space.GENERIC
185-
186-
mod = builder.module
187-
if sig.return_type == types.void:
188-
llretty = llvmir.VoidType()
189-
else:
190-
llretty = context.get_value_type(sig.return_type)
191-
192-
llargs = [ll_p, context.get_value_type(sig.args[2])]
193-
fnty = llvmir.FunctionType(llretty, llargs)
194-
195-
fn = cgutils.get_or_insert_function(mod, fnty, name)
196-
fn.calling_convention = kernel_target.CC_SPIR_FUNC
197-
198-
generic_ptr = context.addrspacecast(builder, ptr, address_space.GENERIC)
199-
200-
return builder.call(fn, [generic_ptr, val])
201-
202-
203146
def native_atomic_add(context, builder, sig, args):
204147
aryty, indty, valty = sig.args
205148
ary, inds, val = args
@@ -282,27 +225,29 @@ def native_atomic_add(context, builder, sig, args):
282225
return builder.call(fn, fn_args)
283226

284227

228+
def support_atomic(dtype: types.Type) -> bool:
229+
# This check should be the same as described in sycl documentation:
230+
# https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:atomic-references
231+
# If atomic is not supported, it will be emulated by the sycl compiler.
232+
return (
233+
dtype == types.int32
234+
or dtype == types.uint32
235+
or dtype == types.float32
236+
or dtype == types.int64
237+
or dtype == types.uint64
238+
or dtype == types.float64
239+
)
240+
241+
285242
@lower(stubs.atomic.add, types.Array, types.intp, types.Any)
286243
@lower(stubs.atomic.add, types.Array, types.UniTuple, types.Any)
287244
@lower(stubs.atomic.add, types.Array, types.Tuple, types.Any)
288245
def atomic_add_tuple(context, builder, sig, args):
289-
device_type = dpctl.get_current_queue().sycl_device.device_type
290246
dtype = sig.args[0].dtype
291-
292-
if dtype == types.float32 or dtype == types.float64:
293-
if (
294-
device_type == dpctl.device_type.gpu
295-
and config.NATIVE_FP_ATOMICS == 1
296-
):
297-
return native_atomic_add(context, builder, sig, args)
298-
else:
299-
# Currently, DPCPP only supports native floating point
300-
# atomics for GPUs.
301-
return atomic_add(context, builder, sig, args, "add")
302-
elif dtype == types.int32 or dtype == types.int64:
247+
if support_atomic(dtype):
303248
return native_atomic_add(context, builder, sig, args)
304249
else:
305-
raise TypeError("Atomic operation on unsupported type %s" % dtype)
250+
raise TypeError(f"Atomic operation on unsupported type {dtype}")
306251

307252

308253
def atomic_sub_wrapper(context, builder, sig, args):
@@ -337,81 +282,11 @@ def atomic_sub_wrapper(context, builder, sig, args):
337282
@lower(stubs.atomic.sub, types.Array, types.UniTuple, types.Any)
338283
@lower(stubs.atomic.sub, types.Array, types.Tuple, types.Any)
339284
def atomic_sub_tuple(context, builder, sig, args):
340-
device_type = dpctl.get_current_queue().sycl_device.device_type
341285
dtype = sig.args[0].dtype
342-
343-
if dtype == types.float32 or dtype == types.float64:
344-
if (
345-
device_type == dpctl.device_type.gpu
346-
and config.NATIVE_FP_ATOMICS == 1
347-
):
348-
return atomic_sub_wrapper(context, builder, sig, args)
349-
else:
350-
# Currently, DPCPP only supports native floating point
351-
# atomics for GPUs.
352-
return atomic_add(context, builder, sig, args, "sub")
353-
elif dtype == types.int32 or dtype == types.int64:
286+
if support_atomic(dtype):
354287
return atomic_sub_wrapper(context, builder, sig, args)
355288
else:
356-
raise TypeError("Atomic operation on unsupported type %s" % dtype)
357-
358-
359-
def atomic_add(context, builder, sig, args, name):
360-
from .atomics import atomic_support_present
361-
362-
if atomic_support_present():
363-
context.extra_compile_options[kernel_target.LINK_ATOMIC] = True
364-
aryty, indty, valty = sig.args
365-
ary, inds, val = args
366-
dtype = aryty.dtype
367-
368-
if indty == types.intp:
369-
indices = [inds] # just a single integer
370-
indty = [indty]
371-
else:
372-
indices = cgutils.unpack_tuple(builder, inds, count=len(indty))
373-
indices = [
374-
context.cast(builder, i, t, types.intp)
375-
for t, i in zip(indty, indices)
376-
]
377-
378-
if dtype != valty:
379-
raise TypeError("expecting %s but got %s" % (dtype, valty))
380-
381-
if aryty.ndim != len(indty):
382-
raise TypeError(
383-
"indexing %d-D array with %d-D index" % (aryty.ndim, len(indty))
384-
)
385-
386-
lary = context.make_array(aryty)(context, builder, ary)
387-
ptr = cgutils.get_item_pointer(context, builder, aryty, lary, indices)
388-
389-
if isinstance(aryty, Array) and aryty.addrspace == address_space.LOCAL:
390-
return insert_and_call_atomic_fn(
391-
context,
392-
builder,
393-
sig,
394-
name,
395-
dtype,
396-
ptr,
397-
val,
398-
address_space.LOCAL,
399-
)
400-
else:
401-
return insert_and_call_atomic_fn(
402-
context,
403-
builder,
404-
sig,
405-
name,
406-
dtype,
407-
ptr,
408-
val,
409-
address_space.GLOBAL,
410-
)
411-
else:
412-
raise ImportError(
413-
"Atomic support is not present, can not perform atomic_add"
414-
)
289+
raise TypeError(f"Atomic operation on unsupported type {dtype}")
415290

416291

417292
@lower(stubs.private.array, types.IntegerLiteral, types.Any)

numba_dpex/spirv_generator.py

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"""A wrapper to connect to the SPIR-V binaries (Tools, Translator)."""
66

77
import os
8-
import shutil
98
import tempfile
109
from subprocess import CalledProcessError, check_call
1110

@@ -75,14 +74,6 @@ def generate(self, llvm_spirv_args, ipath, opath):
7574
if config.DEBUG:
7675
llvm_spirv_flags.append("--spirv-debug-info-version=ocl-100")
7776

78-
if not config.NATIVE_FP_ATOMICS:
79-
# Do NOT upgrade version unless you are 100% confident. Not all
80-
# kernel outputs can be converted to higher version of spirv.
81-
# That results in different spirv file versions. As next step
82-
# requires linking of the result file and
83-
# numba_dpex/ocl/atomics/atomic_ops.spir it will raise an error
84-
# that two spirv files have different version and can't be linked
85-
llvm_spirv_args = ["--spirv-max-version", "1.0"] + llvm_spirv_args
8677
llvm_spirv_tool = self._llvm_spirv()
8778

8879
if config.DEBUG:
@@ -102,17 +93,6 @@ def _llvm_spirv():
10293
result = dls.get_llvm_spirv_path()
10394
return result
10495

105-
def link(self, opath, binaries):
106-
"""
107-
Link spirv modules.
108-
109-
Args:
110-
opath: Output file path of the linked final spirv.
111-
binaries: Spirv modules to be linked.
112-
"""
113-
flags = ["--allow-partial-linkage"]
114-
check_call(["spirv-link", *flags, "-o", opath, *binaries])
115-
11696

11797
class Module(object):
11898
def __init__(self, context, llvmir, llvmbc):
@@ -162,15 +142,9 @@ def finalize(self):
162142
# Generate SPIR-V from "friendly" LLVM-based SPIR 2.0
163143
spirv_path = self._track_temp_file("generated-spirv")
164144

165-
binary_paths = [spirv_path]
166-
167145
llvm_spirv_args = []
168146
for key in list(self.context.extra_compile_options.keys()):
169-
if key == LINK_ATOMIC:
170-
from .ocl.atomics import get_atomic_spirv_path
171-
172-
binary_paths.append(get_atomic_spirv_path())
173-
elif key == LLVM_SPIRV_ARGS:
147+
if key == LLVM_SPIRV_ARGS:
174148
llvm_spirv_args = self.context.extra_compile_options[key]
175149
del self.context.extra_compile_options[key]
176150

@@ -194,10 +168,6 @@ def finalize(self):
194168
opath=spirv_path,
195169
)
196170

197-
if len(binary_paths) > 1:
198-
spirv_path = self._track_temp_file("linked-spirv")
199-
self._cmd.link(spirv_path, binary_paths)
200-
201171
if config.SAVE_IR_FILES != 0:
202172
# Dump the llvmir and llvmbc in file
203173
with open("generated_spirv.spir", "wb") as f1:

0 commit comments

Comments
 (0)