diff --git a/cuda_bindings/cuda/bindings/_lib/cyruntime/cyruntime.pxi b/cuda_bindings/cuda/bindings/_lib/cyruntime/cyruntime.pxi index cd99c894ca6..dbdb3f2110d 100644 --- a/cuda_bindings/cuda/bindings/_lib/cyruntime/cyruntime.pxi +++ b/cuda_bindings/cuda/bindings/_lib/cyruntime/cyruntime.pxi @@ -259,6 +259,26 @@ cdef cudaError_t getDescInfo(const cudaChannelFormatDesc* d, int *numberOfChanne elif d[0].f in (cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized1010102,): if (d[0].x != 10) or (d[0].y != 10) or (d[0].z != 10) or (d[0].w != 2): return cudaErrorInvalidChannelDescriptor + elif d[0].f in (cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Packed422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Packed444,): + if (d[0].x != 8) or (d[0].y != 8) or (d[0].z != 8) or (d[0].w != 8): + return cudaErrorInvalidChannelDescriptor + elif d[0].f in (cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar420, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar444, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar420, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar444,): + if (d[0].x != 8) or (d[0].y != 8) or (d[0].z != 8) or (d[0].w != 0): + return cudaErrorInvalidChannelDescriptor + elif d[0].f in (cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar420, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar444, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar420, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar444,): + if (d[0].x != 16) or (d[0].y != 16) or (d[0].z != 16) or (d[0].w != 0): + return cudaErrorInvalidChannelDescriptor else: return cudaErrorInvalidChannelDescriptor @@ -414,12 +434,104 @@ cdef cudaError_t getDescInfo(const cudaChannelFormatDesc* d, int *numberOfChanne elif case_desc(d, 10, 10, 10, 2, cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized1010102): numberOfChannels[0] = 4 format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UNORM_INT_101010_2 + # 2a: normalized 8/16-bit kinds — validated above but previously had no case_desc arm + elif case_desc(d, 8, 0, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized8X1): + numberOfChannels[0] = 1 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UNORM_INT8X1 + elif case_desc(d, 8, 8, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized8X2): + numberOfChannels[0] = 2 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UNORM_INT8X2 + elif case_desc(d, 8, 8, 8, 8, cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized8X4): + numberOfChannels[0] = 4 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UNORM_INT8X4 + elif case_desc(d, 8, 0, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized8X1): + numberOfChannels[0] = 1 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_SNORM_INT8X1 + elif case_desc(d, 8, 8, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized8X2): + numberOfChannels[0] = 2 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_SNORM_INT8X2 + elif case_desc(d, 8, 8, 8, 8, cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized8X4): + numberOfChannels[0] = 4 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_SNORM_INT8X4 + elif case_desc(d, 16, 0, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized16X1): + numberOfChannels[0] = 1 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UNORM_INT16X1 + elif case_desc(d, 16, 16, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized16X2): + numberOfChannels[0] = 2 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UNORM_INT16X2 + elif case_desc(d, 16, 16, 16, 16, cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized16X4): + numberOfChannels[0] = 4 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UNORM_INT16X4 + elif case_desc(d, 16, 0, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized16X1): + numberOfChannels[0] = 1 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_SNORM_INT16X1 + elif case_desc(d, 16, 16, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized16X2): + numberOfChannels[0] = 2 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_SNORM_INT16X2 + elif case_desc(d, 16, 16, 16, 16, cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized16X4): + numberOfChannels[0] = 4 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_SNORM_INT16X4 + # 2b: CUDA 13.3/13.4 packed and multi-planar YUV kinds + elif case_desc(d, 8, 8, 8, 8, cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Packed422): + numberOfChannels[0] = 4 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT8_PACKED_422 + elif case_desc(d, 8, 8, 8, 8, cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Packed444): + numberOfChannels[0] = 4 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT8_PACKED_444 + elif case_desc(d, 8, 8, 8, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar420): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT8_SEMIPLANAR_420 + elif case_desc(d, 16, 16, 16, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar420): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT16_SEMIPLANAR_420 + elif case_desc(d, 8, 8, 8, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar422): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT8_SEMIPLANAR_422 + elif case_desc(d, 16, 16, 16, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar422): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT16_SEMIPLANAR_422 + elif case_desc(d, 8, 8, 8, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar444): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT8_SEMIPLANAR_444 + elif case_desc(d, 16, 16, 16, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar444): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT16_SEMIPLANAR_444 + elif case_desc(d, 8, 8, 8, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar420): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT8_PLANAR_420 + elif case_desc(d, 16, 16, 16, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar420): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT16_PLANAR_420 + elif case_desc(d, 8, 8, 8, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar422): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT8_PLANAR_422 + elif case_desc(d, 16, 16, 16, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar422): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT16_PLANAR_422 + elif case_desc(d, 8, 8, 8, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar444): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT8_PLANAR_444 + elif case_desc(d, 16, 16, 16, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar444): + numberOfChannels[0] = 3 + format[0] = cydriver.CUarray_format_enum.CU_AD_FORMAT_UINT16_PLANAR_444 else: return cudaErrorInvalidChannelDescriptor if d[0].f in (cudaChannelFormatKind.cudaChannelFormatKindNV12, cudaChannelFormatKind.cudaChannelFormatKindUnsignedBlockCompressed6H, - cudaChannelFormatKind.cudaChannelFormatKindSignedBlockCompressed6H,): + cudaChannelFormatKind.cudaChannelFormatKindSignedBlockCompressed6H, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar420, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar420, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar444, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar444, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar420, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar420, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar422, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar444, + cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar444,): if numberOfChannels[0] != 3: return cudaErrorInvalidChannelDescriptor else: @@ -536,6 +648,49 @@ cdef cudaError_t getChannelFormatDescFromDriverDesc(cudaChannelFormatDesc* pRunt channel_size = 8 elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UNORM_INT_101010_2: pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized1010102 + # 2b: CUDA 13.3/13.4 packed and multi-planar YUV formats + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT8_PACKED_422: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Packed422 + channel_size = 8 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT8_PACKED_444: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Packed444 + channel_size = 8 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT8_SEMIPLANAR_420: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar420 + channel_size = 8 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT16_SEMIPLANAR_420: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar420 + channel_size = 16 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT8_SEMIPLANAR_422: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar422 + channel_size = 8 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT16_SEMIPLANAR_422: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar422 + channel_size = 16 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT8_SEMIPLANAR_444: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar444 + channel_size = 8 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT16_SEMIPLANAR_444: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar444 + channel_size = 16 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT8_PLANAR_420: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar420 + channel_size = 8 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT16_PLANAR_420: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar420 + channel_size = 16 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT8_PLANAR_422: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar422 + channel_size = 8 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT16_PLANAR_422: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar422 + channel_size = 16 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT8_PLANAR_444: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar444 + channel_size = 8 + elif pDriverDesc[0].Format == cydriver.CU_AD_FORMAT_UINT16_PLANAR_444: + pRuntimeDesc[0].f = cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar444 + channel_size = 16 else: return cudaErrorInvalidChannelDescriptor diff --git a/cuda_bindings/cuda/bindings/_lib/utils.pxd b/cuda_bindings/cuda/bindings/_lib/utils.pxd index ca719f54c88..96308f9a96e 100644 --- a/cuda_bindings/cuda/bindings/_lib/utils.pxd +++ b/cuda_bindings/cuda/bindings/_lib/utils.pxd @@ -5,6 +5,7 @@ cimport cuda.bindings.driver as driver cimport cuda.bindings.cydriver as cydriver cimport cuda.bindings.cyruntime as cyruntime from libcpp.vector cimport vector +from libcpp cimport bool as cpp_bool from cpython.buffer cimport PyBuffer_Release, Py_buffer cdef class _HelperKernelParams: @@ -35,6 +36,7 @@ cdef class _HelperCUmemPool_attribute: # Return values cdef int _int_val + cdef unsigned int _uint_val cdef driver.cuuint64_t _cuuint64_t_val @@ -60,7 +62,7 @@ cdef class _HelperCUpointer_attribute: cdef unsigned int _uint cdef int _int cdef driver.CUdeviceptr _devptr - cdef void** _void + cdef void* _void cdef driver.CUDA_POINTER_ATTRIBUTE_P2P_TOKENS _token cdef bint _bool cdef unsigned long long _ull @@ -163,5 +165,6 @@ cdef class _HelperCUcoredumpSettings: cdef object _references # keeps caller bytes alive so _charstar stays valid # Return values - cdef bint _bool + cdef cpp_bool _bool + cdef unsigned int _uint cdef char* _charstar diff --git a/cuda_bindings/cuda/bindings/_lib/utils.pxi b/cuda_bindings/cuda/bindings/_lib/utils.pxi index d69e8ebd669..f2a808077fb 100644 --- a/cuda_bindings/cuda/bindings/_lib/utils.pxi +++ b/cuda_bindings/cuda/bindings/_lib/utils.pxi @@ -244,12 +244,23 @@ cdef class _HelperCUmemPool_attribute: cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_RESERVED_MEM_CURRENT, cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH, cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_USED_MEM_CURRENT, - cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_USED_MEM_HIGH,): + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_USED_MEM_HIGH, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_MAX_POOL_SIZE,): if self._is_getter: self._cuuint64_t_val = _driver["cuuint64_t"]() self._cptr = self._cuuint64_t_val.getPtr() else: self._cptr = init_value.getPtr() + elif self._attr in (cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_ALLOCATION_TYPE, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_LOCATION_ID, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_LOCATION_TYPE, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_HW_DECOMPRESS_ENABLED, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_LOCALITY_DOMAIN_ID,): + self._int_val = init_value + self._cptr = &self._int_val + elif self._attr in (cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_EXPORT_HANDLE_TYPES,): + self._uint_val = init_value + self._cptr = &self._uint_val else: raise TypeError('Unsupported attribute: {}'.format(attr.name)) @@ -270,8 +281,17 @@ cdef class _HelperCUmemPool_attribute: cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_RESERVED_MEM_CURRENT, cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH, cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_USED_MEM_CURRENT, - cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_USED_MEM_HIGH,): + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_USED_MEM_HIGH, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_MAX_POOL_SIZE,): return self._cuuint64_t_val + elif self._attr in (cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_ALLOCATION_TYPE, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_LOCATION_ID, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_LOCATION_TYPE, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_HW_DECOMPRESS_ENABLED, + cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_LOCALITY_DOMAIN_ID,): + return self._int_val + elif self._attr in (cydriver.CUmemPool_attribute_enum.CU_MEMPOOL_ATTR_EXPORT_HANDLE_TYPES,): + return self._uint_val else: raise TypeError('Unsupported attribute value: {}'.format(self._attr)) @@ -283,7 +303,11 @@ cdef class _HelperCUmem_range_attribute: self._attr = attr.value if self._attr in (cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_READ_MOSTLY, cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION, - cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION,): + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION, + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION_TYPE, + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION_ID, + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION_TYPE, + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION_ID,): self._cptr = &self._int_val elif self._attr in (cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_ACCESSED_BY,): self._cptr = _callocWrapper(1, self._data_size) @@ -302,7 +326,11 @@ cdef class _HelperCUmem_range_attribute: def pyObj(self): if self._attr in (cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_READ_MOSTLY, cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION, - cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION,): + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION, + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION_TYPE, + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION_ID, + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION_TYPE, + cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION_ID,): return self._int_val elif self._attr in (cydriver.CUmem_range_attribute_enum.CU_MEM_RANGE_ATTRIBUTE_ACCESSED_BY,): return [self._int_val_list[idx] for idx in range(int(self._data_size/4))] @@ -322,7 +350,6 @@ cdef class _HelperCUpointer_attribute: else: self._cptr = init_value.getPtr() elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MEMORY_TYPE, - cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES, cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_IS_GPU_DIRECT_RDMA_CAPABLE, cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_ACCESS_FLAGS,): self._uint = init_value @@ -338,7 +365,7 @@ cdef class _HelperCUpointer_attribute: else: self._cptr = init_value.getPtr() elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_HOST_POINTER,): - self._void = init_value + self._void = init_value self._cptr = &self._void elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_P2P_TOKENS,): if self._is_getter: @@ -352,10 +379,12 @@ cdef class _HelperCUpointer_attribute: cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MAPPED,): self._bool = init_value self._cptr = &self._bool - elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_BUFFER_ID,): + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_BUFFER_ID, + cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES,): self._ull = init_value self._cptr = &self._ull - elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_RANGE_SIZE,): + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_RANGE_SIZE, + cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MAPPING_SIZE,): self._size = init_value self._cptr = &self._size elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MEMPOOL_HANDLE,): @@ -364,6 +393,21 @@ cdef class _HelperCUpointer_attribute: self._cptr = self._mempool.getPtr() else: self._cptr = init_value.getPtr() + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MAPPING_BASE_ADDR,): + if self._is_getter: + self._devptr = _driver["CUdeviceptr"]() + self._cptr = self._devptr.getPtr() + else: + self._cptr = init_value.getPtr() + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MEMORY_BLOCK_ID,): + self._ull = init_value + self._cptr = &self._ull + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_IS_HW_DECOMPRESS_CAPABLE,): + self._bool = init_value + self._cptr = &self._bool + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_LOCALITY_DOMAIN_ORDINAL,): + self._int = init_value + self._cptr = &self._int else: raise TypeError('Unsupported attribute: {}'.format(attr.name)) @@ -379,11 +423,11 @@ cdef class _HelperCUpointer_attribute: if self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_CONTEXT,): return self._ctx elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MEMORY_TYPE, - cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL, - cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES, cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_IS_GPU_DIRECT_RDMA_CAPABLE, cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_ACCESS_FLAGS,): return self._uint + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL,): + return self._int elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_DEVICE_POINTER, cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_RANGE_START_ADDR,): return self._devptr @@ -396,12 +440,22 @@ cdef class _HelperCUpointer_attribute: cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_IS_LEGACY_CUDA_IPC_CAPABLE, cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MAPPED,): return self._bool - elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_BUFFER_ID,): + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_BUFFER_ID, + cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES,): return self._ull - elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_RANGE_SIZE,): + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_RANGE_SIZE, + cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MAPPING_SIZE,): return self._size elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MEMPOOL_HANDLE,): return self._mempool + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MAPPING_BASE_ADDR,): + return self._devptr + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_MEMORY_BLOCK_ID,): + return self._ull + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_IS_HW_DECOMPRESS_CAPABLE,): + return self._bool + elif self._attr in (cydriver.CUpointer_attribute_enum.CU_POINTER_ATTRIBUTE_LOCALITY_DOMAIN_ORDINAL,): + return self._int else: raise TypeError('Unsupported attribute value: {}'.format(self._attr)) @@ -455,12 +509,17 @@ cdef class _HelperCUjit_option: cydriver.CUjit_option_enum.CU_JIT_REFERENCED_KERNEL_COUNT, cydriver.CUjit_option_enum.CU_JIT_REFERENCED_VARIABLE_COUNT, cydriver.CUjit_option_enum.CU_JIT_MIN_CTA_PER_SM, - cydriver.CUjit_option_enum.CU_JIT_SPLIT_COMPILE,): + cydriver.CUjit_option_enum.CU_JIT_SPLIT_COMPILE, + cydriver.CUjit_option_enum.CU_JIT_BINARY_LOADER_THREAD_COUNT,): self._uint = init_value self._cptr = self._uint elif self._attr in (cydriver.CUjit_option_enum.CU_JIT_WALL_TIME,): self._float = init_value - self._cptr = self._float + # CU_JIT_WALL_TIME is an OUT option: CUDA writes the elapsed float + # back through the pointer. Use the address of _float so CUDA has + # valid storage to write into, rather than value-casting the float + # (which would produce a garbage address). + self._cptr = &self._float elif self._attr in (cydriver.CUjit_option_enum.CU_JIT_INFO_LOG_BUFFER, cydriver.CUjit_option_enum.CU_JIT_ERROR_LOG_BUFFER): self._charstar = init_value @@ -479,7 +538,10 @@ cdef class _HelperCUjit_option: cydriver.CUjit_option_enum.CU_JIT_PREC_DIV, cydriver.CUjit_option_enum.CU_JIT_PREC_SQRT, cydriver.CUjit_option_enum.CU_JIT_FMA, - cydriver.CUjit_option_enum.CU_JIT_OPTIMIZE_UNUSED_DEVICE_VARIABLES,): + cydriver.CUjit_option_enum.CU_JIT_OPTIMIZE_UNUSED_DEVICE_VARIABLES, + cydriver.CUjit_option_enum.CU_JIT_POSITION_INDEPENDENT_CODE, + cydriver.CUjit_option_enum.CU_JIT_MAX_THREADS_PER_BLOCK, + cydriver.CUjit_option_enum.CU_JIT_OVERRIDE_DIRECTIVE_VALUES,): self._int = init_value self._cptr = self._int elif self._attr in (cydriver.CUjit_option_enum.CU_JIT_CACHE_MODE,): @@ -520,7 +582,11 @@ cdef class _HelperCudaJitOption: self._cptr = self._uint elif self._attr in (cyruntime.cudaJitOption.cudaJitWallTime,): self._float = init_value - self._cptr = self._float + # cudaJitWallTime is an OUT option: CUDA writes the elapsed float + # back through the pointer. Use the address of _float so CUDA has + # valid storage to write into, rather than value-casting the float + # (which would produce a garbage address). + self._cptr = &self._float elif self._attr in (cyruntime.cudaJitOption.cudaJitInfoLogBuffer, cyruntime.cudaJitOption.cudaJitErrorLogBuffer): self._charstar = init_value @@ -751,7 +817,13 @@ cdef class _HelperCUcoredumpSettings: self._bool = init_value self._cptr = &self._bool - self._size = 1 + self._size = sizeof(cpp_bool) + elif self._attrib in (cydriver.CUcoredumpSettings_enum.CU_COREDUMP_GENERATION_FLAGS,): + if self._is_getter == False: + self._uint = init_value + + self._cptr = &self._uint + self._size = sizeof(unsigned int) else: raise TypeError('Unsupported attribute: {}'.format(attr.name)) @@ -779,5 +851,7 @@ cdef class _HelperCUcoredumpSettings: cydriver.CUcoredumpSettings_enum.CU_COREDUMP_LIGHTWEIGHT, cydriver.CUcoredumpSettings_enum.CU_COREDUMP_ENABLE_USER_TRIGGER,): return self._bool + elif self._attrib in (cydriver.CUcoredumpSettings_enum.CU_COREDUMP_GENERATION_FLAGS,): + return self._uint else: raise TypeError('Unsupported attribute value: {}'.format(self._attrib)) diff --git a/cuda_bindings/docs/nv-versions.json b/cuda_bindings/docs/nv-versions.json index 35dbae3d406..1f0a4d7483e 100644 --- a/cuda_bindings/docs/nv-versions.json +++ b/cuda_bindings/docs/nv-versions.json @@ -3,6 +3,10 @@ "version": "latest", "url": "https://nvidia.github.io/cuda-python/cuda-bindings/latest/" }, + { + "version": "13.4.3", + "url": "https://nvidia.github.io/cuda-python/cuda-bindings/13.4.3/" + }, { "version": "13.4.2", "url": "https://nvidia.github.io/cuda-python/cuda-bindings/13.4.2/" diff --git a/cuda_bindings/docs/source/release/12.9.9-notes.rst b/cuda_bindings/docs/source/release/12.9.9-notes.rst new file mode 100644 index 00000000000..3d369fc18fd --- /dev/null +++ b/cuda_bindings/docs/source/release/12.9.9-notes.rst @@ -0,0 +1,374 @@ +.. SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-License-Identifier: Apache-2.0 + +.. module:: cuda.bindings + +``cuda-bindings`` 12.9.9 Release notes +======================================= + + +Changes +------- + +- Many ``cuda.bindings.cudla`` and ``cuda.bindings.nvml`` enum members had a + redundant prefix stripped from their name, + e.g. ``nvml.BrandType.BRAND_GEFORCE`` is now ``nvml.BrandType.GEFORCE``. + The old, longer names remain available as backward-compatible aliases and + will continue to work. The full list of renames, excluding the 447 + similarly-renamed ``nvml.GpmMetricId`` members (which had their + ``GPM_METRIC_`` prefix stripped the same way), is below. + (`PR #2822 `_) + +.. csv-table:: Enum member renames (old names remain available as backward-compatible aliases) + :header: "Module", "Enum class", "New name", "Deprecated alias" + :widths: 10, 25, 25, 25 + + "cudla", "FenceType", "FENCE", "NVSCISYNC_FENCE" + "cudla", "FenceType", "FENCE_SOF", "NVSCISYNC_FENCE_SOF" + "cudla", "ModuleLoadFlags", "DEFAULT", "MODULE_DEFAULT" + "cudla", "ModuleLoadFlags", "ENABLE_FAULT_DIAGNOSTICS", "MODULE_ENABLE_FAULT_DIAGNOSTICS" + "cudla", "ScratchMemoryConfig", "CONFIG_MAX", "MAX" + "cudla", "ScratchMemoryConfig", "DEFAULT", "SCRATCH_MEMORY_DEFAULT" + "cudla", "ScratchMemoryConfig", "SHARED_STATIC", "SCRATCH_MEMORY_SHARED_STATIC" + "cudla", "SubmissionFlags", "DIAGNOSTICS_TASK", "SUBMIT_DIAGNOSTICS_TASK" + "cudla", "SubmissionFlags", "NOOP", "SUBMIT_NOOP" + "cudla", "SubmissionFlags", "SKIP_LOCK_ACQUIRE", "SUBMIT_SKIP_LOCK_ACQUIRE" + "nvml", "BrandType", "COUNT", "BRAND_COUNT" + "nvml", "BrandType", "GEFORCE", "BRAND_GEFORCE" + "nvml", "BrandType", "GEFORCE_RTX", "BRAND_GEFORCE_RTX" + "nvml", "BrandType", "GRID", "BRAND_GRID" + "nvml", "BrandType", "NVIDIA", "BRAND_NVIDIA" + "nvml", "BrandType", "NVIDIA_CLOUD_GAMING", "BRAND_NVIDIA_CLOUD_GAMING" + "nvml", "BrandType", "NVIDIA_DLA", "BRAND_NVIDIA_DLA" + "nvml", "BrandType", "NVIDIA_NPU", "BRAND_NVIDIA_NPU" + "nvml", "BrandType", "NVIDIA_RTX", "BRAND_NVIDIA_RTX" + "nvml", "BrandType", "NVIDIA_VAPPS", "BRAND_NVIDIA_VAPPS" + "nvml", "BrandType", "NVIDIA_VCS", "BRAND_NVIDIA_VCS" + "nvml", "BrandType", "NVIDIA_VGAMEDEV", "BRAND_NVIDIA_VGAMEDEV" + "nvml", "BrandType", "NVIDIA_VGAMING", "BRAND_NVIDIA_VGAMING" + "nvml", "BrandType", "NVIDIA_VPC", "BRAND_NVIDIA_VPC" + "nvml", "BrandType", "NVIDIA_VWS", "BRAND_NVIDIA_VWS" + "nvml", "BrandType", "NVS", "BRAND_NVS" + "nvml", "BrandType", "QUADRO", "BRAND_QUADRO" + "nvml", "BrandType", "QUADRO_RTX", "BRAND_QUADRO_RTX" + "nvml", "BrandType", "TESLA", "BRAND_TESLA" + "nvml", "BrandType", "TITAN", "BRAND_TITAN" + "nvml", "BrandType", "TITAN_RTX", "BRAND_TITAN_RTX" + "nvml", "BrandType", "UNKNOWN", "BRAND_UNKNOWN" + "nvml", "BridgeChipType", "BRO4", "BRIDGE_CHIP_BRO4" + "nvml", "BridgeChipType", "PLX", "BRIDGE_CHIP_PLX" + "nvml", "ClockType", "COUNT", "CLOCK_COUNT" + "nvml", "ClockType", "GRAPHICS", "CLOCK_GRAPHICS" + "nvml", "ClockType", "MEM", "CLOCK_MEM" + "nvml", "ClockType", "SM", "CLOCK_SM" + "nvml", "ClockType", "VIDEO", "CLOCK_VIDEO" + "nvml", "ComputeMode", "COUNT", "COMPUTEMODE_COUNT" + "nvml", "ComputeMode", "DEFAULT", "COMPUTEMODE_DEFAULT" + "nvml", "ComputeMode", "EXCLUSIVE_PROCESS", "COMPUTEMODE_EXCLUSIVE_PROCESS" + "nvml", "ComputeMode", "EXCLUSIVE_THREAD", "COMPUTEMODE_EXCLUSIVE_THREAD" + "nvml", "ComputeMode", "PROHIBITED", "COMPUTEMODE_PROHIBITED" + "nvml", "CoolerControl", "COUNT", "THERMAL_COOLER_SIGNAL_COUNT" + "nvml", "CoolerControl", "NONE", "THERMAL_COOLER_SIGNAL_NONE" + "nvml", "CoolerControl", "TOGGLE", "THERMAL_COOLER_SIGNAL_TOGGLE" + "nvml", "CoolerControl", "VARIABLE", "THERMAL_COOLER_SIGNAL_VARIABLE" + "nvml", "CoolerTarget", "GPU", "THERMAL_GPU" + "nvml", "CoolerTarget", "GPU_RELATED", "THERMAL_GPU_RELATED" + "nvml", "CoolerTarget", "MEMORY", "THERMAL_MEMORY" + "nvml", "CoolerTarget", "NONE", "THERMAL_NONE" + "nvml", "CoolerTarget", "POWER_SUPPLY", "THERMAL_POWER_SUPPLY" + "nvml", "DetachGpuState", "KEEP", "DETACH_GPU_KEEP" + "nvml", "DetachGpuState", "REMOVE", "DETACH_GPU_REMOVE" + "nvml", "DeviceAddressingModeType", "ATS", "DEVICE_ADDRESSING_MODE_ATS" + "nvml", "DeviceAddressingModeType", "HMM", "DEVICE_ADDRESSING_MODE_HMM" + "nvml", "DeviceAddressingModeType", "NONE", "DEVICE_ADDRESSING_MODE_NONE" + "nvml", "DeviceGpuRecoveryAction", "BUS_RESET", "GPU_RECOVERY_ACTION_BUS_RESET" + "nvml", "DeviceGpuRecoveryAction", "DRAIN_AND_RESET", "GPU_RECOVERY_ACTION_DRAIN_AND_RESET" + "nvml", "DeviceGpuRecoveryAction", "DRAIN_P2P", "GPU_RECOVERY_ACTION_DRAIN_P2P" + "nvml", "DeviceGpuRecoveryAction", "GPU_RESET", "GPU_RECOVERY_ACTION_GPU_RESET" + "nvml", "DeviceGpuRecoveryAction", "NODE_REBOOT", "GPU_RECOVERY_ACTION_NODE_REBOOT" + "nvml", "DeviceGpuRecoveryAction", "NONE", "GPU_RECOVERY_ACTION_NONE" + "nvml", "DeviceGpuRecoveryAction", "RECOVER_IMEX_DOMAIN", "GPU_RECOVERY_ACTION_RECOVER_IMEX_DOMAIN" + "nvml", "DeviceGpuRecoveryAction", "SYSTEM_REBOOT", "GPU_RECOVERY_ACTION_SYSTEM_REBOOT" + "nvml", "DeviceVgpuCapability", "COMPUTE_MEDIA_ENGINE_GPU", "DEVICE_VGPU_CAP_COMPUTE_MEDIA_ENGINE_GPU" + "nvml", "DeviceVgpuCapability", "COUNT", "DEVICE_VGPU_CAP_COUNT" + "nvml", "DeviceVgpuCapability", "DEVICE_STREAMING", "DEVICE_VGPU_CAP_DEVICE_STREAMING" + "nvml", "DeviceVgpuCapability", "FRACTIONAL_MULTI_VGPU", "DEVICE_VGPU_CAP_FRACTIONAL_MULTI_VGPU" + "nvml", "DeviceVgpuCapability", "HETEROGENEOUS_TIMESLICE_PROFILES", "DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_PROFILES" + "nvml", "DeviceVgpuCapability", "HETEROGENEOUS_TIMESLICE_SIZES", "DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_SIZES" + "nvml", "DeviceVgpuCapability", "HOMOGENEOUS_PLACEMENTS", "DEVICE_VGPU_CAP_HOMOGENEOUS_PLACEMENTS" + "nvml", "DeviceVgpuCapability", "MIG_TIMESLICING_ENABLED", "DEVICE_VGPU_CAP_MIG_TIMESLICING_ENABLED" + "nvml", "DeviceVgpuCapability", "MIG_TIMESLICING_SUPPORTED", "DEVICE_VGPU_CAP_MIG_TIMESLICING_SUPPORTED" + "nvml", "DeviceVgpuCapability", "MINI_QUARTER_GPU", "DEVICE_VGPU_CAP_MINI_QUARTER_GPU" + "nvml", "DeviceVgpuCapability", "READ_DEVICE_BUFFER_BW", "DEVICE_VGPU_CAP_READ_DEVICE_BUFFER_BW" + "nvml", "DeviceVgpuCapability", "WARM_UPDATE", "DEVICE_VGPU_CAP_WARM_UPDATE" + "nvml", "DeviceVgpuCapability", "WRITE_DEVICE_BUFFER_BW", "DEVICE_VGPU_CAP_WRITE_DEVICE_BUFFER_BW" + "nvml", "DriverModel", "MCDM", "DRIVER_MCDM" + "nvml", "DriverModel", "WDDM", "DRIVER_WDDM" + "nvml", "DriverModel", "WDM", "DRIVER_WDM" + "nvml", "EccCounterType", "ECC_COUNTER_TYPE_COUNT", "COUNT" + "nvml", "EnableState", "DISABLED", "FEATURE_DISABLED" + "nvml", "EnableState", "ENABLED", "FEATURE_ENABLED" + "nvml", "EncoderType", "AV1", "ENCODER_QUERY_AV1" + "nvml", "EncoderType", "H264", "ENCODER_QUERY_H264" + "nvml", "EncoderType", "HEVC", "ENCODER_QUERY_HEVC" + "nvml", "EncoderType", "UNKNOWN", "ENCODER_QUERY_UNKNOWN" + "nvml", "EventDataType", "NVML_EVENT", "EVENT" + "nvml", "FanState", "FAILED", "FAN_FAILED" + "nvml", "FanState", "NORMAL", "FAN_NORMAL" + "nvml", "GpuOperationMode", "ALL_ON", "GOM_ALL_ON" + "nvml", "GpuOperationMode", "COMPUTE", "GOM_COMPUTE" + "nvml", "GpuOperationMode", "LOW_DP", "GOM_LOW_DP" + "nvml", "GpuP2PCapsIndex", "ATOMICS", "P2P_CAPS_INDEX_ATOMICS" + "nvml", "GpuP2PCapsIndex", "NVLINK", "P2P_CAPS_INDEX_NVLINK" + "nvml", "GpuP2PCapsIndex", "PCI", "P2P_CAPS_INDEX_PCI" + "nvml", "GpuP2PCapsIndex", "PROP", "P2P_CAPS_INDEX_PROP" + "nvml", "GpuP2PCapsIndex", "READ", "P2P_CAPS_INDEX_READ" + "nvml", "GpuP2PCapsIndex", "UNKNOWN", "P2P_CAPS_INDEX_UNKNOWN" + "nvml", "GpuP2PCapsIndex", "WRITE", "P2P_CAPS_INDEX_WRITE" + "nvml", "GpuP2PStatus", "CHIPSET_NOT_SUPPORED", "P2P_STATUS_CHIPSET_NOT_SUPPORED" + "nvml", "GpuP2PStatus", "CHIPSET_NOT_SUPPORTED", "P2P_STATUS_CHIPSET_NOT_SUPPORTED" + "nvml", "GpuP2PStatus", "DISABLED_BY_REGKEY", "P2P_STATUS_DISABLED_BY_REGKEY" + "nvml", "GpuP2PStatus", "GPU_NOT_SUPPORTED", "P2P_STATUS_GPU_NOT_SUPPORTED" + "nvml", "GpuP2PStatus", "IOH_TOPOLOGY_NOT_SUPPORTED", "P2P_STATUS_IOH_TOPOLOGY_NOT_SUPPORTED" + "nvml", "GpuP2PStatus", "NOT_SUPPORTED", "P2P_STATUS_NOT_SUPPORTED" + "nvml", "GpuP2PStatus", "OK", "P2P_STATUS_OK" + "nvml", "GpuP2PStatus", "UNKNOWN", "P2P_STATUS_UNKNOWN" + "nvml", "GpuTopologyLevel", "HOSTBRIDGE", "TOPOLOGY_HOSTBRIDGE" + "nvml", "GpuTopologyLevel", "INTERNAL", "TOPOLOGY_INTERNAL" + "nvml", "GpuTopologyLevel", "MULTIPLE", "TOPOLOGY_MULTIPLE" + "nvml", "GpuTopologyLevel", "NODE", "TOPOLOGY_NODE" + "nvml", "GpuTopologyLevel", "SINGLE", "TOPOLOGY_SINGLE" + "nvml", "GpuTopologyLevel", "SYSTEM", "TOPOLOGY_SYSTEM" + "nvml", "GpuUtilizationDomainId", "BUS", "GPU_UTILIZATION_DOMAIN_BUS" + "nvml", "GpuUtilizationDomainId", "FB", "GPU_UTILIZATION_DOMAIN_FB" + "nvml", "GpuUtilizationDomainId", "GPU", "GPU_UTILIZATION_DOMAIN_GPU" + "nvml", "GpuUtilizationDomainId", "VID", "GPU_UTILIZATION_DOMAIN_VID" + "nvml", "InforomObject", "COUNT", "INFOROM_COUNT" + "nvml", "InforomObject", "DEN", "INFOROM_DEN" + "nvml", "InforomObject", "ECC", "INFOROM_ECC" + "nvml", "InforomObject", "OEM", "INFOROM_OEM" + "nvml", "InforomObject", "POWER", "INFOROM_POWER" + "nvml", "IntNvLinkDeviceType", "GPU", "NVLINK_DEVICE_TYPE_GPU" + "nvml", "IntNvLinkDeviceType", "IBMNPU", "NVLINK_DEVICE_TYPE_IBMNPU" + "nvml", "IntNvLinkDeviceType", "SWITCH", "NVLINK_DEVICE_TYPE_SWITCH" + "nvml", "IntNvLinkDeviceType", "UNKNOWN", "NVLINK_DEVICE_TYPE_UNKNOWN" + "nvml", "NvLinkCapability", "COUNT", "NVLINK_CAP_COUNT" + "nvml", "NvLinkCapability", "P2P_ATOMICS", "NVLINK_CAP_P2P_ATOMICS" + "nvml", "NvLinkCapability", "P2P_SUPPORTED", "NVLINK_CAP_P2P_SUPPORTED" + "nvml", "NvLinkCapability", "SLI_BRIDGE", "NVLINK_CAP_SLI_BRIDGE" + "nvml", "NvLinkCapability", "SYSMEM_ACCESS", "NVLINK_CAP_SYSMEM_ACCESS" + "nvml", "NvLinkCapability", "SYSMEM_ATOMICS", "NVLINK_CAP_SYSMEM_ATOMICS" + "nvml", "NvLinkCapability", "VALID", "NVLINK_CAP_VALID" + "nvml", "NvLinkErrorCounter", "COUNT", "NVLINK_ERROR_COUNT" + "nvml", "NvLinkErrorCounter", "DL_CRC_DATA", "NVLINK_ERROR_DL_CRC_DATA" + "nvml", "NvLinkErrorCounter", "DL_CRC_FLIT", "NVLINK_ERROR_DL_CRC_FLIT" + "nvml", "NvLinkErrorCounter", "DL_ECC_DATA", "NVLINK_ERROR_DL_ECC_DATA" + "nvml", "NvLinkErrorCounter", "DL_RECOVERY", "NVLINK_ERROR_DL_RECOVERY" + "nvml", "NvLinkErrorCounter", "DL_REPLAY", "NVLINK_ERROR_DL_REPLAY" + "nvml", "NvLinkUtilizationCountPktTypes", "ALL", "NVLINK_COUNTER_PKTFILTER_ALL" + "nvml", "NvLinkUtilizationCountPktTypes", "FLUSH", "NVLINK_COUNTER_PKTFILTER_FLUSH" + "nvml", "NvLinkUtilizationCountPktTypes", "NOP", "NVLINK_COUNTER_PKTFILTER_NOP" + "nvml", "NvLinkUtilizationCountPktTypes", "NRATOM", "NVLINK_COUNTER_PKTFILTER_NRATOM" + "nvml", "NvLinkUtilizationCountPktTypes", "RATOM", "NVLINK_COUNTER_PKTFILTER_RATOM" + "nvml", "NvLinkUtilizationCountPktTypes", "READ", "NVLINK_COUNTER_PKTFILTER_READ" + "nvml", "NvLinkUtilizationCountPktTypes", "RESPDATA", "NVLINK_COUNTER_PKTFILTER_RESPDATA" + "nvml", "NvLinkUtilizationCountPktTypes", "RESPNODATA", "NVLINK_COUNTER_PKTFILTER_RESPNODATA" + "nvml", "NvLinkUtilizationCountPktTypes", "WRITE", "NVLINK_COUNTER_PKTFILTER_WRITE" + "nvml", "NvLinkUtilizationCountUnits", "BYTES", "NVLINK_COUNTER_UNIT_BYTES" + "nvml", "NvLinkUtilizationCountUnits", "COUNT", "NVLINK_COUNTER_UNIT_COUNT" + "nvml", "NvLinkUtilizationCountUnits", "CYCLES", "NVLINK_COUNTER_UNIT_CYCLES" + "nvml", "NvLinkUtilizationCountUnits", "PACKETS", "NVLINK_COUNTER_UNIT_PACKETS" + "nvml", "NvLinkUtilizationCountUnits", "RESERVED", "NVLINK_COUNTER_UNIT_RESERVED" + "nvml", "NvlinkVersion", "NVLINK_VERSION_1_0", "VERSION_1_0" + "nvml", "NvlinkVersion", "NVLINK_VERSION_2_0", "VERSION_2_0" + "nvml", "NvlinkVersion", "NVLINK_VERSION_2_2", "VERSION_2_2" + "nvml", "NvlinkVersion", "NVLINK_VERSION_3_0", "VERSION_3_0" + "nvml", "NvlinkVersion", "NVLINK_VERSION_3_1", "VERSION_3_1" + "nvml", "NvlinkVersion", "NVLINK_VERSION_4_0", "VERSION_4_0" + "nvml", "NvlinkVersion", "NVLINK_VERSION_5_0", "VERSION_5_0" + "nvml", "NvlinkVersion", "NVLINK_VERSION_6_0", "VERSION_6_0" + "nvml", "NvlinkVersion", "NVLINK_VERSION_INVALID", "VERSION_INVALID" + "nvml", "PcieLinkState", "KEEP", "PCIE_LINK_KEEP" + "nvml", "PcieLinkState", "SHUT_DOWN", "PCIE_LINK_SHUT_DOWN" + "nvml", "PcieUtilCounter", "COUNT", "PCIE_UTIL_COUNT" + "nvml", "PcieUtilCounter", "RX_BYTES", "PCIE_UTIL_RX_BYTES" + "nvml", "PcieUtilCounter", "TX_BYTES", "PCIE_UTIL_TX_BYTES" + "nvml", "PerfPolicyType", "BOARD_LIMIT", "PERF_POLICY_BOARD_LIMIT" + "nvml", "PerfPolicyType", "COUNT", "PERF_POLICY_COUNT" + "nvml", "PerfPolicyType", "LOW_UTILIZATION", "PERF_POLICY_LOW_UTILIZATION" + "nvml", "PerfPolicyType", "POWER", "PERF_POLICY_POWER" + "nvml", "PerfPolicyType", "RELIABILITY", "PERF_POLICY_RELIABILITY" + "nvml", "PerfPolicyType", "SYNC_BOOST", "PERF_POLICY_SYNC_BOOST" + "nvml", "PerfPolicyType", "THERMAL", "PERF_POLICY_THERMAL" + "nvml", "PerfPolicyType", "TOTAL_APP_CLOCKS", "PERF_POLICY_TOTAL_APP_CLOCKS" + "nvml", "PerfPolicyType", "TOTAL_BASE_CLOCKS", "PERF_POLICY_TOTAL_BASE_CLOCKS" + "nvml", "PowerProfileType", "BALANCED", "POWER_PROFILE_BALANCED" + "nvml", "PowerProfileType", "COMPUTE", "POWER_PROFILE_COMPUTE" + "nvml", "PowerProfileType", "DCPCIE", "POWER_PROFILE_DCPCIE" + "nvml", "PowerProfileType", "HIGH_THROUGHPUT_INFERENCE", "POWER_PROFILE_HIGH_THROUGHPUT_INFERENCE" + "nvml", "PowerProfileType", "HMMA_DENSE", "POWER_PROFILE_HMMA_DENSE" + "nvml", "PowerProfileType", "HMMA_SPARSE", "POWER_PROFILE_HMMA_SPARSE" + "nvml", "PowerProfileType", "HPC", "POWER_PROFILE_HPC" + "nvml", "PowerProfileType", "INFERENCE", "POWER_PROFILE_INFERENCE" + "nvml", "PowerProfileType", "LLM_INFERENCE", "POWER_PROFILE_LLM_INFERENCE" + "nvml", "PowerProfileType", "LLM_TRAINING", "POWER_PROFILE_LLM_TRAINING" + "nvml", "PowerProfileType", "LOW_LATENCY_INFERENCE", "POWER_PROFILE_LOW_LATENCY_INFERENCE" + "nvml", "PowerProfileType", "LOW_PRIORITY_BACKGROUND", "POWER_PROFILE_LOW_PRIORITY_BACKGROUND" + "nvml", "PowerProfileType", "MAX", "POWER_PROFILE_MAX" + "nvml", "PowerProfileType", "MAX_P", "POWER_PROFILE_MAX_P" + "nvml", "PowerProfileType", "MAX_Q", "POWER_PROFILE_MAX_Q" + "nvml", "PowerProfileType", "MAX_Q_1", "POWER_PROFILE_MAX_Q_1" + "nvml", "PowerProfileType", "MAX_Q_2", "POWER_PROFILE_MAX_Q_2" + "nvml", "PowerProfileType", "MAX_Q_3", "POWER_PROFILE_MAX_Q_3" + "nvml", "PowerProfileType", "MEDIUM_THROUGHPUT_INFERENCE", "POWER_PROFILE_MEDIUM_THROUGHPUT_INFERENCE" + "nvml", "PowerProfileType", "MEMORY_BOUND", "POWER_PROFILE_MEMORY_BOUND" + "nvml", "PowerProfileType", "MIG", "POWER_PROFILE_MIG" + "nvml", "PowerProfileType", "NETWORK", "POWER_PROFILE_NETWORK" + "nvml", "PowerProfileType", "NETWORK_BOUND", "POWER_PROFILE_NETWORK_BOUND" + "nvml", "PowerProfileType", "RBM", "POWER_PROFILE_RBM" + "nvml", "PowerProfileType", "SYNC_BALANCED", "POWER_PROFILE_SYNC_BALANCED" + "nvml", "PowerProfileType", "TRAINING", "POWER_PROFILE_TRAINING" + "nvml", "TemperatureSensors", "COUNT", "TEMPERATURE_COUNT" + "nvml", "TemperatureSensors", "GPU", "TEMPERATURE_GPU" + "nvml", "TemperatureSensors", "GPU_MAX", "TEMPERATURE_GPU_MAX" + "nvml", "TemperatureThresholds", "ACOUSTIC_CURR", "TEMPERATURE_THRESHOLD_ACOUSTIC_CURR" + "nvml", "TemperatureThresholds", "ACOUSTIC_MAX", "TEMPERATURE_THRESHOLD_ACOUSTIC_MAX" + "nvml", "TemperatureThresholds", "ACOUSTIC_MIN", "TEMPERATURE_THRESHOLD_ACOUSTIC_MIN" + "nvml", "TemperatureThresholds", "COUNT", "TEMPERATURE_THRESHOLD_COUNT" + "nvml", "TemperatureThresholds", "GPS_CURR", "TEMPERATURE_THRESHOLD_GPS_CURR" + "nvml", "TemperatureThresholds", "GPU_MAX", "TEMPERATURE_THRESHOLD_GPU_MAX" + "nvml", "TemperatureThresholds", "MEM_MAX", "TEMPERATURE_THRESHOLD_MEM_MAX" + "nvml", "TemperatureThresholds", "SHUTDOWN", "TEMPERATURE_THRESHOLD_SHUTDOWN" + "nvml", "TemperatureThresholds", "SLOWDOWN", "TEMPERATURE_THRESHOLD_SLOWDOWN" + "nvml", "VgpuCapability", "COUNT", "VGPU_CAP_COUNT" + "nvml", "VgpuCapability", "EXCLUSIVE_SIZE", "VGPU_CAP_EXCLUSIVE_SIZE" + "nvml", "VgpuCapability", "EXCLUSIVE_TYPE", "VGPU_CAP_EXCLUSIVE_TYPE" + "nvml", "VgpuCapability", "GPUDIRECT", "VGPU_CAP_GPUDIRECT" + "nvml", "VgpuCapability", "MULTI_VGPU_EXCLUSIVE", "VGPU_CAP_MULTI_VGPU_EXCLUSIVE" + "nvml", "VgpuCapability", "NVLINK_P2P", "VGPU_CAP_NVLINK_P2P" + "nvml", "VgpuDriverCapability", "COUNT", "VGPU_DRIVER_CAP_COUNT" + "nvml", "VgpuDriverCapability", "HETEROGENEOUS_MULTI_VGPU", "VGPU_DRIVER_CAP_HETEROGENEOUS_MULTI_VGPU" + "nvml", "VgpuDriverCapability", "WARM_UPDATE", "VGPU_DRIVER_CAP_WARM_UPDATE" + "nvml", "VgpuGuestInfoState", "INITIALIZED", "VGPU_INSTANCE_GUEST_INFO_STATE_INITIALIZED" + "nvml", "VgpuGuestInfoState", "UNINITIALIZED", "VGPU_INSTANCE_GUEST_INFO_STATE_UNINITIALIZED" + "nvml", "VgpuPgpuCompatibilityLimitCode", "GPU", "VGPU_COMPATIBILITY_LIMIT_GPU" + "nvml", "VgpuPgpuCompatibilityLimitCode", "GUEST_DRIVER", "VGPU_COMPATIBILITY_LIMIT_GUEST_DRIVER" + "nvml", "VgpuPgpuCompatibilityLimitCode", "HOST_DRIVER", "VGPU_COMPATIBILITY_LIMIT_HOST_DRIVER" + "nvml", "VgpuPgpuCompatibilityLimitCode", "NONE", "VGPU_COMPATIBILITY_LIMIT_NONE" + "nvml", "VgpuPgpuCompatibilityLimitCode", "OTHER", "VGPU_COMPATIBILITY_LIMIT_OTHER" + "nvml", "VgpuVmIdType", "DOMAIN_ID", "VGPU_VM_ID_DOMAIN_ID" + "nvml", "VgpuVmIdType", "UUID", "VGPU_VM_ID_UUID" + +- ``nvml.device_get_samples``: On a zero-sample result, the old implementation + returned a bare ``Sample`` instance instead of the documented + ``(sample_val_type, samples)`` tuple. It now always returns the correct 2-tuple. + (`PR #2862 `_) + +- ``nvml.device_get_supported_vgpus``, ``nvml.device_get_creatable_vgpus``, + ``nvml.device_get_active_vgpus``: The old implementations would return a + ``NameError`` at runtime whenever there was at least one result to return. Now + fixed. + (`PR #2862 `_) + +- ``nvml.device_get_gpu_instances``, + ``nvml.gpu_instance_get_compute_instances``: The old implementations would fail + with ``ValueError: Invalid shape in axis 0: 0`` whenever the result is empty. + Now correctly returns an empty array in that case. + (`PR #2862 `_) + +- ``nvml.device_get_vgpu_utilization``: The old implementation would only fill + in the first element of the returned array; the rest was uninitialized + garbage. It is now correctly returned as a properly-sized array. In addition, + the first element of the returned tuple, ``sample_val_type``, is now a plain + ``int`` rather than a length-1 array, since it is a single output parameter, + not a per-sample value. + (`PR #2862 `_) + +- ``nvml.device_get_vgpu_process_utilization``: The old implementation returned + a tuple ``(sample_count, samples)``, and the ``samples`` array only ever + contained one element. It is now correctly returned as a properly-sized array + (and the redundant ``sample_count`` — which was only ever the array's own size — + is no longer part of the returned value; use ``len(result)`` instead). + (`PR #2862 `_) + +Enhancements +------------ + +- ``cuda-bindings`` docstrings now include the full documentation from the + upstream CTK, not just the first paragraph. + (`PR #2816 `_) +- The following functions now accept ``None`` for their buffer-like pointer + argument (an integer address or an object supporting the buffer protocol), + which is treated as ``NULL``. + (`PR #2818 `_) + + - ``cudla.module_load_from_memory`` (``p_module``) + - ``nvfatbin.add_cubin``, ``nvfatbin.add_index``, ``nvfatbin.add_ltoir``, ``nvfatbin.add_ptx``, ``nvfatbin.add_reloc``, ``nvfatbin.add_tile_ir`` (``code``) + - ``nvfatbin.get`` (``buffer``) + - ``nvjitlink.add_data`` (``data``) + - ``nvjitlink.get_error_log``, ``nvjitlink.get_info_log`` (``log``) + - ``nvjitlink.get_linked_cubin`` (``cubin``) + - ``nvjitlink.get_linked_ltoir`` (``ltoir``) + - ``nvjitlink.get_linked_ptx`` (``ptx``) + - ``nvvm.add_module_to_program``, ``nvvm.lazy_add_module_to_program``, ``nvvm.get_compiled_result``, ``nvvm.get_program_log`` (``buffer``) + +- For all ``cuda-bindings`` APIs, functions that accept a struct wrapper will + accept the struct wrapper directly, rather than requiring getting the + ``.ptr`` property. + (`PR #2819 `_) +- Creating class instances in ``cuda-bindings`` should now be faster in most + cases, because it requires 1 heap allocation rather than 2. + (`PR #2821 `_) + +Behavior changes +---------------- + +- Passing a ``None`` to ``nvvm.add_module_to_program`` or + ``nvvm.lazy_add_module_to_program`` will now raise a ``nvvm.nvvmError`` + (``INVALID_INPUT``) rather than a ``ValueError``. + (`PR #2818 `_) + +Bugfixes +-------- + +- A number of incorrect docstrings have been corrected. + (`PR #2820 `_) +- Setting a ``cuda_bindings`` class instance to itself + (``obj = cuda_bindings.driver.Class(); obj[0] = obj``) will no longer crash + or use garbage values. + (`PR #2821 `_) +- Fixed a potential use-after-free error in the destructors of classes in + ``driver``. + (`PR #2874 `_) +- Fixed readonly correctness in ``__setitem__`` for generated struct wrapper + classes in ``cudla``, ``cufile``, and ``nvml``. + (`PR #2875 `_) +- Fixed the internal result storage and Python conversion for several + ``CUpointer_attribute`` and ``CUcoredumpSettings`` result types: + ``CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL`` is now returned from signed integer + storage so negative CUDA device sentinels are preserved, + ``CU_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES`` is stored in its 64-bit + unsigned slot instead of being truncated to 32 bits, + ``CU_POINTER_ATTRIBUTE_HOST_POINTER`` uses a ``void *`` result slot, and the + boolean coredump attributes use a one-byte ``bool`` matching the driver ABI. + (`PR #2930 `_) +- Fixed ``CU_JIT_WALL_TIME`` and ``cudaJitWallTime`` OUT slots: the pointer + passed to the driver is now the address of the float storage cell instead + of the float bit-pattern value-cast to a pointer, which previously produced + a garbage address that could crash or corrupt memory when CUDA wrote back + the elapsed time. + (`PR #2934 `_) +- Added missing helper branches for ``CUpointer_attribute``, + ``CUmem_range_attribute``, ``CUjit_option`` and ``CUcoredumpSettings`` + enumerators that previously raised ``TypeError`` at construction time. + (`PR #2934 `_) +- Added missing ``getDescInfo`` arms for the + ``{Signed,Unsigned}Normalized{8,16}X{1,2,4}`` channel-format kinds, which + previously returned ``cudaErrorInvalidChannelDescriptor``. + (`PR #2934 `_) + +Known issues +------------ + +* Updating from older versions (v12.6.2.post1 and below) via ``pip install -U cuda-python`` might not work. Please do a clean re-installation by uninstalling ``pip uninstall -y cuda-python`` followed by installing ``pip install cuda-python``. +* ``nvml.system_get_process_name`` on WSL can return incorrect values. To work around this, set the locale to "C" before calling ``nvml.device_get_compute_running_processes_v3`` (which sets the process names) and before calling ``nvml.system_get_process_name``. ``cuda_core`` does this automatically, but users of the raw NVML API will need to do this manually. diff --git a/cuda_bindings/docs/source/release/13.4.3-notes.rst b/cuda_bindings/docs/source/release/13.4.3-notes.rst new file mode 100644 index 00000000000..d7b84b02456 --- /dev/null +++ b/cuda_bindings/docs/source/release/13.4.3-notes.rst @@ -0,0 +1,42 @@ +.. SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-License-Identifier: Apache-2.0 + +.. module:: cuda.bindings + +``cuda-bindings`` 13.4.3 Release notes +====================================== + +Bugfixes +-------- + +* Fixed the internal result storage and Python conversion for several + ``CUpointer_attribute`` and ``CUcoredumpSettings`` result types: + ``CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL`` is now returned from signed integer + storage so negative CUDA device sentinels are preserved, + ``CU_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES`` is stored in its 64-bit unsigned + slot instead of being truncated to 32 bits, + ``CU_POINTER_ATTRIBUTE_HOST_POINTER`` uses a ``void *`` result slot, and the + boolean coredump attributes use a one-byte ``bool`` matching the driver ABI. + (`PR #2929 `_) +* Fixed ``CU_JIT_WALL_TIME`` and ``cudaJitWallTime`` OUT slots: the pointer + passed to the driver is now the address of the float storage cell instead + of the float bit-pattern value-cast to a pointer, which previously produced + a garbage address that could crash or corrupt memory when CUDA wrote back + the elapsed time. + (`PR #2931 `_) +* Added missing helper branches for ``CUpointer_attribute``, + ``CUmemPool_attribute``, ``CUmem_range_attribute``, ``CUjit_option`` and + ``CUcoredumpSettings`` enumerators that previously raised ``TypeError`` at + construction time. + (`PR #2931 `_) +* Added missing ``getDescInfo`` and ``getChannelFormatDescFromDriverDesc`` + arms for the ``{Signed,Unsigned}Normalized{8,16}X{1,2,4}`` channel kinds + and for the CUDA 13.3 / 13.4 packed and multi-planar YUV channel kinds, + which previously returned ``cudaErrorInvalidChannelDescriptor``. + (`PR #2931 `_) + +Known issues +------------ + +* Updating from older versions (v12.6.2.post1 and below) via ``pip install -U cuda-python`` might not work. Please do a clean re-installation by uninstalling ``pip uninstall -y cuda-python`` followed by installing ``pip install cuda-python``. +* ``nvml.system_get_process_name`` on WSL can return incorrect values. To work around this, set the locale to "C" before calling ``nvml.device_get_compute_running_processes_v3`` (which sets the process names) and before calling ``nvml.system_get_process_name``. ``cuda_core`` does this automatically, but users of the raw NVML API will need to do this manually. diff --git a/cuda_bindings/tests/test_cuda.py b/cuda_bindings/tests/test_cuda.py index 45e3fac67ab..80ac5da0fd0 100644 --- a/cuda_bindings/tests/test_cuda.py +++ b/cuda_bindings/tests/test_cuda.py @@ -377,12 +377,23 @@ def test_pointer_get_attributes_device_ordinal(): cuda.CUpointer_attribute.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL, ] - attrs = cuda.cuPointerGetAttributes(len(attributes), attributes, 0) + err, attrs = cuda.cuPointerGetAttributes(len(attributes), attributes, 0) - # device ordinals are always small numbers. A large number would indicate - # an overflow error. + assert err == cuda.CUresult.CUDA_SUCCESS + # Drivers use either negative sentinel for a null pointer. Both ensure the + # signed device ordinal is returned rather than an unsigned value. + assert attrs[0] in (cuda.CU_DEVICE_CPU, cuda.CU_DEVICE_INVALID) + + +@pytest.mark.agent_authored(model="gpt-5.6-sol") +def test_pointer_allowed_handle_types_preserves_64_bits(): + helper = cuda._HelperCUpointer_attribute( + cuda.CUpointer_attribute.CU_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES, 0, is_getter=True + ) + expected = 1 << 40 + ctypes.c_uint64.from_address(helper.cptr).value = expected - assert abs(attrs[1][0]) < 256 + assert helper.pyObj() == expected @pytest.mark.skipif(not supportsManagedMemory(), reason="When new attributes were introduced") @@ -544,6 +555,120 @@ def test_cuda_coredump_attr(): assert attr_list[3] is True +@pytest.mark.agent_authored(model="gpt-5.6-sol") +def test_coredump_bool_uses_single_byte_storage(): + helper = cuda._HelperCUcoredumpSettings(cuda.CUcoredumpSettings.CU_COREDUMP_TRIGGER_HOST, 0, is_getter=True) + ctypes.c_uint32.from_address(helper.cptr).value = 0xFFFFFFFF + ctypes.c_uint8.from_address(helper.cptr).value = 0 + + assert helper.size() == ctypes.sizeof(ctypes.c_bool) + assert helper.pyObj() is False + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_coverage_new_pointer_attributes(): + """Smoke-test that every newly added CUpointer_attribute branch can be + constructed without raising TypeError.""" + new_attrs = [ + cuda.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MAPPING_SIZE, + cuda.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MEMORY_BLOCK_ID, + cuda.CUpointer_attribute.CU_POINTER_ATTRIBUTE_IS_HW_DECOMPRESS_CAPABLE, + cuda.CUpointer_attribute.CU_POINTER_ATTRIBUTE_LOCALITY_DOMAIN_ORDINAL, + ] + for attr in new_attrs: + helper = cuda._HelperCUpointer_attribute(attr, 0, is_getter=True) + assert helper.cptr != 0 + _ = helper.pyObj() + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_coverage_mapping_base_addr(): + """CU_POINTER_ATTRIBUTE_MAPPING_BASE_ADDR uses the CUdeviceptr getter path.""" + helper = cuda._HelperCUpointer_attribute( + cuda.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MAPPING_BASE_ADDR, 0, is_getter=True + ) + assert helper.cptr != 0 + _ = helper.pyObj() + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_coverage_new_mempool_attributes(): + """Smoke-test all newly added CUmemPool_attribute branches.""" + int_attrs = [ + cuda.CUmemPool_attribute.CU_MEMPOOL_ATTR_ALLOCATION_TYPE, + cuda.CUmemPool_attribute.CU_MEMPOOL_ATTR_LOCATION_ID, + cuda.CUmemPool_attribute.CU_MEMPOOL_ATTR_LOCATION_TYPE, + cuda.CUmemPool_attribute.CU_MEMPOOL_ATTR_HW_DECOMPRESS_ENABLED, + cuda.CUmemPool_attribute.CU_MEMPOOL_ATTR_LOCALITY_DOMAIN_ID, + ] + for attr in int_attrs: + helper = cuda._HelperCUmemPool_attribute(attr, 0, is_getter=True) + assert helper.cptr != 0 + assert helper.pyObj() == 0 + + uint_attr = cuda.CUmemPool_attribute.CU_MEMPOOL_ATTR_EXPORT_HANDLE_TYPES + helper = cuda._HelperCUmemPool_attribute(uint_attr, 0, is_getter=True) + assert helper.cptr != 0 + assert helper.pyObj() == 0 + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_coverage_new_mem_range_attributes(): + """Smoke-test all newly added CUmem_range_attribute branches (scalar int).""" + new_attrs = [ + cuda.CUmem_range_attribute.CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION_TYPE, + cuda.CUmem_range_attribute.CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION_ID, + cuda.CUmem_range_attribute.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION_TYPE, + cuda.CUmem_range_attribute.CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION_ID, + ] + for attr in new_attrs: + helper = cuda._HelperCUmem_range_attribute(attr, 4) + assert helper.cptr != 0 + assert helper.pyObj() == 0 + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_coverage_jit_option_new_int_attrs(): + """Newly added int-type CUjit_option branches should construct without TypeError. + + These options use the value-cast pattern: the int value is encoded directly + in the void* slot (cptr == NULL when value is 0, which is expected). + """ + new_int_attrs = [ + cuda.CUjit_option.CU_JIT_POSITION_INDEPENDENT_CODE, + cuda.CUjit_option.CU_JIT_MAX_THREADS_PER_BLOCK, + cuda.CUjit_option.CU_JIT_OVERRIDE_DIRECTIVE_VALUES, + ] + for attr in new_int_attrs: + helper = cuda._HelperCUjit_option(attr, 1) + assert helper.cptr == 1 # value is encoded as pointer + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_coverage_jit_option_binary_loader_thread_count(): + """CU_JIT_BINARY_LOADER_THREAD_COUNT is unsigned int, value-cast like other uint options.""" + helper = cuda._HelperCUjit_option(cuda.CUjit_option.CU_JIT_BINARY_LOADER_THREAD_COUNT, 4) + assert helper.cptr != 0 + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_coverage_jit_wall_time_pointer_is_valid(): + """CU_JIT_WALL_TIME must give CUDA a valid writable float address, not a garbage pointer.""" + helper = cuda._HelperCUjit_option(cuda.CUjit_option.CU_JIT_WALL_TIME, 0.0) + # Write a sentinel float via ctypes to confirm the pointer is addressable. + ctypes.c_float.from_address(helper.cptr).value = 3.14 + assert ctypes.c_float.from_address(helper.cptr).value == pytest.approx(3.14, rel=1e-5) + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_coverage_coredump_generation_flags(): + """CU_COREDUMP_GENERATION_FLAGS is an unsigned int bitmask.""" + helper = cuda._HelperCUcoredumpSettings(cuda.CUcoredumpSettings.CU_COREDUMP_GENERATION_FLAGS, 0, is_getter=True) + assert helper.size() == ctypes.sizeof(ctypes.c_uint) + ctypes.c_uint.from_address(helper.cptr).value = 0xDEAD + assert helper.pyObj() == 0xDEAD + + def test_get_error_name_and_string(): err, device = cuda.cuDeviceGet(0) _, s = cuda.cuGetErrorString(err) diff --git a/cuda_bindings/tests/test_cudart.py b/cuda_bindings/tests/test_cudart.py index 53702280679..b4ac2142f35 100644 --- a/cuda_bindings/tests/test_cudart.py +++ b/cuda_bindings/tests/test_cudart.py @@ -1985,3 +1985,65 @@ def test_cudaGraphConditionalHandleCreate_v2(): (err,) = cudart.cudaGraphDestroy(graph) assertSuccess(err) + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_phase2_normalized_channel_kinds_round_trip(): + """Normalized 8/16-bit channel kinds passed validity but hit the else-branch + in the case_desc chain and returned cudaErrorInvalidChannelDescriptor. + Verify they no longer error at the binding layer (CUDA may still reject + the format on a given device, which is fine).""" + pairs = [ + (8, 0, 0, 0, cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized8X1), + (8, 8, 0, 0, cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized8X2), + (8, 8, 8, 8, cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized8X4), + (8, 0, 0, 0, cudart.cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized8X1), + (8, 8, 0, 0, cudart.cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized8X2), + (8, 8, 8, 8, cudart.cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized8X4), + (16, 0, 0, 0, cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized16X1), + (16, 16, 0, 0, cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized16X2), + (16, 16, 16, 16, cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsignedNormalized16X4), + (16, 0, 0, 0, cudart.cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized16X1), + (16, 16, 0, 0, cudart.cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized16X2), + (16, 16, 16, 16, cudart.cudaChannelFormatKind.cudaChannelFormatKindSignedNormalized16X4), + ] + for x, y, z, w, kind in pairs: + desc = cudart.cudaChannelFormatDesc() + desc.x, desc.y, desc.z, desc.w, desc.f = x, y, z, w, kind + assert desc.f == kind + assert desc.x == x + + +@pytest.mark.agent_authored(model="claude-sonnet-4-6") +def test_ffi_phase2_new_yuv_channel_kinds_descriptor_construction(): + """CUDA 13.3/13.4 packed and multi-planar YUV kinds can be placed in a + cudaChannelFormatDesc without raising a Python exception. Whether CUDA's + runtime accepts the descriptor for a given operation (e.g. cudaMallocArray) + is hardware-dependent and is not asserted here — getDescInfo is only called + from the EGL frame conversion path, not from cudaMallocArray.""" + three_ch_8 = [ + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar420, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar422, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned8SemiPlanar444, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar420, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar422, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Planar444, + ] + three_ch_16 = [ + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar420, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar422, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned16SemiPlanar444, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar420, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar422, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned16Planar444, + ] + four_ch_8 = [ + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Packed422, + cudart.cudaChannelFormatKind.cudaChannelFormatKindUnsigned8Packed444, + ] + for bits, w_bit, kinds in ((8, 0, three_ch_8), (16, 0, three_ch_16), (8, 8, four_ch_8)): + for kind in kinds: + desc = cudart.cudaChannelFormatDesc() + desc.x, desc.y, desc.z, desc.w, desc.f = bits, bits, bits, w_bit, kind + assert desc.f == kind + assert desc.x == bits diff --git a/cuda_python/docs/nv-versions.json b/cuda_python/docs/nv-versions.json index 1736a810ca3..c09a80d1aea 100644 --- a/cuda_python/docs/nv-versions.json +++ b/cuda_python/docs/nv-versions.json @@ -3,6 +3,10 @@ "version": "latest", "url": "https://nvidia.github.io/cuda-python/latest/" }, + { + "version": "13.4.3", + "url": "https://nvidia.github.io/cuda-python/13.4.3/" + }, { "version": "13.4.2", "url": "https://nvidia.github.io/cuda-python/13.4.2/"