Skip to content

Commit 32c5bf2

Browse files
committed
added interop functionality and tests, edited str_to_dtype function in dtypes, added opencl tests, chaged get_queue and get_context return types to void pointers
1 parent 4a505dc commit 32c5bf2

File tree

5 files changed

+143
-8
lines changed

5 files changed

+143
-8
lines changed

arrayfire_wrapper/dtypes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def c_api_value_to_dtype(value: int) -> Dtype:
108108

109109
def str_to_dtype(value: str) -> Dtype:
110110
for dtype in supported_dtypes:
111-
if value == dtype.typecode or value == dtype.typename or value == dtype.name:
111+
if value == dtype.typecode or value == dtype.typename or value == dtype.name or value == dtype.c_type:
112112
return dtype
113113

114114
raise TypeError("There is no supported dtype that matches passed dtype typecode.")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import ctypes
2+
3+
import numpy as np
4+
import pyopencl.array as cl # type: ignore[import-untyped]
5+
6+
from arrayfire_wrapper.defines import AFArray, CShape
7+
from arrayfire_wrapper.dtypes import c_api_value_to_dtype, str_to_dtype
8+
from arrayfire_wrapper.lib._utility import call_from_clib
9+
from arrayfire_wrapper.lib.create_and_modify_array.manage_array import create_array, get_data_ptr, get_dims, get_type
10+
11+
12+
def numpy_to_af_array(np_arr: np.ndarray) -> AFArray:
13+
out = AFArray(0)
14+
shape = np_arr.shape
15+
c_shape = CShape(*shape)
16+
17+
c_type = np.ctypeslib.as_ctypes_type(np_arr.dtype)
18+
dtype = str_to_dtype(c_type)
19+
20+
call_from_clib(
21+
create_array.__name__,
22+
ctypes.pointer(out),
23+
np_arr.ctypes.data_as(ctypes.c_void_p),
24+
c_shape.original_shape,
25+
ctypes.pointer(c_shape.c_array),
26+
dtype.c_api_value,
27+
)
28+
return out
29+
30+
31+
def af_to_numpy_array(af_arr: AFArray) -> np.ndarray:
32+
shape = get_dims(af_arr)
33+
dtype = c_api_value_to_dtype(get_type(af_arr))
34+
typecode = dtype.typecode
35+
36+
out = np.empty(shape, typecode, "F")
37+
call_from_clib(get_data_ptr.__name__, ctypes.c_void_p(out.ctypes.data), af_arr)
38+
return out
39+
40+
41+
def pyopencl_to_af_array(pycl_arr: cl.Array) -> AFArray:
42+
out = AFArray(0)
43+
np_arr = pycl_arr.get()
44+
45+
shape = np_arr.shape
46+
c_shape = CShape(*shape)
47+
48+
c_type = np.ctypeslib.as_ctypes_type(np_arr.dtype)
49+
dtype = str_to_dtype(c_type)
50+
51+
call_from_clib(
52+
create_array.__name__,
53+
ctypes.pointer(out),
54+
np_arr.ctypes.data_as(ctypes.c_void_p),
55+
c_shape.original_shape,
56+
ctypes.pointer(c_shape.c_array),
57+
dtype.c_api_value,
58+
)
59+
60+
return out

arrayfire_wrapper/lib/interface_functions/opencl.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,22 @@ class PlatformType(Enum):
2121
UNKNOWN = -1
2222

2323

24-
def get_context(retain: bool = False) -> int:
24+
def get_context(retain: bool = False) -> ctypes.c_void_p:
2525
"""
2626
source: https://arrayfire.org/docs/group__opencl__mat.htm#gad42de383f405b3e38d6eb669c0cbe2e3
2727
"""
2828
out = ctypes.c_void_p()
2929
call_from_clib(get_context.__name__, ctypes.pointer(out), retain, clib_prefix="afcl")
30-
return out.value # type: ignore[return-value]
30+
return out # type: ignore[return-value]
3131

3232

33-
def get_queue(retain: bool = False) -> int:
33+
def get_queue(retain: bool = False) -> ctypes.c_void_p:
3434
"""
3535
source: https://arrayfire.org/docs/group__opencl__mat.htm#gab1701ef4f2b68429eb31c1e21c88d0bc
3636
"""
3737
out = ctypes.c_void_p()
3838
call_from_clib(get_queue.__name__, ctypes.pointer(out), retain, clib_prefix="afcl")
39-
return out.value # type: ignore[return-value]
39+
return out # type: ignore[return-value]
4040

4141

4242
def get_device_id() -> int:
@@ -45,7 +45,7 @@ def get_device_id() -> int:
4545
"""
4646
out = ctypes.c_void_p()
4747
call_from_clib(get_device_id.__name__, ctypes.pointer(out), clib_prefix="afcl")
48-
return out.value # type: ignore[return-value]
48+
return out # type: ignore[return-value]
4949

5050

5151
def set_device_id(idx: int) -> None:

tests/test_interop.py

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import numpy as np
2+
import pyopencl as cl # type: ignore
3+
import pyopencl.array as cl_array # type: ignore
4+
5+
import arrayfire_wrapper.lib as wrapper
6+
from arrayfire_wrapper.defines import AFArray
7+
from arrayfire_wrapper.dtypes import int16
8+
from arrayfire_wrapper.lib.create_and_modify_array.manage_array import get_dims, get_numdims
9+
from arrayfire_wrapper.lib.interface_functions.interop import ( # noqa: E501
10+
af_to_numpy_array,
11+
numpy_to_af_array,
12+
pyopencl_to_af_array,
13+
)
14+
15+
# flake8: noqa: E203
16+
17+
18+
def test_numpy_to_af_array_type():
19+
arr = np.array([1, 2, 3, 4])
20+
21+
af_array = numpy_to_af_array(arr)
22+
23+
assert isinstance(af_array, AFArray)
24+
25+
26+
def test_af_to_numpy_array_type():
27+
arr = wrapper.constant(2, (5, 5), int16)
28+
29+
np_arr = af_to_numpy_array(arr)
30+
31+
assert isinstance(np_arr, np.ndarray)
32+
33+
34+
def test_pyopencl_to_af_array_type():
35+
ctx = cl.create_some_context()
36+
queue = cl.CommandQueue(ctx)
37+
38+
host_array = np.array([1, 2, 3, 4])
39+
40+
cl_array_device = cl_array.to_device(queue, host_array)
41+
42+
af_array = pyopencl_to_af_array(cl_array_device)
43+
44+
assert isinstance(af_array, AFArray)
45+
46+
47+
def test_numpy_to_af_array_shape():
48+
np_arr = np.array([1, 2, 3, 4])
49+
50+
af_arr = numpy_to_af_array(np_arr)
51+
52+
assert get_dims(af_arr)[0 : get_numdims(af_arr)] == np_arr.shape[0 : get_numdims(af_arr)]
53+
54+
55+
def test_af_to_numpy_array_shape():
56+
af_arr = wrapper.constant(2, (5, 5), int16)
57+
58+
np_arr = af_to_numpy_array(af_arr)
59+
assert np_arr.shape[0 : get_numdims(af_arr)] == get_dims(af_arr)[0 : get_numdims(af_arr)]
60+
61+
62+
def test_pyopencl_to_af_array_shape():
63+
ctx = cl.create_some_context()
64+
queue = cl.CommandQueue(ctx)
65+
66+
host_array = np.array([1, 2, 3, 4])
67+
68+
cl_arr = cl_array.to_device(queue, host_array)
69+
70+
af_arr = pyopencl_to_af_array(cl_arr)
71+
72+
assert cl_arr.shape[0 : get_numdims(af_arr)] == get_dims(af_arr)[0 : get_numdims(af_arr)]

tests/test_opencl.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import ctypes
2+
13
import arrayfire_wrapper.lib.interface_functions.opencl as cl
24

35

46
def test_get_context_type() -> None:
5-
assert isinstance(cl.get_context(), int)
7+
ptr = cl.get_context()
8+
assert isinstance(ptr, ctypes.c_void_p)
69

710

811
def test_get_queue_type() -> None:
9-
assert isinstance(cl.get_queue(), int)
12+
assert isinstance(cl.get_queue(), ctypes.c_void_p)
1013

1114

1215
def test_get_device_id() -> None:

0 commit comments

Comments
 (0)