-
Notifications
You must be signed in to change notification settings - Fork 264
Expand file tree
/
Copy pathtest_gpu.sh
More file actions
executable file
·325 lines (262 loc) · 8.79 KB
/
Copy pathtest_gpu.sh
File metadata and controls
executable file
·325 lines (262 loc) · 8.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
#!/usr/bin/env bash
# GPU test suite for slurm-docker-cluster
# Tests GPU node availability and GRES functionality
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Test counter
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0
# Helper functions
log_info() {
echo -e "${YELLOW}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[PASS]${NC} $1"
((++TESTS_PASSED))
}
log_error() {
echo -e "${RED}[FAIL]${NC} $1"
((++TESTS_FAILED))
}
run_test() {
((++TESTS_RUN))
echo ""
echo "=========================================="
echo "Test $TESTS_RUN: $1"
echo "=========================================="
}
# Check if GPU profile is enabled
check_gpu_enabled() {
run_test "Check GPU profile enabled"
if ! grep -q "^GPU_ENABLE=true" .env 2>/dev/null; then
log_error "GPU_ENABLE not set to true in .env"
echo "To enable GPU support:"
echo " 1. Add 'GPU_ENABLE=true' to .env"
echo " 2. Ensure nvidia-container-toolkit is installed on host"
echo " 3. Run: make rebuild"
return 1
fi
log_success "GPU_ENABLE=true found in .env"
return 0
}
# Get the first gpu-worker container name
get_first_gpu_worker() {
docker compose ps gpu-worker --format '{{.Names}}' 2>/dev/null | head -1
}
# Get the first gpu-worker node name from Slurm
get_first_gpu_node() {
docker exec slurmctld scontrol show nodes 2>/dev/null | grep -o 'NodeName=g[0-9]*' | head -1 | cut -d= -f2
}
# Check gpu-worker container is running
check_gpu_worker_running() {
run_test "Check gpu-worker container running"
local gpu_worker
gpu_worker=$(get_first_gpu_worker)
if [[ -z "$gpu_worker" ]]; then
log_error "No gpu-worker containers running"
echo "Start GPU workers with: make up (with GPU_ENABLE=true in .env)"
return 1
fi
local worker_count
worker_count=$(docker compose ps gpu-worker --format '{{.Names}}' 2>/dev/null | wc -l)
log_success "$worker_count gpu-worker container(s) running"
return 0
}
# Check gpu-worker node registered in Slurm
check_gpu_worker_registered() {
run_test "Check gpu-worker node registered in Slurm"
local gpu_node
gpu_node=$(get_first_gpu_node)
if [[ -z "$gpu_node" ]]; then
log_error "No gpu-worker nodes registered in Slurm"
return 1
fi
log_success "gpu-worker node registered in Slurm: $gpu_node"
return 0
}
# Check gpu-worker node has GPU GRES
check_gres_configured() {
run_test "Check GPU GRES configured on gpu-worker"
local gpu_node
gpu_node=$(get_first_gpu_node)
if [[ -z "$gpu_node" ]]; then
log_error "No gpu-worker nodes found"
return 1
fi
local gres_output
gres_output=$(docker exec slurmctld scontrol show node "$gpu_node" | grep "Gres=" || true)
if [[ ! "$gres_output" =~ gpu:nvidia ]]; then
log_error "GPU GRES not configured correctly on $gpu_node"
echo "Expected: Gres containing gpu:nvidia"
echo "Got: $gres_output"
return 1
fi
log_success "GPU GRES configured on $gpu_node: $gres_output"
return 0
}
# Check GPU partition exists
check_gpu_partition() {
run_test "Check 'gpu' partition exists"
if ! docker exec slurmctld scontrol show partition gpu &>/dev/null; then
log_error "'gpu' partition not found"
return 1
fi
local partition_nodes
partition_nodes=$(docker exec slurmctld scontrol show partition gpu | grep -E "^\s+Nodes=" | cut -d= -f2)
if [[ -z "$partition_nodes" ]] || [[ "$partition_nodes" == "(null)" ]]; then
log_error "GPU partition has no nodes"
return 1
fi
log_success "'gpu' partition configured with nodes: $partition_nodes"
return 0
}
# Check nvidia-smi works in gpu-worker container
check_nvidia_smi() {
run_test "Check nvidia-smi works in gpu-worker container"
local gpu_worker
gpu_worker=$(get_first_gpu_worker)
if [[ -z "$gpu_worker" ]]; then
log_error "No gpu-worker container found"
return 1
fi
if ! docker exec "$gpu_worker" nvidia-smi &>/dev/null; then
log_error "nvidia-smi not available in $gpu_worker"
echo "Ensure nvidia-container-toolkit is installed on host"
return 1
fi
local gpu_count
gpu_count=$(docker exec "$gpu_worker" nvidia-smi --query-gpu=count --format=csv,noheader | head -n1)
log_success "nvidia-smi detected $gpu_count GPU(s)"
docker exec "$gpu_worker" nvidia-smi
return 0
}
# Test GPU job submission
test_gpu_job_submission() {
run_test "Submit test job requesting GPU GRES"
# Clean up old job outputs
docker exec slurmctld bash -c "cd /data && rm -f slurm-*.out gpu-test-*.out" || true
# Submit job requesting gpu:1
local job_script='#!/bin/bash
#SBATCH --job-name=gpu-test
#SBATCH --partition=gpu
#SBATCH --gres=gpu:1
#SBATCH --output=gpu-test-%j.out
echo "=== GPU Test Job ==="
echo "Hostname: $(hostname)"
echo "CUDA_VISIBLE_DEVICES: ${CUDA_VISIBLE_DEVICES:-not set}"
echo ""
echo "=== nvidia-smi output ==="
nvidia-smi
echo ""
echo "=== GPU Detection ==="
if command -v nvidia-smi &> /dev/null; then
nvidia-smi --query-gpu=index,name,driver_version,memory.total --format=csv
else
echo "nvidia-smi not found"
fi
'
local jobid
jobid=$(docker exec slurmctld bash -c "cd /data && cat > gpu-job.sh <<'EOF'
$job_script
EOF
chmod +x gpu-job.sh && sbatch gpu-job.sh | grep -oP '\\d+'")
if [[ -z "$jobid" ]]; then
log_error "Failed to submit GPU job"
return 1
fi
log_info "Job $jobid submitted, waiting for completion..."
# Wait for job to complete (max 60 seconds)
local elapsed=0
while [[ $elapsed -lt 60 ]]; do
local state
state=$(docker exec slurmctld scontrol show job "$jobid" | grep "JobState=" | sed -n 's/.*JobState=\([A-Z]*\).*/\1/p' || echo "UNKNOWN")
if [[ "$state" == "COMPLETED" ]]; then
log_success "GPU job $jobid completed successfully"
# Show job output
echo ""
echo "========== Job Output =========="
docker exec slurmctld bash -c "cd /data && cat gpu-test-${jobid}.out"
echo "================================"
return 0
elif [[ "$state" == "FAILED" ]] || [[ "$state" == "CANCELLED" ]] || [[ "$state" == "TIMEOUT" ]]; then
log_error "GPU job $jobid failed with state: $state"
docker exec slurmctld bash -c "cd /data && cat gpu-test-${jobid}.out" || echo "No output file"
return 1
fi
sleep 2
((elapsed+=2))
done
log_error "GPU job $jobid timed out after 60 seconds"
docker exec slurmctld scontrol show job "$jobid"
return 1
}
# Test GPU allocation in squeue
test_gpu_allocation() {
run_test "Verify GPU allocation shows in job"
# Submit a held job to check allocation
local jobid
jobid=$(docker exec slurmctld bash -c "cd /data && sbatch --hold --partition=gpu --gres=gpu:1 --wrap='sleep 10' | grep -oP '\\d+'")
if [[ -z "$jobid" ]]; then
log_error "Failed to submit held GPU job"
return 1
fi
local gres_alloc
gres_alloc=$(docker exec slurmctld scontrol show job "$jobid" | grep "TresPerNode=" || echo "")
# Cancel the held job
docker exec slurmctld scancel "$jobid" || true
if [[ "$gres_alloc" =~ gres/gpu ]]; then
log_success "GPU allocation visible in job: $gres_alloc"
return 0
else
log_error "GPU allocation not visible in job"
echo "Expected TresPerNode to contain gres/gpu"
echo "Got: $gres_alloc"
return 1
fi
}
# Main test execution
main() {
echo ""
echo "=========================================="
echo "GPU Test Suite for slurm-docker-cluster"
echo "=========================================="
echo ""
# Check prerequisites
if ! check_gpu_enabled; then
echo ""
echo "GPU profile not enabled. Exiting."
exit 1
fi
if ! check_gpu_worker_running; then
echo ""
echo "No gpu-worker containers running. Exiting."
exit 1
fi
# Run tests (|| true so set -e doesn't abort on first failure; failures are tracked via TESTS_FAILED)
check_gpu_worker_registered || true
check_gres_configured || true
check_gpu_partition || true
check_nvidia_smi || true
test_gpu_job_submission || true
test_gpu_allocation || true
# Summary
echo ""
echo "=========================================="
echo "Test Summary"
echo "=========================================="
echo "Total tests: $TESTS_RUN"
echo -e "${GREEN}Passed: $TESTS_PASSED${NC}"
if [[ $TESTS_FAILED -gt 0 ]]; then
echo -e "${RED}Failed: $TESTS_FAILED${NC}"
exit 1
else
echo -e "${GREEN}All tests passed!${NC}"
exit 0
fi
}
main "$@"