Skip to content

Commit 4292cec

Browse files
author
Diptorup Deb
committed
Create a new module to store all box/unbox routines.
1 parent f99d3b0 commit 4292cec

File tree

6 files changed

+139
-121
lines changed

6 files changed

+139
-121
lines changed

numba_dpex/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def parse_sem_version(version_string: str) -> Tuple[int, int, int]:
9898

9999
# Re-export types itself
100100
import numba_dpex.core.types as types # noqa E402
101+
from numba_dpex.core import boxing # noqa E402
101102
from numba_dpex.core import config # noqa E402
102103
from numba_dpex.core.kernel_interface import ranges_overloads # noqa E402
103104

numba_dpex/core/boxing/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# SPDX-FileCopyrightText: 2023 - 2024 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
"""Contains the ``box`` and ``unbox`` functions for numba_dpex types that are
6+
passable as arguments to a kernel or dpjit decorated function.
7+
"""
8+
9+
from .ranges import *
10+
from .usm_ndarray import *
File renamed without changes.

numba_dpex/core/boxing/usm_ndarray.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# SPDX-FileCopyrightText: 2023 - 2024 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from contextlib import ExitStack
6+
7+
from numba.core import cgutils, types
8+
from numba.core.datamodel import default_manager
9+
from numba.core.errors import NumbaNotImplementedError
10+
from numba.extending import NativeValue, box, unbox
11+
from numba.np import numpy_support
12+
13+
from numba_dpex.core.exceptions import UnreachableError
14+
from numba_dpex.core.runtime import context as dpexrt
15+
from numba_dpex.core.types import USMNdArray
16+
from numba_dpex.kernel_api import NdRange, Range
17+
18+
19+
@unbox(USMNdArray)
20+
def unbox_dpnp_nd_array(typ, obj, c):
21+
"""Converts a dpctl.tensor.usm_ndarray/dpnp.ndarray object to a Numba-dpex
22+
internal array structure.
23+
24+
Args:
25+
typ : The Numba type of the PyObject
26+
obj : The actual PyObject to be unboxed
27+
c : The unboxing context
28+
29+
Returns: A NativeValue object representing an unboxed
30+
dpctl.tensor.usm_ndarray/dpnp.ndarray
31+
"""
32+
# Reusing the numba.core.base.BaseContext's make_array function to get a
33+
# struct allocated. The same struct is used for numpy.ndarray
34+
# and dpnp.ndarray. It is possible to do so, as the extra information
35+
# specific to dpnp.ndarray such as sycl_queue is inferred statically and
36+
# stored as part of the DpnpNdArray type.
37+
38+
# --------------- Original Numba comment from @ubox(types.Array)
39+
#
40+
# This is necessary because unbox_buffer() does not work on some
41+
# dtypes, e.g. datetime64 and timedelta64.
42+
# TODO check matching dtype.
43+
# currently, mismatching dtype will still work and causes
44+
# potential memory corruption
45+
#
46+
# --------------- End of Numba comment from @ubox(types.Array)
47+
nativearycls = c.context.make_array(typ)
48+
nativeary = nativearycls(c.context, c.builder)
49+
aryptr = nativeary._getpointer()
50+
51+
ptr = c.builder.bitcast(aryptr, c.pyapi.voidptr)
52+
# FIXME : We need to check if Numba_RT as well as DPEX RT are enabled.
53+
if c.context.enable_nrt:
54+
dpexrtCtx = dpexrt.DpexRTContext(c.context)
55+
errcode = dpexrtCtx.arraystruct_from_python(c.pyapi, obj, ptr)
56+
else:
57+
raise UnreachableError
58+
59+
# TODO: here we have minimal typechecking by the itemsize.
60+
# need to do better
61+
try:
62+
expected_itemsize = numpy_support.as_dtype(typ.dtype).itemsize
63+
except NumbaNotImplementedError:
64+
# Don't check types that can't be `as_dtype()`-ed
65+
itemsize_mismatch = cgutils.false_bit
66+
else:
67+
expected_itemsize = nativeary.itemsize.type(expected_itemsize)
68+
itemsize_mismatch = c.builder.icmp_unsigned(
69+
"!=",
70+
nativeary.itemsize,
71+
expected_itemsize,
72+
)
73+
74+
failed = c.builder.or_(
75+
cgutils.is_not_null(c.builder, errcode),
76+
itemsize_mismatch,
77+
)
78+
# Handle error
79+
with c.builder.if_then(failed, likely=False):
80+
c.pyapi.err_set_string(
81+
"PyExc_TypeError",
82+
"can't unbox usm array from PyObject into "
83+
"native value. The object maybe of a "
84+
"different type",
85+
)
86+
return NativeValue(c.builder.load(aryptr), is_error=failed)
87+
88+
89+
@box(USMNdArray)
90+
def box_array(typ, val, c):
91+
"""Boxes a NativeValue representation of USMNdArray/DpnpNdArray type into a
92+
dpctl.tensor.usm_ndarray/dpnp.ndarray PyObject
93+
94+
Args:
95+
typ: The representation of the USMNdArray/DpnpNdArray type.
96+
val: A native representation of a Numba USMNdArray/DpnpNdArray type
97+
object.
98+
c: The boxing context.
99+
100+
Returns: A Pyobject for a dpctl.tensor.usm_ndarray/dpnp.ndarray boxed from
101+
the Numba-dpex native value.
102+
"""
103+
if c.context.enable_nrt:
104+
np_dtype = numpy_support.as_dtype(typ.dtype)
105+
dtypeptr = c.env_manager.read_const(c.env_manager.add_const(np_dtype))
106+
dpexrtCtx = dpexrt.DpexRTContext(c.context)
107+
newary = dpexrtCtx.usm_ndarray_to_python_acqref(
108+
c.pyapi, typ, val, dtypeptr
109+
)
110+
111+
if not newary:
112+
c.pyapi.err_set_string(
113+
"PyExc_TypeError",
114+
"could not box native array into a dpnp.ndarray PyObject.",
115+
)
116+
117+
# Steals NRT ref
118+
# Refer:
119+
# numba.core.base.nrt -> numba.core.runtime.context -> decref
120+
# The `NRT_decref` function is generated directly as LLVM IR inside
121+
# numba.core.runtime.nrtdynmod.py
122+
c.context.nrt.decref(c.builder, typ, val)
123+
124+
return newary
125+
else:
126+
raise UnreachableError

numba_dpex/core/types/dpnp_ndarray_type.py

Lines changed: 1 addition & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,9 @@
33
# SPDX-License-Identifier: Apache-2.0
44

55
import dpnp
6-
from numba.core import cgutils, ir, types
7-
from numba.core.errors import NumbaNotImplementedError
6+
from numba.core import ir, types
87
from numba.core.ir_utils import get_np_ufunc_typ, mk_unique_var
98
from numba.core.pythonapi import NativeValue, PythonAPI, box, unbox
10-
from numba.np import numpy_support
11-
12-
from numba_dpex.core.exceptions import UnreachableError
13-
from numba_dpex.core.runtime import context as dpexrt
149

1510
from .usm_ndarray_type import USMNdArray
1611

@@ -197,117 +192,3 @@ def __allocate__(
197192
out.extend([g_np_assign, attr_assign, typ_var_assign, alloc_assign])
198193

199194
return out
200-
201-
202-
# TODO: move this section to separate file
203-
# --------------- Boxing/Unboxing logic for dpnp.ndarray ----------------------#
204-
205-
206-
@unbox(USMNdArray)
207-
def unbox_dpnp_nd_array(typ, obj, c):
208-
"""Converts a dpctl.tensor.usm_ndarray/dpnp.ndarray object to a Numba-dpex
209-
internal array structure.
210-
211-
Args:
212-
typ : The Numba type of the PyObject
213-
obj : The actual PyObject to be unboxed
214-
c : The unboxing context
215-
216-
Returns: A NativeValue object representing an unboxed
217-
dpctl.tensor.usm_ndarray/dpnp.ndarray
218-
"""
219-
# Reusing the numba.core.base.BaseContext's make_array function to get a
220-
# struct allocated. The same struct is used for numpy.ndarray
221-
# and dpnp.ndarray. It is possible to do so, as the extra information
222-
# specific to dpnp.ndarray such as sycl_queue is inferred statically and
223-
# stored as part of the DpnpNdArray type.
224-
225-
# --------------- Original Numba comment from @ubox(types.Array)
226-
#
227-
# This is necessary because unbox_buffer() does not work on some
228-
# dtypes, e.g. datetime64 and timedelta64.
229-
# TODO check matching dtype.
230-
# currently, mismatching dtype will still work and causes
231-
# potential memory corruption
232-
#
233-
# --------------- End of Numba comment from @ubox(types.Array)
234-
nativearycls = c.context.make_array(typ)
235-
nativeary = nativearycls(c.context, c.builder)
236-
aryptr = nativeary._getpointer()
237-
238-
ptr = c.builder.bitcast(aryptr, c.pyapi.voidptr)
239-
# FIXME : We need to check if Numba_RT as well as DPEX RT are enabled.
240-
if c.context.enable_nrt:
241-
dpexrtCtx = dpexrt.DpexRTContext(c.context)
242-
errcode = dpexrtCtx.arraystruct_from_python(c.pyapi, obj, ptr)
243-
else:
244-
raise UnreachableError
245-
246-
# TODO: here we have minimal typechecking by the itemsize.
247-
# need to do better
248-
try:
249-
expected_itemsize = numpy_support.as_dtype(typ.dtype).itemsize
250-
except NumbaNotImplementedError:
251-
# Don't check types that can't be `as_dtype()`-ed
252-
itemsize_mismatch = cgutils.false_bit
253-
else:
254-
expected_itemsize = nativeary.itemsize.type(expected_itemsize)
255-
itemsize_mismatch = c.builder.icmp_unsigned(
256-
"!=",
257-
nativeary.itemsize,
258-
expected_itemsize,
259-
)
260-
261-
failed = c.builder.or_(
262-
cgutils.is_not_null(c.builder, errcode),
263-
itemsize_mismatch,
264-
)
265-
# Handle error
266-
with c.builder.if_then(failed, likely=False):
267-
c.pyapi.err_set_string(
268-
"PyExc_TypeError",
269-
"can't unbox usm array from PyObject into "
270-
"native value. The object maybe of a "
271-
"different type",
272-
)
273-
return NativeValue(c.builder.load(aryptr), is_error=failed)
274-
275-
276-
@box(USMNdArray)
277-
def box_array(typ, val, c):
278-
"""Boxes a NativeValue representation of USMNdArray/DpnpNdArray type into a
279-
dpctl.tensor.usm_ndarray/dpnp.ndarray PyObject
280-
281-
Args:
282-
typ: The representation of the USMNdArray/DpnpNdArray type.
283-
val: A native representation of a Numba USMNdArray/DpnpNdArray type
284-
object.
285-
c: The boxing context.
286-
287-
Returns: A Pyobject for a dpctl.tensor.usm_ndarray/dpnp.ndarray boxed from
288-
the Numba-dpex native value.
289-
"""
290-
if c.context.enable_nrt:
291-
np_dtype = numpy_support.as_dtype(typ.dtype)
292-
dtypeptr = c.env_manager.read_const(c.env_manager.add_const(np_dtype))
293-
dpexrtCtx = dpexrt.DpexRTContext(c.context)
294-
newary = dpexrtCtx.usm_ndarray_to_python_acqref(
295-
c.pyapi, typ, val, dtypeptr
296-
)
297-
298-
if not newary:
299-
c.pyapi.err_set_string(
300-
"PyExc_TypeError",
301-
"could not box native array into a dpnp.ndarray PyObject.",
302-
)
303-
304-
# Steals NRT ref
305-
# Refer:
306-
# numba.core.base.nrt -> numba.core.runtime.context -> decref
307-
# The `NRT_decref` function is generated directly as LLVM IR inside
308-
# numba.core.runtime.nrtdynmod.py
309-
c.context.nrt.decref(c.builder, typ, val)
310-
311-
return newary
312-
else:
313-
raise UnreachableError

numba_dpex/experimental/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from numba.core.imputils import Registry
1010

1111
# Temporary so that Range and NdRange work in experimental call_kernel
12-
from numba_dpex.core import boxing
12+
from numba_dpex.core.boxing import *
1313

1414
from ._kernel_dpcpp_spirv_overloads import _atomic_ref_overloads
1515
from .decorators import device_func, kernel

0 commit comments

Comments
 (0)