Skip to content

Commit 9b579bc

Browse files
test_nvvm.py simplification / use llvmlite in toolshed/ only (#1047) (#1053)
* Remove bitcode_dynamic code from test_nvvm.py * New toolshed/build_static_bitcode_input.py * Import test_nvvm to get access to MINIMAL_NVVMIR_TXT (to avoid duplicating it). * Rename MINIMAL_NVVMIR_TXT → MINIMAL_NVVMIR_TXT_TEMPLATE for clarity. * Minor simplifications of helper script. (cherry picked from commit 5383cb5) Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
1 parent 41420f9 commit 9b579bc

2 files changed

Lines changed: 70 additions & 45 deletions

File tree

cuda_bindings/tests/test_nvvm.py

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,13 @@
44

55
import binascii
66
import re
7-
import textwrap
87
from contextlib import contextmanager
98

109
import pytest
1110

1211
from cuda.bindings import nvvm
1312

14-
MINIMAL_NVVMIR_FIXTURE_PARAMS = ["txt", "bitcode_static"]
15-
try:
16-
import llvmlite.binding as llvmlite_binding # Optional test dependency.
17-
except ImportError:
18-
llvmlite_binding = None
19-
else:
20-
MINIMAL_NVVMIR_FIXTURE_PARAMS.append("bitcode_dynamic")
21-
22-
MINIMAL_NVVMIR_TXT = b"""\
13+
MINIMAL_NVVMIR_TXT_TEMPLATE = b"""\
2314
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"
2415
2516
target triple = "nvptx64-nvidia-cuda"
@@ -131,43 +122,24 @@
131122
"6e673e0000000000",
132123
}
133124

134-
MINIMAL_NVVMIR_CACHE = {}
135-
136125

137-
@pytest.fixture(params=MINIMAL_NVVMIR_FIXTURE_PARAMS)
126+
@pytest.fixture(params=("txt", "bitcode_static"))
138127
def minimal_nvvmir(request):
139-
for pass_counter in range(2):
140-
nvvmir = MINIMAL_NVVMIR_CACHE.get(request.param, -1)
141-
if nvvmir != -1:
142-
if nvvmir is None:
143-
pytest.skip(f"UNAVAILABLE: {request.param}")
144-
return nvvmir
145-
if pass_counter:
146-
raise AssertionError("This code path is meant to be unreachable.")
147-
# Build cache entries, then try again (above).
148-
major, minor, debug_major, debug_minor = nvvm.ir_version()
149-
txt = MINIMAL_NVVMIR_TXT % (major, debug_major)
150-
if llvmlite_binding is None:
151-
bitcode_dynamic = None
152-
else:
153-
bitcode_dynamic = llvmlite_binding.parse_assembly(txt.decode()).as_bitcode()
154-
bitcode_static = MINIMAL_NVVMIR_BITCODE_STATIC.get((major, debug_major))
155-
if bitcode_static is not None:
156-
bitcode_static = binascii.unhexlify(bitcode_static)
157-
MINIMAL_NVVMIR_CACHE["txt"] = txt
158-
MINIMAL_NVVMIR_CACHE["bitcode_dynamic"] = bitcode_dynamic
159-
MINIMAL_NVVMIR_CACHE["bitcode_static"] = bitcode_static
160-
if bitcode_static is None:
161-
if bitcode_dynamic is None:
162-
raise RuntimeError("Please `pip install llvmlite` to generate `bitcode_static` (see PR #443)")
163-
bitcode_hex = binascii.hexlify(bitcode_dynamic).decode("ascii")
164-
print("\n\nMINIMAL_NVVMIR_BITCODE_STATIC = { # PLEASE ADD TO test_nvvm.py")
165-
print(f" ({major}, {debug_major}): # (major, debug_major)")
166-
lines = textwrap.wrap(bitcode_hex, width=80)
167-
for line in lines[:-1]:
168-
print(f' "{line}"')
169-
print(f' "{lines[-1]}",')
170-
print("}\n", flush=True)
128+
major, minor, debug_major, debug_minor = nvvm.ir_version()
129+
130+
if request.param == "txt":
131+
return MINIMAL_NVVMIR_TXT_TEMPLATE % (major, debug_major)
132+
133+
bitcode_static_binascii = MINIMAL_NVVMIR_BITCODE_STATIC.get((major, debug_major))
134+
if bitcode_static_binascii:
135+
return binascii.unhexlify(bitcode_static_binascii)
136+
raise RuntimeError(
137+
"Static bitcode for NVVM IR version "
138+
f"{major}.{debug_major} is not available in this test.\n"
139+
"Maintainers: Please run the helper script to generate it and add the "
140+
"output to the MINIMAL_NVVMIR_BITCODE_STATIC dict:\n"
141+
" ../../toolshed/build_static_bitcode_input.py"
142+
)
171143

172144

173145
@pytest.fixture(params=[nvvm.compile_program, nvvm.verify_program])
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env python3
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
4+
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
5+
6+
"""
7+
Helper to produce static bitcode input for test_nvvm.py.
8+
9+
Usage:
10+
python toolshed/build_static_bitcode_input.py
11+
12+
It will print a ready-to-paste MINIMAL_NVVMIR_BITCODE_STATIC entry for the
13+
current NVVM IR version detected at runtime.
14+
"""
15+
16+
import binascii
17+
import os
18+
import sys
19+
import textwrap
20+
21+
import llvmlite.binding # HINT: pip install llvmlite
22+
from cuda.bindings import nvvm
23+
24+
25+
def get_minimal_nvvmir_txt_template():
26+
cuda_bindings_tests_dir = os.path.normpath("cuda_bindings/tests")
27+
assert os.path.isdir(cuda_bindings_tests_dir), (
28+
"Please run this helper script from the cuda-python top-level directory."
29+
)
30+
sys.path.insert(0, os.path.abspath(cuda_bindings_tests_dir))
31+
import test_nvvm
32+
33+
return test_nvvm.MINIMAL_NVVMIR_TXT_TEMPLATE
34+
35+
36+
def main():
37+
major, _minor, debug_major, _debug_minor = nvvm.ir_version()
38+
txt = get_minimal_nvvmir_txt_template() % (major, debug_major)
39+
bitcode_dynamic = llvmlite.binding.parse_assembly(txt.decode()).as_bitcode()
40+
bitcode_hex = binascii.hexlify(bitcode_dynamic).decode("ascii")
41+
print("\n\nMINIMAL_NVVMIR_BITCODE_STATIC = { # PLEASE ADD TO test_nvvm.py")
42+
print(f" ({major}, {debug_major}): # (major, debug_major)")
43+
lines = textwrap.wrap(bitcode_hex, width=80)
44+
for line in lines[:-1]:
45+
print(f' "{line}"')
46+
print(f' "{lines[-1]}",')
47+
print("}\n", flush=True)
48+
print()
49+
50+
51+
if __name__ == "__main__":
52+
assert len(sys.argv) == 1, "This helper script does not take any arguments."
53+
main()

0 commit comments

Comments
 (0)