11"""Run pygpubench GPU tests on a Modal L4 GPU.
22
3- Usage: modal run ci/modal_gpu_test.py
3+ Usage: modal run ci/modal_gpu_test.py <wheel_path> <test_dir>
44"""
55
66import modal
77from pathlib import Path
88
9- _repo = Path (__file__ ).resolve ().parent .parent
10-
119image = (
1210 modal .Image .from_registry (
1311 "nvidia/cuda:13.0.1-cudnn-devel-ubuntu24.04" , add_python = "3.12"
1412 )
1513 .entrypoint ([])
16- .apt_install ("git" , "g++-13" , "cmake" , "ninja-build" )
1714 .uv_pip_install ("torch" , index_url = "https://download.pytorch.org/whl/cu130" )
18- .env ({
19- "CUDAARCHS" : "80;90" ,
20- "CC" : "gcc-13" ,
21- "CXX" : "g++-13" ,
22- "CMAKE_GENERATOR" : "Ninja" ,
23- })
24- .add_local_dir (str (_repo / "csrc" ), remote_path = "/root/pygpubench/csrc" )
25- .add_local_dir (str (_repo / "python" ), remote_path = "/root/pygpubench/python" )
26- .add_local_dir (str (_repo / "test" ), remote_path = "/root/pygpubench/test" )
27- .add_local_file (str (_repo / "pyproject.toml" ), remote_path = "/root/pygpubench/pyproject.toml" )
28- .add_local_file (str (_repo / "CMakeLists.txt" ), remote_path = "/root/pygpubench/CMakeLists.txt" )
29- .add_local_file (str (_repo / "README.md" ), remote_path = "/root/pygpubench/README.md" )
3015)
3116
3217app = modal .App ("pygpubench-ci" , image = image )
3318
3419
3520@app .function (gpu = "L4" , timeout = 600 )
36- def run_tests ():
21+ def run_tests (whl_bytes : bytes , whl_name : str , test_files : dict [ str , bytes ] ):
3722 import subprocess
38- import shutil
39- import glob
4023 import sys
4124 import os
4225
43- # Mounts are read-only; copy to a writable location for the build
44- shutil .copytree ("/root/pygpubench" , "/tmp/pygpubench" )
45- os .chdir ("/tmp/pygpubench" )
26+ # Write wheel and install it
27+ whl_path = f"/tmp/{ whl_name } "
28+ with open (whl_path , "wb" ) as f :
29+ f .write (whl_bytes )
30+ subprocess .run ([sys .executable , "-m" , "pip" , "install" , whl_path ], check = True )
4631
47- subprocess .run (["uv" , "build" , "--wheel" ], check = True )
32+ # Write test files
33+ test_dir = "/tmp/tests"
34+ os .makedirs (test_dir , exist_ok = True )
35+ for name , content in test_files .items ():
36+ with open (os .path .join (test_dir , name ), "wb" ) as f :
37+ f .write (content )
4838
49- whl = glob .glob ("dist/*.whl" )[0 ]
50- subprocess .run ([sys .executable , "-m" , "pip" , "install" , whl ], check = True )
51-
52- # Run all test scripts in test/
53- os .chdir ("/tmp/pygpubench/test" )
39+ # Run all test scripts
40+ os .chdir (test_dir )
5441 failed = []
55- for test_file in sorted (glob . glob ( "*.py" ) ):
42+ for test_file in sorted (test_files ):
5643 if test_file == "submission.py" :
5744 continue
5845 print (f"\n === { test_file } ===" )
@@ -66,5 +53,17 @@ def run_tests():
6653
6754
6855@app .local_entrypoint ()
69- def main ():
70- run_tests .remote ()
56+ def main (wheel : str , test_dir : str = "test" ):
57+ import glob
58+
59+ # Read the wheel
60+ whl_path = Path (wheel )
61+ whl_bytes = whl_path .read_bytes ()
62+
63+ # Read all test files
64+ test_path = Path (test_dir )
65+ test_files = {}
66+ for f in test_path .glob ("*.py" ):
67+ test_files [f .name ] = f .read_bytes ()
68+
69+ run_tests .remote (whl_bytes , whl_path .name , test_files )
0 commit comments