@@ -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