BookNotesSlidesP-sets Syllabusdraft · v0.2.49.1
💬Comments welcome. To leave a note, select any text and click the note / highlight button that pops up — or open the panel with the tab at the top-right (‹). Notes are visible only inside our private review group.
Computational Photography, an AI-powered Slopendium — 29 Making computational photography code fast
expand to📖 Full book outline1 parts · 9 chapters · 83 sections · 0 figures embedded · 1 placeholders · double-click a figure to enlarge
▸Part 29 MAKING COMPUTATIONAL PHOTOGRAPHY CODE FAST⧉
<!--uid: making-computational-photography-code-fast-->
▸29.1 Algorithmic speedups⧉
29.1.1 Precompute and look up — pay once, before the loop⧉
29.1.2 Separability — a 2-D pass for the price of two 1-D passes⧉
29.1.3 Recursive / IIR filters — a running state, cost independent of radius⧉
29.1.4 Integral images / summed-area tables — any box sum in four lookups⧉
29.1.5 Fast median filters — a sliding histogram for a constant-time median⧉
29.1.6 Pyramids and multiscale — do the large-scale work on small images⧉
29.1.7 Discretize the range to accelerate non-linear filters⧉
29.1.9 Choosing a method⧉
29.1.10 Where this goes next⧉
▸29.2 Modern CPUs: memory hierarchy, parallelism, and what it takes to go fast⧉
29.2.5 Measuring and improving a kernel⧉
29.2.7 Why photography is hard for the machine⧉
29.2.8 Keep the comparison valid⧉
29.2.9 Where this goes next⧉
▸29.3 Halide at a high level: decoupling algorithms from schedules⧉
29.3.1 Images as pure functions⧉
29.3.2 The schedule: four questions for every stage⧉
29.3.3 What the compiler derives⧉
29.3.4 The compiler makes almost no decisions⧉
29.3.5 What the split buys, measured⧉
29.3.6 How long does a schedule take to write?⧉
29.3.7 Where it ended up⧉
29.3.8 Letting the compiler find the schedule⧉
29.3.9 The split was always there, done by hand⧉
29.3.10 Gradient Halide: differentiating the pipeline⧉
29.3.11 When to use the split⧉
29.3.12 Where this goes next⧉
▸29.4 Halide programming⧉
29.4.1 Getting started with Halide⧉
29.4.2 Functional, with no loops: `Func`, `Var`, `Expr`⧉
29.4.3 A first image pipeline: brighten, then blur⧉
29.4.4 Reductions: `RDom`, sums, and histograms⧉
29.4.5 The two extremes: root and inline⧉
29.4.6 Scheduling the loops within a stage: `reorder`, `split`, `tile`, `vectorize`, `unroll`, `parallel`, `fuse`⧉
29.4.7 The heart of it: producer-consumer granularity (`compute_at`, `store_at`)⧉
29.4.8 Comparing schedules with measurements⧉
29.4.9 The schedule ladder, with numbers: ten times faster from one line⧉
29.4.10 Boundaries and bounds⧉
29.4.11 Same algorithm, new machine: the GPU⧉
29.4.12 Letting the compiler schedule: the auto-scheduler⧉
29.4.13 A repeatable scheduling experiment⧉
29.4.14 Where this goes next⧉
▸29.5 Scaling up Halide⧉
⬜ figure not yet created
the lab's per-pipeline Func graph and result boxes (`fig-halide-box7-graph`, `fig-halide-box7-result`, `fig-halide-harris-graph`, `fig-halide-harris-result`, `fig-halide-bilateral-graph`, `fig-halide-bilateral-result`, `fig-halide-pyramid-graph`, `fig-halide-pyramid-result`). fig-halide-box7-graph
29.5.1 Decoupling storage from computation: `store_at`⧉
29.5.2 A 7×7 box blur: reductions and update definitions⧉
29.5.3 Harris corner detection: ten stages, fifteen edges⧉
29.5.4 A brute-force bilateral filter: what a schedule cannot fix⧉
29.5.5 The bilateral grid: changing the algorithm instead⧉
29.5.6 A three-level Laplacian pyramid: multi-resolution stages⧉
29.5.7 The development loop: correctness, measurement, and benchmarking hygiene⧉
29.5.8 Going farther: what the tutorials cover that we did not⧉
▸29.6 Hardware backends: GPU, NPU, DSP⧉
*(Follows the CPU primer: the real-world hardware imaging code runs fast on, beyond hand-written C++/Halide — the heterogeneous units a modern camera SoC orchestrates.)*
• **GPU compute — OpenCL / Vulkan for image processing**: the per-pixel work (filters, pyramids, warps, blending, demosaicking) is **embarrassingly parallel**, so it maps naturally to the GPU. **OpenCL** kernels and **Vulkan compute shaders** are the cross-platform ways to run it on mobile and desktop GPUs; **Halide can target these backends**, so the same algorithm retargets from CPU SIMD to GPU compute. The GPU is the workhorse for **real-time** image processing (camera preview, video).
• **On-device ML framework (e.g. LiteRT)**: trained imaging models — denoise, super-resolution, segmentation/portrait, semantic ISP, HDR fusion — increasingly run **locally on the device** for latency, privacy, and offline use. **LiteRT** (formerly TensorFlow Lite), Core ML, and ONNX Runtime Mobile load **quantized (int8/fp16)** models and **delegate** the heavy layers to the GPU or NPU. Cross-ref [[Deep learning]] (the models).
• **NPU acceleration for imaging models**: dedicated **neural processing units** (Apple **Neural Engine**, Qualcomm **Hexagon** AI, Google **Tensor** TPU) run CNN/transformer inference at **far higher throughput per watt** than CPU/GPU — the engine behind Night mode, learned demosaicking/denoising, face & scene understanding in the live pipeline. The scheduling problem shifts from cache tiling to **operator fusion, quantization, and keeping the NPU fed**.
• **DSP programming for real-time 3A control**: the **3A** loop — **auto-exposure, auto-focus, auto-white-balance** — needs per-frame scene statistics and control at video rate with minimal power, so it typically runs on a low-power **DSP** (e.g. Hexagon) inside the camera subsystem/ISP rather than the application CPU. Real-time, deadline-driven, and tightly coupled to the sensor — a different optimization regime from batch image processing.
29.6.1 GPU — the data-parallel workhorse⧉
29.6.2 The neural accelerator: NPU and TPU⧉
29.6.3 DSP — the real-time control loop⧉
29.6.4 ISP, FPGA, and ASIC — the fixed-function end⧉
29.6.5 The heterogeneous SoC, and the spectrum to carry away⧉
29.6.6 On-device ML runtimes, and why the work stays on the phone⧉
▸29.7 Efficient neural network inference⧉
29.7.1 Quantization: fewer bits per weight⧉
29.7.2 Pruning: fewer weights⧉
29.7.3 Knowledge distillation: a small student, a big teacher⧉
29.7.4 Low-rank and tensor factorization⧉
29.7.5 Efficient architectures: cheapness designed in⧉
29.7.6 Neural architecture search: let the machine design it⧉
29.7.7 Hardware-aware deployment and the roofline⧉
29.7.8 Comparing deployable models⧉
29.7.9 Where this leaves the part⧉
▸29.8 Automatic search for fast methods⧉
29.8.1 The problem is a curve, not a point⧉
29.8.2 What a broader search space can offer⧉
29.8.3 Ma et al. 2022: searching structure and parameters together⧉
29.8.4 Three axes of "search instead of design"⧉
29.8.5 The broader family, and what it costs⧉
29.8.6 From search result to implementation⧉
▸29.9 8-bit and fixed-point arithmetic⧉
29.9.1 Integer versus fixed-point: where the binary point sits⧉
29.9.2 Rounding, dithering, and the banding trap⧉
29.9.3 Saturation and the width of the accumulator⧉
29.9.4 fp16 versus bf16: the exponent–mantissa bargain⧉
29.9.5 int8 quantization for neural inference⧉
29.9.6 Where wider arithmetic matters⧉
29.9.7 When float is non-negotiable⧉