@@ -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,
@@ -364,6 +367,15 @@ cdef class _kernel_arg_type:
364
367
_arg_data_type._WORK_GROUP_MEMORY
365
368
)
366
369
370
+ @property
371
+ def dpctl_raw_kernel_arg (self ):
372
+ cdef str p_name = " dpctl_raw_kernel_arg"
373
+ return kernel_arg_type_attribute(
374
+ self ._name,
375
+ p_name,
376
+ _arg_data_type._RAW_KERNEL_ARG
377
+ )
378
+
367
379
368
380
kernel_arg_type = _kernel_arg_type()
369
381
@@ -973,6 +985,9 @@ cdef class SyclQueue(_SyclQueue):
973
985
elif isinstance (arg, LocalAccessor):
974
986
kargs[idx] = < void * > ((< LocalAccessor> arg).addressof())
975
987
kargty[idx] = _arg_data_type._LOCAL_ACCESSOR
988
+ elif isinstance (arg, RawKernelArg):
989
+ kargs[idx] = < void * > (< size_t> arg._ref)
990
+ kargty[idx] = _arg_data_type._RAW_KERNEL_ARG
976
991
else :
977
992
ret = - 1
978
993
return ret
@@ -1738,3 +1753,98 @@ cdef class WorkGroupMemory:
1738
1753
"""
1739
1754
def __get__ (self ):
1740
1755
return < size_t> self ._mem_ref
1756
+
1757
+
1758
+ cdef class _RawKernelArg:
1759
+ def __dealloc (self ):
1760
+ if (self ._arg_ref):
1761
+ DPCTLRawKernelArg_Delete(self ._arg_ref)
1762
+
1763
+
1764
+ cdef class RawKernelArg:
1765
+ """
1766
+ RawKernelArg(*args)
1767
+ Python class representing the ``raw_kernel_arg`` class from the Raw Kernel
1768
+ Argument oneAPI SYCL extension for passing binary data as data to kernels.
1769
+
1770
+ This class is intended to be used as kernel argument when launching kernels.
1771
+
1772
+ This is based on a DPC++ SYCL extension and only available in newer
1773
+ versions. Use ``is_available()`` to check availability in your build.
1774
+
1775
+ There are multiple ways to create a ``RawKernelArg``.
1776
+
1777
+ - If the constructor is invoked with just a single argument, this argument
1778
+ is expected to expose the Python buffer interface. The raw kernel arg will
1779
+ be constructed from the data in that buffer.
1780
+
1781
+ - If the constructor is invoked with two arguments, the first argument is
1782
+ interpreted as the number of bytes in the binary argument, while the
1783
+ second argument is interpreted as a pointer to the data.
1784
+
1785
+ Note that construction of the ``RawKernelArg`` copies the bytes, so
1786
+ modifications made after construction of the ``RawKernelArg`` will not be
1787
+ reflected in the kernel launch.
1788
+
1789
+ Args:
1790
+ args:
1791
+ Variadic argument, see class documentation.
1792
+
1793
+ Raises:
1794
+ TypeError: In case of incorrect arguments given to constructurs,
1795
+ unexpected types of input arguments.
1796
+ """
1797
+ def __cinit__ (self , *args ):
1798
+ cdef void * ptr = NULL
1799
+ cdef size_t count
1800
+ cdef int ret_code = 0
1801
+ cdef Py_buffer _buffer
1802
+ cdef bint _is_buf
1803
+
1804
+ if not DPCTLRawKernelArg_Available():
1805
+ raise RuntimeError (" Raw kernel arg extension not available" )
1806
+
1807
+ if not (0 < len (args) < 3 ):
1808
+ raise TypeError (" RawKernelArg constructor takes 1 or 2 "
1809
+ f" arguments, but {len(args)} were given" )
1810
+
1811
+ if len (args) == 1 :
1812
+ if not _is_buffer(args[0 ]):
1813
+ raise TypeError (" RawKernelArg single argument constructor"
1814
+ " expects argument to be buffer" ,
1815
+ f" but got {type(args[0])}" )
1816
+
1817
+ ret_code = PyObject_GetBuffer(args[0 ], & (_buffer),
1818
+ PyBUF_SIMPLE | PyBUF_ANY_CONTIGUOUS)
1819
+ if ret_code != 0 : # pragma: no cover
1820
+ raise RuntimeError (" Could not access buffer" )
1821
+
1822
+ ptr = _buffer.buf
1823
+ count = _buffer.len
1824
+ _is_buf = True
1825
+ else :
1826
+ if not isinstance (args[0 ], numbers.Integral):
1827
+ raise TypeError (" RawKernelArg constructor expects first"
1828
+ " argument to be `int`, but got {type(args[0])}" )
1829
+ if not isinstance (args[1 ], numbers.Integral):
1830
+ raise TypeError (" RawKernelArg constructor expects second"
1831
+ " argument to be `int`, but got {type(args[1])}" )
1832
+
1833
+ _is_buf = False
1834
+ count = args[0 ]
1835
+ ptr = < void * > (< unsigned long long > args[1 ])
1836
+
1837
+ self ._arg_ref = DPCTLRawKernelArg_Create(ptr, count)
1838
+ if (_is_buf):
1839
+ PyBuffer_Release(& (_buffer))
1840
+
1841
+ @staticmethod
1842
+ def is_available ():
1843
+ return DPCTLRawKernelArg_Available()
1844
+
1845
+ property _ref :
1846
+ """ Returns the address of the C API ``DPCTLRawKernelArgRef`` pointer
1847
+ as a ``size_t``.
1848
+ """
1849
+ def __get__ (self ):
1850
+ return < size_t> self ._arg_ref
0 commit comments