Generated from the full canonical file for this source snapshot. Line numbers match the library source.
Source SHA256: adfa3e500c96ba985f37545ead61c7cce5aa47cfe4792eb13d9c12d792147739
1"""Strict mixed-precision transmission kernels, with no launch-time allocation.23The host boundary owns domain, shape, stream and alias validation. Every launch4must use ``record_tape=False``: the public operator supplies its explicit VJP.5Mask bits select transmission (1), counts (2), log transmission (4), removed6primary fraction (8). Beam modes are absent (0), fixed scalar (1), device scalar7(2) and per-pixel (3). Unused array arguments may be empty device placeholders.89Status is an int32 array with at least one element: bit 0 is invalid input,10bit 1 is a non-finite gradient. The caller resets it before checked execution.11Only exceptional lanes update status; numerical reductions never use atomics.12"""1314from functools import cache1516import warp as wp1718TILE_SIZE = 25619STRICT_OPTIONS = {"fast_math": False, "fuse_fp": True, "enable_backward": False}202122# region book:transmission-weak-attenuation23@wp.func_native("return -expm1f(-optical_depth);")24def removed_primary(optical_depth: wp.float32) -> wp.float32:25"""Evaluate the decrement directly, without subtracting two near-unities."""26...272829@wp.func_native("return -log1pf(-decrement);")30def optical_depth_from_decrement(decrement: wp.float32) -> wp.float32:31"""Invert a supplied decrement; the caller requires 0 <= decrement < 1."""32...333435# endregion book:transmission-weak-attenuation363738# region book:transmission-evaluate39@wp.func_native("return -value;")40def log_transmission_exact(value: wp.float32) -> wp.float32:41"""Use IEEE unary negation; Warp 1.17's generic neg is ``0 - value``."""42...434445@wp.func46def transmission_factor(optical_depth: wp.float32) -> wp.float64:47"""Keep exponent range until all requested physical products are formed."""48if optical_depth <= wp.float32(64.0):49# Here exp(-L) is normal in FP32. Promotion retains its range, while50# keeping the common case on the single-precision exponential path.51return wp.float64(wp.exp(-optical_depth))52return wp.exp(-wp.float64(optical_depth))535455# endregion book:transmission-evaluate565758# region book:transmission-forward59@cache60def get_forward_kernel(mask: int, beam_mode: int):61"""Return a specialised pointwise kernel, launched with ``dim=P``.6263Inputs: L, beam_array, beam_scalar. Outputs: T, counts, log_T, removed.64Static selection eliminates unused array reads, stores and mathematics.65"""66if mask < 1 or mask > 15 or beam_mode not in (0, 1, 2, 3):67raise ValueError("Invalid output mask or beam mode")68if mask & 2 and beam_mode == 0:69raise ValueError("Counts require an open beam")7071@wp.kernel(module="unique", module_options=STRICT_OPTIONS)72def forward(73optical_depth: wp.array(dtype=wp.float32),74beam: wp.array(dtype=wp.float32),75beam_scalar: wp.float32,76transmission: wp.array(dtype=wp.float32),77counts: wp.array(dtype=wp.float32),78log_transmission: wp.array(dtype=wp.float32),79removed: wp.array(dtype=wp.float32),80):81p = wp.tid()82depth = optical_depth[p]83if wp.static(mask & 3 != 0):84factor = transmission_factor(depth)85if wp.static(mask & 1 != 0):86transmission[p] = wp.float32(factor)87if wp.static(mask & 2 != 0):88illumination = beam_scalar89if wp.static(beam_mode == 2):90illumination = beam[0]91elif wp.static(beam_mode == 3):92illumination = beam[p]93# In particular, never multiply illumination by stored T.94count = wp.float32(wp.float64(illumination) * factor)95if count == wp.float32(0.0):96count = wp.float32(0.0)97counts[p] = count98if wp.static(mask & 4 != 0):99log_transmission[p] = log_transmission_exact(depth)100if wp.static(mask & 8 != 0):101decrement = removed_primary(depth)102if decrement == wp.float32(0.0):103decrement = wp.float32(0.0)104removed[p] = decrement105106return forward107108109# endregion book:transmission-forward110111112@wp.func113def checked_gradient(value: wp.float64, status: wp.array(dtype=wp.int32)) -> wp.float32:114"""Round once and flag overflow, including after tape accumulation."""115rounded = wp.float32(value)116if not wp.isfinite(rounded):117wp.atomic_or(status, 0, 2)118return rounded119120121# region book:transmission-vjp122@wp.func123def weighted_depth_adjoint(124factor: wp.float64,125illumination: wp.float32,126seed_transmission: wp.float32,127seed_counts: wp.float32,128seed_log: wp.float32,129seed_removed: wp.float32,130) -> wp.float64:131"""Differentiate the real-valued map, retaining range before rounding."""132optical = (wp.float64(seed_removed) - wp.float64(seed_transmission)) * factor133count = wp.float64(seed_counts) * wp.float64(illumination) * factor134return optical - count - wp.float64(seed_log)135136137# endregion book:transmission-vjp138139140@cache141def get_vjp_kernel(142seed_mask: int, beam_mode: int, write_depth: bool, write_beam: bool, accumulate: bool143):144"""Pointwise VJP: inputs L, beam, scalar, seed_T/counts/log/removed;145outputs grad_L, grad_beam, status. Launch ``dim=P``.146147``write_beam`` is only for per-pixel beams. Broadcast beams use the tiled148reduction below. ``accumulate`` is reserved for the tape adapter.149"""150if seed_mask < 0 or seed_mask > 15 or beam_mode not in (0, 1, 2, 3):151raise ValueError("Invalid seed mask or beam mode")152if seed_mask & 2 and beam_mode == 0:153raise ValueError("Count cotangents require an open beam")154if write_beam and beam_mode != 3:155raise ValueError("Pointwise beam gradients require a per-pixel beam")156157@wp.kernel(module="unique", module_options=STRICT_OPTIONS)158def vjp(159optical_depth: wp.array(dtype=wp.float32),160beam: wp.array(dtype=wp.float32),161beam_scalar: wp.float32,162seed_transmission: wp.array(dtype=wp.float32),163seed_counts: wp.array(dtype=wp.float32),164seed_log: wp.array(dtype=wp.float32),165seed_removed: wp.array(dtype=wp.float32),166grad_depth: wp.array(dtype=wp.float32),167grad_beam: wp.array(dtype=wp.float32),168status: wp.array(dtype=wp.int32),169):170p = wp.tid()171factor = wp.float64(0.0)172if wp.static(seed_mask & 11 != 0):173factor = transmission_factor(optical_depth[p])174a = wp.float32(0.0)175b = wp.float32(0.0)176c = wp.float32(0.0)177r = wp.float32(0.0)178if wp.static(seed_mask & 1 != 0):179a = seed_transmission[p]180if wp.static(seed_mask & 2 != 0):181b = seed_counts[p]182if wp.static(seed_mask & 4 != 0):183c = seed_log[p]184if wp.static(seed_mask & 8 != 0):185r = seed_removed[p]186if wp.static(write_depth):187illumination = wp.float32(0.0)188if wp.static(seed_mask & 2 != 0):189illumination = beam_scalar190if wp.static(beam_mode == 2):191illumination = beam[0]192elif wp.static(beam_mode == 3):193illumination = beam[p]194derivative = weighted_depth_adjoint(factor, illumination, a, b, c, r)195if wp.static(accumulate):196derivative = derivative + wp.float64(grad_depth[p])197grad_depth[p] = checked_gradient(derivative, status)198if wp.static(write_beam):199derivative_beam = wp.float64(b) * factor200if wp.static(accumulate):201derivative_beam = derivative_beam + wp.float64(grad_beam[p])202grad_beam[p] = checked_gradient(derivative_beam, status)203204return vjp205206207@wp.func208def beam_contribution(depth: wp.float32, seed: wp.float32) -> wp.float64:209return wp.float64(seed) * transmission_factor(depth)210211212# region book:transmission-beam-reduction213@cache214def get_beam_partial_kernel():215"""Inputs L, seed_counts; output FP64 partials.216217Use ``launch_tiled(dim=ceil(P/256), block_dim=256)``. Tile loads zero-pad218their bounds, so padded seeds contribute zero even though exp(-0) is one.219The separate pass deliberately avoids retaining an 8P-byte contribution220image or contending for a global scalar. Its traffic is accounted separately.221"""222223@wp.kernel(module="unique", module_options=STRICT_OPTIONS)224def partials(225optical_depth: wp.array(dtype=wp.float32),226seed_counts: wp.array(dtype=wp.float32),227output: wp.array(dtype=wp.float64),228):229block = wp.tid()230depths = wp.tile_load(optical_depth, shape=TILE_SIZE, offset=block * TILE_SIZE)231seeds = wp.tile_load(seed_counts, shape=TILE_SIZE, offset=block * TILE_SIZE)232contributions = wp.tile_map(beam_contribution, depths, seeds)233total = wp.tile_sum(contributions)234wp.tile_store(output, total, offset=block)235236return partials237238239# endregion book:transmission-beam-reduction240241242@cache243def get_inverse_kernel():244"""Inputs decrement; outputs optical depth; launch ``dim=P``."""245246@wp.kernel(module="unique", module_options=STRICT_OPTIONS)247def inverse(delta: wp.array(dtype=wp.float32), depth: wp.array(dtype=wp.float32)):248p = wp.tid()249value = optical_depth_from_decrement(delta[p])250if value == wp.float32(0.0):251value = wp.float32(0.0)252depth[p] = value253254return inverse255256257@cache258def get_inverse_vjp_kernel(accumulate: bool):259"""Inputs delta, seed_L; outputs grad_delta, status; launch ``dim=P``."""260261@wp.kernel(module="unique", module_options=STRICT_OPTIONS)262def inverse_vjp(263delta: wp.array(dtype=wp.float32),264seed: wp.array(dtype=wp.float32),265gradient: wp.array(dtype=wp.float32),266status: wp.array(dtype=wp.int32),267):268p = wp.tid()269derivative = wp.float64(seed[p]) / (wp.float64(1.0) - wp.float64(delta[p]))270if wp.static(accumulate):271derivative = derivative + wp.float64(gradient[p])272gradient[p] = checked_gradient(derivative, status)273274return inverse_vjp275276277@wp.kernel(module="unique", module_options=STRICT_OPTIONS)278def finite_nonnegative(values: wp.array(dtype=wp.float32), status: wp.array(dtype=wp.int32)):279"""Inputs values; outputs status; launch dim=values.shape[0]."""280value = values[wp.tid()]281if not wp.isfinite(value) or value < wp.float32(0.0):282wp.atomic_or(status, 0, 1)283284285@wp.kernel(module="unique", module_options=STRICT_OPTIONS)286def finite_seed(values: wp.array(dtype=wp.float32), status: wp.array(dtype=wp.int32)):287"""Inputs cotangents; outputs status; launch dim=values.shape[0]."""288if not wp.isfinite(values[wp.tid()]):289wp.atomic_or(status, 0, 1)290291292@wp.kernel(module="unique", module_options=STRICT_OPTIONS)293def decrement_domain(values: wp.array(dtype=wp.float32), status: wp.array(dtype=wp.int32)):294"""Inputs decrements; outputs status; launch dim=values.shape[0]."""295value = values[wp.tid()]296if not wp.isfinite(value) or value < wp.float32(0.0) or value >= wp.float32(1.0):297wp.atomic_or(status, 0, 1)298299300@wp.kernel(module="unique", module_options={"enable_backward": True})301def dependency_marker(302depth: wp.array(dtype=wp.float32),303beam: wp.array(dtype=wp.float32),304transmission: wp.array(dtype=wp.float32),305counts: wp.array(dtype=wp.float32),306log_transmission: wp.array(dtype=wp.float32),307removed: wp.array(dtype=wp.float32),308):309"""Zero-dimensional tape bookkeeping only; never executes a CUDA thread."""310pass311