diff --git a/README.md b/README.md index 0c753cc37d..e4b0ebf0f1 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ https://intelpython.github.io/dpnp/ ## Dependencies -* numba 0.52.* (IntelPython/numba) +* numba 0.53.* (IntelPython/numba) * dpctl 0.7.* * dpnp 0.6.* (optional) * llvm-spirv (SPIRV generation from LLVM IR) diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 9ac1da1a44..391222ab5f 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -18,13 +18,13 @@ requirements: - python - setuptools - cython - - numba 0.52.* + - numba 0.53* - dpctl 0.7.* - dpnp >=0.6*,<0.7* # [linux] - wheel run: - python - - numba 0.52.* + - numba 0.53* - dpctl 0.7.* - spirv-tools - llvm-spirv diff --git a/numba_dppy/compiler.py b/numba_dppy/compiler.py index 226ca4444c..9e85bd8cc6 100644 --- a/numba_dppy/compiler.py +++ b/numba_dppy/compiler.py @@ -168,7 +168,7 @@ def compile_kernel(sycl_queue, pyfunc, args, access_types, debug=False): def compile_kernel_parfor(sycl_queue, func_ir, args, args_with_addrspaces, debug=False): if DEBUG: print("compile_kernel_parfor", args) - for a in args: + for a in args_with_addrspaces: print(a, type(a)) if isinstance(a, types.npytypes.Array): print("addrspace:", a.addrspace) diff --git a/numba_dppy/dppy_array_type.py b/numba_dppy/dppy_array_type.py new file mode 100644 index 0000000000..62a89aff62 --- /dev/null +++ b/numba_dppy/dppy_array_type.py @@ -0,0 +1,95 @@ +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from numba.core.types.npytypes import Array +from numba.core import types +from numba.core.datamodel.models import StructModel +import numpy as np + + +class DPPYArray(Array): + """ + Type class for DPPY arrays. + """ + + def __init__( + self, + dtype, + ndim, + layout, + py_type=np.ndarray, + readonly=False, + name=None, + aligned=True, + addrspace=None, + ): + self.addrspace = addrspace + super(DPPYArray, self).__init__( + dtype, + ndim, + layout, + py_type=py_type, + readonly=readonly, + name=name, + aligned=aligned, + ) + + def copy(self, dtype=None, ndim=None, layout=None, readonly=None, addrspace=None): + if dtype is None: + dtype = self.dtype + if ndim is None: + ndim = self.ndim + if layout is None: + layout = self.layout + if readonly is None: + readonly = not self.mutable + if addrspace is None: + addrspace = self.addrspace + return DPPYArray( + dtype=dtype, + ndim=ndim, + layout=layout, + readonly=readonly, + aligned=self.aligned, + addrspace=addrspace, + ) + + @property + def key(self): + return ( + self.dtype, + self.ndim, + self.layout, + self.mutable, + self.aligned, + self.addrspace, + ) + + def is_precise(self): + return self.dtype.is_precise() + + +class DPPYArrayModel(StructModel): + def __init__(self, dmm, fe_type): + ndim = fe_type.ndim + members = [ + ("meminfo", types.MemInfoPointer(fe_type.dtype)), + ("parent", types.pyobject), + ("nitems", types.intp), + ("itemsize", types.intp), + ("data", types.CPointer(fe_type.dtype, addrspace=fe_type.addrspace)), + ("shape", types.UniTuple(types.intp, ndim)), + ("strides", types.UniTuple(types.intp, ndim)), + ] + super(DPPYArrayModel, self).__init__(dmm, fe_type, members) diff --git a/numba_dppy/dppy_lowerer.py b/numba_dppy/dppy_lowerer.py index 1544e5a75e..f5e4b4b725 100644 --- a/numba_dppy/dppy_lowerer.py +++ b/numba_dppy/dppy_lowerer.py @@ -25,6 +25,7 @@ import numba from numba.core import compiler, ir, types, sigutils, lowering, funcdesc, config from numba.parfors import parfor +from numba.parfors.parfor_lowering import _lower_parfor_parallel import numba_dppy, numba_dppy as dppy from numba.core.ir_utils import ( add_offset_to_labels, @@ -56,6 +57,7 @@ from . import dppy_host_fn_call_gen as dppy_call_gen import dpctl from numba_dppy.target import DPPYTargetContext +from numba_dppy.dppy_array_type import DPPYArray def _print_block(block): @@ -397,8 +399,16 @@ def addrspace_from(params, def_addr): if addrspaces[i] is not None: # print("before:", id(param_types_addrspaces[i])) assert isinstance(param_types_addrspaces[i], types.npytypes.Array) - param_types_addrspaces[i] = param_types_addrspaces[i].copy( - addrspace=addrspaces[i] + _param = param_types_addrspaces[i] + param_types_addrspaces[i] = DPPYArray( + _param.dtype, + _param.ndim, + _param.layout, + _param.py_type, + not _param.mutable, + _param.name, + _param.aligned, + addrspace=addrspaces[i], ) # print("setting param type", i, param_types[i], id(param_types[i]), # "to addrspace", param_types_addrspaces[i].addrspace) @@ -1243,9 +1253,17 @@ def lower(self): # WARNING: this approach only works in case no device specific modifications were added to # parent function (function with parfor). In case parent function was patched with device specific # different solution should be used. - try: - lowering.lower_extensions[parfor.Parfor].append(lower_parfor_rollback) + context = self.gpu_lower.context + try: + # Only Numba's CPUContext has the `lower_extension` attribute + lower_extension_parfor = context.lower_extensions[parfor.Parfor] + context.lower_extensions[parfor.Parfor] = lower_parfor_rollback + except Exception as e: + if numba_dppy.compiler.DEBUG: + print(e) + pass + self.gpu_lower.lower() # if lower dont crash, and parfor_diagnostics is empty then it is kernel if not self.gpu_lower.metadata["parfor_diagnostics"].extra_info: @@ -1254,7 +1272,13 @@ def lower(self): "kernel" ] = str_name self.base_lower = self.gpu_lower - lowering.lower_extensions[parfor.Parfor].pop() + + try: + context.lower_extensions[parfor.Parfor] = lower_extension_parfor + except Exception as e: + if numba_dppy.compiler.DEBUG: + print(e) + pass except Exception as e: if numba_dppy.compiler.DEBUG: import traceback @@ -1267,11 +1291,11 @@ def lower(self): e, ) print(traceback.format_exc()) - lowering.lower_extensions[parfor.Parfor].pop() - if ( - lowering.lower_extensions[parfor.Parfor][-1] - == numba.parfors.parfor_lowering._lower_parfor_parallel - ) and numba_dppy.config.FALLBACK_ON_CPU == 1: + + if numba_dppy.config.FALLBACK_ON_CPU == 1: + self.cpu_lower.context.lower_extensions[ + parfor.Parfor + ] = _lower_parfor_parallel self.cpu_lower.lower() self.base_lower = self.cpu_lower else: diff --git a/numba_dppy/dppy_passes.py b/numba_dppy/dppy_passes.py index cc30e0dee1..40918b6f9d 100644 --- a/numba_dppy/dppy_passes.py +++ b/numba_dppy/dppy_passes.py @@ -226,6 +226,7 @@ def run_pass(self, state): state.typingctx, state.flags.auto_parallel, state.flags, + state.metadata, state.parfor_diagnostics, ) diff --git a/numba_dppy/numpy_usm_shared.py b/numba_dppy/numpy_usm_shared.py index de12599db1..61166a4128 100644 --- a/numba_dppy/numpy_usm_shared.py +++ b/numba_dppy/numpy_usm_shared.py @@ -47,6 +47,7 @@ import dpctl.dptensor.numpy_usm_shared as nus from dpctl.dptensor.numpy_usm_shared import ndarray, functions_list, class_list from . import target as dppy_target +from numba_dppy.dppy_array_type import DPPYArray, DPPYArrayModel debug = config.DEBUG @@ -73,7 +74,7 @@ def dprint(*args): llb.add_symbol(py_name, c_address) -class UsmSharedArrayType(types.Array): +class UsmSharedArrayType(DPPYArray): """Creates a Numba type for Numpy arrays that are stored in USM shared memory. We inherit from Numba's existing Numpy array type but overload how this type is printed during dumping of typing information and we @@ -141,10 +142,8 @@ def typeof_ta_ndarray(val, c): # This tells Numba to use the default Numpy ndarray data layout for # object of type UsmArray. -register_model(UsmSharedArrayType)(numba.core.datamodel.models.ArrayModel) -dppy_target.spirv_data_model_manager.register( - UsmSharedArrayType, numba.core.datamodel.models.ArrayModel -) +register_model(UsmSharedArrayType)(DPPYArrayModel) +dppy_target.spirv_data_model_manager.register(UsmSharedArrayType, DPPYArrayModel) # This tells Numba how to convert from its native representation # of a UsmArray in a njit function back to a Python UsmArray. diff --git a/numba_dppy/ocl/ocldecl.py b/numba_dppy/ocl/ocldecl.py index dde1605421..4062cdd9c6 100644 --- a/numba_dppy/ocl/ocldecl.py +++ b/numba_dppy/ocl/ocldecl.py @@ -25,6 +25,7 @@ ) import numba_dppy, numba_dppy as dppy from numba_dppy import target +from numba_dppy.dppy_array_type import DPPYArray registry = Registry() intrinsic = registry.register @@ -164,7 +165,7 @@ def typer(shape, dtype): ndim = parse_shape(shape) nb_dtype = parse_dtype(dtype) if nb_dtype is not None and ndim is not None: - return types.Array( + return DPPYArray( dtype=nb_dtype, ndim=ndim, layout="C", diff --git a/numba_dppy/ocl/oclimpl.py b/numba_dppy/ocl/oclimpl.py index 9b6ef35925..8de23306bb 100644 --- a/numba_dppy/ocl/oclimpl.py +++ b/numba_dppy/ocl/oclimpl.py @@ -29,6 +29,7 @@ from numba_dppy import target from . import stubs from numba_dppy.codegen import SPIR_DATA_LAYOUT +from numba_dppy.dppy_array_type import DPPYArray registry = Registry() @@ -292,7 +293,10 @@ def atomic_add_tuple(context, builder, sig, args): lary = context.make_array(aryty)(context, builder, ary) ptr = cgutils.get_item_pointer(context, builder, aryty, lary, indices) - if aryty.addrspace == target.SPIR_LOCAL_ADDRSPACE: + if ( + isinstance(aryty, DPPYArray) + and aryty.addrspace == target.SPIR_LOCAL_ADDRSPACE + ): return insert_and_call_atomic_fn( context, builder, @@ -350,7 +354,10 @@ def atomic_sub_tuple(context, builder, sig, args): lary = context.make_array(aryty)(context, builder, ary) ptr = cgutils.get_item_pointer(context, builder, aryty, lary, indices) - if aryty.addrspace == target.SPIR_LOCAL_ADDRSPACE: + if ( + isinstance(aryty, DPPYArray) + and aryty.addrspace == target.SPIR_LOCAL_ADDRSPACE + ): return insert_and_call_atomic_fn( context, builder, @@ -451,7 +458,7 @@ def _make_array( ): ndim = len(shape) # Create array object - aryty = types.Array(dtype=dtype, ndim=ndim, layout="C", addrspace=addrspace) + aryty = DPPYArray(dtype=dtype, ndim=ndim, layout="C", addrspace=addrspace) ary = context.make_array(aryty)(context, builder) targetdata = _get_target_data(context) diff --git a/numba_dppy/target.py b/numba_dppy/target.py index 6026188919..5ed9d397a3 100644 --- a/numba_dppy/target.py +++ b/numba_dppy/target.py @@ -28,6 +28,7 @@ from numba.core.registry import cpu_target from numba.core.callconv import MinimalCallConv from . import codegen +from numba_dppy.dppy_array_type import DPPYArray, DPPYArrayModel CC_SPIR_KERNEL = "spir_kernel" @@ -85,6 +86,7 @@ def __init__(self, dmm, fe_type): def _init_data_model_manager(): dmm = datamodel.default_manager.copy() dmm.register(types.CPointer, GenericPointerModel) + dmm.register(DPPYArray, DPPYArrayModel) return dmm diff --git a/setup.py b/setup.py index 74ab6dc73a..ddcb2e7683 100644 --- a/setup.py +++ b/setup.py @@ -131,7 +131,7 @@ def spirv_compile(): packages = find_packages(include=["numba_dppy", "numba_dppy.*"]) build_requires = ["cython"] install_requires = [ - "numba", + "numba >={},<{}".format("0.53.1", "0.54"), "dpctl", ]