Shadows

Pol.ShadowedType
Shadowed(primal, shadow)
Shadowed(primal, [T=eltype(primal)])
Shadowed(space::Space, primal, [T=eltype(primal)])

A primal array paired with a gradient buffer, passed positionally to in-place -kernels: the backward pass reads primals and writes input gradients into shadows. Shadows are overwritten, never accumulated — cross-call accumulation is the AD backend's job. (Same shape as Enzyme's Duplicated, deliberately not its name: Enzyme's shadows accumulate.)

The shadow need not share the primal's eltype — a narrow-precision forward usually pairs with wider gradients (Shadowed(x, BFloat16) for an fp8 x); the backward kernel writes in the shadow's eltype. The one-argument form pairs x with an uninitialized similar(x) shadow, the type form with similar(x, T). A leading Space materializes the shadow from it instead: Shadowed(space, x, [T]). A shadow needs no description protocol — its spec is the primal itself.

Forward kernels accept a bare array or a Shadowed interchangeably via primal.

source
Pol.primalFunction
primal(x)

The primal value of x: x itself for a bare array, or d.primal for a Shadowed. Lets forward kernels accept either.

source
Pol.shadowFunction
shadow(x)

The gradient shadow of a Shadowed, or nothing for anything else: a bare array passed where a Shadowed is accepted is a constant — no gradient is requested and none is written.

source