From bdd48873dd82aaf9c4e6b14a52ffa2d015bc8fa8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 29 Sep 2025 09:37:52 -0700 Subject: [PATCH 1/5] Remove bitcode_dynamic code from test_nvvm.py --- cuda_bindings/tests/test_nvvm.py | 60 +++++++++----------------------- 1 file changed, 16 insertions(+), 44 deletions(-) diff --git a/cuda_bindings/tests/test_nvvm.py b/cuda_bindings/tests/test_nvvm.py index 29e5d89a91..8e4f0f0952 100644 --- a/cuda_bindings/tests/test_nvvm.py +++ b/cuda_bindings/tests/test_nvvm.py @@ -4,20 +4,11 @@ import binascii import re -import textwrap from contextlib import contextmanager import pytest from cuda.bindings import nvvm -MINIMAL_NVVMIR_FIXTURE_PARAMS = ["txt", "bitcode_static"] -try: - import llvmlite.binding as llvmlite_binding # Optional test dependency. -except ImportError: - llvmlite_binding = None -else: - MINIMAL_NVVMIR_FIXTURE_PARAMS.append("bitcode_dynamic") - MINIMAL_NVVMIR_TXT = b"""\ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64" @@ -130,43 +121,24 @@ "6e673e0000000000", } -MINIMAL_NVVMIR_CACHE = {} - -@pytest.fixture(params=MINIMAL_NVVMIR_FIXTURE_PARAMS) +@pytest.fixture(params=("txt", "bitcode_static")) def minimal_nvvmir(request): - for pass_counter in range(2): - nvvmir = MINIMAL_NVVMIR_CACHE.get(request.param, -1) - if nvvmir != -1: - if nvvmir is None: - pytest.skip(f"UNAVAILABLE: {request.param}") - return nvvmir - if pass_counter: - raise AssertionError("This code path is meant to be unreachable.") - # Build cache entries, then try again (above). - major, minor, debug_major, debug_minor = nvvm.ir_version() - txt = MINIMAL_NVVMIR_TXT % (major, debug_major) - if llvmlite_binding is None: - bitcode_dynamic = None - else: - bitcode_dynamic = llvmlite_binding.parse_assembly(txt.decode()).as_bitcode() - bitcode_static = MINIMAL_NVVMIR_BITCODE_STATIC.get((major, debug_major)) - if bitcode_static is not None: - bitcode_static = binascii.unhexlify(bitcode_static) - MINIMAL_NVVMIR_CACHE["txt"] = txt - MINIMAL_NVVMIR_CACHE["bitcode_dynamic"] = bitcode_dynamic - MINIMAL_NVVMIR_CACHE["bitcode_static"] = bitcode_static - if bitcode_static is None: - if bitcode_dynamic is None: - raise RuntimeError("Please `pip install llvmlite` to generate `bitcode_static` (see PR #443)") - bitcode_hex = binascii.hexlify(bitcode_dynamic).decode("ascii") - print("\n\nMINIMAL_NVVMIR_BITCODE_STATIC = { # PLEASE ADD TO test_nvvm.py") - print(f" ({major}, {debug_major}): # (major, debug_major)") - lines = textwrap.wrap(bitcode_hex, width=80) - for line in lines[:-1]: - print(f' "{line}"') - print(f' "{lines[-1]}",') - print("}\n", flush=True) + major, minor, debug_major, debug_minor = nvvm.ir_version() + + if request.param == "txt": + return MINIMAL_NVVMIR_TXT % (major, debug_major) + + bitcode_static_binascii = MINIMAL_NVVMIR_BITCODE_STATIC.get((major, debug_major)) + if bitcode_static_binascii: + return binascii.unhexlify(bitcode_static_binascii) + raise RuntimeError( + "Static bitcode for NVVM IR version " + f"{major}.{debug_major} is not available in this test.\n" + "Maintainers: Please run the helper script to generate it and add the " + "output to the MINIMAL_NVVMIR_BITCODE_STATIC dict:\n" + " ../../toolshed/build_static_bitcode_input.py" + ) @pytest.fixture(params=[nvvm.compile_program, nvvm.verify_program]) From 35b0a6d12c9acf05c6378b8698f9eb25793052c0 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 29 Sep 2025 09:53:04 -0700 Subject: [PATCH 2/5] New toolshed/build_static_bitcode_input.py --- toolshed/build_static_bitcode_input.py | 63 ++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 toolshed/build_static_bitcode_input.py diff --git a/toolshed/build_static_bitcode_input.py b/toolshed/build_static_bitcode_input.py new file mode 100755 index 0000000000..40152d69f0 --- /dev/null +++ b/toolshed/build_static_bitcode_input.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 + +# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. +# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE + +""" +Helper to produce static bitcode input for test_nvvm.py. + +Usage: + python toolshed/build_static_bitcode_input.py + +It will print a ready-to-paste MINIMAL_NVVMIR_BITCODE_STATIC entry for the +current NVVM IR version detected at runtime. +""" + +import binascii +import sys +import textwrap + +try: + import llvmlite.binding +except Exception: + sys.exit("HINT: pip install llvmlite") + +from cuda.bindings import nvvm + +# Keep this template in sync with test_nvvm.py +MINIMAL_NVVMIR_TXT = b"""\ +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64" + +target triple = "nvptx64-nvidia-cuda" + +define void @kernel() { +entry: + ret void +} + +!nvvm.annotations = !{!0} +!0 = !{void ()* @kernel, !"kernel", i32 1} + +!nvvmir.version = !{!1} +!1 = !{i32 %d, i32 0, i32 %d, i32 0} +""" # noqa: E501 + + +def main(): + major, _minor, debug_major, _debug_minor = nvvm.ir_version() + txt = MINIMAL_NVVMIR_TXT % (major, debug_major) + bitcode_dynamic = llvmlite.binding.parse_assembly(txt.decode()).as_bitcode() + bitcode_hex = binascii.hexlify(bitcode_dynamic).decode("ascii") + print("\n\nMINIMAL_NVVMIR_BITCODE_STATIC = { # PLEASE ADD TO test_nvvm.py") + print(f" ({major}, {debug_major}): # (major, debug_major)") + lines = textwrap.wrap(bitcode_hex, width=80) + for line in lines[:-1]: + print(f' "{line}"') + print(f' "{lines[-1]}",') + print("}\n", flush=True) + print() + + +if __name__ == "__main__": + assert len(sys.argv) == 1, "This helper script does not take any arguments." + main() From 4079a55b3f629fa9fac85eeb9aa275dba9c0487e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 29 Sep 2025 10:25:48 -0700 Subject: [PATCH 3/5] Import test_nvvm to get access to MINIMAL_NVVMIR_TXT (to avoid duplicating it). --- toolshed/build_static_bitcode_input.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/toolshed/build_static_bitcode_input.py b/toolshed/build_static_bitcode_input.py index 40152d69f0..54c9f81f09 100755 --- a/toolshed/build_static_bitcode_input.py +++ b/toolshed/build_static_bitcode_input.py @@ -14,6 +14,7 @@ """ import binascii +import os import sys import textwrap @@ -24,28 +25,20 @@ from cuda.bindings import nvvm -# Keep this template in sync with test_nvvm.py -MINIMAL_NVVMIR_TXT = b"""\ -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64" -target triple = "nvptx64-nvidia-cuda" +def get_minimal_nvvmir_txt_template(): + cuda_bindings_tests_dir = os.path.normpath("cuda_bindings/tests") + if not os.path.isdir(cuda_bindings_tests_dir): + raise RuntimeError("Please run this helper script from the cuda-python top-level directory.") + sys.path.insert(0, os.path.abspath(cuda_bindings_tests_dir)) + import test_nvvm -define void @kernel() { -entry: - ret void -} - -!nvvm.annotations = !{!0} -!0 = !{void ()* @kernel, !"kernel", i32 1} - -!nvvmir.version = !{!1} -!1 = !{i32 %d, i32 0, i32 %d, i32 0} -""" # noqa: E501 + return test_nvvm.MINIMAL_NVVMIR_TXT def main(): major, _minor, debug_major, _debug_minor = nvvm.ir_version() - txt = MINIMAL_NVVMIR_TXT % (major, debug_major) + txt = get_minimal_nvvmir_txt_template() % (major, debug_major) bitcode_dynamic = llvmlite.binding.parse_assembly(txt.decode()).as_bitcode() bitcode_hex = binascii.hexlify(bitcode_dynamic).decode("ascii") print("\n\nMINIMAL_NVVMIR_BITCODE_STATIC = { # PLEASE ADD TO test_nvvm.py") From b054e9e87647bc288113dad9cadcba75ab8820a7 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 29 Sep 2025 10:28:42 -0700 Subject: [PATCH 4/5] =?UTF-8?q?Rename=20MINIMAL=5FNVVMIR=5FTXT=20=E2=86=92?= =?UTF-8?q?=20MINIMAL=5FNVVMIR=5FTXT=5FTEMPLATE=20for=20clarity.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cuda_bindings/tests/test_nvvm.py | 4 ++-- toolshed/build_static_bitcode_input.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cuda_bindings/tests/test_nvvm.py b/cuda_bindings/tests/test_nvvm.py index 8e4f0f0952..060a5268be 100644 --- a/cuda_bindings/tests/test_nvvm.py +++ b/cuda_bindings/tests/test_nvvm.py @@ -9,7 +9,7 @@ import pytest from cuda.bindings import nvvm -MINIMAL_NVVMIR_TXT = b"""\ +MINIMAL_NVVMIR_TXT_TEMPLATE = b"""\ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64" target triple = "nvptx64-nvidia-cuda" @@ -127,7 +127,7 @@ def minimal_nvvmir(request): major, minor, debug_major, debug_minor = nvvm.ir_version() if request.param == "txt": - return MINIMAL_NVVMIR_TXT % (major, debug_major) + return MINIMAL_NVVMIR_TXT_TEMPLATE % (major, debug_major) bitcode_static_binascii = MINIMAL_NVVMIR_BITCODE_STATIC.get((major, debug_major)) if bitcode_static_binascii: diff --git a/toolshed/build_static_bitcode_input.py b/toolshed/build_static_bitcode_input.py index 54c9f81f09..9d37142a7c 100755 --- a/toolshed/build_static_bitcode_input.py +++ b/toolshed/build_static_bitcode_input.py @@ -33,7 +33,7 @@ def get_minimal_nvvmir_txt_template(): sys.path.insert(0, os.path.abspath(cuda_bindings_tests_dir)) import test_nvvm - return test_nvvm.MINIMAL_NVVMIR_TXT + return test_nvvm.MINIMAL_NVVMIR_TXT_TEMPLATE def main(): From 1019685099771a104899fa6f2289aa5db9f16040 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 29 Sep 2025 10:32:31 -0700 Subject: [PATCH 5/5] Minor simplifications of helper script. --- toolshed/build_static_bitcode_input.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/toolshed/build_static_bitcode_input.py b/toolshed/build_static_bitcode_input.py index 9d37142a7c..95c3a610f6 100755 --- a/toolshed/build_static_bitcode_input.py +++ b/toolshed/build_static_bitcode_input.py @@ -18,18 +18,15 @@ import sys import textwrap -try: - import llvmlite.binding -except Exception: - sys.exit("HINT: pip install llvmlite") - +import llvmlite.binding # HINT: pip install llvmlite from cuda.bindings import nvvm def get_minimal_nvvmir_txt_template(): cuda_bindings_tests_dir = os.path.normpath("cuda_bindings/tests") - if not os.path.isdir(cuda_bindings_tests_dir): - raise RuntimeError("Please run this helper script from the cuda-python top-level directory.") + assert os.path.isdir(cuda_bindings_tests_dir), ( + "Please run this helper script from the cuda-python top-level directory." + ) sys.path.insert(0, os.path.abspath(cuda_bindings_tests_dir)) import test_nvvm