Skip to content

Commit 7e62861

Browse files
author
Diptorup Deb
authored
Merge pull request #1023 from IntelPython/fix/rambo-dpnp-impl
Fixes stride calculation when unboxing a dpnp ndarray
2 parents 094f852 + 43920fb commit 7e62861

File tree

5 files changed

+130
-35
lines changed

5 files changed

+130
-35
lines changed

numba_dpex/core/runtime/_dpexrt_python.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ static int DPEXRT_sycl_usm_ndarray_from_python(PyObject *obj,
731731
arystruct_t *arystruct)
732732
{
733733
struct PyUSMArrayObject *arrayobj = NULL;
734-
int i = 0, ndim = 0, exp = 0;
734+
int i = 0, j = 0, k = 0, ndim = 0, exp = 0;
735735
npy_intp *shape = NULL, *strides = NULL;
736736
npy_intp *p = NULL, nitems;
737737
void *data = NULL;
@@ -812,10 +812,12 @@ static int DPEXRT_sycl_usm_ndarray_from_python(PyObject *obj,
812812
}
813813
}
814814
else {
815-
for (i = 1; i < ndim; ++i, ++p) {
816-
*p = shape[i] << exp;
815+
for (i = ndim * 2 - 1; i >= ndim; --i, ++p) {
816+
*p = 1;
817+
for (j = i, k = ndim - 1; j > ndim; --j, --k)
818+
*p *= shape[k];
819+
*p <<= exp;
817820
}
818-
*p = 1;
819821
}
820822

821823
return 0;
@@ -859,13 +861,21 @@ static PyObject *box_from_arystruct_parent(arystruct_t *arystruct,
859861
struct PyUSMArrayObject *arrayobj = NULL;
860862
npy_intp itemsize = 0;
861863

862-
DPEXRT_DEBUG(drt_debug_print("DPEXRT-DEBUG: In try_to_return_parent.\n"));
864+
DPEXRT_DEBUG(
865+
drt_debug_print("DPEXRT-DEBUG: In box_from_arystruct_parent.\n"));
863866

864-
if (!(arrayobj = PyUSMNdArray_ARRAYOBJ(arystruct->parent)))
867+
if (!(arrayobj = PyUSMNdArray_ARRAYOBJ(arystruct->parent))) {
868+
DPEXRT_DEBUG(
869+
drt_debug_print("DPEXRT-DEBUG: Arrayobj cannot be boxed from "
870+
"parent as parent pointer is NULL.\n"));
865871
return NULL;
872+
}
866873

867-
if ((void *)UsmNDArray_GetData(arrayobj) != arystruct->data)
874+
if ((void *)UsmNDArray_GetData(arrayobj) != arystruct->data) {
875+
DPEXRT_DEBUG(drt_debug_print("DPEXRT-DEBUG: Arrayobj cannot be boxed "
876+
"from parent as data pointer is NULL.\n"));
868877
return NULL;
878+
}
869879

870880
if (UsmNDArray_GetNDim(arrayobj) != ndim)
871881
return NULL;
@@ -985,6 +995,10 @@ DPEXRT_sycl_usm_ndarray_to_python_acqref(arystruct_t *arystruct,
985995
// return back to Python memory that was allocated inside Numba and let
986996
// Python manage the lifetime of the memory.
987997
if (arystruct->meminfo) {
998+
DPEXRT_DEBUG(
999+
drt_debug_print("DPEXRT-DEBUG: Set the base of the boxed array "
1000+
"from arystruct's meminfo pointer at %s, line %d\n",
1001+
__FILE__, __LINE__));
9881002
// wrap into MemInfoObject
9891003
if (!(miobj = PyObject_New(MemInfoObject, &MemInfoType))) {
9901004
PyErr_Format(PyExc_ValueError,

numba_dpex/tests/core/types/DpctlSyclQueue/test_box_unbox.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"""
88

99
import dpctl
10-
import pytest
1110

1211
from numba_dpex import dpjit
1312

numba_dpex/tests/core/types/DpnpNdArray/test_boxing.py

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# SPDX-FileCopyrightText: 2020 - 2023 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
"""
6+
Tests for boxing for dpnp.ndarray
7+
"""
8+
9+
import dpnp
10+
11+
from numba_dpex import dpjit
12+
13+
14+
def test_boxing_unboxing():
15+
"""Tests basic boxing and unboxing of a dpnp.ndarray object.
16+
17+
Checks if we can pass in and return a dpctl.ndarray object to and
18+
from a dpjit decorated function.
19+
"""
20+
21+
@dpjit
22+
def func(a):
23+
return a
24+
25+
a = dpnp.empty(10)
26+
try:
27+
b = func(a)
28+
except:
29+
assert False, "Failure during unbox/box of dpnp.ndarray"
30+
31+
assert a.shape == b.shape
32+
assert a.device == b.device
33+
assert a.strides == b.strides
34+
assert a.dtype == b.dtype
35+
36+
37+
def test_stride_calc_at_unboxing():
38+
"""Tests if strides were correctly computed during unboxing."""
39+
40+
def _tester(a):
41+
return a.strides
42+
43+
b = dpnp.empty((4, 16, 4))
44+
strides = dpjit(_tester)(b)
45+
46+
# Numba computes strides as bytes
47+
assert list(strides) == [512, 32, 8]
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# SPDX-FileCopyrightText: 2020 - 2023 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
"""
6+
Tests for boxing for dpnp.ndarray
7+
"""
8+
9+
import dpnp
10+
import numpy
11+
12+
from numba_dpex import dpjit
13+
14+
15+
def test_1d_slicing():
16+
"""Tests if dpjit properly computes strides and returns them to Python."""
17+
18+
def _tester(a):
19+
return a[1:5]
20+
21+
a = dpnp.arange(10)
22+
b = dpnp.asnumpy(dpjit(_tester)(a))
23+
24+
na = numpy.arange(10)
25+
nb = _tester(na)
26+
27+
assert (b == nb).all()
28+
29+
30+
def test_1d_slicing2():
31+
"""Tests if dpjit properly computes strides and returns them to Python."""
32+
33+
def _tester(a):
34+
b = a[1:4]
35+
a[6:9] = b
36+
37+
a = dpnp.arange(10)
38+
b = dpnp.asnumpy(dpjit(_tester)(a))
39+
40+
na = numpy.arange(10)
41+
nb = _tester(na)
42+
43+
assert (b == nb).all()
44+
45+
46+
def test_multidim_slicing():
47+
"""Tests if dpjit properly slices strides and returns them to Python."""
48+
49+
def _tester(a, b):
50+
b[:, :, 0] = a
51+
52+
a = dpnp.arange(64, dtype=numpy.int64)
53+
a = a.reshape(4, 16)
54+
b = dpnp.empty((4, 16, 4), dtype=numpy.int64)
55+
dpjit(_tester)(a, b)
56+
57+
na = numpy.arange(64, dtype=numpy.int64)
58+
na = na.reshape(4, 16)
59+
nb = numpy.empty((4, 16, 4), dtype=numpy.int64)
60+
_tester(na, nb)
61+
62+
assert (nb[:, :, 0] == dpnp.asnumpy(b)[:, :, 0]).all()

0 commit comments

Comments
 (0)