gitarsenal-cli 1.6.6 → 1.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/python/fix_modal_token.py +14 -14
- package/python/fix_modal_token_advanced.py +1 -0
- package/python/test_modalSandboxScript.py +33 -34
- package/test_modalSandboxScript.py +33 -34
- package/test_cuda_setup.py +0 -148
package/package.json
CHANGED
@@ -60,19 +60,19 @@ except (ImportError, ValueError) as e:
|
|
60
60
|
# os.environ["MODAL_TOKEN_SECRET"] = TOKEN_SECRET
|
61
61
|
# print(f"✅ Set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables")
|
62
62
|
|
63
|
-
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
# Create token file
|
64
|
+
modal_dir = Path.home() / ".modal"
|
65
|
+
modal_dir.mkdir(exist_ok=True)
|
66
|
+
token_file = modal_dir / "token.json"
|
67
|
+
with open(token_file, 'w') as f:
|
68
|
+
f.write(f'{{"token_id": "{TOKEN_ID}", "token_secret": "{TOKEN_SECRET}"}}')
|
69
|
+
print(f"✅ Created token file at {token_file}")
|
70
70
|
|
71
|
-
#
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
# Create .modalconfig file
|
72
|
+
modalconfig_file = Path.home() / ".modalconfig"
|
73
|
+
with open(modalconfig_file, 'w') as f:
|
74
|
+
f.write(f"token_id = {TOKEN_ID}\n")
|
75
|
+
f.write(f"token_secret = {TOKEN_SECRET}\n")
|
76
|
+
print(f"✅ Created .modalconfig file at {modalconfig_file}")
|
77
77
|
|
78
|
-
|
78
|
+
print("\n✅ Done fixing Modal token. Please try your command again.")
|
@@ -1184,12 +1184,11 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1184
1184
|
try:
|
1185
1185
|
print("📦 Building SSH-enabled image...")
|
1186
1186
|
ssh_image = (
|
1187
|
-
|
1188
|
-
modal.Image.debian_slim()
|
1187
|
+
modal.Image.from_registry("nvidia/cuda:12.4.0-devel-ubuntu22.04", add_python="3.11")
|
1189
1188
|
.apt_install(
|
1190
1189
|
"openssh-server", "sudo", "curl", "wget", "vim", "htop", "git",
|
1191
1190
|
"python3", "python3-pip", "build-essential", "tmux", "screen", "nano",
|
1192
|
-
"gpg", "ca-certificates", "software-properties-common"
|
1191
|
+
"gpg", "ca-certificates", "software-properties-common", "nvtop"
|
1193
1192
|
)
|
1194
1193
|
.pip_install("uv", "modal", "requests", "openai") # Fast Python package installer and Modal
|
1195
1194
|
.run_commands(
|
@@ -1198,6 +1197,9 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1198
1197
|
"mkdir -p /root/.ssh",
|
1199
1198
|
"chmod 700 /root/.ssh",
|
1200
1199
|
|
1200
|
+
# Generate SSH host keys
|
1201
|
+
"ssh-keygen -A",
|
1202
|
+
|
1201
1203
|
# Configure SSH server
|
1202
1204
|
"sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config",
|
1203
1205
|
"sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config",
|
@@ -1207,8 +1209,9 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1207
1209
|
"echo 'ClientAliveInterval 60' >> /etc/ssh/sshd_config",
|
1208
1210
|
"echo 'ClientAliveCountMax 3' >> /etc/ssh/sshd_config",
|
1209
1211
|
|
1210
|
-
#
|
1211
|
-
"
|
1212
|
+
# Set up CUDA environment
|
1213
|
+
"echo 'export PATH=/usr/local/cuda/bin:$PATH' >> /root/.bashrc",
|
1214
|
+
"echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> /root/.bashrc",
|
1212
1215
|
|
1213
1216
|
# Set up a nice bash prompt
|
1214
1217
|
"echo 'export PS1=\"\\[\\e[1;32m\\]modal:\\[\\e[1;34m\\]\\w\\[\\e[0m\\]$ \"' >> /root/.bashrc",
|
@@ -1224,7 +1227,7 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1224
1227
|
if volume:
|
1225
1228
|
volumes_config[volume_mount_path] = volume
|
1226
1229
|
|
1227
|
-
# Define the SSH container function
|
1230
|
+
# Define the SSH container function - simplified like the example
|
1228
1231
|
@app.function(
|
1229
1232
|
image=ssh_image,
|
1230
1233
|
timeout=timeout_minutes * 60, # Convert to seconds
|
@@ -1234,7 +1237,7 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1234
1237
|
serialized=True,
|
1235
1238
|
volumes=volumes_config if volumes_config else None,
|
1236
1239
|
)
|
1237
|
-
def
|
1240
|
+
def start_ssh():
|
1238
1241
|
"""Start SSH container with password authentication and optional setup."""
|
1239
1242
|
import subprocess
|
1240
1243
|
import time
|
@@ -1244,14 +1247,25 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1244
1247
|
subprocess.run(["bash", "-c", f"echo 'root:{ssh_password}' | chpasswd"], check=True)
|
1245
1248
|
|
1246
1249
|
# Set OpenAI API key if provided
|
1250
|
+
openai_api_key = os.environ.get("OPENAI_API_KEY")
|
1247
1251
|
if openai_api_key:
|
1248
1252
|
os.environ['OPENAI_API_KEY'] = openai_api_key
|
1249
1253
|
print(f"✅ Set OpenAI API key in container environment (length: {len(openai_api_key)})")
|
1250
1254
|
else:
|
1251
1255
|
print("⚠️ No OpenAI API key provided to container")
|
1252
1256
|
|
1253
|
-
# Start SSH service
|
1254
|
-
subprocess.
|
1257
|
+
# Start SSH service using Popen (non-blocking) like in the example
|
1258
|
+
subprocess.Popen(["/usr/sbin/sshd", "-D"])
|
1259
|
+
time.sleep(2) # Give SSH time to start
|
1260
|
+
|
1261
|
+
# Test CUDA setup
|
1262
|
+
try:
|
1263
|
+
print("🔧 Testing CUDA setup...")
|
1264
|
+
subprocess.run(["nvidia-smi"], check=True)
|
1265
|
+
subprocess.run(["nvcc", "--version"], check=True)
|
1266
|
+
print("✅ CUDA setup verified")
|
1267
|
+
except subprocess.CalledProcessError as e:
|
1268
|
+
print(f"⚠️ CUDA test failed: {e}")
|
1255
1269
|
|
1256
1270
|
# Clone repository if provided
|
1257
1271
|
if repo_url:
|
@@ -1379,43 +1393,28 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1379
1393
|
print(f"🔍 Analyzing directory structure after failed cd command...")
|
1380
1394
|
subprocess.run("pwd && ls -la && echo '--- Parent directory ---' && ls -la ..", shell=True, check=False)
|
1381
1395
|
|
1382
|
-
#
|
1383
|
-
with modal.forward(22, unencrypted=True) as tunnel:
|
1384
|
-
|
1396
|
+
# Forward SSH port and keep container alive - exactly like the example
|
1397
|
+
with modal.forward(port=22, unencrypted=True) as tunnel:
|
1398
|
+
hostname, port = tunnel.tcp_socket
|
1385
1399
|
|
1386
1400
|
print("\n" + "=" * 80)
|
1387
1401
|
print("🎉 SSH CONTAINER IS READY!")
|
1388
1402
|
print("=" * 80)
|
1389
|
-
print(f"
|
1390
|
-
print(f"
|
1391
|
-
print(f"👤 Username: root")
|
1392
|
-
print(f"🔐 Password: {ssh_password}")
|
1393
|
-
print()
|
1394
|
-
print("🔗 CONNECT USING THIS COMMAND:")
|
1395
|
-
print(f"ssh -p {port} root@{host}")
|
1403
|
+
print(f"SSH: ssh -p {port} root@{hostname}")
|
1404
|
+
print(f"Password: {ssh_password}")
|
1396
1405
|
print("=" * 80)
|
1397
1406
|
|
1398
|
-
# Keep the
|
1407
|
+
# Keep alive - simplified like the example
|
1399
1408
|
while True:
|
1400
|
-
time.sleep(
|
1401
|
-
# Check if SSH service is still running
|
1402
|
-
try:
|
1403
|
-
subprocess.run(["service", "ssh", "status"], check=True,
|
1404
|
-
capture_output=True)
|
1405
|
-
except subprocess.CalledProcessError:
|
1406
|
-
print("⚠️ SSH service stopped, restarting...")
|
1407
|
-
subprocess.run(["service", "ssh", "start"], check=True)
|
1409
|
+
time.sleep(60)
|
1408
1410
|
|
1409
1411
|
# Run the container
|
1410
1412
|
try:
|
1411
1413
|
print("⏳ Starting container... This may take 1-2 minutes...")
|
1412
1414
|
|
1413
|
-
# Start the container
|
1414
|
-
with
|
1415
|
-
|
1416
|
-
# Get the API key from environment
|
1417
|
-
api_key = os.environ.get("OPENAI_API_KEY")
|
1418
|
-
ssh_container_function.remote(ssh_password, repo_url, repo_name, setup_commands, api_key)
|
1415
|
+
# Start the container - simplified like the example
|
1416
|
+
with app.run():
|
1417
|
+
start_ssh.remote()
|
1419
1418
|
|
1420
1419
|
# Clean up Modal token after container is successfully created
|
1421
1420
|
cleanup_modal_token()
|
@@ -1184,12 +1184,11 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1184
1184
|
try:
|
1185
1185
|
print("📦 Building SSH-enabled image...")
|
1186
1186
|
ssh_image = (
|
1187
|
-
|
1188
|
-
modal.Image.debian_slim()
|
1187
|
+
modal.Image.from_registry("nvidia/cuda:12.4.0-devel-ubuntu22.04", add_python="3.11")
|
1189
1188
|
.apt_install(
|
1190
1189
|
"openssh-server", "sudo", "curl", "wget", "vim", "htop", "git",
|
1191
1190
|
"python3", "python3-pip", "build-essential", "tmux", "screen", "nano",
|
1192
|
-
"gpg", "ca-certificates", "software-properties-common"
|
1191
|
+
"gpg", "ca-certificates", "software-properties-common", "nvtop"
|
1193
1192
|
)
|
1194
1193
|
.pip_install("uv", "modal", "requests", "openai") # Fast Python package installer and Modal
|
1195
1194
|
.run_commands(
|
@@ -1198,6 +1197,9 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1198
1197
|
"mkdir -p /root/.ssh",
|
1199
1198
|
"chmod 700 /root/.ssh",
|
1200
1199
|
|
1200
|
+
# Generate SSH host keys
|
1201
|
+
"ssh-keygen -A",
|
1202
|
+
|
1201
1203
|
# Configure SSH server
|
1202
1204
|
"sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config",
|
1203
1205
|
"sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config",
|
@@ -1207,8 +1209,9 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1207
1209
|
"echo 'ClientAliveInterval 60' >> /etc/ssh/sshd_config",
|
1208
1210
|
"echo 'ClientAliveCountMax 3' >> /etc/ssh/sshd_config",
|
1209
1211
|
|
1210
|
-
#
|
1211
|
-
"
|
1212
|
+
# Set up CUDA environment
|
1213
|
+
"echo 'export PATH=/usr/local/cuda/bin:$PATH' >> /root/.bashrc",
|
1214
|
+
"echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> /root/.bashrc",
|
1212
1215
|
|
1213
1216
|
# Set up a nice bash prompt
|
1214
1217
|
"echo 'export PS1=\"\\[\\e[1;32m\\]modal:\\[\\e[1;34m\\]\\w\\[\\e[0m\\]$ \"' >> /root/.bashrc",
|
@@ -1224,7 +1227,7 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1224
1227
|
if volume:
|
1225
1228
|
volumes_config[volume_mount_path] = volume
|
1226
1229
|
|
1227
|
-
# Define the SSH container function
|
1230
|
+
# Define the SSH container function - simplified like the example
|
1228
1231
|
@app.function(
|
1229
1232
|
image=ssh_image,
|
1230
1233
|
timeout=timeout_minutes * 60, # Convert to seconds
|
@@ -1234,7 +1237,7 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1234
1237
|
serialized=True,
|
1235
1238
|
volumes=volumes_config if volumes_config else None,
|
1236
1239
|
)
|
1237
|
-
def
|
1240
|
+
def start_ssh():
|
1238
1241
|
"""Start SSH container with password authentication and optional setup."""
|
1239
1242
|
import subprocess
|
1240
1243
|
import time
|
@@ -1244,14 +1247,25 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1244
1247
|
subprocess.run(["bash", "-c", f"echo 'root:{ssh_password}' | chpasswd"], check=True)
|
1245
1248
|
|
1246
1249
|
# Set OpenAI API key if provided
|
1250
|
+
openai_api_key = os.environ.get("OPENAI_API_KEY")
|
1247
1251
|
if openai_api_key:
|
1248
1252
|
os.environ['OPENAI_API_KEY'] = openai_api_key
|
1249
1253
|
print(f"✅ Set OpenAI API key in container environment (length: {len(openai_api_key)})")
|
1250
1254
|
else:
|
1251
1255
|
print("⚠️ No OpenAI API key provided to container")
|
1252
1256
|
|
1253
|
-
# Start SSH service
|
1254
|
-
subprocess.
|
1257
|
+
# Start SSH service using Popen (non-blocking) like in the example
|
1258
|
+
subprocess.Popen(["/usr/sbin/sshd", "-D"])
|
1259
|
+
time.sleep(2) # Give SSH time to start
|
1260
|
+
|
1261
|
+
# Test CUDA setup
|
1262
|
+
try:
|
1263
|
+
print("🔧 Testing CUDA setup...")
|
1264
|
+
subprocess.run(["nvidia-smi"], check=True)
|
1265
|
+
subprocess.run(["nvcc", "--version"], check=True)
|
1266
|
+
print("✅ CUDA setup verified")
|
1267
|
+
except subprocess.CalledProcessError as e:
|
1268
|
+
print(f"⚠️ CUDA test failed: {e}")
|
1255
1269
|
|
1256
1270
|
# Clone repository if provided
|
1257
1271
|
if repo_url:
|
@@ -1379,43 +1393,28 @@ def create_modal_ssh_container(gpu_type, repo_url=None, repo_name=None, setup_co
|
|
1379
1393
|
print(f"🔍 Analyzing directory structure after failed cd command...")
|
1380
1394
|
subprocess.run("pwd && ls -la && echo '--- Parent directory ---' && ls -la ..", shell=True, check=False)
|
1381
1395
|
|
1382
|
-
#
|
1383
|
-
with modal.forward(22, unencrypted=True) as tunnel:
|
1384
|
-
|
1396
|
+
# Forward SSH port and keep container alive - exactly like the example
|
1397
|
+
with modal.forward(port=22, unencrypted=True) as tunnel:
|
1398
|
+
hostname, port = tunnel.tcp_socket
|
1385
1399
|
|
1386
1400
|
print("\n" + "=" * 80)
|
1387
1401
|
print("🎉 SSH CONTAINER IS READY!")
|
1388
1402
|
print("=" * 80)
|
1389
|
-
print(f"
|
1390
|
-
print(f"
|
1391
|
-
print(f"👤 Username: root")
|
1392
|
-
print(f"🔐 Password: {ssh_password}")
|
1393
|
-
print()
|
1394
|
-
print("🔗 CONNECT USING THIS COMMAND:")
|
1395
|
-
print(f"ssh -p {port} root@{host}")
|
1403
|
+
print(f"SSH: ssh -p {port} root@{hostname}")
|
1404
|
+
print(f"Password: {ssh_password}")
|
1396
1405
|
print("=" * 80)
|
1397
1406
|
|
1398
|
-
# Keep the
|
1407
|
+
# Keep alive - simplified like the example
|
1399
1408
|
while True:
|
1400
|
-
time.sleep(
|
1401
|
-
# Check if SSH service is still running
|
1402
|
-
try:
|
1403
|
-
subprocess.run(["service", "ssh", "status"], check=True,
|
1404
|
-
capture_output=True)
|
1405
|
-
except subprocess.CalledProcessError:
|
1406
|
-
print("⚠️ SSH service stopped, restarting...")
|
1407
|
-
subprocess.run(["service", "ssh", "start"], check=True)
|
1409
|
+
time.sleep(60)
|
1408
1410
|
|
1409
1411
|
# Run the container
|
1410
1412
|
try:
|
1411
1413
|
print("⏳ Starting container... This may take 1-2 minutes...")
|
1412
1414
|
|
1413
|
-
# Start the container
|
1414
|
-
with
|
1415
|
-
|
1416
|
-
# Get the API key from environment
|
1417
|
-
api_key = os.environ.get("OPENAI_API_KEY")
|
1418
|
-
ssh_container_function.remote(ssh_password, repo_url, repo_name, setup_commands, api_key)
|
1415
|
+
# Start the container - simplified like the example
|
1416
|
+
with app.run():
|
1417
|
+
start_ssh.remote()
|
1419
1418
|
|
1420
1419
|
# Clean up Modal token after container is successfully created
|
1421
1420
|
cleanup_modal_token()
|
package/test_cuda_setup.py
DELETED
@@ -1,148 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
Test script to verify CUDA setup in GitArsenal containers
|
4
|
-
"""
|
5
|
-
|
6
|
-
import subprocess
|
7
|
-
import sys
|
8
|
-
import os
|
9
|
-
|
10
|
-
def test_cuda_basic():
|
11
|
-
"""Test basic CUDA functionality"""
|
12
|
-
print("🧪 Testing basic CUDA functionality...")
|
13
|
-
|
14
|
-
try:
|
15
|
-
# Test nvidia-smi
|
16
|
-
result = subprocess.run(["nvidia-smi"], capture_output=True, text=True, timeout=30)
|
17
|
-
if result.returncode == 0:
|
18
|
-
print("✅ nvidia-smi working")
|
19
|
-
print(f"Output: {result.stdout[:200]}...")
|
20
|
-
else:
|
21
|
-
print(f"❌ nvidia-smi failed: {result.stderr}")
|
22
|
-
return False
|
23
|
-
|
24
|
-
# Test nvcc
|
25
|
-
result = subprocess.run(["nvcc", "--version"], capture_output=True, text=True, timeout=30)
|
26
|
-
if result.returncode == 0:
|
27
|
-
print("✅ nvcc available")
|
28
|
-
print(f"Version: {result.stdout.split('release')[0].strip()}")
|
29
|
-
else:
|
30
|
-
print(f"❌ nvcc failed: {result.stderr}")
|
31
|
-
return False
|
32
|
-
|
33
|
-
return True
|
34
|
-
|
35
|
-
except subprocess.TimeoutExpired:
|
36
|
-
print("❌ CUDA test timed out")
|
37
|
-
return False
|
38
|
-
except Exception as e:
|
39
|
-
print(f"❌ CUDA test error: {e}")
|
40
|
-
return False
|
41
|
-
|
42
|
-
def test_cupy_import():
|
43
|
-
"""Test cupy import"""
|
44
|
-
print("🧪 Testing cupy import...")
|
45
|
-
|
46
|
-
try:
|
47
|
-
import cupy as cp
|
48
|
-
print("✅ cupy imported successfully")
|
49
|
-
|
50
|
-
# Test basic cupy functionality
|
51
|
-
x = cp.array([1, 2, 3, 4, 5])
|
52
|
-
y = cp.square(x)
|
53
|
-
print(f"✅ cupy basic operation: {y}")
|
54
|
-
|
55
|
-
return True
|
56
|
-
|
57
|
-
except ImportError as e:
|
58
|
-
print(f"❌ cupy import failed: {e}")
|
59
|
-
return False
|
60
|
-
except Exception as e:
|
61
|
-
print(f"❌ cupy test error: {e}")
|
62
|
-
return False
|
63
|
-
|
64
|
-
def test_gpu_environment():
|
65
|
-
"""Test GPU environment variables"""
|
66
|
-
print("🧪 Testing GPU environment variables...")
|
67
|
-
|
68
|
-
gpu_vars = {
|
69
|
-
'CUDA_VISIBLE_DEVICES': '0',
|
70
|
-
'NVIDIA_VISIBLE_DEVICES': 'all',
|
71
|
-
'NVIDIA_DRIVER_CAPABILITIES': 'compute,utility'
|
72
|
-
}
|
73
|
-
|
74
|
-
for var, value in gpu_vars.items():
|
75
|
-
os.environ[var] = value
|
76
|
-
print(f"✅ Set {var}={value}")
|
77
|
-
|
78
|
-
# Verify they're set
|
79
|
-
for var, expected_value in gpu_vars.items():
|
80
|
-
actual_value = os.environ.get(var)
|
81
|
-
if actual_value == expected_value:
|
82
|
-
print(f"✅ {var} correctly set to {actual_value}")
|
83
|
-
else:
|
84
|
-
print(f"❌ {var} not set correctly. Expected: {expected_value}, Got: {actual_value}")
|
85
|
-
return False
|
86
|
-
|
87
|
-
return True
|
88
|
-
|
89
|
-
def test_modal_cuda_image():
|
90
|
-
"""Test Modal CUDA image creation"""
|
91
|
-
print("🧪 Testing Modal CUDA image creation...")
|
92
|
-
|
93
|
-
try:
|
94
|
-
import modal
|
95
|
-
|
96
|
-
# Test the same image configuration as the SSH container
|
97
|
-
image = (
|
98
|
-
modal.Image.from_registry("nvidia/cuda:12.4.0-devel-ubuntu22.04", add_python="3.11")
|
99
|
-
.pip_install("cupy-cuda12x", "setuptools", "uv", "modal", "requests", "openai")
|
100
|
-
)
|
101
|
-
|
102
|
-
print("✅ Modal CUDA image created successfully")
|
103
|
-
return True
|
104
|
-
|
105
|
-
except ImportError as e:
|
106
|
-
print(f"❌ Modal import failed: {e}")
|
107
|
-
return False
|
108
|
-
except Exception as e:
|
109
|
-
print(f"❌ Modal CUDA image creation failed: {e}")
|
110
|
-
return False
|
111
|
-
|
112
|
-
def main():
|
113
|
-
"""Run all CUDA tests"""
|
114
|
-
print("🧪 GitArsenal CUDA Setup Tests")
|
115
|
-
print("=" * 50)
|
116
|
-
|
117
|
-
tests = [
|
118
|
-
("GPU Environment", test_gpu_environment),
|
119
|
-
("Modal CUDA Image", test_modal_cuda_image),
|
120
|
-
("Basic CUDA", test_cuda_basic),
|
121
|
-
("Cupy Import", test_cupy_import),
|
122
|
-
]
|
123
|
-
|
124
|
-
passed = 0
|
125
|
-
total = len(tests)
|
126
|
-
|
127
|
-
for test_name, test_func in tests:
|
128
|
-
print(f"\n🔍 Running: {test_name}")
|
129
|
-
try:
|
130
|
-
if test_func():
|
131
|
-
passed += 1
|
132
|
-
print(f"✅ {test_name} PASSED")
|
133
|
-
else:
|
134
|
-
print(f"❌ {test_name} FAILED")
|
135
|
-
except Exception as e:
|
136
|
-
print(f"❌ {test_name} ERROR: {e}")
|
137
|
-
|
138
|
-
print(f"\n📊 Test Results: {passed}/{total} tests passed")
|
139
|
-
|
140
|
-
if passed == total:
|
141
|
-
print("🎉 All CUDA tests passed! The SSH container should work correctly.")
|
142
|
-
return 0
|
143
|
-
else:
|
144
|
-
print("⚠️ Some CUDA tests failed. The SSH container may have issues.")
|
145
|
-
return 1
|
146
|
-
|
147
|
-
if __name__ == "__main__":
|
148
|
-
sys.exit(main())
|