Add `xtrain_autodiff::checkpoint::checkpoint(segment_fn, input, params)`, a higher-order autograd node (à la torch.utils.checkpoint) for activation recomputation (Phase T13 / KI-3): - forward: run `segment_fn` on detached leaves so its internal ops are NOT recorded on the outer tape; keep only the output value (the local sub-tape — and thus the segment's intermediate activations — drops immediately). The checkpoint node's parents are [input, ..params]. - backward: re-run `segment_fn` from the saved input + (unchanged) param values into a fresh local tape, seed the recomputed output with the upstream grad, backprop, then push the recovered input/param grads to the real parents. Local tape drops at the end → recomputed activations freed. Exact by construction (same deterministic kernels, same inputs) → grads match the non-checkpointed path. Composes with bf16 (T12, same path on recompute) and DDP (T8, per-rank). Supporting change: `Var::backward_seeded(seed)` — backward from an explicit non-scalar upstream grad (the segment output is generally not a scalar); `backward()` is now the scalar wrapper that seeds ones. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
29 lines
1.1 KiB
Rust
29 lines
1.1 KiB
Rust
//! Reusable numerical-gradient checking for xtrain (Phase T3+).
|
|
//!
|
|
//! Given a scalar loss `f(x)` and an analytic gradient `g`, verify that `g`
|
|
//! matches the central finite-difference estimate
|
|
//! `(f(x+ε·eᵢ) - f(x-ε·eᵢ)) / 2ε` for every element `i`, within a relative
|
|
//! tolerance. Later phases (T4 autograd) reuse this per-op: wrap each op's
|
|
//! forward as the loss, run its backward to get `g`, and `grad_check`.
|
|
//!
|
|
//! The harness is host-only and dtype-agnostic at this layer: it works on a
|
|
//! flat `&[f32]` parameter vector + shape and a closure. The closure is free to
|
|
//! push the data to the GPU and run kernels — that detail stays out of here.
|
|
|
|
pub mod finite_diff;
|
|
|
|
pub use finite_diff::{GradCheckConfig, GradCheckResult, ParamFn, grad_check};
|
|
|
|
// Tape-based autograd engine + differentiable ops (Phase T4). These call GPU
|
|
// kernels via xtrain-tensor, so they are gated behind `not(no_cuda)` (the
|
|
// per-crate convention); the grad_check harness above stays host-only.
|
|
#[cfg(not(no_cuda))]
|
|
pub mod checkpoint;
|
|
#[cfg(not(no_cuda))]
|
|
pub mod ops;
|
|
#[cfg(not(no_cuda))]
|
|
pub mod tape;
|
|
|
|
#[cfg(not(no_cuda))]
|
|
pub use tape::Var;
|