Skip to content

Commit f5ca9e8

Browse files
authored
add interoperability tests (#853)
1 parent f6dd61a commit f5ca9e8

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import sys
2+
import importlib
3+
import pytest
4+
5+
class dummymodule:
6+
pass
7+
8+
sys.modules['numba_dppy'] = dummymodule
9+
10+
module_not_found = False
11+
12+
reason = ""
13+
14+
try:
15+
zero_copy_test1 = importlib.import_module("zero-copy-test1")
16+
except ModuleNotFoundError as e:
17+
module_not_found = True
18+
reason = str(e)
19+
20+
21+
@pytest.mark.skipif(module_not_found, reason=reason)
22+
def test_dpnp_interaction_with_dpctl_memory():
23+
return zero_copy_test1.test_dpnp_interaction_with_dpctl_memory()
24+
25+
26+
@pytest.mark.skipif(module_not_found, reason=reason)
27+
def test_dpnp_array_has_iface():
28+
return zero_copy_test1.test_dpnp_array_has_iface()
29+
30+
31+
@pytest.mark.skipif(module_not_found, reason=reason)
32+
def test_dpctl_dparray_has_iface():
33+
return zero_copy_test1.test_dpctl_dparray_has_iface()
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import dpctl
2+
import dpctl.memory as dpmem
3+
import dpnp
4+
import numpy as np
5+
import pytest
6+
import numba_dppy as dppy
7+
import dpctl.tensor.numpy_usm_shared as usmarray
8+
9+
10+
class DuckUSMArray:
11+
def __init__(self, shape, dtype="d", host_buffer=None):
12+
nelems = np.prod(shape)
13+
bytes = nelems * np.dtype(dtype).itemsize
14+
shmem = dpmem.MemoryUSMShared(bytes)
15+
if isinstance(host_buffer, np.ndarray):
16+
shmem.copy_from_host(host_buffer.view(dtype="|u1"))
17+
self.arr = np.ndarray(shape, dtype=dtype, buffer=shmem)
18+
19+
def __getitem__(self, indx):
20+
return self.arr[indx]
21+
22+
def __setitem__(self, indx, val):
23+
self.arr.__setitem__(indx, val)
24+
25+
@property
26+
def __sycl_usm_array_interface__(self):
27+
iface = self.arr.__array_interface__
28+
b = self.arr.base
29+
iface["syclobj"] = b.__sycl_usm_array_interface__["syclobj"]
30+
iface["version"] = 1
31+
return iface
32+
33+
34+
def test_dpnp_interaction_with_dpctl_memory():
35+
"""Tests if dpnp supports zero-copy data exchange with another Python
36+
object that defines `__sycl_usm_array_interface__`
37+
"""
38+
hb = np.arange(0, 100, dtype=np.int64)
39+
da = DuckUSMArray(hb.shape, dtype=hb.dtype, host_buffer=hb)
40+
41+
Y = dpnp.asarray(da)
42+
# dpnp array must infer dimensions/dtype from input object
43+
assert Y.dtype == hb.dtype
44+
assert Y.shape == hb.shape
45+
46+
Y[0] = 10
47+
assert da[0] == 10 # check zero copy
48+
49+
50+
def test_dppy_array_pass():
51+
"""Tests if dppy supports passing an array-like object DuckArray that defines `__sycl_usm_array_interface__`
52+
to a dppy.kernel
53+
"""
54+
55+
@dppy.kernel
56+
def dppy_f(array_like_obj):
57+
i = dppy.get_global_id(0)
58+
array_like_obj[i] = 10
59+
60+
global_size = 100
61+
hb = np.arange(0, global_size, dtype="i4")
62+
da = DuckUSMArray(hb.shape, dtype=hb.dtype, host_buffer=hb)
63+
64+
if dpctl.has_gpu_queues(dpctl.backend_type.level_zero):
65+
print("\nScheduling on OpenCL GPU\n")
66+
with dpctl.device_context("opencl:gpu") as gpu_queue:
67+
dppy_f[global_size, dppy.DEFAULT_LOCAL_SIZE](da)
68+
else:
69+
print("\nSkip scheduling on OpenCL GPU\n")
70+
71+
assert da[0] == 10
72+
73+
74+
def test_dpctl_dparray_has_iface():
75+
"""Tests if dpctl.dptensor.numpy_usm_shared defines '__sycl_usm_array_interface__'"""
76+
X = usmarray.ones(10)
77+
assert type(getattr(X, "__sycl_usm_array_interface__", None) is dict)
78+
79+
80+
def test_dpnp_array_has_iface():
81+
"""Tests if dpnp.ndarray defines '__sycl_usm_array_interface__'"""
82+
X = dpnp.array([1])
83+
assert type(getattr(X, "__sycl_usm_array_interface__", None) is dict)

0 commit comments

Comments
 (0)