diff --git a/cuda_core/cuda/core/experimental/_device.py b/cuda_core/cuda/core/experimental/_device.py index 384db9195c..0499baa581 100644 --- a/cuda_core/cuda/core/experimental/_device.py +++ b/cuda_core/cuda/core/experimental/_device.py @@ -1112,6 +1112,11 @@ def compute_capability(self) -> ComputeCapability: self.properties._cache["compute_capability"] = cc return cc + @property + def arch(self) -> str: + """Return compute capability as a string (e.g., '75' for CC 7.5).""" + return f"{self.compute_capability.major}{self.compute_capability.minor}" + @property def context(self) -> Context: """Return the current :obj:`~_context.Context` associated with this device. diff --git a/cuda_core/docs/source/release/0.X.Y-notes.rst b/cuda_core/docs/source/release/0.X.Y-notes.rst index 3a9c7076a7..7ad3f616d6 100644 --- a/cuda_core/docs/source/release/0.X.Y-notes.rst +++ b/cuda_core/docs/source/release/0.X.Y-notes.rst @@ -24,7 +24,7 @@ Breaking Changes New features ------------ -None. +- Added :attr:`Device.arch` property that returns the compute capability as a string (e.g., '75' for CC 7.5), providing a convenient alternative to manually concatenating the compute capability tuple. New examples diff --git a/cuda_core/examples/cuda_graphs.py b/cuda_core/examples/cuda_graphs.py index b6c5edbe18..38c48fb111 100644 --- a/cuda_core/examples/cuda_graphs.py +++ b/cuda_core/examples/cuda_graphs.py @@ -53,8 +53,7 @@ def main(): cp.cuda.ExternalStream(int(stream.handle)).use() # Compile the program - arch = "".join(f"{i}" for i in dev.compute_capability) - program_options = ProgramOptions(std="c++17", arch=f"sm_{arch}") + program_options = ProgramOptions(std="c++17", arch=f"sm_{dev.arch}") prog = Program(code, code_type="c++", options=program_options) mod = prog.compile( "cubin", name_expressions=("vector_add", "vector_multiply", "vector_subtract") diff --git a/cuda_core/examples/memory_ops.py b/cuda_core/examples/memory_ops.py index 6f3de7a670..b12bc5039a 100644 --- a/cuda_core/examples/memory_ops.py +++ b/cuda_core/examples/memory_ops.py @@ -54,8 +54,7 @@ cp.cuda.ExternalStream(int(stream.handle)).use() # Compile kernel -arch = "".join(f"{i}" for i in dev.compute_capability) -program_options = ProgramOptions(std="c++17", arch=f"sm_{arch}") +program_options = ProgramOptions(std="c++17", arch=f"sm_{dev.arch}") prog = Program(code, code_type="c++", options=program_options) mod = prog.compile("cubin") kernel = mod.get_kernel("memory_ops") diff --git a/cuda_core/examples/pytorch_example.py b/cuda_core/examples/pytorch_example.py index 11f049443d..37288ebab3 100644 --- a/cuda_core/examples/pytorch_example.py +++ b/cuda_core/examples/pytorch_example.py @@ -51,8 +51,7 @@ def __cuda_stream__(self): s = dev.create_stream(PyTorchStreamWrapper(pt_stream)) # prepare program -arch = "".join(f"{i}" for i in dev.compute_capability) -program_options = ProgramOptions(std="c++11", arch=f"sm_{arch}") +program_options = ProgramOptions(std="c++11", arch=f"sm_{dev.arch}") prog = Program(code, code_type="c++", options=program_options) mod = prog.compile( "cubin", diff --git a/cuda_core/examples/saxpy.py b/cuda_core/examples/saxpy.py index 6048c6d5df..4e4d548bbc 100644 --- a/cuda_core/examples/saxpy.py +++ b/cuda_core/examples/saxpy.py @@ -38,8 +38,7 @@ s = dev.create_stream() # prepare program -arch = "".join(f"{i}" for i in dev.compute_capability) -program_options = ProgramOptions(std="c++11", arch=f"sm_{arch}") +program_options = ProgramOptions(std="c++11", arch=f"sm_{dev.arch}") prog = Program(code, code_type="c++", options=program_options) # Note the use of the `name_expressions` argument to specify the template diff --git a/cuda_core/examples/simple_multi_gpu_example.py b/cuda_core/examples/simple_multi_gpu_example.py index 456c7cacaa..1f9e43c03a 100644 --- a/cuda_core/examples/simple_multi_gpu_example.py +++ b/cuda_core/examples/simple_multi_gpu_example.py @@ -40,8 +40,7 @@ } } """ -arch0 = "".join(f"{i}" for i in dev0.compute_capability) -prog_add = Program(code_add, code_type="c++", options={"std": "c++17", "arch": f"sm_{arch0}"}) +prog_add = Program(code_add, code_type="c++", options={"std": "c++17", "arch": f"sm_{dev0.arch}"}) mod_add = prog_add.compile("cubin") ker_add = mod_add.get_kernel("vector_add") @@ -63,8 +62,7 @@ } } """ -arch1 = "".join(f"{i}" for i in dev1.compute_capability) -prog_sub = Program(code_sub, code_type="c++", options={"std": "c++17", "arch": f"sm_{arch1}"}) +prog_sub = Program(code_sub, code_type="c++", options={"std": "c++17", "arch": f"sm_{dev1.arch}"}) mod_sub = prog_sub.compile("cubin") ker_sub = mod_sub.get_kernel("vector_sub") diff --git a/cuda_core/examples/strided_memory_view_gpu.py b/cuda_core/examples/strided_memory_view_gpu.py index 58bc9634bd..5fb723ac70 100644 --- a/cuda_core/examples/strided_memory_view_gpu.py +++ b/cuda_core/examples/strided_memory_view_gpu.py @@ -103,8 +103,7 @@ def run(): # To know the GPU's compute capability, we need to identify which GPU to use. dev = Device(0) dev.set_current() - arch = "".join(f"{i}" for i in dev.compute_capability) - gpu_prog = Program(gpu_code, code_type="c++", options=ProgramOptions(arch=f"sm_{arch}", std="c++11")) + gpu_prog = Program(gpu_code, code_type="c++", options=ProgramOptions(arch=f"sm_{dev.arch}", std="c++11")) mod = gpu_prog.compile(target_type="cubin") gpu_ker = mod.get_kernel(func_name) diff --git a/cuda_core/examples/vector_add.py b/cuda_core/examples/vector_add.py index a5b9b036fb..303c774180 100644 --- a/cuda_core/examples/vector_add.py +++ b/cuda_core/examples/vector_add.py @@ -33,8 +33,7 @@ s = dev.create_stream() # prepare program -arch = "".join(f"{i}" for i in dev.compute_capability) -program_options = ProgramOptions(std="c++17", arch=f"sm_{arch}") +program_options = ProgramOptions(std="c++17", arch=f"sm_{dev.arch}") prog = Program(code, code_type="c++", options=program_options) mod = prog.compile("cubin", name_expressions=("vector_add",)) diff --git a/cuda_core/tests/test_device.py b/cuda_core/tests/test_device.py index 2a135c49a9..1eebd784f1 100644 --- a/cuda_core/tests/test_device.py +++ b/cuda_core/tests/test_device.py @@ -105,6 +105,18 @@ def test_compute_capability(): assert device.compute_capability == expected_cc +def test_arch(): + device = Device() + # Test that arch returns the same as the old pattern + expected_arch = "".join(f"{i}" for i in device.compute_capability) + assert device.arch == expected_arch + # Test that it's a string + assert isinstance(device.arch, str) + # Test that it matches the expected format (e.g., "75" for CC 7.5) + cc = device.compute_capability + assert device.arch == f"{cc.major}{cc.minor}" + + cuda_base_properties = [ ("max_threads_per_block", int), ("max_block_dim_x", int),