Skip to content

Commit 81ec5ce

Browse files
chudur-budurDiptorup Deb
authored andcommitted
Refactor all tests for strided dpnp arrays in kernel with different layouts
1 parent 12ebcd3 commit 81ec5ce

File tree

1 file changed

+231
-46
lines changed

1 file changed

+231
-46
lines changed

numba_dpex/tests/experimental/test_strided_dpnp_array_in_kernel.py

Lines changed: 231 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,99 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5+
import math
6+
57
import dpnp
8+
import numpy as np
9+
import pytest
610

711
import numba_dpex
812
import numba_dpex.experimental as exp_dpex
9-
from numba_dpex import NdRange, Range
13+
from numba_dpex import Range
14+
15+
16+
def get_order(a):
17+
"""Get order of an array.
18+
19+
Args:
20+
a (numpy.ndarray, dpnp.ndarray): Input array.
21+
22+
Raises:
23+
Exception: _description_
24+
25+
Returns:
26+
str: 'C' if c-contiguous, 'F' if f-contiguous or 'A' if aligned.
27+
"""
28+
if a.flags.c_contiguous and not a.flags.f_contiguous:
29+
return "C"
30+
elif not a.flags.c_contiguous and a.flags.f_contiguous:
31+
return "F"
32+
elif a.flags.c_contiguous and a.flags.f_contiguous:
33+
return "A"
34+
else:
35+
raise Exception("Unknown order/layout")
1036

1137

1238
@exp_dpex.kernel
1339
def change_values_1d(x, v):
40+
"""Assign values in a 1d dpnp.ndarray
41+
42+
Args:
43+
x (dpnp.ndarray): Input array.
44+
v (int): Value to be assigned.
45+
"""
1446
i = numba_dpex.get_global_id(0)
1547
p = x[i] # getitem
1648
p = v
1749
x[i] = p # setitem
1850

1951

52+
def change_values_1d_func(a, p):
53+
"""Assign values in a 1d numpy.ndarray
54+
55+
Args:
56+
a (numpy.ndarray): Input array.
57+
p (int): Value to be assigned.
58+
"""
59+
for i in range(a.shape[0]):
60+
a[i] = p
61+
62+
2063
@exp_dpex.kernel
2164
def change_values_2d(x, v):
65+
"""Assign values in a 2d dpnp.ndarray
66+
67+
Args:
68+
x (dpnp.ndarray): Input array.
69+
v (int): Value to be assigned.
70+
"""
2271
i = numba_dpex.get_global_id(0)
2372
j = numba_dpex.get_global_id(1)
2473
p = x[i, j] # getitem
2574
p = v
2675
x[i, j] = p # setitem
2776

2877

78+
def change_values_2d_func(a, p):
79+
"""Assign values in a 2d numpy.ndarray
80+
81+
Args:
82+
a (numpy.ndarray): Input array.
83+
p (int): Value to be assigned.
84+
"""
85+
for i in range(a.shape[0]):
86+
for j in range(a.shape[1]):
87+
a[i, j] = p
88+
89+
2990
@exp_dpex.kernel
3091
def change_values_3d(x, v):
92+
"""Assign values in a 3d dpnp.ndarray
93+
94+
Args:
95+
x (dpnp.ndarray): Input array.
96+
v (int): Value to be assigned.
97+
"""
3198
i = numba_dpex.get_global_id(0)
3299
j = numba_dpex.get_global_id(1)
33100
k = numba_dpex.get_global_id(2)
@@ -36,74 +103,192 @@ def change_values_3d(x, v):
36103
x[i, j, k] = p # setitem
37104

38105

39-
def test_strided_dpnp_array_in_kernel():
106+
def change_values_3d_func(a, p):
107+
"""Assign values in a 3d numpy.ndarray
108+
109+
Args:
110+
a (numpy.ndarray): Input array.
111+
p (int): Value to be assigned.
112+
"""
113+
for i in range(a.shape[0]):
114+
for j in range(a.shape[1]):
115+
for k in range(a.shape[2]):
116+
a[i, j, k] = p
117+
118+
119+
@pytest.mark.parametrize("N", [8, 16, 32, 64, 128, 256, 512])
120+
@pytest.mark.parametrize("s", [1, 2, 3, 4, 5, 6, 7])
121+
def test_1d_strided_dpnp_array_in_kernel(N, s):
40122
"""
41123
Tests if we can correctly handle a strided 1d dpnp array
42124
inside dpex kernel.
43125
"""
44-
N = 1024
45-
out = dpnp.arange(0, N * 2, dtype=dpnp.int64)
46-
b = out[::2]
126+
k = -3
127+
128+
t = np.arange(0, N, dtype=dpnp.int64)
129+
u = dpnp.asarray(t)
130+
131+
v = u[::s]
132+
exp_dpex.call_kernel(change_values_1d, Range(v.shape[0]), v, k)
47133

48-
r = Range(N)
49-
v = -3
50-
exp_dpex.call_kernel(change_values_1d, r, b, v)
134+
x = t[::s]
135+
change_values_1d_func(x, k)
51136

52-
assert (dpnp.asnumpy(b) == v).all()
137+
# check the value of the array view
138+
assert np.all(dpnp.asnumpy(v) == x)
139+
# check the value of the original arrays
140+
assert np.all(dpnp.asnumpy(u) == t)
53141

54142

55-
def test_multievel_strided_dpnp_array_in_kernel():
143+
@pytest.mark.parametrize("N", [8, 16, 32, 64, 128])
144+
@pytest.mark.parametrize("s", [2, 3, 4, 5])
145+
def test_multievel_1d_strided_dpnp_array_in_kernel(N, s):
56146
"""
57147
Tests if we can correctly handle a multilevel strided 1d dpnp array
58148
inside dpex kernel.
59149
"""
60-
N = 128
61-
out = dpnp.arange(0, N * 2, dtype=dpnp.int64)
62-
v = -3
150+
k = -3
151+
152+
t = dpnp.arange(0, N, dtype=dpnp.int64)
153+
u = dpnp.asarray(t)
154+
155+
v, x = u, t
156+
while v.shape[0] > 1:
157+
v = v[::s]
158+
exp_dpex.call_kernel(change_values_1d, Range(v.shape[0]), v, k)
159+
160+
x = x[::s]
161+
change_values_1d_func(x, k)
63162

64-
b = out
65-
n = N
66-
K = 7
67-
for _ in range(K):
68-
b = b[::2]
69-
exp_dpex.call_kernel(change_values_1d, Range(n), b, v)
70-
assert (dpnp.asnumpy(b) == v).all()
71-
n = int(n / 2)
163+
# check the value of the array view
164+
assert np.all(dpnp.asnumpy(v) == x)
165+
# check the value of the original arrays
166+
assert np.all(dpnp.asnumpy(u) == t)
72167

73168

74-
def test_multilevel_2d_strided_dpnp_array_in_kernel():
169+
@pytest.mark.parametrize("M", [3, 5, 7, 9])
170+
@pytest.mark.parametrize("N", [2, 4, 6, 8])
171+
@pytest.mark.parametrize("s1", [2, 4, 6])
172+
@pytest.mark.parametrize("s2", [1, 3, 5])
173+
@pytest.mark.parametrize("order", ["C", "F"])
174+
def test_2d_strided_dpnp_array_in_kernel(M, N, s1, s2, order):
175+
"""
176+
Tests if we can correctly handle a strided 2d dpnp array
177+
inside dpex kernel.
178+
"""
179+
k = -3
180+
181+
t = np.arange(0, M * N, dtype=np.int64).reshape(M, N, order=order)
182+
u = dpnp.asarray(t)
183+
184+
# check order, sanity check
185+
assert get_order(u) == order
186+
187+
v = u[::s1, ::s2]
188+
exp_dpex.call_kernel(change_values_2d, Range(*v.shape), v, k)
189+
190+
x = t[::s1, ::s2]
191+
change_values_2d_func(x, k)
192+
193+
# check the value of the array view
194+
assert np.all(dpnp.asnumpy(v) == x)
195+
# check the value of the original arrays
196+
assert np.all(dpnp.asnumpy(u) == t)
197+
198+
199+
@pytest.mark.parametrize("M", [5, 7, 9, 11])
200+
@pytest.mark.parametrize("N", [4, 6, 8, 10])
201+
@pytest.mark.parametrize("s1", [2, 4, 6])
202+
@pytest.mark.parametrize("s2", [3, 5, 7])
203+
@pytest.mark.parametrize("order", ["C", "F"])
204+
def test_multilevel_2d_strided_dpnp_array_in_kernel(M, N, s1, s2, order):
75205
"""
76206
Tests if we can correctly handle a multilevel strided 2d dpnp array
77207
inside dpex kernel.
78208
"""
79-
N = 128
80-
out, _ = dpnp.mgrid[0 : N * 2, 0 : N * 2] # noqa: E203
81-
v = -3
209+
k = -3
210+
211+
t = np.arange(0, M * N, dtype=np.int64).reshape(M, N, order=order)
212+
u = dpnp.asarray(t)
213+
214+
# check order, sanity check
215+
assert get_order(u) == order
82216

83-
b = out
84-
n = N
85-
K = 7
86-
for _ in range(K):
87-
b = b[::2, ::2]
88-
exp_dpex.call_kernel(change_values_2d, Range(n, n), b, v)
89-
assert (dpnp.asnumpy(b) == v).all()
90-
n = int(n / 2)
217+
v, x = u, t
218+
while v.shape[0] > 1 and v.shape[1] > 1:
219+
v = v[::s1, ::s2]
220+
exp_dpex.call_kernel(change_values_2d, Range(*v.shape), v, k)
91221

222+
x = x[::s1, ::s2]
223+
change_values_2d_func(x, k)
92224

93-
def test_multilevel_3d_strided_dpnp_array_in_kernel():
225+
# check the value of the array view
226+
assert np.all(dpnp.asnumpy(v) == x)
227+
# check the value of the original arrays
228+
assert np.all(dpnp.asnumpy(u) == t)
229+
230+
231+
@pytest.mark.parametrize("M", [2, 3, 4])
232+
@pytest.mark.parametrize("N", [5, 6, 7])
233+
@pytest.mark.parametrize("K", [8, 9, 10])
234+
@pytest.mark.parametrize("s1", [1, 2, 3])
235+
@pytest.mark.parametrize("s2", [2, 3, 4])
236+
@pytest.mark.parametrize("s3", [3, 4, 5])
237+
@pytest.mark.parametrize("order", ["C", "F"])
238+
def test_3d_strided_dpnp_array_in_kernel(M, N, K, s1, s2, s3, order):
239+
"""
240+
Tests if we can correctly handle a strided 3d dpnp array
241+
inside dpex kernel.
242+
"""
243+
k = -3
244+
245+
t = np.arange(0, M * N * K, dtype=np.int64).reshape((M, N, K), order=order)
246+
u = dpnp.asarray(t)
247+
248+
# check order, sanity check
249+
assert get_order(u) == order
250+
251+
v = u[::s1, ::s2, ::s3]
252+
exp_dpex.call_kernel(change_values_3d, Range(*v.shape), v, k)
253+
254+
x = t[::s1, ::s2, ::s3]
255+
change_values_3d_func(x, k)
256+
257+
# check the value of the array view
258+
assert np.all(dpnp.asnumpy(v) == x)
259+
# check the value of the original arrays
260+
assert np.all(dpnp.asnumpy(u) == t)
261+
262+
263+
@pytest.mark.parametrize("M", [5, 6, 7])
264+
@pytest.mark.parametrize("N", [8, 9, 10])
265+
@pytest.mark.parametrize("K", [11, 12, 13])
266+
@pytest.mark.parametrize("s1", [2, 3, 4])
267+
@pytest.mark.parametrize("s2", [3, 4, 5])
268+
@pytest.mark.parametrize("s3", [4, 5, 6])
269+
@pytest.mark.parametrize("order", ["C", "F"])
270+
def test_multilevel_3d_strided_dpnp_array_in_kernel(M, N, K, s1, s2, s3, order):
94271
"""
95272
Tests if we can correctly handle a multilevel strided 3d dpnp array
96273
inside dpex kernel.
97274
"""
98-
N = 128
99-
out, _, _ = dpnp.mgrid[0 : N * 2, 0 : N * 2, 0 : N * 2] # noqa: E203
100-
v = -3
101-
102-
b = out
103-
n = N
104-
K = 7
105-
for _ in range(K):
106-
b = b[::2, ::2, ::2]
107-
exp_dpex.call_kernel(change_values_3d, Range(n, n, n), b, v)
108-
assert (dpnp.asnumpy(b) == v).all()
109-
n = int(n / 2)
275+
k = -3
276+
277+
t = np.arange(0, M * N * K, dtype=np.int64).reshape((M, N, K), order=order)
278+
u = dpnp.asarray(t)
279+
280+
# check order, sanity check
281+
assert get_order(u) == order
282+
283+
v, x = u, t
284+
while v.shape[0] > 1 and v.shape[1] > 1 and v.shape[2] > 1:
285+
v = v[::s1, ::s2, ::s3]
286+
exp_dpex.call_kernel(change_values_3d, Range(*v.shape), v, k)
287+
288+
x = x[::s1, ::s2, ::s3]
289+
change_values_3d_func(x, k)
290+
291+
# check the value of the array view
292+
assert np.all(dpnp.asnumpy(v) == x)
293+
# check the value of the original arrays
294+
assert np.all(dpnp.asnumpy(u) == t)

0 commit comments

Comments
 (0)