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
36 changes: 30 additions & 6 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,28 @@ build-support-test:
-o "$temp/build-support-tests"
"$temp/build-support-tests"

# Test the pure Linux backend build planner without configuring CMake.
backend-config:
#!/usr/bin/env bash
set -euo pipefail
temp=$(mktemp -d)
trap 'rm -rf "$temp"' EXIT
rustc --edition=2021 --test -D warnings \
{{ quote(root + "/vllm-cpp-sys/tests/build_config.rs") }} \
-o "$temp/build-config-tests"
"$temp/build-config-tests"

# Verify pinned CUDA architecture mappings and vendored Triton AOT inputs.
backend-integrity:
cd {{ quote(root) }} && cmake -P vllm-cpp-sys/vllm.cpp/cmake/CudaArchFeaturesTest.cmake
cd {{ quote(root) }} && bash vllm-cpp-sys/vllm.cpp/scripts/check-triton-aot-drift.sh

# Run the focused C/Rust layout conformance test.
layout-test:
CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-{{ root }}/target/layout-test}" cargo test --locked -p vllm-cpp-sys --release --test layout

# Run generated-binding, header, and layout conformance checks.
sys: bindings-check header-check build-support-test layout-test
# Run generated-binding, header, layout, and backend configuration conformance checks.
sys: bindings-check header-check build-support-test backend-config backend-integrity layout-test

# Test all Linux CPU link modes and the exact shared-library exports.
link-modes:
Expand Down Expand Up @@ -368,10 +384,14 @@ package-test:
README.md
THIRD_PARTY.md
build.rs
licenses/FLASH-ATTENTION-BSD-3-CLAUSE.txt
licenses/FLASH-LINEAR-ATTENTION-MIT.txt
wrapper.h
src/bindings.rs
src/build_config.rs
src/build_support.rs
src/lib.rs
tests/build_config.rs
tests/build_support.rs
tests/layout.c
tests/layout.rs
Expand All @@ -385,11 +405,15 @@ package-test:
vllm.cpp/src/capi/engine_handle.h
vllm.cpp/src/capi/vllm_c.cpp
vllm.cpp/src/vllm/version.cpp
vllm.cpp/src/vt/cuda/triton_aot_vendored/sm_121a/MANIFEST
vllm.cpp/scripts/triton-aot-compile.py
vllm.cpp/triton_kernels/chunk_delta_h.py
vllm.cpp/third_party/README.md
vllm.cpp/third_party/blake3/LICENSE_A2
vllm.cpp/third_party/blake3/LICENSE_CC0
vllm.cpp/third_party/minja/LICENSE
vllm.cpp/third_party/nlohmann/json.hpp
vllm.cpp/third_party/vulkan/vulkan_core.h
)
for member in "${required_members[@]}"; do
[[ -s $package_root/$member ]] || {
Expand All @@ -413,16 +437,19 @@ package-test:
vllm.cpp/cmake
vllm.cpp/include
vllm.cpp/src
vllm.cpp/scripts/triton-aot-compile.py
vllm.cpp/triton_kernels
vllm.cpp/third_party/README.md
vllm.cpp/third_party/blake3
vllm.cpp/third_party/minja
vllm.cpp/third_party/nlohmann
vllm.cpp/third_party/vulkan
)
diff -u \
<(native_inventory "$repo_root/vllm-cpp-sys" "${native_members[@]}") \
<(native_inventory "$package_root" "${native_members[@]}")
diff -u \
<(printf '%s\n' CMakeLists.txt LICENSE NOTICE cmake include src third_party | LC_ALL=C sort) \
<(printf '%s\n' CMakeLists.txt LICENSE NOTICE cmake include scripts src third_party triton_kernels | LC_ALL=C sort) \
<(find "$package_root/vllm.cpp" -mindepth 1 -maxdepth 1 -printf '%f\n' | LC_ALL=C sort)
denied_members=(
Justfile
Expand All @@ -434,13 +461,10 @@ package-test:
vllm.cpp/benchmarks
vllm.cpp/docs
vllm.cpp/examples
vllm.cpp/scripts
vllm.cpp/tests
vllm.cpp/tools
vllm.cpp/triton_kernels
vllm.cpp/third_party/doctest
vllm.cpp/third_party/httplib
vllm.cpp/third_party/vulkan
)
for member in "${denied_members[@]}"; do
[[ ! -e $package_root/$member ]] || {
Expand Down
48 changes: 35 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ 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. 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. 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.

## Prerequisites

Expand All @@ -22,10 +22,12 @@ Initial development and testing support Linux CPU builds. They require:
- A system linker and C++ standard library.
- Just 1.40 or newer for maintainer workflows, plus Git, `jq`, GNU tar, and `curl` for the model fixture recipe.

This repository provides a Nix development shell with the pinned development tools:
This repository provides a Nix development shell with the pinned development tools. Linux also has minimal CUDA and Vulkan shells:

```console
nix develop
nix develop .#cuda
nix develop .#vulkan
```

## Checkout
Expand Down Expand Up @@ -60,15 +62,7 @@ println!("{:?}", request.wait()?);

All streaming callbacks receive copied UTF-8 deltas. Blocking callbacks may borrow stack data; their panics are caught before the C boundary and resumed only after the native call returns. Asynchronous callbacks must be `Send + 'static`, run on a native delivery thread, and report panic as `Error::CallbackPanicked` from `wait`. Waiting for or freeing a request from its own callback thread is prohibited by ABI v10: `wait` returns `Error::RequestCallbackThread`, while drop transfers cleanup to a prestarted reaper that owns the request, callback, and engine until native free/cancel/join completes. Chat methods accept raw OpenAI-compatible request JSON; enable `serde` for `serde_json::Value` request and response helpers.

Run the practical examples with a model directory:

```console
cargo run -p vllm-cpp --example complete -- <model-directory>
cargo run -p vllm-cpp --example stream -- <model-directory>
cargo run -p vllm-cpp --example concurrent -- <model-directory>
cargo run -p vllm-cpp --example chat -- <model-directory>
cargo run -p vllm-cpp --example structured -- <model-directory>
```
See [the examples guide](vllm-cpp/examples/README.md) for ordinary Linux and optional Nix setup and commands for every example.

## Build and Test

Expand All @@ -81,10 +75,38 @@ cargo test --locked -p vllm-cpp --release --features serde
just ci
```

Set `CMAKE_BUILD_PARALLEL_LEVEL` to control native parallelism. The bundled build is deterministic and CPU-only: native tests, examples, the HTTP server, CUDA, Metal, MLX, Vulkan, Triton, and CUTLASS fetching are disabled explicitly.
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.

`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.

- `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.

For example:

```console
nix develop .#cuda
VLLM_CPP_CUDA_ARCHITECTURES=120a \
CARGO_TARGET_DIR=target/cuda-static \
cargo build --locked --release --features cuda
VLLM_CPP_CUDA_ARCHITECTURES=120a \
CARGO_TARGET_DIR=target/cuda-dynamic \
cargo build --locked --release --features cuda,dynamic-link

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

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.

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.

## Test Model and Sanitizers

Model-backed tests use Apache-2.0 `Qwen/Qwen3-0.6B` at pinned revision `c1899de289a04d12100db370d81485cdf75e47ca`. Download or reuse the cache and verify every file, then run exactly 14 blocking and request-lifecycle model tests serially:
Expand Down Expand Up @@ -129,7 +151,7 @@ The package gate preserves the sys crate inventory, tests the extracted sys crat

## Support

The supported target is native Linux x86_64 CPU. Maintainer tests cover the four bundled/system static/dynamic 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. Other operating systems, architectures, and accelerator builds are not supported by this Rust build.
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.

## Licensing and Affiliation

Expand Down
120 changes: 101 additions & 19 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,110 @@
pkgs = import inputs.nixpkgs {
inherit system overlays;
};
cudaPkgs = import inputs.nixpkgs {
inherit system overlays;
config.allowUnfree = true;
};

rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
in {
devShells.default = pkgs.mkShell {
packages = [
rustToolchain
pkgs.cmake
pkgs.git
pkgs.just
pkgs.jq
pkgs.ninja
pkgs.pkg-config
pkgs.gnutar
pkgs.llvmPackages.clang
pkgs.llvmPackages.bintools
pkgs.rust-bindgen
];

shellHook = ''
export PS1="(dev:vllm-cpp-rs) $PS1"
'';
};
devShells =
{
default = pkgs.mkShell {
packages = [
rustToolchain
pkgs.cmake
pkgs.git
pkgs.just
pkgs.jq
pkgs.ninja
pkgs.pkg-config
pkgs.gnutar
pkgs.llvmPackages.clang
pkgs.llvmPackages.bintools
pkgs.rust-bindgen
];

shellHook = ''
export PS1="(dev:vllm-cpp-rs) $PS1"
'';
};
}
// pkgs.lib.optionalAttrs
(builtins.elem system [
"x86_64-linux"
"aarch64-linux"
]) {
cuda = let
toolkit = cudaPkgs.cudaPackages.cudatoolkit;
cutlass = cudaPkgs.cudaPackages.cutlass;
in
pkgs.mkShell {
packages = [
rustToolchain
pkgs.cmake
pkgs.git
pkgs.just
pkgs.jq
pkgs.ninja
pkgs.pkg-config
pkgs.gnutar
pkgs.llvmPackages.clang
pkgs.llvmPackages.bintools
pkgs.rust-bindgen
toolkit
cutlass
];

shellHook = ''
export PS1="(cuda:vllm-cpp-rs) $PS1"
export CUDA_PATH="${toolkit}"
export CUDA_HOME="$CUDA_PATH"
export CUDAToolkit_ROOT="$CUDA_PATH"
export VLLM_CPP_CUTLASS_DIR="${cutlass.src}"
if [ -d /run/opengl-driver/lib ]; then
export LD_LIBRARY_PATH="/run/opengl-driver/lib:${toolkit}/lib''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
else
export LD_LIBRARY_PATH="${toolkit}/lib''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
fi
'';
};

vulkan = let
vulkanLibraryPath = pkgs.lib.makeLibraryPath [
pkgs.vulkan-loader
pkgs.vulkan-validation-layers
];
in
pkgs.mkShell {
packages = [
rustToolchain
pkgs.cmake
pkgs.git
pkgs.just
pkgs.jq
pkgs.ninja
pkgs.pkg-config
pkgs.gnutar
pkgs.llvmPackages.clang
pkgs.llvmPackages.bintools
pkgs.rust-bindgen
pkgs.vulkan-tools
pkgs.vulkan-loader
pkgs.vulkan-validation-layers
];

shellHook = ''
export PS1="(vulkan:vllm-cpp-rs) $PS1"
if [ -d /run/opengl-driver/lib ]; then
export LD_LIBRARY_PATH="/run/opengl-driver/lib:${vulkanLibraryPath}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
else
export LD_LIBRARY_PATH="${vulkanLibraryPath}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
fi
export VK_LAYER_PATH="${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d"
'';
};
};
};
};
}
8 changes: 8 additions & 0 deletions vllm-cpp-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ include = [
"/LICENSE-MIT",
"/NOTICE",
"/THIRD_PARTY.md",
"/licenses/**",
"/vllm.cpp/CMakeLists.txt",
"/vllm.cpp/cmake/**",
"/vllm.cpp/include/**",
"/vllm.cpp/src/**",
"/vllm.cpp/triton_kernels/**",
"/vllm.cpp/scripts/triton-aot-compile.py",
"/vllm.cpp/third_party/blake3/**",
"/vllm.cpp/third_party/minja/**",
"/vllm.cpp/third_party/nlohmann/**",
"/vllm.cpp/third_party/vulkan/**",
"/vllm.cpp/LICENSE",
"/vllm.cpp/NOTICE",
"/vllm.cpp/third_party/README.md",
Expand All @@ -36,6 +40,10 @@ default = ["bundled"]
bundled = []
system = []
dynamic-link = []
cuda = []
cuda-cutlass = ["cuda"]
triton-aot = ["cuda"]
vulkan = []

[build-dependencies]
cmake = "0.1.58"
Loading
Loading