Skip to content

Commit 0f907e3

Browse files
Bordaclaude[bot]
andcommitted
feat(xla): test marker, extra + CPU-PJRT CI job
- register `@pytest.mark.xla` marker in pyproject.toml for XLA/torch_xla-runtime tests (any PJRT backend) - add `xla` optional-dependency extra: `torch_xla>=2.5,<3.0; sys_platform == 'linux'` (linux-only wheels; coexists with torch) - exclude xla-marked tests from CPU CI filter (`and not xla`) in ci-tests-cpu.yml - add ci-tests-xla.yml: Linux CPU-PJRT lane (`PJRT_DEVICE=CPU`) running `-m "xla and not gpu"`, self-passes via pytest exit-5 guard until xla tests land --- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
1 parent c3294a5 commit 0f907e3

3 files changed

Lines changed: 96 additions & 1 deletion

File tree

.github/workflows/ci-tests-cpu.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
- name: 🧪 Run the Test
6666
run: |
6767
uv run --no-sync pytest src/ tests/ \
68-
-n 2 -m "not gpu and not coco17 and not e2e_coreml and not e2e_executorch" \
68+
-n 2 -m "not gpu and not coco17 and not e2e_coreml and not e2e_executorch and not xla" \
6969
--ignore=tests/run_smoke_all_models.py \
7070
--ignore=tests/legacy/test_checkpoint_compat.py \
7171
--cov=rfdetr --cov-report=xml \

.github/workflows/ci-tests-xla.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: XLA tests Workflow
2+
3+
# Hardware-free validation of the XLA code paths (grid_sample gather branch, all_gather device
4+
# probe, XLAPrecision selection, bool-mask dtype, keypoint host-sync gates, ...). torch_xla reports
5+
# device.type == "xla" on ANY PJRT backend, so PJRT_DEVICE=CPU exercises every device-gated branch
6+
# without a TPU. Real-TPU-only concerns (MXU/TFLOPS, bf16-MXU convergence parity) stay on Colab/Kaggle.
7+
#
8+
# torch_xla ships Linux x86_64 wheels only -> ubuntu runner. Its minor must match torch's minor;
9+
# floating both to the latest in torch>=2.2,<3 keeps them aligned (torch_xla 2.9 <-> torch 2.9).
10+
#
11+
# Trigger is manual + PR for now; the job self-passes while no @pytest.mark.xla tests exist yet
12+
# (pytest exit code 5 = "no tests collected"). Flip the guard off once Phase 1 lands xla tests.
13+
14+
on:
15+
workflow_dispatch:
16+
pull_request:
17+
branches: ["main", "release/*", "develop"]
18+
paths:
19+
- "src/rfdetr/**"
20+
- "tests/**"
21+
- "pyproject.toml"
22+
- ".github/workflows/ci-tests-xla.yml"
23+
24+
permissions:
25+
contents: read
26+
defaults:
27+
run:
28+
shell: bash
29+
30+
env:
31+
UV_TORCH_BACKEND: "cpu" # CPU-only torch; works with 'uv pip'
32+
PJRT_DEVICE: "CPU" # run XLA on the CPU PJRT plugin (no TPU, no libtpu)
33+
34+
concurrency:
35+
group: pytest-xla-${{ github.ref }}
36+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
37+
38+
jobs:
39+
run-xla-tests:
40+
name: XLA CPU-PJRT testing
41+
timeout-minutes: 25
42+
runs-on: ubuntu-latest
43+
steps:
44+
- name: 📥 Checkout the repository
45+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
46+
47+
- name: 🐍 Install uv and set Python version 3.11
48+
uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0
49+
with:
50+
version: "0.9.26"
51+
python-version: "3.11"
52+
activate-environment: true
53+
54+
- name: 🚀 Install Packages (torch + torch_xla, CPU)
55+
timeout-minutes: 8
56+
# [xla] pulls torch_xla; UV_TORCH_BACKEND=cpu keeps torch CPU-only. Both float to the latest
57+
# matching minor within torch>=2.2,<3, so torch_xla and torch stay ABI-aligned.
58+
run: |
59+
uv pip install -e ".[train,xla,cli]" --group tests
60+
61+
- name: 🔎 Verify torch_xla runtime
62+
run: |
63+
uv run --no-sync python -c "import torch, torch_xla, torch_xla.core.xla_model as xm; d = xm.xla_device(); print('torch', torch.__version__, '| torch_xla', torch_xla.__version__, '| device', d); assert str(d).startswith('xla')"
64+
65+
- name: 🧪 Run the XLA-marked Tests
66+
run: |
67+
set +e
68+
uv run --no-sync pytest src/ tests/ \
69+
-n 1 -m "xla and not gpu" \
70+
--ignore=tests/run_smoke_all_models.py \
71+
--ignore=tests/legacy/test_checkpoint_compat.py \
72+
--timeout=420 \
73+
--durations=50
74+
rc=$?
75+
set -e
76+
if [ "$rc" -eq 5 ]; then
77+
echo "No @pytest.mark.xla tests collected yet (Phase 1 not landed) — passing."
78+
exit 0
79+
fi
80+
exit $rc
81+
82+
- name: Minimize uv cache
83+
continue-on-error: true
84+
run: uv cache prune --ci

pyproject.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,16 @@ visual = [
132132
]
133133
cli = ["jsonargparse[signatures]>=4.27.7"]
134134
plus = ["rfdetr_plus>=1.0.1, <2.0.0"]
135+
# XLA backend for TPU training AND hardware-free XLA validation on CPU/GPU PJRT.
136+
# torch_xla is built on top of torch (NOT mutually exclusive — it requires torch present) and its
137+
# minor MUST match the installed torch minor (torch_xla 2.7.* <-> torch 2.7.*); it does not hard-pin
138+
# torch in requires_dist, so keep the two aligned yourself. Wheels are Linux x86_64 only (py3.10-3.13)
139+
# -> sys_platform marker keeps macOS/Windows installs of this extra a no-op. The bare wheel runs the
140+
# CPU PJRT plugin (PJRT_DEVICE=CPU) with no libtpu; real TPU adds torch_xla[tpu] (libtpu), GPU PJRT
141+
# needs the separate CUDA plugin wheel. Used by ci-tests-xla.yml to exercise @pytest.mark.xla paths.
142+
xla = [
143+
"torch_xla>=2.5,<3.0; sys_platform == 'linux'",
144+
]
135145

136146
[dependency-groups]
137147
# TODO: Temporary: GPU runner only has CUDA 12.8 driver (12080); torch>=2.11 requires a newer driver.
@@ -287,6 +297,7 @@ doctest_norecursedirs = ["tests/*"]
287297
pythonpath = ["src", "."]
288298
markers = [
289299
"gpu: tests that require GPU or are slow on CPU",
300+
"xla: tests that require an XLA device or torch_xla runtime (TPU, or CPU/GPU PJRT)",
290301
"coco17: tests that require COCO 2017 images or annotations",
291302
# `flaky` is provided by pytest-rerunfailures; registered here too for clarity and to stay
292303
# safe under --strict-markers (used by tests/benchmarks/test_training_*.py).

0 commit comments

Comments
 (0)