Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
178 changes: 178 additions & 0 deletions .github/workflows/platforms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
name: platforms

on:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
CMAKE_BUILD_PARALLEL_LEVEL: "2"
CMAKE_GENERATOR: Ninja
NATIVE_SHA: 34aedfbe8ed9779697905541a62e2160ccfd9c05

jobs:
msrv:
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Check out exact sources
uses: actions/checkout@v4.4.0
with:
submodules: recursive
- name: Verify checkout and native pin
shell: bash
run: |
set -euo pipefail
test "$(git rev-parse HEAD)" = "$GITHUB_SHA"
test "$(git rev-parse HEAD:vllm-cpp-sys/vllm.cpp)" = "$NATIVE_SHA"
test "$(git -C vllm-cpp-sys/vllm.cpp rev-parse HEAD)" = "$NATIVE_SHA"
test -z "$(git -C vllm-cpp-sys/vllm.cpp status --porcelain)"
- name: Install exact Rust toolchain
uses: dtolnay/rust-toolchain@1.85.0
- name: Install native dependencies
run: sudo apt-get update && sudo apt-get install --yes --no-install-recommends build-essential cmake ninja-build
- name: Install Just
uses: extractions/setup-just@v3.1.0
with:
just-version: "1.40.0"
- name: Check exact MSRV
env:
RUSTUP_TOOLCHAIN: 1.85.0
run: just msrv

linux-arm64-cpu:
runs-on: ubuntu-24.04-arm
timeout-minutes: 60
steps:
- name: Check out exact sources
uses: actions/checkout@v4.4.0
with:
submodules: recursive
- name: Verify checkout, native pin, and host
shell: bash
run: |
set -euo pipefail
test "$(uname -m)" = aarch64
test "$(git rev-parse HEAD)" = "$GITHUB_SHA"
test "$(git rev-parse HEAD:vllm-cpp-sys/vllm.cpp)" = "$NATIVE_SHA"
test "$(git -C vllm-cpp-sys/vllm.cpp rev-parse HEAD)" = "$NATIVE_SHA"
test -z "$(git -C vllm-cpp-sys/vllm.cpp status --porcelain)"
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install native dependencies
run: sudo apt-get update && sudo apt-get install --yes --no-install-recommends build-essential cmake ninja-build
- name: Test model-free ARM64 CPU targets
run: env -u VLLM_CPP_TEST_MODEL cargo test --locked --workspace --all-targets --features vllm-cpp/serde

macos-arm64-cpu:
runs-on: macos-15
timeout-minutes: 60
steps:
- name: Check out exact sources
uses: actions/checkout@v4.4.0
with:
submodules: recursive
- name: Verify checkout, native pin, and host
shell: bash
run: |
set -euo pipefail
test "$(uname -m)" = arm64
test "$(sw_vers -productVersion | cut -d. -f1)" -ge 15
test "$(git rev-parse HEAD)" = "$GITHUB_SHA"
test "$(git rev-parse HEAD:vllm-cpp-sys/vllm.cpp)" = "$NATIVE_SHA"
test "$(git -C vllm-cpp-sys/vllm.cpp rev-parse HEAD)" = "$NATIVE_SHA"
test -z "$(git -C vllm-cpp-sys/vllm.cpp status --porcelain)"
command -v cmake
command -v ninja
xcrun --find clang++
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Test model-free Apple ARM64 CPU targets
run: env -u VLLM_CPP_TEST_MODEL cargo test --locked --workspace --all-targets --features vllm-cpp/serde

macos-arm64-metal-build:
runs-on: macos-15
timeout-minutes: 60
steps:
- name: Check out exact sources
uses: actions/checkout@v4.4.0
with:
submodules: recursive
- name: Verify checkout, native pin, and Metal toolchain
shell: bash
run: |
set -euo pipefail
test "$(uname -m)" = arm64
test "$(sw_vers -productVersion | cut -d. -f1)" -ge 15
test "$(git rev-parse HEAD)" = "$GITHUB_SHA"
test "$(git rev-parse HEAD:vllm-cpp-sys/vllm.cpp)" = "$NATIVE_SHA"
test "$(git -C vllm-cpp-sys/vllm.cpp rev-parse HEAD)" = "$NATIVE_SHA"
test -z "$(git -C vllm-cpp-sys/vllm.cpp status --porcelain)"
command -v cmake
command -v ninja
xcrun --find clang++
sdk=$(xcrun --sdk macosx --show-sdk-path)
test -d "$sdk/System/Library/Frameworks/Metal.framework"
test -d "$sdk/System/Library/Frameworks/Foundation.framework"
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Compile and link Metal Rust targets
run: cargo test --locked -p vllm-cpp-sys --release --tests --features metal --no-run

vulkan-llvmpipe:
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- name: Check out exact sources
uses: actions/checkout@v4.4.0
with:
submodules: recursive
- name: Verify checkout and native pin
shell: bash
run: |
set -euo pipefail
test "$(git rev-parse HEAD)" = "$GITHUB_SHA"
test "$(git rev-parse HEAD:vllm-cpp-sys/vllm.cpp)" = "$NATIVE_SHA"
test "$(git -C vllm-cpp-sys/vllm.cpp rev-parse HEAD)" = "$NATIVE_SHA"
test -z "$(git -C vllm-cpp-sys/vllm.cpp status --porcelain)"
- name: Install Rust and Vulkan dependencies
uses: dtolnay/rust-toolchain@stable
- name: Install Mesa llvmpipe
shell: bash
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install --yes --no-install-recommends build-essential cmake mesa-vulkan-drivers ninja-build python3 vulkan-tools
mapfile -t icds < <(dpkg -L mesa-vulkan-drivers | grep -E '/lvp_icd[^/]*\.json$')
test "${#icds[@]}" -eq 1
echo "VK_DRIVER_FILES=${icds[0]}" >> "$GITHUB_ENV"
echo "VK_ICD_FILENAMES=${icds[0]}" >> "$GITHUB_ENV"
- name: Require llvmpipe Vulkan 1.1 and 16-bit storage
shell: bash
run: |
set -euo pipefail
vulkaninfo --summary | tee vulkan-summary.txt
grep -Eiq 'deviceName.*llvmpipe' vulkan-summary.txt
grep -Eq 'apiVersion.*1\.[1-9]' vulkan-summary.txt
vulkaninfo | tee vulkan-info.txt
grep -Eq 'storageBuffer16BitAccess[[:space:]]*=[[:space:]]*true' vulkan-info.txt
- name: Compile and link the Rust Vulkan surface
run: cargo test --locked -p vllm-cpp-sys --release --tests --features vulkan --no-run
- name: Build and run native Vulkan backend and op gates
shell: bash
run: |
set -euo pipefail
cmake -S vllm-cpp-sys/vllm.cpp -B target/vulkan-native \
-G Ninja -DCMAKE_BUILD_TYPE=Release \
-DVLLM_CPP_BUILD_TESTS=ON -DVLLM_CPP_BUILD_EXAMPLES=OFF \
-DVLLM_CPP_SERVER=OFF -DVLLM_CPP_CUDA=OFF \
-DVLLM_CPP_METAL=OFF -DVLLM_CPP_MLX=OFF \
-DVLLM_CPP_VULKAN=ON -DVLLM_CPP_TRITON=OFF
cmake --build target/vulkan-native --target test_vulkan_backend test_backend_cross_device
ctest --test-dir target/vulkan-native --output-on-failure \
--tests-regex '^(test_vulkan_backend|test_backend_cross_device)$'
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file.
- RAII ownership for native engines, requests, completions, and strings, including callback panic containment and callback-thread-safe deferred request cleanup.
- Linux x86_64 CPU builds for bundled and system libraries with static or dynamic linking.
- Experimental bundled Linux x86_64/aarch64 build integration for CUDA, external CUTLASS, Triton AOT, and Vulkan.
- Bundled Apple ARM64 CPU and Metal build/link integration, plus optional external MLX integration with deterministic target/root/file validation and no packaged MLX payload or rpath.
- Manual hosted exact Rust 1.85.0, Linux ARM64 CPU, Apple ARM64 CPU/Metal compile-link, and Mesa llvmpipe Vulkan lanes.

### Compatibility

Expand All @@ -20,5 +22,6 @@ All notable changes to this project will be documented in this file.
### Known limitations

- The supported runtime tier is native Linux x86_64 CPU. Accelerator features are experimental build/configuration surfaces, not runtime-support claims.
- Known native blockers include a CUDA teardown SIGSEGV after otherwise successful tests, a CUDA bf16 numerical tolerance failure, CUTLASS concurrent-output differences, and incomplete Vulkan runtime coverage.
- Dynamic builds require callers to deploy `libvllm.so` and its runtime dependencies through a loader-visible path. System static builds must also provide the matching private BLAKE3 archive.
- Known native blockers include a CUDA teardown SIGSEGV after otherwise successful tests, a CUDA bf16 numerical tolerance failure, CUTLASS concurrent-output differences, incomplete Vulkan attention/model runtime, and external MLX deployment plus unvalidated release-lane model/runtime behavior.
- The hosted Metal lane checks compile/link only, the software Vulkan lane checks backend/ops only, and accelerator builds do not establish runtime correctness.
- Dynamic builds require callers to deploy `libvllm.so` or `libvllm.dylib` and its runtime dependencies through a loader-visible path. System static builds must also provide the matching private BLAKE3 archive.
25 changes: 18 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ Rust bindings for [vllm.cpp](https://github.com/mudler/vllm.cpp), organized as:

The safe crate provides a cloneable engine API for model loading, blocking completion and streaming, non-blocking concurrent requests, structured output, and raw-JSON chat. An optional `serde` feature adds `serde_json::Value` chat helpers. The sys crate provides checked-in generated FFI declarations with C/Rust layout checks and coverage for all 19 exported C symbols.

Linux x86_64 CPU builds support bundled static, bundled dynamic, system static, and system dynamic linking. Experimental bundled builds also expose Linux x86_64/aarch64 build configuration for CUDA, external CUTLASS, Triton AOT, and Vulkan. These accelerator features are build-only integration surfaces, not runtime-support claims. vllm.cpp is pinned at `34aedfbe8ed9779697905541a62e2160ccfd9c05`, which exposes C ABI version 10.
Linux x86_64 CPU builds support bundled static, bundled dynamic, system static, and system dynamic linking. Bundled CPU builds also target Linux aarch64 and Apple ARM64. Experimental bundled builds expose Linux x86_64/aarch64 build configuration for CUDA, external CUTLASS, Triton AOT, and Vulkan, plus Apple ARM64 Metal and external MLX configuration. Accelerator features are build integration surfaces, not runtime-support claims. vllm.cpp is pinned at `34aedfbe8ed9779697905541a62e2160ccfd9c05`, which exposes C ABI version 10.

## Prerequisites

Initial development and testing support Linux CPU builds. They require:
Native builds require:

- Rust and Cargo.
- CMake 3.24 or newer.
Expand Down Expand Up @@ -62,18 +62,20 @@ cargo test --locked -p vllm-cpp --release --features serde
just ci
```

Set `CMAKE_BUILD_PARALLEL_LEVEL` to control native parallelism. The default bundled build remains deterministic and CPU-only: native tests, examples, the HTTP server, CUDA, Metal, MLX, Vulkan, Triton, and CUTLASS fetching are disabled explicitly. Use `nix develop .#msrv -c just msrv` for the exact local Rust 1.85.0 policy check; hosted exact-MSRV validation is deferred to a later CI slice.
Set `CMAKE_BUILD_PARALLEL_LEVEL` to control native parallelism. The default bundled build remains deterministic and CPU-only: native tests, examples, the HTTP server, CUDA, Metal, MLX, Vulkan, Triton, and CUTLASS fetching are disabled explicitly. Use `nix develop .#msrv -c just msrv` for the exact local Rust 1.85.0 policy check; the manual `platforms` workflow runs the same exact toolchain policy.

`build.rs` is consumer-only native build/link integration; it does not download dependencies or compile/execute the maintainer layout probe. Ordinary consumers do not need Just, bindgen, or libclang. Normal first-time Cargo dependency resolution may access crates.io; use Cargo's standard `--offline` mode after dependencies are cached.

## Experimental Backend Builds

Backend features apply to bundled Linux x86_64/aarch64 builds only and are mutually exclusive with `system`; CUDA and Vulkan are also mutually exclusive. Backend features do not enable `bundled`: normal default-feature commands may use `--features cuda`, while `--no-default-features` callers must include it explicitly, for example `--features bundled,cuda`. Use a fresh `CARGO_TARGET_DIR` for every backend and link mode.
Backend features are bundled-only and mutually exclusive with `system`; CUDA and Vulkan are also mutually exclusive. CUDA/CUTLASS/Triton/Vulkan target Linux x86_64/aarch64, while Metal/MLX require exact `aarch64-apple-darwin`. Backend features do not enable `bundled`: normal default-feature commands may use `--features cuda`, while `--no-default-features` callers must include it explicitly, for example `--features bundled,cuda`. Use a fresh `CARGO_TARGET_DIR` for every backend and link mode.

- `cuda` requires `VLLM_CPP_CUDA_ARCHITECTURES` equal to `80`, `86`, `87`, `89`, `90a`, `100a`, `103a`, `110`, `120a`, `121a`, or `120a;121a`. Leave this variable unset when `cuda` is disabled, including CPU and system builds.
- `cuda-cutlass` implies `cuda`, requires an explicit canonical `VLLM_CPP_CUTLASS_DIR` containing CUTLASS >=4.5.0, disables fetching, and rejects `103a` and `110`. Plain CUDA uses a nonexistent sentinel CUTLASS root so an ambient checkout cannot alter the build.
- `triton-aot` implies `cuda`, enables only checked-in AOT artifacts for one of `80`, `86`, `89`, `90a`, `100a`, or `121a`, and forces regeneration off.
- `vulkan` uses packaged Khronos headers and checked-in SPIR-V. It does not link a Vulkan SDK library; the native library opens the runtime loader dynamically.
- `metal` enables the native Metal backend on Apple ARM64 and links Apple's `Metal` and `Foundation` frameworks. Its MSL is compiled at runtime.
- `mlx` implies `metal` and requires canonical `MLX_ROOT` containing `include/mlx/array.h`, `lib/libmlx.dylib`, and `lib/mlx.metallib`. MLX remains an external dependency: Cargo neither fetches nor packages it and emits no machine-local rpath.

For example:

Expand All @@ -88,11 +90,16 @@ VLLM_CPP_CUDA_ARCHITECTURES=120a \

nix develop .#vulkan
CARGO_TARGET_DIR=target/vulkan-static cargo build --locked --release --features vulkan

# Apple ARM64 only
CARGO_TARGET_DIR=target/metal-static cargo build --locked --release --features metal
MLX_ROOT=/absolute/path/to/mlx CARGO_TARGET_DIR=target/mlx-static \
cargo build --locked --release --features mlx
```

Static CUDA links the exact `cudart`, `cublasLt`, and, for Triton, CUDA driver locations selected by CMake. Dynamic builds rely on `libvllm.so` `DT_NEEDED` entries instead of repeating those transitive Cargo links; deploy the shared library and toolkit libraries through normal loader paths.
Static CUDA links the exact `cudart`, `cublasLt`, and, for Triton, CUDA driver locations selected by CMake. Static Apple builds link `libc++`; Metal adds the `Metal` and `Foundation` frameworks, while MLX adds its canonical `lib` search path before `dylib=mlx`. Dynamic builds rely on the shared native library's transitive dependencies instead of repeating them through Cargo. Deploy `libvllm.so`/`libvllm.dylib` and optional toolkit/MLX libraries through normal loader paths.

Compilation does not establish runtime correctness. Known native evidence blockers remain: CUDA teardown can SIGSEGV after otherwise successful tests; CUDA bf16 testing has a numerical tolerance failure; CUTLASS concurrent output differs from the non-concurrent path; Vulkan runtime coverage is incomplete. No runtime support is claimed here.
Compilation does not establish runtime correctness. Known native evidence blockers remain: CUDA teardown can SIGSEGV after otherwise successful tests; CUDA bf16 testing has a numerical tolerance failure; CUTLASS concurrent output differs from the non-concurrent path; Vulkan attention/model runtime is incomplete; and MLX is an external, numerically distinct provider without release-lane model evidence. No accelerator runtime support is claimed here.

## Test Model and Sanitizers

Expand Down Expand Up @@ -138,9 +145,13 @@ The package gate validates deterministic inventories for both crates, package me

`just publish-dry-run` performs a sys-then-safe workspace packaging dry-run without uploading; it uses `--no-verify` to avoid the pre-publication registry cycle. As required by [RELEASING.md](RELEASING.md), after `vllm-cpp-sys` is available from crates.io, run the full `cargo publish -p vllm-cpp --locked --dry-run` verification before publishing the safe crate.

## Platform and Backend Validation

The manual `platforms` workflow provides exact Rust 1.85.0, Linux ARM64 CPU, Apple ARM64 CPU, Apple ARM64 Metal compile/link, and Mesa llvmpipe Vulkan jobs without duplicating ordinary Linux x86_64 CPU CI. The Vulkan job requires a real llvmpipe device and `storageBuffer16BitAccess`, then runs native backend/op gates; its scope is backend/op checking, not attention or model-inference support. The hosted Metal job checks compile/link only, not runtime correctness.

## Support

The supported runtime target is native Linux x86_64 CPU. Maintainer tests cover the four bundled/system static/dynamic CPU link modes plus bundled blocking and concurrent request inference with the pinned Qwen fixture. Sanitizer evidence covers native ASan/UBSan/leak detection and selected native-only GCC TSan lifecycle paths as described above. Linux CUDA/CUTLASS/Triton/Vulkan features remain experimental build-only surfaces with the limitations listed above; Apple and other accelerator targets are out of scope.
The supported runtime target is native Linux x86_64 CPU. Maintainer tests cover the four bundled/system static/dynamic CPU link modes plus bundled blocking and concurrent request inference with the pinned Qwen fixture. Sanitizer evidence covers native ASan/UBSan/leak detection and selected native-only GCC TSan lifecycle paths as described above. The manual Linux ARM64 and Apple ARM64 CPU jobs are configured for model-free build/test coverage. CUDA/CUTLASS/Triton/Vulkan/Metal/MLX remain experimental surfaces with the evidence boundaries and limitations listed above; CPU is the only supported runtime family.

## Licensing and Affiliation

Expand Down
2 changes: 2 additions & 0 deletions vllm-cpp-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ cuda = []
cuda-cutlass = ["cuda"]
triton-aot = ["cuda"]
vulkan = []
metal = []
mlx = ["metal"]

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
Expand Down
Loading
Loading