From 26b48814ce7aa2f304d4c4bfb71d85ec1233e008 Mon Sep 17 00:00:00 2001 From: LeSingh1 Date: Sun, 9 Aug 2026 13:45:55 -0700 Subject: [PATCH] fix(bindings): repair the two example command-line paths that #2546 revives Both defects sit behind an argv option, and `check_cmd_line_flag` currently always returns False (enumerate unpacked backwards -- see #2546), so neither can fire today. Fixing the helper turns both into immediate failures, and tests/test_examples.py runs every example with no arguments, so CI will not catch either. 1. simple_zero_copy.py: cudaGetDeviceCount() is not unwrapped. device_count = cudart.cudaGetDeviceCount() idev = int(get_cmd_line_argument_int("device=")) if idev >= device_count or idev < 0: The bindings return (cudaError_t, count), so the comparison raises "TypeError: '>=' not supported between instances of 'int' and 'tuple'". Every other call site in the examples wraps it, e.g. simple_p2p.py:52. 2. global_to_shmem_async_copy.py: grid_shared_state_kernel.z is never set. C++ `dim3` defaults every component to 1, which is why the C sample can write `dim3 gridSharedStateKernel(a, b)`. `cudart.dim3` is a cdef class over a zero-initialised struct, so .z stays 0 -- and it is passed as gridDimZ at both cuLaunchKernel sites for AsyncCopyMultiStageSharedState (kernel=3), which the driver rejects with CUDA_ERROR_INVALID_VALUE. Every other dim3 in the file and in the sibling examples sets .z explicitly, including the `grid` twelve lines above. Refs #2546 --- cuda_bindings/examples/0_Introduction/simple_zero_copy.py | 4 +++- .../examples/3_CUDA_Features/global_to_shmem_async_copy.py | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cuda_bindings/examples/0_Introduction/simple_zero_copy.py b/cuda_bindings/examples/0_Introduction/simple_zero_copy.py index 72c5fe8b701..0fa11ebec94 100644 --- a/cuda_bindings/examples/0_Introduction/simple_zero_copy.py +++ b/cuda_bindings/examples/0_Introduction/simple_zero_copy.py @@ -69,7 +69,9 @@ def main(): # Get the device selected by the user or default to 0, and then set it. if check_cmd_line_flag("device="): - device_count = cudart.cudaGetDeviceCount() + # cudaGetDeviceCount returns (cudaError_t, count); comparing the raw + # tuple against an int below raises TypeError. + device_count = check_cuda_errors(cudart.cudaGetDeviceCount()) idev = int(get_cmd_line_argument_int("device=")) if idev >= device_count or idev < 0: diff --git a/cuda_bindings/examples/3_CUDA_Features/global_to_shmem_async_copy.py b/cuda_bindings/examples/3_CUDA_Features/global_to_shmem_async_copy.py index 9a2ec3dec3b..475bb33e581 100644 --- a/cuda_bindings/examples/3_CUDA_Features/global_to_shmem_async_copy.py +++ b/cuda_bindings/examples/3_CUDA_Features/global_to_shmem_async_copy.py @@ -799,6 +799,11 @@ def matrix_multiply(dims_a, dims_b, kernel_number): grid_shared_state_kernel = cudart.dim3() grid_shared_state_kernel.x = dims_b.x / threads_shared_state_kernel.x grid_shared_state_kernel.y = dims_a.y / threads_shared_state_kernel.x + # C++ dim3 defaults every component to 1; cudart.dim3 wraps a + # zero-initialised struct, so .z must be set explicitly or the two + # cuLaunchKernel calls below pass gridDimZ=0 and fail with + # CUDA_ERROR_INVALID_VALUE. + grid_shared_state_kernel.z = 1 print(f"Running kernel = {kernel_number} - {kernel_names[kernel_number.value]}") # Create and start timer