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
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,42 @@ jobs:
- run: python -m pip install -r benchmarks/requirements.txt
- run: python benchmarks/bench.py validate benchmarks/smoke.jsonl
- run: python -m unittest discover -s tests/benchmarks -p 'test_*.py' -v

cuda-contract:
# The CUDA backend contract and its checker. No CUDA toolkit and no GPU: both
# read files as text.
#
# The checker and its tests arrive in #25, so on a tree without them those
# two steps are a skip, not a failure: this job has to be green on the branch
# that carries it before #25 lands, and it has to start running by itself
# once #25 does, in either merge order. Failing instead would redden whichever
# PR arrived second. The backend tests come from the repository tests/ tree,
# which is already in main, so they run either way.
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Check for the checker
id: present
run: |
if [ -f src/backends/cuda/check_contract.py ] && [ -d src/backends/cuda/tests ]; then
echo "ready=true" >> "$GITHUB_OUTPUT"
else
echo "ready=false" >> "$GITHUB_OUTPUT"
echo "::notice::src/backends/cuda/check_contract.py and src/backends/cuda/tests are not in this tree; they arrive in #25. Skipping."
fi
- name: Contract checker tests
if: steps.present.outputs.ready == 'true'
run: python -m unittest discover -s src/backends/cuda/tests -t . -v
- name: Backend tests
# Tests live under the repository-level tests/ tree, not beside the
# kernels they cover (CONTRIBUTING.md, "Adding a model"). Same
# invocation as the benchmarks job: tests/cuda is not a package, so
# discovery has to use the start directory as its own top level.
run: python -m unittest discover -s tests/cuda -p 'test_*.py' -v
- name: Contract check
if: steps.present.outputs.ready == 'true'
run: python src/backends/cuda/check_contract.py --repo-root .
7 changes: 6 additions & 1 deletion src/backends/cuda/qwen3_5/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Qwen3.5/3.8 prefill operations

CUDA kernels for a prefill-only Qwen3.5/3.8 forward pass, built into `libqwen3_5_cuda.so` with a C interface ([`ops.h`](ops.h)), so that a Rust model engine loads it at run time and builds without a CUDA toolkit. The Cua-S1 and Open-Jev native workers share the layer loop and buffers in [`src/models/qwen3_5/native/`](../../../models/qwen3_5/native/).
CUDA kernels for a prefill-only Qwen3.5/3.8 forward pass, built into `libqwen3_5_cuda.so` with a C interface ([`ops.h`](ops.h)), so that a Rust model engine loads it at run time and builds without a CUDA toolkit. The Cua-S1, Open-Jev and experimental JEV-VL native workers share the layer loop and buffers in [`src/models/qwen3_5/native/`](../../../models/qwen3_5/native/).

The backend manifest remains `experimental`. Maintained CI checks source/build
metadata and CPU tests; it does not compile this backend with NVCC or establish
GPU numerical parity. Current-head CUDA compilation and GPU regressions remain
separate release checks.

```sh
src/backends/cuda/qwen3_5/build.sh <output dir> [compute capability, default 89]
Expand Down
31 changes: 31 additions & 0 deletions src/backends/cuda/qwen3_5/qwen3_5.backend.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "qwen3_5",
"abi_version": 6,
"status": "experimental",
"sources": [
"ops.h",
"common.cuh",
"mma.cuh",
"norm.cu",
"elementwise.cu",
"attention.cu",
"gdn_prefill.cu",
"gemm.cu",
"runtime.cu",
"vision.cu"
],
"models": [
"src/models/cua_s1/native/",
"src/models/open_jev/native/",
"src/models/jev_vl/native/"
],
"build": {
"script": "build.sh",
"output": "libqwen3_5_cuda.so",
"default_arch": 89,
"architectures": [
89
],
"min_capability": 80
}
}