77
88import os
99import re
10- import pytest
1110from pathlib import Path
1211
12+ import pytest
13+
1314
1415class TestDockerfileCUDASupport :
1516 """Test that Dockerfiles support configurable CUDA versions."""
@@ -34,56 +35,63 @@ def test_vibevoice_dockerfile_has_cuda_arg(self, vibevoice_dockerfile_path):
3435 content = vibevoice_dockerfile_path .read_text ()
3536
3637 # Should have ARG declaration
37- assert re .search (r"ARG\s+PYTORCH_CUDA_VERSION" , content ), \
38- "Dockerfile must declare PYTORCH_CUDA_VERSION build arg"
38+ assert re .search (
39+ r"ARG\s+PYTORCH_CUDA_VERSION" , content
40+ ), "Dockerfile must declare PYTORCH_CUDA_VERSION build arg"
3941
4042 # Should have default value
4143 arg_match = re .search (r"ARG\s+PYTORCH_CUDA_VERSION=(\w+)" , content )
4244 assert arg_match , "PYTORCH_CUDA_VERSION should have default value"
4345 default_version = arg_match .group (1 )
44- assert default_version in ["cu121" , "cu126" , "cu128" ], \
45- f"Default CUDA version { default_version } should be cu121, cu126, or cu128"
46-
47- def test_vibevoice_dockerfile_uses_cuda_arg_in_uv_sync (self , vibevoice_dockerfile_path ):
46+ assert default_version in [
47+ "cu121" ,
48+ "cu126" ,
49+ "cu128" ,
50+ ], f"Default CUDA version { default_version } should be cu121, cu126, or cu128"
51+
52+ def test_vibevoice_dockerfile_uses_cuda_arg_in_uv_sync (
53+ self , vibevoice_dockerfile_path
54+ ):
4855 """Test that VibeVoice Dockerfile uses CUDA arg in uv sync command."""
4956 content = vibevoice_dockerfile_path .read_text ()
5057
5158 # Should use --extra ${PYTORCH_CUDA_VERSION}
52- assert re .search (r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}" , content ), \
53- "uv sync command must include --extra ${PYTORCH_CUDA_VERSION}"
59+ assert re .search (
60+ r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}" , content
61+ ), "uv sync command must include --extra ${PYTORCH_CUDA_VERSION}"
5462
5563 def test_nemo_dockerfile_has_cuda_support (self , nemo_dockerfile_path ):
5664 """Test that NeMo Dockerfile (reference implementation) has CUDA support."""
5765 content = nemo_dockerfile_path .read_text ()
5866
59- assert re .search (r"ARG\s+PYTORCH_CUDA_VERSION" , content ), \
60- "NeMo Dockerfile should have PYTORCH_CUDA_VERSION arg"
67+ assert re .search (
68+ r"ARG\s+PYTORCH_CUDA_VERSION" , content
69+ ), "NeMo Dockerfile should have PYTORCH_CUDA_VERSION arg"
6170
62- assert re .search (r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}" , content ), \
63- "NeMo Dockerfile should use CUDA version in uv sync"
71+ assert re .search (
72+ r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}" , content
73+ ), "NeMo Dockerfile should use CUDA version in uv sync"
6474
6575 def test_docker_compose_passes_cuda_arg_to_vibevoice (self , docker_compose_path ):
6676 """Test that docker-compose.yml passes PYTORCH_CUDA_VERSION to vibevoice service."""
6777 content = docker_compose_path .read_text ()
6878
6979 # Find vibevoice-asr service section
7080 vibevoice_section = re .search (
71- r"vibevoice-asr:.*?(?=^\S|\Z)" ,
72- content ,
73- re .MULTILINE | re .DOTALL
81+ r"vibevoice-asr:.*?(?=^\S|\Z)" , content , re .MULTILINE | re .DOTALL
7482 )
7583 assert vibevoice_section , "docker-compose.yml must have vibevoice-asr service"
7684
7785 section_text = vibevoice_section .group (0 )
7886
7987 # Should have build args section
80- assert re .search (r"args:" , section_text ), \
81- "vibevoice-asr service should have build args section"
88+ assert re .search (
89+ r"args:" , section_text
90+ ), "vibevoice-asr service should have build args section"
8291
8392 # Should pass PYTORCH_CUDA_VERSION
8493 assert re .search (
85- r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu126\}" ,
86- section_text
94+ r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu126\}" , section_text
8795 ), "vibevoice-asr should pass PYTORCH_CUDA_VERSION build arg with cu126 default"
8896
8997 def test_docker_compose_cuda_arg_consistency (self , docker_compose_path ):
@@ -95,9 +103,7 @@ def test_docker_compose_cuda_arg_consistency(self, docker_compose_path):
95103
96104 for service_name in gpu_services :
97105 service_match = re .search (
98- rf"{ service_name } :.*?(?=^\S|\Z)" ,
99- content ,
100- re .MULTILINE | re .DOTALL
106+ rf"{ service_name } :.*?(?=^\S|\Z)" , content , re .MULTILINE | re .DOTALL
101107 )
102108
103109 if service_match :
@@ -108,7 +114,7 @@ def test_docker_compose_cuda_arg_consistency(self, docker_compose_path):
108114 # Should have PYTORCH_CUDA_VERSION arg
109115 assert re .search (
110116 r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu\d+\}" ,
111- service_text
117+ service_text ,
112118 ), f"{ service_name } with GPU should have PYTORCH_CUDA_VERSION build arg"
113119
114120
@@ -120,8 +126,9 @@ def test_cuda_version_env_var_format(self):
120126 valid_versions = ["cu121" , "cu126" , "cu128" ]
121127
122128 for version in valid_versions :
123- assert re .match (r"^cu\d{3}$" , version ), \
124- f"{ version } should match pattern cu### (e.g., cu121, cu126)"
129+ assert re .match (
130+ r"^cu\d{3}$" , version
131+ ), f"{ version } should match pattern cu### (e.g., cu121, cu126)"
125132
126133 def test_cuda_version_from_env (self ):
127134 """Test reading CUDA version from environment."""
@@ -161,22 +168,30 @@ def test_rtx_5090_requires_cu128(self):
161168 # Map GPU architecture to minimum CUDA version
162169 arch_to_cuda = {
163170 "sm_120" : "cu128" , # RTX 5090, RTX 50 series
164- "sm_90" : "cu126" , # RTX 4090, H100
165- "sm_89" : "cu121" , # RTX 4090
166- "sm_86" : "cu121" , # RTX 3090, A6000
171+ "sm_90" : "cu126" , # RTX 4090, H100
172+ "sm_89" : "cu121" , # RTX 4090
173+ "sm_86" : "cu121" , # RTX 3090, A6000
167174 }
168175
169- assert arch_to_cuda .get (gpu_arch ) == required_cuda , \
170- f"GPU architecture { gpu_arch } requires CUDA version { required_cuda } "
176+ assert (
177+ arch_to_cuda .get (gpu_arch ) == required_cuda
178+ ), f"GPU architecture { gpu_arch } requires CUDA version { required_cuda } "
179+
180+ # Architectures supported by each CUDA version (minimum cu version that supports them)
181+ # Used as authoritative reference for architecture-to-CUDA mapping tests.
182+ CUDA_ARCH_SUPPORT = {
183+ "cu121" : {"sm_75" , "sm_80" , "sm_86" , "sm_89" },
184+ "cu126" : {"sm_75" , "sm_80" , "sm_86" , "sm_89" , "sm_90" },
185+ "cu128" : {"sm_75" , "sm_80" , "sm_86" , "sm_89" , "sm_90" , "sm_120" },
186+ }
171187
172188 def test_older_gpus_work_with_cu121 (self ):
173189 """Test that older GPUs (sm_86, sm_80) work with cu121."""
174190 older_archs = ["sm_86" , "sm_80" , "sm_75" ] # RTX 3090, A100, RTX 2080
191+ cu121_supported = self .CUDA_ARCH_SUPPORT ["cu121" ]
175192
176193 for arch in older_archs :
177- # cu121 supports these architectures
178- assert arch in ["sm_75" , "sm_80" , "sm_86" ], \
179- f"{ arch } should be supported by CUDA 12.1"
194+ assert arch in cu121_supported , f"{ arch } should be supported by CUDA 12.1"
180195
181196
182197class TestPyProjectCUDAExtras :
@@ -199,8 +214,9 @@ def test_pyproject_has_cuda_extras(self, pyproject_path):
199214
200215 for version in cuda_versions :
201216 # Look for the CUDA version as an extra
202- assert re .search (rf'["\']?{ version } ["\']?\s*=' , content ), \
203- f"pyproject.toml should define { version } extra"
217+ assert re .search (
218+ rf'["\']?{ version } ["\']?\s*=' , content
219+ ), f"pyproject.toml should define { version } extra"
204220
205221 def test_pyproject_cuda_extras_have_pytorch (self , pyproject_path ):
206222 """Test that CUDA extras include torch/torchaudio dependencies."""
@@ -211,9 +227,9 @@ def test_pyproject_cuda_extras_have_pytorch(self, pyproject_path):
211227
212228 # Each CUDA extra should reference torch with the appropriate index
213229 # e.g., { extra = "cu128" } or { index = "pytorch-cu128" }
214- assert re .search (r'extra\s*=\s*["\']cu\d{3}["\']' , content ) or \
215- re . search ( r'index\s*=\s*["\']pytorch-cu\d{3}["\']' , content ), \
216- "CUDA extras should reference PyTorch with CUDA version"
230+ assert re .search (r'extra\s*=\s*["\']cu\d{3}["\']' , content ) or re . search (
231+ r'index\s*=\s*["\']pytorch-cu\d{3}["\']' , content
232+ ), "CUDA extras should reference PyTorch with CUDA version"
217233
218234
219235if __name__ == "__main__" :
0 commit comments