Skip to content

Commit c919166

Browse files
committed
release: RayD 0.8.0
1 parent af0ee6e commit c919166

82 files changed

Lines changed: 6059 additions & 619 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
run: |
4040
python -m unittest \
4141
tests.packaging.test_project_metadata \
42+
tests.governance.test_gpu_ci_contract \
4243
tests.governance.test_drjit_project_metadata \
4344
tests.governance.test_verify_cuda_binary_arches_jit \
4445
tests.test_rt_host_compile \

‎.github/workflows/multi_gpu.yml‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
#
33
# This workflow is the CI half of Phase 4 item 3 of
44
# `docs/dev/multi_gpu_plan.md`. It runs the multi-device acceptance set that
5-
# the Phase 2-3 verifications ran by hand, and it is the only job in this
6-
# repository that needs a GPU: every other workflow (`ci.yml`,
7-
# `stable-abi-ci.yml`, `pypi.yml`) builds wheels on GitHub-hosted runners,
8-
# which have no CUDA device at all. Those jobs are untouched by this file, and
9-
# nothing here changes what they run.
5+
# the Phase 2-3 verifications ran by hand. The hosted workflows (`ci.yml`,
6+
# `stable-abi-ci.yml`, `pypi.yml`) build wheels without CUDA devices. The
7+
# separate `single_gpu.yml` workflow owns routine one-or-more-GPU CUDA/OptiX
8+
# execution; this file owns only the two-device replicated-scene acceptance.
109
#
1110
# EXTERNAL RUNNER REQUIRED. GitHub-hosted runners do not satisfy the labels
1211
# below. A labelled PR, scheduled run, or manual dispatch only queues while no
@@ -130,7 +129,10 @@ jobs:
130129
tests.scene.test_chunked_executor \
131130
tests.scene.test_multi_device_policy \
132131
tests.scene.test_multi_device_resilience \
133-
tests.diffraction.test_lane_offset
132+
tests.diffraction.test_lane_offset \
133+
tests.test_multi_device_diffraction_paths \
134+
tests.test_multi_device_coherent_accum \
135+
tests.test_multi_device_reflection_accum
134136
do
135137
echo "::group::$module"
136138
"$PYTHON" -m unittest "$module" -v || status=1

‎.github/workflows/pypi.yml‎

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,18 @@ jobs:
4040
with:
4141
python-version: ${{ matrix.python-version }}
4242
- run: python -m pip install "tomli>=2; python_version < '3.11'"
43+
- name: Validate published release tag
44+
if: github.event_name == 'release' && github.event.action == 'published'
45+
env:
46+
RAYD_RELEASE_TAG: ${{ github.event.release.tag_name }}
47+
run: python scripts/validate_release_tag.py --tag "$RAYD_RELEASE_TAG" --pyproject pyproject.toml
4348
- name: Validate package and release metadata
4449
shell: bash
4550
run: |
4651
python -m unittest \
4752
tests.packaging.test_project_metadata \
53+
tests.packaging.test_release_metadata \
54+
tests.governance.test_gpu_ci_contract \
4855
tests.governance.test_drjit_project_metadata \
4956
tests.governance.test_verify_cuda_binary_arches_jit \
5057
tests.test_rt_host_compile \
@@ -144,6 +151,11 @@ jobs:
144151
CUDAHOSTCXX=/opt/rh/gcc-toolset-12/root/usr/bin/g++
145152
PATH=/usr/local/cuda/bin:$PATH
146153
LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
154+
CIBW_TEST_COMMAND: >-
155+
python -I {project}/tests/packaging/wheel_lifecycle_smoke.py installed drjit &&
156+
python -m pip uninstall -y rayd-drjit &&
157+
python -I {project}/tests/packaging/wheel_lifecycle_smoke.py absent drjit
158+
CIBW_TEST_REQUIRES: "drjit==1.3.1"
147159
CIBW_REPAIR_WHEEL_COMMAND_LINUX: >-
148160
auditwheel repair --plat manylinux_2_28_x86_64
149161
--exclude libcuda.so.1
@@ -273,6 +285,11 @@ jobs:
273285
CUDAHOSTCXX=/opt/rh/gcc-toolset-12/root/usr/bin/g++
274286
PATH=/usr/local/cuda/bin:$PATH
275287
LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
288+
CIBW_TEST_COMMAND: >-
289+
python -I {project}/tests/packaging/wheel_lifecycle_smoke.py installed torch &&
290+
python -m pip uninstall -y rayd-torch &&
291+
python -I {project}/tests/packaging/wheel_lifecycle_smoke.py absent torch
292+
CIBW_TEST_REQUIRES: "torch==2.10.0"
276293
CIBW_REPAIR_WHEEL_COMMAND_LINUX: >-
277294
auditwheel repair --plat manylinux_2_28_x86_64
278295
--exclude libcuda.so.1
@@ -432,6 +449,16 @@ jobs:
432449
python drjit/scripts/verify_cuda_binary_arches.py --stem _legacy_ops --stem _stable_ops $wheel
433450
python torch/scripts/verify_stable_abi.py --source-root src $wheel
434451
python -m twine check $wheel
452+
- name: Validate wheel install and uninstall lifecycle
453+
shell: pwsh
454+
working-directory: ${{ runner.temp }}
455+
run: |
456+
$backend = "${{ matrix.backend }}"
457+
$wheel = (Get-ChildItem "$env:GITHUB_WORKSPACE/dist/$backend/*.whl").FullName
458+
python -m pip install --no-deps --force-reinstall $wheel
459+
python -I "$env:GITHUB_WORKSPACE/tests/packaging/wheel_lifecycle_smoke.py" installed $backend
460+
python -m pip uninstall -y "rayd-$backend"
461+
python -I "$env:GITHUB_WORKSPACE/tests/packaging/wheel_lifecycle_smoke.py" absent $backend
435462
- uses: actions/upload-artifact@v4
436463
with:
437464
name: release-rayd-${{ matrix.backend }}-windows-py${{ matrix.python-version }}
@@ -554,9 +581,27 @@ jobs:
554581
- name: Validate representative wheel layout
555582
shell: bash
556583
run: |
557-
echo "RAYD_META_WHEEL=$(find dist -maxdepth 1 -name 'rayd-*-none-any.whl' -print -quit)" >> "$GITHUB_ENV"
558-
echo "RAYD_DRJIT_WHEEL=$(find dist -maxdepth 1 -name 'rayd_drjit-*-cp312-cp312-manylinux_2_28_x86_64.whl' -print -quit)" >> "$GITHUB_ENV"
559-
echo "RAYD_TORCH_WHEEL=$(find dist -maxdepth 1 -name 'rayd_torch-*-cp312-cp312-manylinux_2_28_x86_64.whl' -print -quit)" >> "$GITHUB_ENV"
584+
set -euo pipefail
585+
mapfile -t meta_wheels < <(find dist -maxdepth 1 -name 'rayd-*-none-any.whl' -print)
586+
mapfile -t drjit_wheels < <(find dist -maxdepth 1 -name 'rayd_drjit-*-cp312-cp312-*manylinux_2_28_x86_64.whl' -print)
587+
mapfile -t torch_wheels < <(find dist -maxdepth 1 -name 'rayd_torch-*-cp312-cp312-*manylinux_2_28_x86_64.whl' -print)
588+
if [[ ${#meta_wheels[@]} -ne 1 || ${#drjit_wheels[@]} -ne 1 || ${#torch_wheels[@]} -ne 1 ]]; then
589+
printf 'Expected exactly one representative wheel per distribution; meta=%s drjit=%s torch=%s\n' \
590+
"${#meta_wheels[@]}" "${#drjit_wheels[@]}" "${#torch_wheels[@]}" >&2
591+
exit 1
592+
fi
593+
meta_wheel="${meta_wheels[0]}"
594+
drjit_wheel="${drjit_wheels[0]}"
595+
torch_wheel="${torch_wheels[0]}"
596+
if [[ -z "$meta_wheel" || -z "$drjit_wheel" || -z "$torch_wheel" ]]; then
597+
echo "Representative wheel selection produced an empty path." >&2
598+
exit 1
599+
fi
600+
{
601+
echo "RAYD_META_WHEEL=$meta_wheel"
602+
echo "RAYD_DRJIT_WHEEL=$drjit_wheel"
603+
echo "RAYD_TORCH_WHEEL=$torch_wheel"
604+
} >> "$GITHUB_ENV"
560605
- run: >-
561606
python -m unittest
562607
tests.packaging.test_wheel_layout

‎.github/workflows/single_gpu.yml‎

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Single-GPU CUDA and OptiX acceptance.
2+
#
3+
# EXTERNAL RUNNER REQUIRED. Register a runner carrying every label in
4+
# `runs-on` below (`self-hosted`, `linux`, `x64`, `cuda`, `single-gpu`) with
5+
# CUDA Torch, Dr.Jit, the native build dependencies, and OptiX headers.
6+
# Labelled PRs opt in with `run-gpu-ci`; the weekly run detects driver and
7+
# pipeline drift; manual dispatch remains available for release validation.
8+
9+
name: Single-GPU CUDA and OptiX Acceptance
10+
11+
on:
12+
pull_request:
13+
types: [labeled]
14+
schedule:
15+
- cron: "41 8 * * 4"
16+
workflow_dispatch:
17+
inputs:
18+
python:
19+
description: >-
20+
Interpreter of the prepared CUDA build environment on the runner.
21+
It must contain CUDA Torch, Dr.Jit, Ninja, CMake, scikit-build-core,
22+
nanobind, and access to the OptiX headers.
23+
required: false
24+
default: python
25+
26+
concurrency:
27+
group: single-gpu-${{ github.ref }}
28+
cancel-in-progress: true
29+
30+
permissions:
31+
contents: read
32+
33+
jobs:
34+
single-gpu:
35+
name: CUDA and OptiX acceptance / 1+ GPU (self-hosted)
36+
if: >-
37+
github.event_name == 'workflow_dispatch' ||
38+
github.event_name == 'schedule' ||
39+
(github.event_name == 'pull_request' &&
40+
github.event.label.name == 'run-gpu-ci')
41+
runs-on: [self-hosted, linux, x64, cuda, single-gpu]
42+
timeout-minutes: 180
43+
env:
44+
PYTHON: ${{ inputs.python || 'python' }}
45+
PYTHONPATH: ${{ github.workspace }}/python
46+
OPTIX_CACHE_PATH: ${{ runner.temp }}/rayd-optix-${{ github.run_id }}-${{ github.run_attempt }}
47+
RAYD_CI_BUILD_ROOT: ${{ runner.temp }}/rayd-build-${{ github.run_id }}-${{ github.run_attempt }}
48+
RAYD_CI_BUILD_MARKER: ${{ runner.temp }}/rayd-build-${{ github.run_id }}-${{ github.run_attempt }}.marker
49+
50+
steps:
51+
- uses: actions/checkout@v5
52+
53+
- name: Report the runner's GPUs
54+
shell: bash
55+
run: nvidia-smi
56+
57+
- name: Require a working CUDA device in Torch and Dr.Jit
58+
shell: bash
59+
run: "$PYTHON" -I tests/support/single_gpu_ci_preflight.py device
60+
61+
- name: Build both backends from the checked-out source
62+
shell: bash
63+
run: |
64+
mkdir -p "$OPTIX_CACHE_PATH"
65+
mkdir -p "$RAYD_CI_BUILD_ROOT"
66+
"$PYTHON" -m pip uninstall -y rayd-drjit rayd-torch
67+
touch "$RAYD_CI_BUILD_MARKER"
68+
"$PYTHON" -m pip install --no-deps --no-build-isolation -e drjit \
69+
-Cbuild-dir="$RAYD_CI_BUILD_ROOT/drjit"
70+
"$PYTHON" -m pip install --no-deps --no-build-isolation -e torch \
71+
-Cbuild-dir="$RAYD_CI_BUILD_ROOT/torch"
72+
73+
- name: Print import paths and require both OptiX backends
74+
shell: bash
75+
run: "$PYTHON" -I tests/support/single_gpu_ci_preflight.py optix
76+
77+
- name: Torch CUDA and OptiX core
78+
shell: bash
79+
run: |
80+
status=0
81+
for module in \
82+
tests.parity.test_cuda_geometry \
83+
tests.parity.test_cuda_multipath \
84+
tests.native.test_dispatcher_bindings \
85+
tests.native.test_multipath \
86+
tests.scene.test_mesh_instancing \
87+
tests.reflection.test_torch_high_level_api
88+
do
89+
echo "::group::$module"
90+
"$PYTHON" -m unittest "$module" -v || status=1
91+
echo "::endgroup::"
92+
done
93+
exit "$status"
94+
95+
- name: Dr.Jit CUDA and OptiX core
96+
shell: bash
97+
run: |
98+
status=0
99+
for module in \
100+
tests.scene.test_geometry_jit \
101+
tests.reflection.test_epc_jit \
102+
tests.reflection.test_accumulation_jit \
103+
tests.diffraction.test_accumulation_jit \
104+
tests.visibility.test_visibility_topk_jit
105+
do
106+
echo "::group::$module"
107+
"$PYTHON" -m unittest "$module" -v || status=1
108+
echo "::endgroup::"
109+
done
110+
exit "$status"
111+
112+
- name: Dr.Jit cold OptiX pipeline matrix
113+
shell: bash
114+
run: "$PYTHON" -m unittest tests.native.test_optix_pipeline_cold_create_jit -v
115+
116+
- name: Mixed geometry and SDF acceptance
117+
shell: bash
118+
run: |
119+
status=0
120+
for module in \
121+
tests.mixed.test_mixed_torch \
122+
tests.mixed.test_mixed_jit \
123+
tests.sdf.test_intersect \
124+
tests.sdf.test_operations \
125+
tests.sdf.test_operations_jit
126+
do
127+
echo "::group::$module"
128+
"$PYTHON" -m unittest "$module" -v || status=1
129+
echo "::endgroup::"
130+
done
131+
exit "$status"
132+
133+
- name: Cross-backend numerical and AD parity
134+
shell: bash
135+
env:
136+
RAYD_TORCH_RUN_DR_JIT_PARITY: "1"
137+
run: |
138+
"$PYTHON" -m unittest \
139+
tests.parity.test_drjit \
140+
tests.parity.test_share2_ad -v
141+
142+
- name: CI and numerical contract governance
143+
shell: bash
144+
run: |
145+
"$PYTHON" -m unittest \
146+
tests.governance.test_gpu_ci_contract \
147+
tests.test_public_api_manifest \
148+
tests.test_ptx_source_digest \
149+
tests.test_compile_flag_policy_contract -v

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ scripts/*
1414
!scripts/build_local.ps1
1515
!scripts/build_local.cmd
1616
!scripts/format_code.py
17+
!scripts/validate_release_tag.py
1718
AGENTS.md
1819
claude.md
1920
dev_notes.md

‎AGENTS.md‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,12 @@ class in `contracts/operations.json`.
208208
gradient to make a shard or chunk proceed.
209209
- A single-device `Scene` never imports the orchestration layer and stays
210210
bitwise unchanged; the Phase 0 device guards are the only single-GPU-path
211-
change. `trace_dfr_paths` and `accum_dfr_coherent_direct` raise on a
212-
multi-device scene instead of changing meaning.
211+
change. `trace_dfr_paths` uses transmitter-aligned `SourceLane` shards and
212+
`accum_dfr_coherent_direct` uses a deterministic lane window, and
213+
`accumulate_reflections` shards warp-aligned ray batches before a
214+
master-ordered grid reduction. Reflection wedge collection keeps one full
215+
master launch because its bounded event buffer is not reducible.
216+
`trace_refl_epc` still raises on a multi-device scene.
213217

214218
See `docs/adr/0038-replicated-multi-device-execution.md` for the decisions and
215219
stop conditions, `docs/dev/multi_gpu_operations.md` for the operational

‎CHANGELOG.md‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,34 @@
22

33
All notable changes to RayD are documented in this file.
44

5+
## [0.8.0] - 2026-07-30
6+
7+
### Added
8+
9+
- Added true mesh instancing with shared geometry acceleration structures,
10+
per-instance transforms and IDs, scene-global primitive IDs, transform
11+
derivatives, and transform-only acceleration-structure updates.
12+
- Added Torch high-level reflection accumulation and EPC APIs, a valid
13+
cross-backend EPC-field numerical parity fixture, replicated multi-GPU
14+
diffraction path, coherent diffraction, and reflection-accumulation
15+
execution, and conditional packed SDF-grid batching.
16+
17+
### Changed
18+
19+
- Replaced backend-wide AD claims with operation- and input-domain-level
20+
VJP/JVP capabilities; Torch EPC-field evaluation is now explicitly
21+
forward-only until its physical Fresnel and polarization derivatives are
22+
implemented.
23+
- Expanded single- and multi-GPU CUDA/OptiX CI, Stable ABI checks, wheel
24+
install/uninstall lifecycle validation, and release-artifact verification.
25+
26+
### Fixed
27+
28+
- Restored the `rayd.drjit._C` package stub layout and repaired editable-source
29+
validation so tests cannot silently exercise stale installed frontends.
30+
- Fixed Torch reflection material defaults and EPC-field parity coverage so a
31+
validated reflected path produces and compares a nonzero physical field.
32+
533
## [0.7.0] - 2026-07-23
634

735
### Added
@@ -67,5 +95,6 @@ All notable changes to RayD are documented in this file.
6795
diffraction accumulation, EPC bindings, and native AD propagation across
6896
both backends.
6997

98+
[0.8.0]: https://github.com/Asixa/RayD/releases/tag/v0.8.0
7099
[0.7.0]: https://github.com/Asixa/RayD/releases/tag/v0.7.0
71100
[0.6.0]: https://github.com/Asixa/RayD/releases/tag/v0.6.0

‎CLAUDE.md‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,12 @@ class in `contracts/operations.json`.
208208
gradient to make a shard or chunk proceed.
209209
- A single-device `Scene` never imports the orchestration layer and stays
210210
bitwise unchanged; the Phase 0 device guards are the only single-GPU-path
211-
change. `trace_dfr_paths` and `accum_dfr_coherent_direct` raise on a
212-
multi-device scene instead of changing meaning.
211+
change. `trace_dfr_paths` uses transmitter-aligned `SourceLane` shards and
212+
`accum_dfr_coherent_direct` uses a deterministic lane window, and
213+
`accumulate_reflections` shards warp-aligned ray batches before a
214+
master-ordered grid reduction. Reflection wedge collection keeps one full
215+
master launch because its bounded event buffer is not reducible.
216+
`trace_refl_epc` still raises on a multi-device scene.
213217

214218
See `docs/adr/0038-replicated-multi-device-execution.md` for the decisions and
215219
stop conditions, `docs/dev/multi_gpu_operations.md` for the operational

0 commit comments

Comments
 (0)