@@ -37,7 +37,7 @@ from cpython.buffer cimport (
3737from cpython.bytes cimport PyBytes_FromStringAndSize
3838from libc.stdint cimport uint32_t
3939from libc.stdlib cimport free, malloc
40- from libc.string cimport memcmp
40+ from libc.string cimport memcmp, memcpy
4141
4242import warnings
4343
@@ -298,12 +298,10 @@ cdef class SpecializationConstant:
298298 integers, the first argument is interpreted as the number of bytes and
299299 the second argument is interpreted as a pointer to the data.
300300
301- Note that when constructing from a buffer, the
302- :class:`.SpecializationConstant`, shares memory with the original object.
303- Modifications to the original object's data after construction will be
304- reflected when the :class:`.SpecializationConstant` is used to create a
305- :class:`.SyclKernelBundle`. This is not the case when constructing from a
306- raw pointer, as the data is copied.
301+ Note that construction of the :class:`.SpecializationConstant` copies the
302+ input, so modifications made after construction of the
303+ :class:`.SpecializationConstant` will not be reflected in the
304+ :class:`.SyclKernelBundle`.
307305
308306 Args:
309307 spec_id (int):
@@ -319,11 +317,11 @@ cdef class SpecializationConstant:
319317 """
320318
321319 cdef _spec_const _spec_const
322- cdef Py_buffer _buffer
323320
324321 def __cinit__ (self , spec_id , *args ):
325322 cdef int ret_code = 0
326323 cdef object target_obj = None
324+ cdef Py_buffer _local_buffer
327325
328326 if not isinstance (spec_id, numbers.Integral):
329327 raise TypeError (
@@ -348,16 +346,16 @@ cdef class SpecializationConstant:
348346 )
349347 elif isinstance (args[0 ], str ):
350348 target_obj = np.ascontiguousarray(args[1 ], dtype = args[0 ])
349+ else :
350+ raise TypeError (
351+ " Invalid arguments."
352+ )
351353
352354 elif len (args) == 1 :
353355 target_obj = args[0 ]
354356 if not PyObject_CheckBuffer(target_obj):
355357 # attempt to coerce to a numpy array
356358 target_obj = np.ascontiguousarray(target_obj)
357- else :
358- raise TypeError (
359- " Invalid arguments."
360- )
361359
362360 if isinstance (target_obj, np.ndarray):
363361 if target_obj.dtype.kind not in (" b" , " i" , " u" , " f" , " c" ):
@@ -372,17 +370,28 @@ cdef class SpecializationConstant:
372370 )
373371
374372 ret_code = PyObject_GetBuffer(
375- target_obj, & (self ._buffer ), PyBUF_SIMPLE | PyBUF_ANY_CONTIGUOUS
373+ target_obj, & (_local_buffer ), PyBUF_SIMPLE | PyBUF_ANY_CONTIGUOUS
376374 )
377375 if ret_code != 0 :
378376 raise ValueError (
379377 " Failed to get buffer view for the provided object."
380378 )
381- self ._spec_const.value = < void * > self ._buffer.buf
382- self ._spec_const.size = < size_t> self ._buffer.len
379+ self ._spec_const.value = < void * > malloc(self ._spec_const.size)
380+ self ._spec_const.size = < size_t> _local_buffer.len
381+
382+ if self ._spec_const.value == NULL :
383+ PyBuffer_Release(& (_local_buffer))
384+ raise MemoryError (
385+ " Failed to allocate memory for specialization constant data."
386+ )
387+
388+ memcpy(self ._spec_const.value, _local_buffer.buf, self ._spec_const.size)
389+
390+ PyBuffer_Release(& (_local_buffer))
383391
384392 def __dealloc__ (self ):
385- PyBuffer_Release(& (self ._buffer))
393+ if self ._spec_const.value != NULL :
394+ free(self ._spec_const.value)
386395
387396 def __repr__ (self ):
388397 return f" SpecializationConstant({self._spec_const.id})"
0 commit comments