Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
6756997
docs: add GPUDirect model loading guide for Racer
jveski Oct 27, 2026
377fee4
racer: add opt-in GPU hardware tests for the CUDA shim
jveski Oct 27, 2026
9b48bed
racer: add opt-in Python gpu-read test against a live dataplane
jveski Oct 27, 2026
ac9a79d
racer: add make racer-gpu-test
jveski Oct 27, 2026
aaf9dbd
racer: compile the GPU decrypt kernels with nvcc in CI
jveski Oct 27, 2026
5fe884b
racer: add GPU runner workflow for hardware tests
jveski Oct 27, 2026
f717ca9
racer: document how to run the GPU hardware tests
jveski Oct 27, 2026
9c629f2
racer: expire remembered unsupported read modes and warn on fallback
jveski Oct 27, 2026
6660e89
racer: pin model file versions and log a load summary in racer-vllm
jveski Oct 27, 2026
2af1c0b
racer: support vLLM sharded_state checkpoints in racer-vllm
jveski Oct 27, 2026
541df30
racer: make racer-client and racer-vllm publishable
jveski Oct 27, 2026
3703fe2
racer: document racer-vllm pinning, load summary, mode retry, and sha…
jveski Oct 27, 2026
d6a1dcc
hack: install nvidia-fs for GPUDirect Storage with --gds
jveski Oct 27, 2026
53f4f9a
racer: document how the dataplane sees /dev/nvidia-fs
jveski Oct 27, 2026
651ac36
docs: describe GPUDirect host requirements and the --gds install
jveski Oct 27, 2026
f1d6fac
racer: validate racer-dataplane-config in the operator
jveski Oct 27, 2026
671851a
racer: document what each RACER_DATAPLANE_NVIDIA mode adds
jveski Oct 27, 2026
dac16ab
racer: mount the client socket into init containers
jveski Oct 27, 2026
ffeed0d
racer: ship a cufile.json for the dataplane image
jveski Oct 27, 2026
befca69
racer: select the CUDA dataplane image with RACER_DATAPLANE_CUDA
jveski Oct 27, 2026
0b815d2
racer: publish CUDA dataplane, vLLM images, and Python packages
jveski Oct 28, 2026
ad738d1
racer: route gpu-read imports by client GPU UUID
jveski Oct 27, 2026
87304f8
racer: send the GPU UUID with gpu-read from the Python client
jveski Oct 27, 2026
49b5961
racer: document Racer-Gpu-Uuid for gpu-read
jveski Oct 27, 2026
799c3e5
racer: make the PyPI publish job safe to re-run
jveski Oct 28, 2026
6abab3d
racer: land pages for every GPU on every RDMA rail and free landing b…
jveski Oct 28, 2026
5914188
racer: ask the next provider when a GPU landing misses
jveski Oct 28, 2026
df5f23f
racer: document per-GPU landing across rails and landing lifetime
jveski Oct 28, 2026
482dff3
racer: drop a needless cast in a GPU test helper
jveski Oct 28, 2026
ffc4fe4
racer: keep cuFile on when one device is unsupported
jveski Oct 28, 2026
cc222d4
racer: document per-device cuFile fallback
jveski Oct 28, 2026
4febb50
docs: use the published CUDA dataplane and vLLM images in the vLLM guide
jveski Oct 28, 2026
1a2708a
docs: rewrite the GPUDirect guide for the new setup and checks
jveski Oct 28, 2026
4e0bed4
racer: add RACER_GPU_PCI_P2PDMA to turn on cuFile PCI P2PDMA
jveski Oct 28, 2026
901bf17
racer: validate RACER_GPU_PCI_P2PDMA in the operator
jveski Oct 28, 2026
c37a22b
racer: document RACER_GPU_PCI_P2PDMA
jveski Oct 28, 2026
79c819a
docs: show the P2PDMA setting in the GPUDirect guide
jveski Oct 28, 2026
8487eb8
racer: count GPU plaintext pages, cuFile turn-offs, and landing exhau…
jveski Oct 28, 2026
1f66c2e
racer: export gpu-read, cuFile, and GPU landing metrics
jveski Oct 28, 2026
6aa081c
racer: count landing exhaustion per slice and cuFile-unsupported devices
jveski Oct 28, 2026
5e4dcac
docs: list the GPU metrics in the GPUDirect guide
jveski Oct 28, 2026
df69b11
racer: publish the Python packages only as GitHub release assets
jveski Oct 28, 2026
198335a
docs: install racer-client and racer-vllm from a GitHub release
jveski Oct 28, 2026
eae70eb
racer: build GPU reads into the racer-dataplane image by default
jveski Oct 28, 2026
2a3cdaf
racer: drop the RACER_DATAPLANE_CUDA image switch
jveski Oct 28, 2026
9120a90
docs: GPU mode works with the released racer-dataplane image
jveski Oct 28, 2026
6ef0fba
racer: add GpuSlot for a GPU helper started once on first use
jveski Oct 28, 2026
eff0136
racer: attach GPU landing on already active rails when set late
jveski Oct 28, 2026
6f1c3b9
racer: report racer_gpu_standby while the GPU helper waits
jveski Oct 28, 2026
30e998a
racer: start the GPU helper on the first gpu-read in auto mode
jveski Oct 28, 2026
8086ba5
docs: GPU mode in auto touches no GPU until the first gpu-read
jveski Oct 28, 2026
f30e686
racer-vllm: rewrite the plugin as one module
jveski Oct 28, 2026
cc58c4d
racer-vllm: note in the README that headers are read first
jveski Oct 28, 2026
5168597
racer-vllm: import racer submodules with plain import
jveski Oct 28, 2026
0c8e81b
racer: honor request expiry and cancellation while the GPU helper starts
jveski Oct 28, 2026
6f90914
racer: mirror dataplane per-key config bounds in operator validation
jveski Oct 28, 2026
18a26c3
racer: pass gpu-vm run-command parameters as name=value
jveski Oct 28, 2026
f4c8cbb
racer: honor CUFILE_ALLOW_COMPAT_MODE over cufile.json default
jveski Oct 28, 2026
1d44770
racer: drop canceled waiters while the GPU helper starts
jveski Oct 28, 2026
70c5e8e
racer: install GDS before forcing Fabric Manager in the GPU VM script
jveski Oct 28, 2026
be085c2
racer: replace the CUDA keyring apt pin when keeping the Ubuntu driver
jveski Oct 28, 2026
022e171
docs: note that pages landed over GPUDirect RDMA are not kept
jveski Oct 28, 2026
a5a021a
racer: fail racer-gpu-test when RACER_GPU_E2E=require and no socket i…
jveski Oct 28, 2026
b4f790b
release: include racer-vllm in the release BOM and signature checks
jveski Oct 28, 2026
e78d4dc
racer-vllm: refuse unpinned weight files when racer-model.json exists
jveski Oct 28, 2026
46b8e35
racer-vllm: detect formatted rank placeholders when finding sharded_s…
jveski Oct 28, 2026
7088f63
Delete docs/content/guides/racer-gpudirect.md
jveski Oct 28, 2026
266355a
docs: drop the link to the removed GPUDirect guide
jveski Oct 28, 2026
de8d935
Merge branch 'main' into docs/racer-gpudirect-guide
jveski Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,16 @@ jobs:
- configuration: simulation
features: simulation
native: false
# native compiles the decrypt kernels with nvcc; native-and-simulation
# keeps covering the build without them.
- configuration: native
features: native
native: true
kernels: true
- configuration: native-and-simulation
features: native,simulation
native: true
kernels: false
env:
CARGO_TARGET_DIR: ${{ github.workspace }}/bin/racer-gpu-cargo
CARGO_BUILD_JOBS: "2"
Expand All @@ -387,11 +391,26 @@ jobs:
- name: Set up pinned Rust
run: timeout --signal=TERM --kill-after=10s 300s rustup toolchain install 1.96.0 --profile minimal --component rustfmt,clippy

# No CUDA toolkit on hosted runners: the shim builds without decrypt
# kernels and loads without a driver. Kernel math is covered by the
# C-core tests below and the kernel emulation step.
# Hosted runners have no GPU. nvcc (same package as the dataplane image)
# compiles the decrypt kernels to PTX so they at least build; running
# them needs .github/workflows/racer-gpu.yaml on a GPU runner. Kernel
# math is covered by the C-core tests below and the kernel emulation step.
- name: Install nvcc
if: matrix.kernels
run: |
timeout --signal=TERM --kill-after=10s 120s curl -fsSL -o "$RUNNER_TEMP/cuda-keyring.deb" \
https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i "$RUNNER_TEMP/cuda-keyring.deb"
timeout --signal=TERM --kill-after=10s 300s sudo apt-get update
timeout --signal=TERM --kill-after=10s 600s sudo apt-get install -y --no-install-recommends cuda-nvcc-12-9
echo /usr/local/cuda/bin >> "$GITHUB_PATH"

- name: Compile CUDA shim with kernels (not hardware validation)
if: matrix.kernels
run: RACER_GPU_REQUIRE_PTX=1 timeout --signal=TERM --kill-after=10s 300s sh images/racer-dataplane/build-native-cuda.sh cmd/racer-dataplane/gpu/native bin/racer-gpu-native/libracer_gpu_cuda.so.1

- name: Compile CUDA shim without kernels (not hardware validation)
if: matrix.native
if: matrix.native && !matrix.kernels
run: timeout --signal=TERM --kill-after=10s 300s sh images/racer-dataplane/build-native-cuda.sh cmd/racer-dataplane/gpu/native bin/racer-gpu-native/libracer_gpu_cuda.so.1

- name: Require CUDA shim ABI and symbols (no hardware)
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ jobs:
# - orca : deployed separately by deploy-orca
# - racer-object : injected sidecars and per-ClusterCache
# origin DaemonSets from the racer component
# - racer-vllm : vLLM with the Racer loader; not deployed
#
# machine-ops-controller is omitted on purpose: the operator synthesizes
# metalman per Site instead, so machine-ops is never rolled out here.
Expand Down Expand Up @@ -297,6 +298,9 @@ jobs:
file: images/racer-dataplane/Containerfile
- name: racer-object
file: images/racer-object/Containerfile
- name: racer-vllm
file: images/racer-vllm/Containerfile
large: true
- name: orca
file: images/orca/Containerfile
- name: inventory-aggregator
Expand All @@ -316,6 +320,14 @@ jobs:
- name: Normalize container registry to lowercase
run: echo "REGISTRY=${REGISTRY,,}" >> "$GITHUB_ENV"

- name: Free disk space for large images
# The vLLM base image alone is larger than a hosted runner's free disk.
if: matrix.component.large
run: |
set -euo pipefail
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
df -h /

- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1

- name: Log in to ghcr.io
Expand Down
73 changes: 73 additions & 0 deletions .github/workflows/racer-gpu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0

name: racer gpu

# Runs `make racer-gpu-test` on a GPU runner: the CUDA shim with its decrypt
# kernels, device discovery, client allocation import, GPU decrypt against the
# CPU result, and cuFile reads. Hosted runners have no GPU, so this runs only
# when the repository variable RACER_GPU_RUNNER holds the runner labels as a
# JSON array, for example ["self-hosted", "linux", "gpu"]. Without it the job
# is skipped instead of queuing forever (forks, repos without GPU runners).
#
# The runner needs an NVIDIA driver, gcc, curl and sudo apt access (for nvcc
# if it is not installed). Set RACER_GPU_CUFILE=require to fail when cuFile
# cannot open, on runners with GPUDirect Storage.
on:
workflow_dispatch:
schedule:
- cron: "17 6 * * *"

permissions:
contents: read

concurrency:
group: racer-gpu-${{ github.ref }}
cancel-in-progress: true

jobs:
gpu:
name: Racer GPU hardware tests
if: vars.RACER_GPU_RUNNER != ''
runs-on: ${{ fromJSON(vars.RACER_GPU_RUNNER || '["ubuntu-24.04"]') }}
timeout-minutes: 45
env:
CARGO_TARGET_DIR: ${{ github.workspace }}/bin/racer-gpu-cargo
RACER_GPU_TESTS_CUFILE: ${{ vars.RACER_GPU_CUFILE }}
RACER_GPU_TEST_DIR: ${{ github.workspace }}/tmp/racer-gpu
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Show GPUs
run: timeout --signal=TERM --kill-after=10s 60s nvidia-smi

- name: Set up pinned Rust
run: |
if ! command -v rustup >/dev/null; then
timeout --signal=TERM --kill-after=10s 300s sh -c 'curl -fsSL https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain none'
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.cargo/bin:$PATH"
fi
timeout --signal=TERM --kill-after=10s 300s rustup toolchain install 1.96.0 --profile minimal
rustup override set 1.96.0

- name: Install nvcc if missing
run: |
if command -v nvcc >/dev/null || [ -x /usr/local/cuda/bin/nvcc ]; then
echo /usr/local/cuda/bin >> "$GITHUB_PATH"
exit 0
fi
. /etc/os-release
repo="${ID}${VERSION_ID//./}/$(uname -m | sed 's/aarch64/sbsa/')"
timeout --signal=TERM --kill-after=10s 120s curl -fsSL -o "$RUNNER_TEMP/cuda-keyring.deb" \
"https://developer.download.nvidia.com/compute/cuda/repos/$repo/cuda-keyring_1.1-1_all.deb"
sudo dpkg -i "$RUNNER_TEMP/cuda-keyring.deb"
timeout --signal=TERM --kill-after=10s 300s sudo apt-get update
timeout --signal=TERM --kill-after=10s 600s sudo apt-get install -y --no-install-recommends cuda-nvcc-12-9
echo /usr/local/cuda/bin >> "$GITHUB_PATH"

- name: Run GPU hardware tests
run: |
mkdir -p "$RACER_GPU_TEST_DIR"
timeout --signal=TERM --kill-after=30s 2400s make racer-gpu-test RACER_GPU_TESTS=require
54 changes: 53 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ name: unbounded release
# -> metalman-image (stamped with the matching default netboot image)
# -> component-images (matrix: machina, machine-ops-controller, unbounded-operator,
# token-refresher, orca, gantry, racer-dataplane,
# racer-object, host-ubuntu2404,
# racer-object, racer-vllm,
# host-ubuntu2404,
# host-azurelinux3, host-azurelinux3-nvidia,
# inventory-aggregator, inventory-inspector,
# inventory-viewer)
# -> gantry-chart (OCI chart + signed downloadable archive)
# -> manifests-tarball (make release-manifests + cosign sign)
# -> python-packages (racer-client and racer-vllm sdists and wheels)
# -> finalize (attach extras + krew manifest)
#
# All artifacts land on a single GitHub release that is left as a draft.
Expand Down Expand Up @@ -867,6 +869,8 @@ jobs:
file: images/gantry/Containerfile
platforms: linux/amd64,linux/arm64
trivy: true
# Includes GPU reads (CUDA shim and cuFile). The dataplane touches no
# GPU until a client sends the first gpu-read.
- name: racer-dataplane
file: images/racer-dataplane/Containerfile
platforms: linux/amd64,linux/arm64
Expand All @@ -875,6 +879,13 @@ jobs:
file: images/racer-object/Containerfile
platforms: linux/amd64,linux/arm64
trivy: true
# vLLM with racer-client and racer-vllm. The upstream vLLM base is
# not ours to patch, so it is not gated on Trivy.
- name: racer-vllm
file: images/racer-vllm/Containerfile
platforms: linux/amd64
trivy: false
large: true
- name: host-ubuntu2404
file: images/host-ubuntu2404/Containerfile
platforms: linux/amd64,linux/arm64
Expand Down Expand Up @@ -905,6 +916,14 @@ jobs:
- name: Normalize container registry to lowercase
run: echo "REGISTRY=${REGISTRY,,}" >> "$GITHUB_ENV"

- name: Free disk space for large images
# The vLLM base image alone is larger than a hosted runner's free disk.
if: matrix.component.large
run: |
set -euo pipefail
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
df -h /

- name: Install cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2

Expand Down Expand Up @@ -1143,6 +1162,38 @@ jobs:
# Past the window the only recovery is a full re-run.
retention-days: 7

# ---------------------------------------------------------------------------
# Build sdists and wheels for the Racer Python packages (racer-client and
# racer-vllm) and attach them to the draft release. The release is the only
# place they are published; nothing is uploaded to PyPI.
# ---------------------------------------------------------------------------
python-packages:
needs: version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Build sdists and wheels
run: |
set -euo pipefail
python3 -m venv "$RUNNER_TEMP/build-venv"
"$RUNNER_TEMP/build-venv/bin/pip" install --quiet build==1.3.0
for package in racer racer-vllm; do
timeout --signal=TERM --kill-after=10s 300s \
"$RUNNER_TEMP/build-venv/bin/python" -m build --sdist --wheel \
--outdir dist/python "clients/python/$package"
done
ls -l dist/python

- name: Attach Python packages to the release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
TAG: ${{ needs.version.outputs.tag }}
run: |
set -euo pipefail
gh release upload "$TAG" dist/python/* --clobber

# ---------------------------------------------------------------------------
# Attach the manifests tarball + krew manifest to the draft release that
# GoReleaser created and set release notes. The release stays a draft here;
Expand All @@ -1160,6 +1211,7 @@ jobs:
- component-images
- gantry-chart
- manifests-tarball
- python-packages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
26 changes: 26 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ help: ## Show this help
@echo ""
@echo "Racer:"
@echo " racer-test Test the Rust Racer workspace and Go Racer API and wire contracts"
@echo " racer-gpu-test Build the CUDA shim with kernels and run GPU hardware tests"
@echo " racer-envtest Run Racer API-server tests with KUBEBUILDER_ASSETS"
@echo " racer-envtest-ci Provision pinned assets and run Racer API-server tests"
@echo " racer-generate Generate Racer deepcopy and CRD artifacts"
Expand Down Expand Up @@ -575,6 +576,23 @@ racer-rust-test: ## Test the Rust Racer workspace, including the embedded cluste

racer-test: racer-go-test racer-rust-test ## Check Racer

RACER_GPU_NATIVE ?= $(CURDIR)/bin/racer-gpu-native
# 1 skips when no GPU is found; require fails instead (dedicated GPU runners).
RACER_GPU_TESTS ?= require

.PHONY: racer-gpu-test
racer-gpu-test: ## Build the CUDA shim with kernels (needs nvcc) and run GPU hardware tests (needs a GPU)
RACER_GPU_REQUIRE_PTX=1 timeout --signal=TERM --kill-after=10s 600s sh images/racer-dataplane/build-native-cuda.sh cmd/racer-dataplane/gpu/native "$(RACER_GPU_NATIVE)/libracer_gpu_cuda.so.1"
LD_LIBRARY_PATH="$(RACER_GPU_NATIVE)$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}" timeout --signal=TERM --kill-after=10s 300s cargo test --locked --manifest-path cmd/racer-dataplane/Cargo.toml -p racer-gpu --no-default-features --features native --lib ffi::tests::required_native_shim_loads_abi_and_symbols -- --exact --ignored
LD_LIBRARY_PATH="$(RACER_GPU_NATIVE)$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}" RACER_GPU_TESTS=$(RACER_GPU_TESTS) timeout --signal=TERM --kill-after=10s 900s cargo test --locked --manifest-path cmd/racer-dataplane/Cargo.toml -p racer-gpu --no-default-features --features native --test hardware -- --nocapture --test-threads=1
@if [ -n "$$RACER_GPU_E2E_SOCKET" ]; then \
test -x "$(RACER_PY_VENV)/bin/pytest" || { timeout --signal=TERM --kill-after=10s 120s python3 -m venv "$(RACER_PY_VENV)" && \
timeout --signal=TERM --kill-after=10s 300s "$(RACER_PY_VENV)/bin/pip" install -q pytest; }; \
cd clients/python/racer && PYTHONPATH=src timeout --signal=TERM --kill-after=10s 300s "$(RACER_PY_VENV)/bin/pytest" -q -p no:cacheprovider -m gpu -rs; \
elif [ "$$RACER_GPU_E2E" = require ]; then \
echo "RACER_GPU_E2E=require but RACER_GPU_E2E_SOCKET is unset" >&2; exit 1; \
else echo "RACER_GPU_E2E_SOCKET unset: skipping the Python gpu-read test against a live dataplane"; fi

RACER_PY_VENV ?= $(CURDIR)/tmp/racer-python-venv

.PHONY: racer-python-test
Expand All @@ -584,6 +602,14 @@ racer-python-test: ## Run the Racer Python client and vLLM plugin tests (no GPU
cd clients/python/racer && PYTHONPATH=src timeout --signal=TERM --kill-after=10s 300s "$(RACER_PY_VENV)/bin/pytest" -q -p no:cacheprovider
cd clients/python/racer-vllm && PYTHONPATH=src:../racer/src timeout --signal=TERM --kill-after=10s 300s "$(RACER_PY_VENV)/bin/pytest" -q -p no:cacheprovider

.PHONY: racer-python-dist
racer-python-dist: ## Build sdists and wheels for racer-client and racer-vllm into tmp/racer-python-dist
@test -x "$(RACER_PY_VENV)/bin/pyproject-build" || { timeout --signal=TERM --kill-after=10s 120s python3 -m venv "$(RACER_PY_VENV)" && \
timeout --signal=TERM --kill-after=10s 300s "$(RACER_PY_VENV)/bin/pip" install -q build; }
rm -rf tmp/racer-python-dist
timeout --signal=TERM --kill-after=10s 300s "$(RACER_PY_VENV)/bin/python" -m build -o tmp/racer-python-dist clients/python/racer
timeout --signal=TERM --kill-after=10s 300s "$(RACER_PY_VENV)/bin/python" -m build -o tmp/racer-python-dist clients/python/racer-vllm

$(SETUP_ENVTEST):
@mkdir -p bin tmp/envtest-tools
TMPDIR="$(CURDIR)/tmp/envtest-tools" GOBIN="$(CURDIR)/bin" timeout --signal=TERM --kill-after=10s 300s $(GOCMD) install sigs.k8s.io/controller-runtime/tools/setup-envtest@$(SETUP_ENVTEST_VERSION)
Expand Down
Loading
Loading