pub struct ResidentBaseArrowFrameHandle { /* private fields */ }Expand description
#1017: a BASE-block-resident Arrow-Schur frame for the LM ridge ladder.
Unlike ResidentArrowFrameHandle — which BAKES one ridge into its factors
and then serves cheap re-solves for a NEW GRADIENT at that SAME ridge — this
frame holds the ridge-INDEPENDENT base blocks (D = H_tt, B = H_tβ, border
H_ββ, gradient) resident and RE-FACTORS on-device at each requested
(ridge_t, ridge_beta). That is the regime solve_with_lm_escalation_inner
actually runs: its trials re-solve the SAME system (same gradient) at
ESCALATING ridges, so the factor changes every trial but the base blocks do
not. The base blocks upload ONCE; each trial pays only a device-to-device
copy of the base blocks into scratch, an on-device diagonal ridge add, and the
factor/solve — in place of the full O(n·d·k) host→device re-upload that
solve_arrow_newton_step performs every trial. The per-trial numerics are
bit-identical to that re-upload path (same POTRF/TRSM/Schur/back-sub order).
Implementations§
Source§impl ResidentBaseArrowFrameHandle
impl ResidentBaseArrowFrameHandle
Sourcepub fn new(
sys: &ArrowSchurSystem,
newton_schur_tikhonov_rel_floor: Option<f64>,
) -> Result<Self, ArrowSchurGpuFailure>
pub fn new( sys: &ArrowSchurSystem, newton_schur_tikhonov_rel_floor: Option<f64>, ) -> Result<Self, ArrowSchurGpuFailure>
Upload the ridge-independent base blocks once. No factorization runs here;
each Self::refactor_and_solve performs the ridge-dependent factor+solve.
The dense device path requires materialised blocks, so a matrix-free
H_ββ / H_tβ operator is rejected (same admission as
solve_arrow_newton_step).
Sourcepub fn refactor_and_solve(
&self,
ridge_t: f64,
ridge_beta: f64,
) -> Result<ArrowSchurGpuSolution, ArrowSchurGpuFailure>
pub fn refactor_and_solve( &self, ridge_t: f64, ridge_beta: f64, ) -> Result<ArrowSchurGpuSolution, ArrowSchurGpuFailure>
Factor the resident base blocks at (ridge_t, ridge_beta) and solve
(H + ridge)·δ = −gradient. Only the two ridge scalars and the tiny
re-diagonalised D cross to the device; only δ crosses back. A non-PD
per-row block surfaces as ArrowSchurGpuFailure::RidgeBumpRequired so
the LM escalation bumps and retries at the larger ridge exactly as the
re-upload path does.
Sourcepub fn refactor_and_solve_with_gradient(
&self,
ridge_t: f64,
ridge_beta: f64,
g_t: &[f64],
g_beta: &[f64],
) -> Result<ArrowSchurGpuSolution, ArrowSchurGpuFailure>
pub fn refactor_and_solve_with_gradient( &self, ridge_t: f64, ridge_beta: f64, g_t: &[f64], g_beta: &[f64], ) -> Result<ArrowSchurGpuSolution, ArrowSchurGpuFailure>
As Self::refactor_and_solve, but solves for a FRESH gradient instead
of the one captured at construction (#2539).
Self::refactor_and_solve was built for the LM ridge ladder, whose
trials re-solve the SAME system at escalating ridges, so it reads the
resident g_t/g_β. An inner Newton moves the gradient every iterate
while the Hessian blocks stay fixed, so it needs this variant: g_t
(n·d doubles) and g_β (k) cross to the device in place of the
device-to-device copy of the resident gradient, and the D/B/H_ββ
blocks stay resident exactly as they do there. Everything after the
gradient sourcing — POTRF/TRSM/Schur/back-substitution and their order —
is the same code, so a solve here is bit-identical to a
ResidentArrowFrameHandle rebuild at the same ridge and gradient.
Sourcepub fn factor_at(
&self,
ridge_t: f64,
ridge_beta: f64,
) -> Result<ResidentBaseRidgeFactorsHandle, ArrowSchurGpuFailure>
pub fn factor_at( &self, ridge_t: f64, ridge_beta: f64, ) -> Result<ResidentBaseRidgeFactorsHandle, ArrowSchurGpuFailure>
Run only the ridge-dependent FACTOR work and hand the factors back, so a caller whose ridge does not move on the next iterate can re-solve without re-factoring (#2539).
Self::refactor_and_solve_with_gradient is exactly this followed by
Self::solve_with_factors. An inner Newton needs them separately: its
ridge changes only on an LM accept/reject, while its gradient changes
every iterate, so factoring per iterate would pay a POTRF/TRSM/Schur
chain for a factor that did not move — the accepted-step cost the
ridge-keyed frame used to avoid.
Sourcepub fn solve_with_factors(
&self,
factors: &ResidentBaseRidgeFactorsHandle,
g_t: &[f64],
g_beta: &[f64],
) -> Result<ArrowSchurGpuSolution, ArrowSchurGpuFailure>
pub fn solve_with_factors( &self, factors: &ResidentBaseRidgeFactorsHandle, g_t: &[f64], g_beta: &[f64], ) -> Result<ArrowSchurGpuSolution, ArrowSchurGpuFailure>
Solve (H + ridge)·δ = −gradient against factors from
Self::factor_at. No POTRF, no B whitening: only the gradient
(n·d + k doubles) crosses to the device and only δ crosses back.
Auto Trait Implementations§
impl Freeze for ResidentBaseArrowFrameHandle
impl RefUnwindSafe for ResidentBaseArrowFrameHandle
impl Send for ResidentBaseArrowFrameHandle
impl Sync for ResidentBaseArrowFrameHandle
impl Unpin for ResidentBaseArrowFrameHandle
impl UnsafeUnpin for ResidentBaseArrowFrameHandle
impl UnwindSafe for ResidentBaseArrowFrameHandle
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.