Gamma-CDF derivative
The problem
The regularised lower incomplete gamma P(a, z) is the Gamma CDF, and SpecialFunctions.gamma_inc computes it accurately across every regime. Its ChainRule, though, leaves the partial with respect to the shape parameter a as @not_implemented. A Gamma CDF differentiated in its shape therefore has no derivative on any ChainRules-based backend, and the forward-mode Dual and Enzyme paths hit the same wall.
The fix
_gamma_cdf(k, θ, x) evaluates P(k, x/θ) on the primal path through gamma_inc, and the extensions supply the derivative analytically:
_grad_p_a_seriescomputes the missing shape partial by term-by-term differentiation of the Tricomi series, following Moore (1982), Algorithm AS 187 — the same construction Stan (grad_reg_inc_gamma) and JAX (igamma_grad_a) use._gamma_cdf_value_and_partialsreturns the primal and the(dk, dθ, dx)partials from one helper, so the ChainRules rule, the ForwardDiffDualmethods, and the Enzyme rule share the same formulas.EpiAwareADToolsChainRulesCoreExtdefines the reverse-moderruleand forward-modefrule;EpiAwareADToolsReverseDiffExtandEpiAwareADToolsMooncakeExtlift these into their backends;EpiAwareADToolsForwardDiffExtaddsDualmethods directly; andEpiAwareADToolsEnzymeExtadds a direct Enzyme rule.
The Enzyme extension also carries a rule for SpecialFunctions.gamma, whose own Enzyme lowering is wrong by a factor of Γ(x) (an upstream Enzyme bug); the gamma density in _gamma_cdf_value_and_partials needs it.
This machinery is internal. Consumers reach it through the AD-safe hooks; the Internal API page carries the full docstrings.
Upstream target
The whole family stands in for a differentiable gamma_inc. SpecialFunctions.jl issue #531 tracks the missing shape derivative. Once gamma_inc carries a complete ChainRule, _gamma_cdf and its rules are deleted and the hooks route through the stock CDF.