From aeef8df172c46ea40df6fcc46aa68c6442f2342b Mon Sep 17 00:00:00 2001 From: Jinfeng Date: Fri, 2 Oct 2026 06:54:20 +0000 Subject: [PATCH 1/3] rebase and regenerate --- .../cuda/bindings/_internal/driver_linux.pyx | 12 ++++++------ .../cuda/bindings/_internal/driver_windows.pyx | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cuda_bindings/cuda/bindings/_internal/driver_linux.pyx b/cuda_bindings/cuda/bindings/_internal/driver_linux.pyx index 6fc1ca20c77..59d14f75b9e 100644 --- a/cuda_bindings/cuda/bindings/_internal/driver_linux.pyx +++ b/cuda_bindings/cuda/bindings/_internal/driver_linux.pyx @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 # # This code was automatically generated across versions from 12.9.0 to 13.4.1. Do not modify it directly. -# CYTHON-BINDINGS-GENERATED-DO-NOT-MODIFY-THIS-FILE: format=1; content-sha256=f23c5b6833163c19813f5a513216d2a4192b545a5ae8a47ffe7c95ebbc9bdbaf +# CYTHON-BINDINGS-GENERATED-DO-NOT-MODIFY-THIS-FILE: format=1; content-sha256=c6a477ceb1a35675c0ffe5e40f9826ea3e3bd9cbec23720f78fe4cf28feafbe0 # <<<< PREAMBLE CONTENT >>>> @@ -1896,19 +1896,19 @@ cdef int _init_driver() except -1 nogil: cuGetProcAddress_v2('cuGreenCtxStreamCreate', &__cuGreenCtxStreamCreate, 12050, ptds_mode, NULL) global __cuLogsRegisterCallback - cuGetProcAddress_v2('cuLogsRegisterCallback', &__cuLogsRegisterCallback, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsRegisterCallback', &__cuLogsRegisterCallback, 12090, ptds_mode, NULL) global __cuLogsUnregisterCallback - cuGetProcAddress_v2('cuLogsUnregisterCallback', &__cuLogsUnregisterCallback, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsUnregisterCallback', &__cuLogsUnregisterCallback, 12090, ptds_mode, NULL) global __cuLogsCurrent - cuGetProcAddress_v2('cuLogsCurrent', &__cuLogsCurrent, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsCurrent', &__cuLogsCurrent, 12090, ptds_mode, NULL) global __cuLogsDumpToFile - cuGetProcAddress_v2('cuLogsDumpToFile', &__cuLogsDumpToFile, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsDumpToFile', &__cuLogsDumpToFile, 12090, ptds_mode, NULL) global __cuLogsDumpToMemory - cuGetProcAddress_v2('cuLogsDumpToMemory', &__cuLogsDumpToMemory, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsDumpToMemory', &__cuLogsDumpToMemory, 12090, ptds_mode, NULL) global __cuCheckpointProcessGetRestoreThreadId cuGetProcAddress_v2('cuCheckpointProcessGetRestoreThreadId', &__cuCheckpointProcessGetRestoreThreadId, 12080, ptds_mode, NULL) diff --git a/cuda_bindings/cuda/bindings/_internal/driver_windows.pyx b/cuda_bindings/cuda/bindings/_internal/driver_windows.pyx index 729808ed432..3d298bc3ba1 100644 --- a/cuda_bindings/cuda/bindings/_internal/driver_windows.pyx +++ b/cuda_bindings/cuda/bindings/_internal/driver_windows.pyx @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 # # This code was automatically generated across versions from 12.9.0 to 13.4.1. Do not modify it directly. -# CYTHON-BINDINGS-GENERATED-DO-NOT-MODIFY-THIS-FILE: format=1; content-sha256=f49a90c93b3876714d90f8948fabc654d408ba6c8bc3a122503b1d1ef663f434 +# CYTHON-BINDINGS-GENERATED-DO-NOT-MODIFY-THIS-FILE: format=1; content-sha256=a04dbfec5a461010c493b3aca0b092910ff3eb49d31942a68c957309892b2aa6 # <<<< PREAMBLE CONTENT >>>> @@ -1899,19 +1899,19 @@ cdef int _init_driver() except -1 nogil: cuGetProcAddress_v2('cuGreenCtxStreamCreate', &__cuGreenCtxStreamCreate, 12050, ptds_mode, NULL) global __cuLogsRegisterCallback - cuGetProcAddress_v2('cuLogsRegisterCallback', &__cuLogsRegisterCallback, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsRegisterCallback', &__cuLogsRegisterCallback, 12090, ptds_mode, NULL) global __cuLogsUnregisterCallback - cuGetProcAddress_v2('cuLogsUnregisterCallback', &__cuLogsUnregisterCallback, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsUnregisterCallback', &__cuLogsUnregisterCallback, 12090, ptds_mode, NULL) global __cuLogsCurrent - cuGetProcAddress_v2('cuLogsCurrent', &__cuLogsCurrent, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsCurrent', &__cuLogsCurrent, 12090, ptds_mode, NULL) global __cuLogsDumpToFile - cuGetProcAddress_v2('cuLogsDumpToFile', &__cuLogsDumpToFile, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsDumpToFile', &__cuLogsDumpToFile, 12090, ptds_mode, NULL) global __cuLogsDumpToMemory - cuGetProcAddress_v2('cuLogsDumpToMemory', &__cuLogsDumpToMemory, 12080, ptds_mode, NULL) + cuGetProcAddress_v2('cuLogsDumpToMemory', &__cuLogsDumpToMemory, 12090, ptds_mode, NULL) global __cuCheckpointProcessGetRestoreThreadId cuGetProcAddress_v2('cuCheckpointProcessGetRestoreThreadId', &__cuCheckpointProcessGetRestoreThreadId, 12080, ptds_mode, NULL) From 474b3b6e3bf8945fdaf34c44c28fee44f6171841 Mon Sep 17 00:00:00 2001 From: Jinfeng Date: Fri, 2 Oct 2026 07:05:47 +0000 Subject: [PATCH 2/3] test(driver): add regression test for cuLogs* version pinning Adds test_culogs_functions_are_resolved to confirm cuLogsRegisterCallback, cuLogsUnregisterCallback, cuLogsCurrent, cuLogsDumpToFile, and cuLogsDumpToMemory are resolved by cuGetProcAddress_v2 and do not raise FunctionNotFoundError, guarding against the version mismatch fixed in this PR. Addresses review feedback on #2978, closes #2979. --- cuda_bindings/tests/test_cuda.py | 56 ++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/cuda_bindings/tests/test_cuda.py b/cuda_bindings/tests/test_cuda.py index 65212efbcb7..a82898c772f 100644 --- a/cuda_bindings/tests/test_cuda.py +++ b/cuda_bindings/tests/test_cuda.py @@ -2,7 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 import ctypes +import os import shutil +import tempfile import textwrap import numpy as np @@ -13,6 +15,7 @@ import cuda.bindings.driver as cuda import cuda.bindings.runtime as cudart from cuda.bindings import driver +from cuda.bindings._internal.utils import FunctionNotFoundError from cuda_python_test_helpers import driver_version_less_than @@ -974,6 +977,59 @@ def test_cuCheckpointProcessGetState_failure(): assert state is None +@pytest.mark.skipif( + driver_version_less_than(12090), + reason="cuLogs* functions were introduced in CUDA 12.9", +) +def test_culogs_functions_are_resolved(): + """ + Regression test for https://github.com/NVIDIA/cuda-python/issues/2979 + + cuLogsRegisterCallback, cuLogsUnregisterCallback, cuLogsCurrent, + cuLogsDumpToFile, and cuLogsDumpToMemory were introduced in CUDA 12.9, + but were incorrectly requested from cuGetProcAddress_v2 with version + 12080 (CUDA 12.8). On a driver that enforces the requested symbol + version, that mismatch causes the internal function pointer to never + be resolved, so calling the function raises FunctionNotFoundError + instead of actually invoking the driver. + + cuLogsRegisterCallback, cuLogsUnregisterCallback, cuLogsCurrent, and + cuLogsDumpToFile are called directly below since they can be exercised + safely without a real log message or a fixed-size memory buffer. We + deliberately avoid calling cuLogsDumpToMemory with a real buffer here: + it writes a driver-chosen amount of data into the caller-supplied + buffer, which makes it unsafe to invoke blindly in a regression test. + Instead, its resolution is verified the same way + test_private_function_pointer_inspector does: by inspecting the + internal function pointer directly. + """ + from cuda.bindings._internal.driver import _inspect_function_pointer + + try: + err, callback_handle = cuda.cuLogsRegisterCallback(0, None) + assert err == cuda.CUresult.CUDA_SUCCESS + + err, _ = cuda.cuLogsCurrent(0) + assert err == cuda.CUresult.CUDA_SUCCESS + + with tempfile.NamedTemporaryFile(delete=False) as f: + log_path = f.name + try: + err, _ = cuda.cuLogsDumpToFile(None, log_path.encode(), 0) + assert err == cuda.CUresult.CUDA_SUCCESS + finally: + os.remove(log_path) + + (err,) = cuda.cuLogsUnregisterCallback(callback_handle) + assert err == cuda.CUresult.CUDA_SUCCESS + except FunctionNotFoundError as e: + pytest.fail(f"cuLogs* function unexpectedly not found on the driver: {e}") + + assert _inspect_function_pointer("__cuLogsDumpToMemory") != 0, ( + "cuLogsDumpToMemory was not resolved by cuGetProcAddress_v2" + ) + + def test_private_function_pointer_inspector(): from cuda.bindings._internal.driver import _inspect_function_pointer From cdecc5f5060cc5ded7bd32953bf4c269259e8475 Mon Sep 17 00:00:00 2001 From: Jinfeng Date: Fri, 2 Oct 2026 07:27:59 +0000 Subject: [PATCH 3/3] add regression test, driver log could be non zero, for example per cudaVersion argument (13030) exceeds the driver version (13020) --- cuda_bindings/tests/test_cuda.py | 36 +++++++------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/cuda_bindings/tests/test_cuda.py b/cuda_bindings/tests/test_cuda.py index a82898c772f..33e9e7f6b5b 100644 --- a/cuda_bindings/tests/test_cuda.py +++ b/cuda_bindings/tests/test_cuda.py @@ -981,30 +981,7 @@ def test_cuCheckpointProcessGetState_failure(): driver_version_less_than(12090), reason="cuLogs* functions were introduced in CUDA 12.9", ) -def test_culogs_functions_are_resolved(): - """ - Regression test for https://github.com/NVIDIA/cuda-python/issues/2979 - - cuLogsRegisterCallback, cuLogsUnregisterCallback, cuLogsCurrent, - cuLogsDumpToFile, and cuLogsDumpToMemory were introduced in CUDA 12.9, - but were incorrectly requested from cuGetProcAddress_v2 with version - 12080 (CUDA 12.8). On a driver that enforces the requested symbol - version, that mismatch causes the internal function pointer to never - be resolved, so calling the function raises FunctionNotFoundError - instead of actually invoking the driver. - - cuLogsRegisterCallback, cuLogsUnregisterCallback, cuLogsCurrent, and - cuLogsDumpToFile are called directly below since they can be exercised - safely without a real log message or a fixed-size memory buffer. We - deliberately avoid calling cuLogsDumpToMemory with a real buffer here: - it writes a driver-chosen amount of data into the caller-supplied - buffer, which makes it unsafe to invoke blindly in a regression test. - Instead, its resolution is verified the same way - test_private_function_pointer_inspector does: by inspecting the - internal function pointer directly. - """ - from cuda.bindings._internal.driver import _inspect_function_pointer - +def test_culogs_functions(): try: err, callback_handle = cuda.cuLogsRegisterCallback(0, None) assert err == cuda.CUresult.CUDA_SUCCESS @@ -1020,15 +997,18 @@ def test_culogs_functions_are_resolved(): finally: os.remove(log_path) + # cuLogsDumpToMemory's own docstring states the driver's internal log + # buffer is capped at 25600 bytes, so a buffer of that size is always + # large enough to hold the dump without risking a buffer overrun. + buf = bytearray(25600) + err, _, _ = cuda.cuLogsDumpToMemory(None, buf, len(buf), 0) + assert err == cuda.CUresult.CUDA_SUCCESS + (err,) = cuda.cuLogsUnregisterCallback(callback_handle) assert err == cuda.CUresult.CUDA_SUCCESS except FunctionNotFoundError as e: pytest.fail(f"cuLogs* function unexpectedly not found on the driver: {e}") - assert _inspect_function_pointer("__cuLogsDumpToMemory") != 0, ( - "cuLogsDumpToMemory was not resolved by cuGetProcAddress_v2" - ) - def test_private_function_pointer_inspector(): from cuda.bindings._internal.driver import _inspect_function_pointer