@@ -51,6 +51,9 @@ from ._backend cimport ( # noqa: E211
51
51
DPCTLQueue_SubmitNDRange,
52
52
DPCTLQueue_SubmitRange,
53
53
DPCTLQueue_Wait,
54
+ DPCTLRawKernelArg_Available,
55
+ DPCTLRawKernelArg_Create,
56
+ DPCTLRawKernelArg_Delete,
54
57
DPCTLSyclContextRef,
55
58
DPCTLSyclDeviceSelectorRef,
56
59
DPCTLSyclEventRef,
@@ -353,6 +356,15 @@ cdef class _kernel_arg_type:
353
356
_arg_data_type._WORK_GROUP_MEMORY
354
357
)
355
358
359
+ @property
360
+ def dpctl_raw_kernel_arg (self ):
361
+ cdef str p_name = " dpctl_raw_kernel_arg"
362
+ return kernel_arg_type_attribute(
363
+ self ._name,
364
+ p_name,
365
+ _arg_data_type._RAW_KERNEL_ARG
366
+ )
367
+
356
368
357
369
kernel_arg_type = _kernel_arg_type()
358
370
@@ -958,6 +970,9 @@ cdef class SyclQueue(_SyclQueue):
958
970
elif isinstance (arg, LocalAccessor):
959
971
kargs[idx] = < void * > ((< LocalAccessor> arg).addressof())
960
972
kargty[idx] = _arg_data_type._LOCAL_ACCESSOR
973
+ elif isinstance (arg, RawKernelArg):
974
+ kargs[idx] = < void * > (< size_t> arg._ref)
975
+ kargty[idx] = _arg_data_type._RAW_KERNEL_ARG
961
976
else :
962
977
ret = - 1
963
978
return ret
@@ -1719,3 +1734,93 @@ cdef class WorkGroupMemory:
1719
1734
"""
1720
1735
def __get__ (self ):
1721
1736
return < size_t> self ._mem_ref
1737
+
1738
+
1739
+ cdef class _RawKernelArg:
1740
+ def __dealloc (self ):
1741
+ if (self ._arg_ref):
1742
+ DPCTLRawKernelArg_Delete(self ._arg_ref)
1743
+ if (self ._is_buf):
1744
+ PyBuffer_Release(& (self ._buf))
1745
+
1746
+ cdef class RawKernelArg:
1747
+ """
1748
+ RawKernelArg(*args)
1749
+ Python class representing the ``raw_kernel_arg`` class from the Raw Kernel
1750
+ Argument oneAPI SYCL extension for passing binary data as data to kernels.
1751
+
1752
+ This class is intended to be used as kernel argument when launching kernels.
1753
+
1754
+ This is based on a DPC++ SYCL extension and only available in newer
1755
+ versions. Use ``is_available()`` to check availability in your build.
1756
+
1757
+ There are multiple ways to create a ``RawKernelArg``.
1758
+
1759
+ - If the constructor is invoked with just a single argument, this argument
1760
+ is expected to expose the Python buffer interface. The raw kernel arg will
1761
+ be constructed from the data in that buffer.
1762
+
1763
+ - If the constructor is invoked with two arguments, the first argument is
1764
+ interpreted as the number of bytes in the binary argument, while the
1765
+ second argument is interpreted as a pointer to the data. Note that the
1766
+ raw kernel arg does not own or copy the data, so the pointed-to object
1767
+ must be kept alive by the user until kernel launch.
1768
+
1769
+ Args:
1770
+ args:
1771
+ Variadic argument, see class documentation.
1772
+
1773
+ Raises:
1774
+ TypeError: In case of incorrect arguments given to constructurs,
1775
+ unexpected types of input arguments.
1776
+ """
1777
+ def __cinit__ (self , *args ):
1778
+ cdef void * ptr = NULL
1779
+ cdef size_t count
1780
+ cdef int ret_code = 0
1781
+
1782
+ if not DPCTLRawKernelArg_Available():
1783
+ raise RuntimeError (" Raw kernel arg extension not available" )
1784
+
1785
+ if not (0 < len (args) < 3 ):
1786
+ raise TypeError (" RawKernelArg constructor takes 1 or 2 "
1787
+ f" arguments, but {len(args)} were given" )
1788
+
1789
+ if len (args) == 1 :
1790
+ if not _is_buffer(args[0 ]):
1791
+ raise TypeError (" RawKernelArg single argument constructor"
1792
+ " expects argument to be buffer" ,
1793
+ f" but got {type(args[0])}" )
1794
+
1795
+ ret_code = PyObject_GetBuffer(args[0 ], & (self ._buf), PyBUF_SIMPLE | PyBUF_ANY_CONTIGUOUS)
1796
+ if ret_code != 0 : # pragma: no cover
1797
+ raise RuntimeError (" Could not access buffer" )
1798
+
1799
+ ptr = self ._buf.buf
1800
+ count = self ._buf.len
1801
+ self ._is_buf = True
1802
+ else :
1803
+ if not isinstance (args[0 ], numbers.Integral):
1804
+ raise TypeError (" RawKernelArg constructor expects first"
1805
+ " argument to be `int`, but got {type(args[0])}" )
1806
+ if not isinstance (args[1 ], numbers.Integral):
1807
+ raise TypeError (" RawKernelArg constructor expects second"
1808
+ " argument to be `int`, but got {type(args[1])}" )
1809
+
1810
+ self ._is_buf = False
1811
+ count = args[0 ]
1812
+ ptr = < void * > (< unsigned long long > args[1 ])
1813
+
1814
+ self ._arg_ref = DPCTLRawKernelArg_Create(ptr, count)
1815
+
1816
+ """ Check whether the raw_kernel_arg extension is available"""
1817
+ @staticmethod
1818
+ def is_available ():
1819
+ return DPCTLRawKernelArg_Available();
1820
+
1821
+ property _ref :
1822
+ """ Returns the address of the C API ``DPCTLRawKernelArgRef`` pointer
1823
+ as a ``size_t``.
1824
+ """
1825
+ def __get__ (self ):
1826
+ return < size_t> self ._arg_ref
0 commit comments