Files
lightcraft/docs/guided-filter-memory.md
T
2026-10-15 20:26:21 -07:00

3.3 KiB
Raw Blame History

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.

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.