GPUVern7 Float32 dense output is ~60 ulps off at mid-step for a constant RHS (visible at tstops)

Aperta
#554 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
62/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
julia

Direzione di ricerca

Start by running the provided CPU reproducer and inspect the GPUVern7 interpolant and integ(t) path. Compare the current interpolant with the pre-97e5ac9 source and the tstop tests from PR #544. Done means exact endpoint behavior is preserved, mid-step Float32 error is reduced, and the tstop tests assert an appropriate tolerance.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

In Float32, GPUVern7's dense output loses about 60 ulps at mid-step even for a constant right-hand side, where the interpolant should be exact up to rounding. It shows up whenever an adaptive solve stops at a tstop inside a step, because the state there comes from integ(t).

Reproducer (CPU backend, no GPU needed):

using DiffEqGPU, SciMLBase, StaticArrays, KernelAbstractions
for alg in (GPUTsit5(), GPUVern7(), GPUVern9()), stops in (nothing, Float32[0.875])
    prob = ODEProblem{false}((u, p, t) -> SVector(1f0, 1f0), SVector(1f0, 1f0), (0.75f0, 1f0))
    kw = stops === nothing ? (;) : (; tstops = stops)
    sol = solve(EnsembleProblem(prob), alg, EnsembleGPUKernel(CPU(), 0.0); trajectories = 2,
        adaptive = true, dt = prevfloat(0.25f0), abstol = 1f-9, reltol = 1f-6,
        save_everystep = false, kw...)
    u = sol.u[1].u[end][1]
    println(nameof(typeof(alg)), " tstops=", stops, " u_end=", u, " ulps=", round(Int, (u - 1.25f0) / eps(1.25f0)))
end

On master b3d6a17 (Julia 1.12.7), the exact answer is 1.25:

algorithm no tstop tstop at 0.875
GPUTsit5 1.25 (0 ulps) 1.25 (0 ulps)
GPUVern7 1.25 (0 ulps) 1.2500077 (65 ulps)
GPUVern9 1.25 (0 ulps) 1.2499995 (−4 ulps)

The review of https://github.com/SciML/DiffEqGPU.jl/pull/544 reports that substituting the Vern7 interpolant from before https://github.com/SciML/DiffEqGPU.jl/commit/97e5ac9bd03ce7f075432ac9c784031ccc917aa2 ("Restructure Vern7 interpolant with (1-Θ) factors for exact endpoints") into the same environment brought this case from 65 ulps down to 2. That was a source substitution, not a bisect, and I have not reproduced it independently. That commit made the endpoints exact (see https://github.com/SciML/DiffEqGPU.jl/issues/412), so a fix needs to keep exact endpoints while restoring mid-step accuracy.

Found while working on https://github.com/SciML/DiffEqGPU.jl/pull/544. That PR's tstop tests only check that the callback fired and that the state is finite for Vern7/Vern9, rather than fitting a tolerance to this error. They should be tightened once this is fixed.

🤖 Generated with Claude Code (model: claude-opus-5-5[1m])

https://claude.ai/code/session_01SJfy3ez7u4CqvAerKrT5np

Lingua principale
Julia
Stelle
331
Fork
43
Merge medio
1g 20h
PR unite (30g)
10

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di SciML/DiffEqGPU.jl

Tutte le issue di SciML/DiffEqGPU.jl

Issue simili

Altre issue su Julia

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.