Skip to content

Commit 39cb970

Browse files
Fix runners GPU isolation
1 parent 72d01a0 commit 39cb970

1 file changed

Lines changed: 113 additions & 70 deletions

File tree

.github/workflows/rocm-ci.yml

Lines changed: 113 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,19 @@ jobs:
147147
run: |
148148
DEVICE_FLAG="$(cat /etc/podinfo/gha-render-devices 2>/dev/null || echo --device=/dev/dri)"
149149
test -n "$DEVICE_FLAG"
150+
mapfile -t RENDER_DEVICES < <(grep -oE '/dev/dri/renderD[0-9]+' <<< "$DEVICE_FLAG" || true)
151+
GPU_COUNT="${#RENDER_DEVICES[@]}"
152+
GPU_ENV=()
153+
if [ "$GPU_COUNT" -gt 0 ]; then
154+
GPU_IDS="$(seq -s, 0 $((GPU_COUNT - 1)))"
155+
GPU_ENV=(-e "ROCR_VISIBLE_DEVICES=$GPU_IDS" -e "HIP_VISIBLE_DEVICES=$GPU_IDS")
156+
fi
150157
docker run -dt \
151158
--rm \
152159
--name te-runner \
153160
--network=host \
154161
--device=/dev/kfd $DEVICE_FLAG \
162+
"${GPU_ENV[@]}" \
155163
--shm-size=16G \
156164
--pid=host \
157165
--group-add $(getent group render | cut -d: -f3) \
@@ -182,9 +190,7 @@ jobs:
182190
183191
- name: Run sGPU tests in parallel (pytorch, jax, examples, core)
184192
id: run-tests
185-
# Below the job's timeout-minutes so an overrun kills only this step;
186-
# the `if: always()` report + upload steps still run (artifacts survive).
187-
timeout-minutes: 180
193+
timeout-minutes: 240
188194
env:
189195
HF_TOKEN: ${{ secrets.HF_TOKEN }}
190196
run: |
@@ -194,97 +200,132 @@ jobs:
194200
# exists in both the torch and jax suites and runs in parallel).
195201
rm -rf test-results && mkdir -p test-results/torch test-results/jax test-results/core
196202
197-
docker exec \
198-
-e TEST_SGPU=1 \
199-
-e TEST_LEVEL=${{ env.TEST_LEVEL }} \
200-
-e JUNITXML_PREFIX=/workspace/test-results/ \
201-
-e JUNITXML_SUFFIX=.xml \
202-
-e HF_TOKEN="$HF_TOKEN" \
203-
te-runner bash -c "$(cat <<'EOF'
204-
#!/usr/bin/bash
205-
set -x -o pipefail
206-
ulimit -c 0 # Disable core dumps
207-
208-
# Each suite appends its own subdir to the inherited base prefix so the
209-
# base path is defined once in the docker-exec env above (inline VAR=val
210-
# applies only to that backgrounded subprocess; the sourced _utils.sh
211-
# reads it from the env).
212-
HIP_VISIBLE_DEVICES=0 JUNITXML_PREFIX=${JUNITXML_PREFIX}torch/ ci/pytorch.sh > /workspace/torch.log 2>&1 &
213-
TORCH_PID=$!
214-
215-
HIP_VISIBLE_DEVICES=1 JUNITXML_PREFIX=${JUNITXML_PREFIX}jax/ ci/jax.sh > /workspace/jax.log 2>&1 &
216-
JAX_PID=$!
217-
218-
(
219-
set -e
220-
python -c "import os; print('HF_TOKEN set:', bool(os.environ.get('HF_TOKEN')))"
203+
INSTALLED_IMAGE="te-runner-installed:${{ github.run_id }}-${{ matrix.arch_label }}"
204+
docker commit te-runner "$INSTALLED_IMAGE" >/dev/null
221205
222-
JAX_CONSTRAINTS=/tmp/jax-constraints.txt
223-
pip freeze | grep -iE '^(jax|jaxlib|jax[_-]rocm|jax[_-]plugins)[=@]' > "$JAX_CONSTRAINTS" || true
224-
225-
export HIP_VISIBLE_DEVICES=2
226-
227-
cd /workspace/examples/pytorch/mnist
228-
python main.py
229-
python main.py --use-te
230-
python main.py --use-fp8
206+
mapfile -t RENDER_DEVICES < <(grep -oE '/dev/dri/renderD[0-9]+' /etc/podinfo/gha-render-devices 2>/dev/null || true)
207+
if [ "${#RENDER_DEVICES[@]}" -eq 0 ]; then
208+
mapfile -t RENDER_DEVICES < <(find /dev/dri -maxdepth 1 -name 'renderD*' | sort | head -4)
209+
fi
210+
if [ "${#RENDER_DEVICES[@]}" -lt 4 ]; then
211+
echo "::error::Expected at least 4 render devices, found ${#RENDER_DEVICES[@]}."
212+
exit 1
213+
fi
231214
232-
cd /workspace/examples/jax/mnist
233-
pip3 install -c "$JAX_CONSTRAINTS" -r requirements.txt
234-
python test_single_gpu_mnist.py
235-
python test_single_gpu_mnist.py --use-te
236-
python test_single_gpu_mnist.py --use-fp8
215+
cat > .te-ci-torch.sh <<'EOF'
216+
set -x -o pipefail
217+
ulimit -c 0
218+
JUNITXML_PREFIX=${JUNITXML_PREFIX}torch/ ci/pytorch.sh
219+
EOF
237220
238-
cd /workspace/examples/jax/encoder
239-
pip3 install -c "$JAX_CONSTRAINTS" -r requirements.txt
240-
python test_single_gpu_encoder.py
241-
python test_single_gpu_encoder.py --use-fp8
242-
) > /workspace/examples.log 2>&1 &
243-
EXAMPLES_PID=$!
221+
cat > .te-ci-jax.sh <<'EOF'
222+
set -x -o pipefail
223+
ulimit -c 0
224+
JUNITXML_PREFIX=${JUNITXML_PREFIX}jax/ ci/jax.sh
225+
EOF
244226
245-
HIP_VISIBLE_DEVICES=3 JUNITXML_PREFIX=${JUNITXML_PREFIX}core/ ci/core.sh > /workspace/core.log 2>&1 &
246-
CORE_PID=$!
227+
cat > .te-ci-examples.sh <<'EOF'
228+
set -ex -o pipefail
229+
ulimit -c 0
230+
python -c "import os; print('HF_TOKEN set:', bool(os.environ.get('HF_TOKEN')))"
231+
232+
JAX_CONSTRAINTS=/tmp/jax-constraints.txt
233+
pip freeze | grep -iE '^(jax|jaxlib|jax[_-]rocm|jax[_-]plugins)[=@]' > "$JAX_CONSTRAINTS" || true
234+
235+
cd /workspace/examples/pytorch/mnist
236+
python main.py
237+
python main.py --use-te
238+
python main.py --use-fp8
239+
240+
cd /workspace/examples/jax/mnist
241+
pip3 install -c "$JAX_CONSTRAINTS" -r requirements.txt
242+
python test_single_gpu_mnist.py
243+
python test_single_gpu_mnist.py --use-te
244+
python test_single_gpu_mnist.py --use-fp8
245+
246+
cd /workspace/examples/jax/encoder
247+
pip3 install -c "$JAX_CONSTRAINTS" -r requirements.txt
248+
python test_single_gpu_encoder.py
249+
python test_single_gpu_encoder.py --use-fp8
250+
EOF
247251
248-
wait $TORCH_PID; torch_rc=$?
249-
wait $JAX_PID; jax_rc=$?
250-
wait $EXAMPLES_PID; examples_rc=$?
251-
wait $CORE_PID; core_rc=$?
252+
cat > .te-ci-core.sh <<'EOF'
253+
set -x -o pipefail
254+
ulimit -c 0
255+
JUNITXML_PREFIX=${JUNITXML_PREFIX}core/ ci/core.sh
256+
EOF
252257
253-
if [ $torch_rc -ne 0 ]; then
258+
run_gpu_suite() {
259+
local name="$1"
260+
local gpu_index="$2"
261+
local log_file="$3"
262+
local script_path="$4"
263+
docker rm -f "te-runner-$name" >/dev/null 2>&1 || true
264+
docker run -d \
265+
--name "te-runner-$name" \
266+
--network=host \
267+
--device=/dev/kfd \
268+
--device="${RENDER_DEVICES[$gpu_index]}" \
269+
--shm-size=16G \
270+
--pid=host \
271+
--group-add "$(getent group render | cut -d: -f3)" \
272+
--group-add "$(getent group video | cut -d: -f3)" \
273+
-e TEST_SGPU=1 \
274+
-e TEST_LEVEL=${{ env.TEST_LEVEL }} \
275+
-e JUNITXML_PREFIX=/workspace/test-results/ \
276+
-e JUNITXML_SUFFIX=.xml \
277+
-e HF_TOKEN="$HF_TOKEN" \
278+
-e ROCR_VISIBLE_DEVICES=0 \
279+
-e HIP_VISIBLE_DEVICES=0 \
280+
-v "${{ github.workspace }}:/workspace" \
281+
-w /workspace \
282+
"$INSTALLED_IMAGE" \
283+
bash -lc "bash $script_path > $log_file 2>&1"
284+
}
285+
286+
TORCH_CID="$(run_gpu_suite torch 0 /workspace/torch.log /workspace/.te-ci-torch.sh)"
287+
JAX_CID="$(run_gpu_suite jax 1 /workspace/jax.log /workspace/.te-ci-jax.sh)"
288+
EXAMPLES_CID="$(run_gpu_suite examples 2 /workspace/examples.log /workspace/.te-ci-examples.sh)"
289+
CORE_CID="$(run_gpu_suite core 3 /workspace/core.log /workspace/.te-ci-core.sh)"
290+
291+
torch_rc="$(docker wait "$TORCH_CID")"
292+
jax_rc="$(docker wait "$JAX_CID")"
293+
examples_rc="$(docker wait "$EXAMPLES_CID")"
294+
core_rc="$(docker wait "$CORE_CID")"
295+
296+
if [ "$torch_rc" -ne 0 ]; then
254297
echo "::group::[FAILED] PyTorch Log"
255-
cat /workspace/torch.log
298+
cat torch.log || true
256299
echo "::endgroup::"
257300
echo "::error::PyTorch tests FAILED."
258-
touch /workspace/FAIL_TORCH
301+
touch FAIL_TORCH
259302
fi
260303
261-
if [ $jax_rc -ne 0 ]; then
304+
if [ "$jax_rc" -ne 0 ]; then
262305
echo "::group::[FAILED] JAX Log"
263-
cat /workspace/jax.log
306+
cat jax.log || true
264307
echo "::endgroup::"
265308
echo "::error::JAX tests FAILED."
266-
touch /workspace/FAIL_JAX
309+
touch FAIL_JAX
267310
fi
268311
269-
if [ $examples_rc -ne 0 ]; then
312+
if [ "$examples_rc" -ne 0 ]; then
270313
echo "::group::[FAILED] Examples Log"
271-
cat /workspace/examples.log
314+
cat examples.log || true
272315
echo "::endgroup::"
273316
echo "::error::Examples FAILED."
274-
touch /workspace/FAIL_EXAMPLES
317+
touch FAIL_EXAMPLES
275318
fi
276319
277-
if [ $core_rc -ne 0 ]; then
320+
if [ "$core_rc" -ne 0 ]; then
278321
echo "::group::[FAILED] Core Log"
279-
cat /workspace/core.log
322+
cat core.log || true
280323
echo "::endgroup::"
281324
echo "::error::Core tests FAILED."
282-
touch /workspace/FAIL_CORE
325+
touch FAIL_CORE
283326
fi
284327
285-
test $torch_rc -eq 0 -a $jax_rc -eq 0 -a $examples_rc -eq 0 -a $core_rc -eq 0
286-
EOF
287-
)"
328+
test "$torch_rc" -eq 0 -a "$jax_rc" -eq 0 -a "$examples_rc" -eq 0 -a "$core_rc" -eq 0
288329
289330
- name: Generate test report
290331
if: always()
@@ -335,7 +376,9 @@ jobs:
335376

336377
- name: Cleanup container
337378
if: always()
338-
run: docker rm -f te-runner || true
379+
run: |
380+
docker rm -f te-runner te-runner-torch te-runner-jax te-runner-examples te-runner-core || true
381+
docker image rm "te-runner-installed:${{ github.run_id }}-${{ matrix.arch_label }}" || true
339382
340383
mgpu_tests:
341384
name: mGPU ${{ matrix.framework == 'pytorch' && 'Torch' || 'JAX' }} (${{ matrix.arch_label }})
@@ -398,7 +441,7 @@ jobs:
398441
id: mgpu-tests
399442
# Below the job's timeout-minutes so an overrun kills only this step;
400443
# the `if: always()` report + upload steps still run (artifacts survive).
401-
timeout-minutes: 180
444+
timeout-minutes: 240
402445
env:
403446
HF_TOKEN: ${{ secrets.HF_TOKEN }}
404447
run: |

0 commit comments

Comments
 (0)