mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-11 16:31:32 -06:00
Merge PR #1976: GUM-3201: Reduce guided-filter coefficient allocations
This commit is contained in:
@@ -4,6 +4,10 @@ The CPU pipeline (`crates/pipeline`) is the reference ("oracle"). `lightcraft-gp
|
||||
evaluates the same stages with wgpu compute shaders (WGSL) on Metal / Vulkan / DX12. Everything is
|
||||
pure Rust (wgpu, naga); the drivers are the system's. No GL backend is compiled in.
|
||||
|
||||
CPU fast guided-filter allocation measurements and reproduction commands are documented in
|
||||
[guided-filter-memory.md](guided-filter-memory.md). That optimization retains the full-size base
|
||||
and does not change the GPU's coefficient buffers.
|
||||
|
||||
Warped geometry uses a CPU-computed coverage bit mask for the source boundary.
|
||||
The CPU reference evaluates that boundary in double precision; GPU float
|
||||
rounding otherwise can turn a blank edge pixel into a photo pixel. The mask
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# CPU fast guided-filter memory
|
||||
|
||||
`local::guided_fast` computes blurred coefficients on the same reduced grid as before, then
|
||||
samples them while applying `a * p + b`. It keeps the raster resizer's weights, boundary
|
||||
normalization and horizontal-then-vertical accumulation order. Odd dimensions therefore use
|
||||
their actual reduced/full dimension ratios. Four coefficient row pairs and one bias row are cached
|
||||
per active 32-row band; adjacent output rows reuse their horizontal samples.
|
||||
|
||||
The two full-resolution coefficient planes and their resize intermediates are gone. The returned
|
||||
full-resolution base remains: downstream CPU tone mapping and the spatial-plane cache need it.
|
||||
The step-1 filter, Box reduction, Gaussian coefficients, V2's median input, process selection and
|
||||
Draft sigma cap are unchanged. The GPU implementation is unchanged; this reduces CPU memory only.
|
||||
|
||||
## Reproduce
|
||||
|
||||
The dev-only example includes the previous materialized algorithm and uses the workspace's
|
||||
existing `dhat` allocator. No allocator or profiling dependency is added to product builds.
|
||||
|
||||
```sh
|
||||
cargo build --release -p lightcraft-pipeline --example guided_memory
|
||||
RAYON_NUM_THREADS=1 target/release/examples/guided_memory old 6000 4000 120 15
|
||||
RAYON_NUM_THREADS=1 target/release/examples/guided_memory new 6000 4000 120 15
|
||||
RAYON_NUM_THREADS=1 target/release/examples/guided_memory old 6000 4000 120 1 --heap
|
||||
RAYON_NUM_THREADS=1 target/release/examples/guided_memory new 6000 4000 120 1 --heap
|
||||
```
|
||||
|
||||
If `CARGO_TARGET_DIR` is set, use that directory instead of `target` for the executable.
|
||||
Arguments are mode, width, height, integer sigma and timing iterations. The example warms up
|
||||
before measurement; `--heap` counts one filter call with the source allocated beforehand.
|
||||
Time the runs without `--heap`: allocation profiling significantly changes timings. It reports
|
||||
the minimum wall time; on a shared machine repeat when other builds/renders have stopped.
|
||||
Use `LIGHTCRAFT_PROFILE=1` and `cargo xtask bench` for broader pipeline measurements.
|
||||
|
||||
## Observed allocation and time
|
||||
|
||||
Measured 2026-10-16 UTC, macOS aarch64, Rust 1.96.0, release build, one Rayon thread. Bytes are
|
||||
requested heap bytes counted by dhat, not process RSS. Timings are minimums of 15 unprofiled
|
||||
calls on a shared machine with concurrent builds; they are indicative, not a speed guarantee.
|
||||
|
||||
| Dimensions / sigma / step | Old peak bytes | New peak bytes | Old total allocated bytes | New total allocated bytes | Old / new wall ms |
|
||||
|---|---:|---:|---:|---:|---:|
|
||||
| 6000 × 4000 / 120 / 16 | 289,125,000 | 97,780,856 | 313,083,488 | 135,643,856 | 42.135 / 45.131 |
|
||||
| 1601 × 1067 / 24 / 8 | 20,822,412 | 7,331,172 | 25,102,604 | 11,562,560 | 3.359 / 3.121 |
|
||||
|
||||
The 24 MP result saves about 191 MB of peak allocation (66%). Its **96,000,000-byte output is
|
||||
included**; its **96,000,000-byte input is excluded**. Application RGB images, log luminance,
|
||||
V2 median input and its construction temporaries, other spatial planes and caches also remain
|
||||
outside this isolated measurement. More Rayon threads can hold more band scratch concurrently.
|
||||
This is not a bound on total pipeline memory.
|
||||
|
||||
Regression tests compare the sampled result exactly against materialized bilinear resizes for
|
||||
empty/singleton/one-dimensional, odd/even and multiple-band images; flat fields, signed texture,
|
||||
edges and impulses; small/full and reduced filters; and median tone bases.
|
||||
Reference in New Issue
Block a user