Repository navigation
v0.5.0
Headline: the wgpu (portable GPU) backend becomes device-resident end to end,
closing most of the gap to CUDA — analytic recon, streaming, SIRT and the
gridding recons now keep their data on the GPU across the pipeline, and the
scatter kernels use native f32 atomics (wgpu 30). The workspace is also now
self-contained (all dependencies resolve from crates.io) and gains
CI on every branch push across Linux, Windows and macOS.
Added
- CGLS reconstruction (
--algorithm cgls). Conjugate-gradient least squares
(the standard algorithm; recurrence parity-checked against ASTRA's
CglsAlgorithmbut implemented independently — ASTRA is GPL-3.0, no ASTRA code
is used): a Krylov solver of the same‖Ax − b‖²normal equations as SIRT/GRAD
but with the optimal step and conjugate directions, so it reaches a given
residual in far fewer iterations (≈4–30× vs SIRT). Runs on every backend via
the generic solver, plus a CUDA device-resident fast path (per-slice dot/axpy
kernels; one upload / one download across all iterations). Parameter-free;
supports warm-start chaining. No built-in regularization, so it needs early
stopping on ill-posed data. - Per-stage iteration budgets in algorithm chains. An iterative stage in a
--algorithmchain can carry a:iterssuffix
(e.g.--algorithm fbp,sirt:30,tv:10); stages without one fall back to
--num_iter. Analytic stages reject the suffix. Lets a chain spend, say, 30
SIRT iterations then 10 TV iterations in one run — previously every stage shared
a single--num_iter. - Continuous integration (GitHub Actions). Runs on every branch push and
every pull request:rustfmt, then a per-platform matrix — Linux/x86_64,
Windows/x86_64, macOS/arm64 — each runningclippy -D warnings, the test
suite and doctests on the default (CPU) build plus agpu-wgpucompile-check,
and a Linux job that type-checks the CUDA FFI bindings without an nvcc toolkit.
Changed
- wgpu backend upgraded to wgpu 30 (from 23). Enables
SHADER_FLOAT32_ATOMIC
(VulkanVK_EXT_shader_atomic_float); devices without it fall back to the
portable compare-exchange emulation automatically. - wgpu reconstruction is now device-resident. A fused analytic path keeps the
filtered sinogram on-GPU (fbp/linerec/fourierrec); device-resident streaming
reconstructs chunk-by-chunk (fbp/linerec/fourierrec and lprec, the latter
caching its log-polar grids across chunks); SIRT keeps volume/sinogram resident
across iterations; the FBP filter and the fourierrec/lprec gridding run on the
GPU. The scatter kernels (forward projection, fourierrec gather/wrap, lprec
gather) use nativef32atomicAdd, replacing the CAS-emulation penalty —
forward projection ~6.6× and SIRT ~6.4× faster (same-build A/B). Net effect:
fbp/linerec reach CUDA parity, SIRT and lprec beat CUDA on this hardware. - Shared host precompute sped up. lprec precomputes its FFTs on the CPU
(rustfft) instead of a GPU round-trip (wgpu and CUDA),build_gridscoordinate
loops are parallelised with rayon, and the CPUminus_logprep is parallelised
across the projection volume. xraylib(the optionalbeam-hardeningdependency) is now sourced from
crates.io instead of an out-of-repo path dependency, so a fresh clone / CI
resolves the workspace without a sibling checkout. Local development against a
sibling checkout can override via[patch.crates-io].
Fixed
- wgpu forward projection now applies the
π/nprojadjoint gain, so the
{A, Aᵀ}pair is matched — fixesforward_projectoutput scale and the
iterative solvers built on it (SIRT). - stripe TI block-size division uses
checked_div(satisfies
clippy::manual_checked_ops, new on stable Rust 1.96). - HDF5 test fixtures were swallowed by the repo-wide
*.h5gitignore and
never committed; they are now tracked so the test suite runs on a fresh clone.