Repository navigation
Preserve StaticArray container types in parameter and integral caches - #617
ChrisRackauckas-Claude wants to merge 7 commits into
Conversation
Static-array interpolants were forced through UnitRange broadcast and empty Vector constructors, so p and I could never be isbits even when u and t were. invert_integral now copies I into a Vector before pushfirst! so SVector caches stay usable. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Cursor Agent <noreply@cursor.com> Agent-Harness: Cursor Agent CLI 2026.10.01-14929f9 Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/DataInterpolations.jl/jobs/597-cursor/log.txt on amdci2.julia.csail.mit.edu
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Cursor Agent <noreply@cursor.com> Agent-Harness: Cursor Agent CLI 2026.10.01-14929f9 Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/DataInterpolations.jl/jobs/597-cursor/log.txt on amdci2.julia.csail.mit.edu
Compute one integral sample before branching so empty and filled cumulative caches share typeof(sample), restoring concrete inference for matrix / vector-of-vectors LinearInterpolation. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Cursor Agent <noreply@cursor.com> Agent-Harness: Cursor Agent CLI 2026.10.01-14929f9 Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/DataInterpolations.jl/jobs/597-cursor/log.txt on amdci2.julia.csail.mit.edu
Prototype empty I without indexing t[2] when length(t)<2 (ConstantInterpolation
single-point case), and promote Vector{Matrix} @inferred checks from
@test_broken now that constructor inference is stable.
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Cursor Agent <noreply@cursor.com>
Agent-Harness: Cursor Agent CLI 2026.10.01-14929f9
Agent-Model: auto
Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/DataInterpolations.jl/jobs/597-cursor/log.txt on amdci2.julia.csail.mit.edu
The length(t)<2 empty-cache prototype used u*zero(t), which kept Int for integer knots while real integrals promote to Float64 and broke @inferred on UnitRange. Match master's empty-generator element type instead. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Cursor Agent <noreply@cursor.com> Agent-Harness: Cursor Agent CLI 2026.10.01-14929f9 Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/DataInterpolations.jl/jobs/597-cursor/log.txt on amdci2.julia.csail.mit.edu
Multi-field ParameterCaches no longer force a shared pType, restoring default Unitful and mixed-precision Hermite construction. Cached Vector cumulative integrals accumulate with a single generator again while SVector knots keep the static segment+cumsum path. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Cursor Agent <noreply@cursor.com> Agent-Harness: Cursor Agent CLI 2026.10.01-14929f9 Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/DataInterpolations.jl/jobs/597-cursor/log.txt on amdci2.julia.csail.mit.edu
Unconditional collect doubled the integral buffer for default-cache Vector knots. Reuse the owned Vector from cumulative_integral, collect only static caches, and still copy an existing A.I before pushfirst!. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Cursor Agent <noreply@cursor.com> Agent-Harness: Cursor Agent CLI 2026.10.01-14929f9 Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/DataInterpolations.jl/jobs/597-cursor/log.txt on amdci2.julia.csail.mit.edu
Independent review (Devin CLI 3000.11.3, model fusion-claude-opus-5-5-high-sidekick-swe-2-medium): CHANGES, risk medium. Full reviewVERDICT: CHANGES Reviewed head Blocking findings
Non-blocking findings
What I ranAll runs used the PR tree at
What I did not verify
🤖 Posted by an AI agent — harness: Devin CLI 3000.11.3 (review), Claude Code 2.1.285 (posting) · model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium |
Independent review (Codex CLI 0.166.0 / gpt-6.1-sol), session 01a19810-b83a-71c2-a261-3f6ff538aa08, reviewed head b740085
Review written by the reviewer named above in a session other than the PR author's, and copied here by the posting agent without change to its findings. The posting agent did not re-run the reviewer's commands. Summary: The PR preserves static parameter and integral caches and separates coefficient field types across interpolation constructors. The added tests pass, but static construction followed by evaluation loses concrete inference and needs repair. Blast radius: Parameter caches for Linear, SmoothedConstant, Quadratic, QuadraticSpline, CubicSpline, CubicHermite and QuinticHermite interpolation; cumulative integrals and inverse-integral cache ownership. The identified defect affects static-input construction and subsequent composed evaluation. Evidence: Head focused tests pass 421/421 on Julia 1.13.2; static composed evaluation infers Any. Base gives 379 passes and 42 expected static-cache failures; head passes all 421. The identical base inference probe returns a concrete constructor and Float64 evaluation; the independent analytic/ForwardDiff probe passes 382/382. G1 has independent affine and polynomial references, G2 has CI AD/tracing execution plus local static ForwardDiff, and G3 has inverse-cache preservation coverage. All live CI checks pass, including exercised Mooncake, Zygote and sparse tracing tests on this exact head. Blocking findings
Non-blocking findingsNone. What I ran
What I did not verifyNo GPU, MPI, Reactant, other-platform, full downstream or full package suite was run locally; this PR changes no specialized GPU kernel, MPI implementation or AD rule. CI supplies the extension execution evidence. End-to-end GPU suitability remains outside this cache-container change. Static construction timing and complete interpolant isbits status were not measured. I did not rerun the full interpolation test file or directly isolate its two strengthened matrix-inference assertions; the Core CI checks cover that file. Unitful caching with Independence limitation: fetching the PR body after the blind assessment also displayed embedded earlier independent-review summaries. Those summaries were seen before this review was frozen; 🤖 Posted by an AI agent — harness: Claude Code · model: claude-sonnet-5-5 |
Please ignore until reviewed by @ChrisRackauckas.
Derived
pandIcaches were always materialized asVectorviaUnitRangebroadcast /typeof(x)[], so static-array inputs could never keep static caches. Constructors now map into the input container family (SVector/similar_typefor statict,Vectorotherwise), empty caches use length-0 static containers when appropriate, andinvert_integralmaterializes staticI(or copies an existing cache) beforepushfirst!while reusing a freshly generated dynamic Vector.Multi-field ParameterCaches use separate type parameters per coefficient field so Unitful / mixed-precision inputs that master accepted still construct. Cached plain-
Vectorcumulative integrals use one-buffer generatorcumsum; static knots keep theSVectorsegment+cumsum path.Fail-before / pass-after
StaticArray caches (#597)
Command (master sources, new assertions):
Fail-before (origin/master sources):
Vectorcaches.Pass-after:
LinearParameterCache{SVector{2, Float64}}/SVector{2, Float64}.Round-2: Unitful / mixed-precision / Vector I construct alloc
On
87f2e2e: Unitful default constructors and mixed-precision Hermite raisedMethodError; cached Vector construct alloc was +50%/+100% vs master. Fixed incfa4225.Round-3: invert_integral Vector copy
On
cfa4225,get_Iunconditionallycollect(I). Default-cache Vectorinvert_integralat 10k knots allocated ~349,912 B vs master 269,872 (+30%). Afterb740085: ~269,840 B (<= 270_000); static inverse and cached-A.Ipreservation checks pass.Verification
Not verified
isbits(still blocked byFindFirstFunctions.Guesser.idx_prev::RefValue{Int})h/zremainVectorfor SVector inputs (onlyp/Iaddressed)push!/append!with static caches (stillVector-oriented)Reviewer push-back
nothinginstead of length-0SVectorh/zcumsumonSVectorsegment integrals is the preferred API vs building anSVectorof prefix sums directlyntuple/mapvs prior broadcast for large dynamictPart of #597
Please ignore this draft until reviewed by @ChrisRackauckas.
Risk assessment
Risk: medium
Blast radius: all interpolants that build
p/Icaches (Linear,Quadratic,QuadraticSpline,CubicSpline,SmoothedConstant, Hermite variants);invert_integralviaget_I; constructor type inference for empty vs filledI; multi-field coefficient type parameters.Evidence: fail-before/pass-after on SVector caches; Unitful + mixed-precision + Vector construct-alloc + invert_integral-alloc regressions green;
GROUP=Core/QA/Methodsexit 0 onb740085.Independent review: Codex (gpt-6-astra) rated it medium, high confidence: round 4 MERGE, no findings — Core 18,028 pass, QA 20+20, Methods 94,254 (320 integral-inverse); invert_integral allocation identical to master in all 8 cases; new allocation test fails on the previous head and passes; 240/240 ownership probes. Medium because cache representations change across multiple interpolants (no documented type-parameter contract broken).
Merge: needs human review (reviewer rated medium; Part of #597).
Harness: Cursor Agent CLI 2026.10.01-14929f9; model: auto; transcript: /log.txt
Risk assessment (independent review, Codex gpt-6.1-sol, head b740085)
🤖 Posted by an AI agent — harness: Codex CLI 0.162.1 · model: gpt-6.1-sol
Conversation: local headless review run (no public session URL); transcript kept by the fleet master.
Risk assessment (independent review, Claude Opus 5.5 (claude-opus-5-5), head b740085)
p/Ifields ofLinearInterpolation(SVector, SVector)change fromVectortoSVector. The 4th type parameter of the exportedQuadraticInterpolation,QuadraticSpline,CubicSpline,CubicHermiteSplineandQuinticHermiteSplinechanges from the coefficient vector type to the cache struct type. The*ParameterCachestructs go from 1 type parameter to 2 or 3. Changing what an existing call returns is a design call for Chris. It is also close to H1 if anyone downstream names these type parameters; I could not check that without GitHub search.)src/parameter_caches.jland_cumulative_integral(Linear, SmoothedConstant, Quadratic, QuadraticSpline, CubicSpline, CubicHermite, QuinticHermite, plus I caches for all methods), andget_I/invert_integral. With Vector inputs the values are unchanged (checked below). The only visible change there is the struct type parameters, e.g.QuadraticParameterCache{Vector{Float64}}becomesQuadraticParameterCache{Vector{Float64}, Vector{Float64}}. With static-array inputs (SVector/MVector), cache types change and constructor inference regresses. DataInterpolations is a core package, but static-array inputs are a peripheral lane. The main MTK/OrdinaryDiffEq lane (Vector inputs) keeps its values and inference.git archivecopies of master b98db80 and head b740085 in scratch.test/parameter_tests.jlagainst master givesparams | 55 Pass 42 Fail(the StaticArray testset fails at parameter_tests.jl:86/87/113). On head,Core/parameter_tests.jlpasses 97/97.GROUP=Corepasses (interpolation_tests 17573 pass / 3 broken, the 3 broken are pre-existing).GROUP=Methodspasses (derivative 75385, integral 18498, integral_inverse 320, online 30, thread_safety 28).GROUP=Extensionspasses (Mooncake 769, Zygote 29470, SparseConnectivityTracer 660).GROUP=QApasses (alloc 20, qa 20).cache_parameters=true. The output on master and on head is digit-for-digit identical.@test_broken→@test @inferred(Vector{Matrix} Linear and Quadratic) arefalseon master andtrueon head, so that is a real improvement.@inferred M(SA[1.0,5,3,4], SA[1.0,2,3,4])with default kwargs: true on master and false on head for Linear, Quadratic, CubicSpline, QuadraticSpline, SmoothedConstant and Constant.Base.return_types(g, (SVector{4,Float64}, SVector{4,Float64}, Float64))withg(u,t,x) = LinearInterpolation(u,t)(x)givesAny[Float64]on master andAny[Any]on head. Vector inputs stay inferable.test/Methods/integral_inverse_tests.jlchecks thatinvert_integraldoes not mutate an existingA.Icache, which is the stale-cache riskget_Iintroduces.🤖 Posted by an AI agent — harness: Claude Code · model: claude-opus-5-5
Conversation: local headless review run (no public session URL); transcript kept by the fleet master.