@@ -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,99 @@ 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
+
1744
+
1745
+ cdef class RawKernelArg:
1746
+ """
1747
+ RawKernelArg(*args)
1748
+ Python class representing the ``raw_kernel_arg`` class from the Raw Kernel
1749
+ Argument oneAPI SYCL extension for passing binary data as data to kernels.
1750
+
1751
+ This class is intended to be used as kernel argument when launching kernels.
1752
+
1753
+ This is based on a DPC++ SYCL extension and only available in newer
1754
+ versions. Use ``is_available()`` to check availability in your build.
1755
+
1756
+ There are multiple ways to create a ``RawKernelArg``.
1757
+
1758
+ - If the constructor is invoked with just a single argument, this argument
1759
+ is expected to expose the Python buffer interface. The raw kernel arg will
1760
+ be constructed from the data in that buffer.
1761
+
1762
+ - If the constructor is invoked with two arguments, the first argument is
1763
+ interpreted as the number of bytes in the binary argument, while the
1764
+ second argument is interpreted as a pointer to the data.
1765
+
1766
+ Note that construction of the ``RawKernelArg`` copies the bytes, so
1767
+ modifications made after construction of the ``RawKernelArg`` will not be
1768
+ reflected in the kernel launch.
1769
+
1770
+ Args:
1771
+ args:
1772
+ Variadic argument, see class documentation.
1773
+
1774
+ Raises:
1775
+ TypeError: In case of incorrect arguments given to constructurs,
1776
+ unexpected types of input arguments.
1777
+ """
1778
+ def __cinit__ (self , *args ):
1779
+ cdef void * ptr = NULL
1780
+ cdef size_t count
1781
+ cdef int ret_code = 0
1782
+ cdef Py_buffer _buffer
1783
+ cdef bint _is_buf
1784
+
1785
+ if not DPCTLRawKernelArg_Available():
1786
+ raise RuntimeError (" Raw kernel arg extension not available" )
1787
+
1788
+ if not (0 < len (args) < 3 ):
1789
+ raise TypeError (" RawKernelArg constructor takes 1 or 2 "
1790
+ f" arguments, but {len(args)} were given" )
1791
+
1792
+ if len (args) == 1 :
1793
+ if not _is_buffer(args[0 ]):
1794
+ raise TypeError (" RawKernelArg single argument constructor"
1795
+ " expects argument to be buffer" ,
1796
+ f" but got {type(args[0])}" )
1797
+
1798
+ ret_code = PyObject_GetBuffer(args[0 ], & (_buffer), PyBUF_SIMPLE | PyBUF_ANY_CONTIGUOUS)
1799
+ if ret_code != 0 : # pragma: no cover
1800
+ raise RuntimeError (" Could not access buffer" )
1801
+
1802
+ ptr = _buffer.buf
1803
+ count = _buffer.len
1804
+ _is_buf = True
1805
+ else :
1806
+ if not isinstance (args[0 ], numbers.Integral):
1807
+ raise TypeError (" RawKernelArg constructor expects first"
1808
+ " argument to be `int`, but got {type(args[0])}" )
1809
+ if not isinstance (args[1 ], numbers.Integral):
1810
+ raise TypeError (" RawKernelArg constructor expects second"
1811
+ " argument to be `int`, but got {type(args[1])}" )
1812
+
1813
+ _is_buf = False
1814
+ count = args[0 ]
1815
+ ptr = < void * > (< unsigned long long > args[1 ])
1816
+
1817
+ self ._arg_ref = DPCTLRawKernelArg_Create(ptr, count)
1818
+ if (_is_buf):
1819
+ PyBuffer_Release(& (_buffer))
1820
+
1821
+
1822
+ """ Check whether the raw_kernel_arg extension is available"""
1823
+ @staticmethod
1824
+ def is_available ():
1825
+ return DPCTLRawKernelArg_Available();
1826
+
1827
+ property _ref :
1828
+ """ Returns the address of the C API ``DPCTLRawKernelArgRef`` pointer
1829
+ as a ``size_t``.
1830
+ """
1831
+ def __get__ (self ):
1832
+ return < size_t> self ._arg_ref
0 commit comments