Skip to content

Make SearchProperties probes robust to non-primitive Real eltypes (AD)#100

Merged
ChrisRackauckas merged 2 commits into
SciML:mainfrom
ChrisRackauckas-Claude:ad-valued-search-probes
Jul 13, 2026
Merged

Make SearchProperties probes robust to non-primitive Real eltypes (AD)#100
ChrisRackauckas merged 2 commits into
SciML:mainfrom
ChrisRackauckas-Claude:ad-valued-search-probes

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

Please ignore until reviewed by @ChrisRackauckas. Draft — opened by an agent.

Problem

Constructing SearchProperties on a ForwardDiff.Dual-valued knot vector throws a MethodError:

MethodError: no method matching Float64(::ForwardDiff.Dual{...})

ForwardDiff.Dual <: Real, so it dispatches to SearchProperties(v::AbstractVector{<:Real}), whose sampled linearity / uniformity / log-linearity probes coerce intermediates with Float64(...). Float64(::Dual) is deliberately undefined. This surfaces downstream when an interpolation is reconstructed inside ForwardDiff and both values and knots are promoted to Duals (e.g. SciML/DataInterpolations.jl#557).

Fix

The Float64(...) coercions are redundant for the primitive eltypes — for Int/Float32/Float64 the probe expressions are already Float64. Removing them and computing in native arithmetic:

  • makes the probes work for any ordered Real (classification is taken from the primal, partials are preserved), and
  • leaves the Int/Float64 hot path byte-for-byte unchanged.

I verified ForwardDiff defines unsafe_trunc(Int, ::Dual), so once the probe stops calling Float64, the closed-form UniformStep search path also works end-to-end and derivatives propagate correctly.

Tests

Adds a regression testset differentiating through both values and Dual-valued knots (uniform + non-uniform), plus a full Auto search over uniform Dual knots checked against Base on the primal. Wires ForwardDiff into the test targets.

  • Full GROUP=Core suite: 171,933 pass locally.
  • Runic clean.

Relation to other work

This unblocks SciML/DataInterpolations.jl#557 — with this merged, that PR can drop its _default_search_properties/_search_properties opt-out helpers and just bump the FindFirstFunctions compat bound. A separate PR handles a distinct pre-existing Rational crash in the UniformStep kernel found while testing eltype robustness.

`SearchProperties(v::AbstractVector{<:Real})` runs sampled linearity /
uniformity / log-linearity probes that coerced intermediate values with
`Float64(...)`. `ForwardDiff.Dual <: Real`, but `Float64(::Dual)` is
deliberately undefined, so constructing `SearchProperties` on a Dual-valued
knot vector — as happens when an interpolation is reconstructed inside
`ForwardDiff` and the knots are promoted to Duals — threw a `MethodError`.

The `Float64(...)` coercions are redundant for the primitive eltypes: for
`Int`/`Float32`/`Float64` the probe expressions are already `Float64`. Drop
them and compute in native arithmetic, so the probes work for any ordered
`Real` (the classification is taken from the primal and partials are kept
intact), while the primitive hot path is byte-for-byte unchanged.

Adds a ForwardDiff regression testset differentiating through both values
and Dual-valued knots, and wires ForwardDiff into the test targets.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FvBXVKGujjeaCB3iLwsDeG
Comment thread src/search_properties.jl Outdated
@ChrisRackauckas ChrisRackauckas marked this pull request as ready for review July 13, 2026 19:49
@ChrisRackauckas ChrisRackauckas merged commit 1351a3a into SciML:main Jul 13, 2026
23 of 24 checks passed
ChrisRackauckas-Claude pushed a commit to ChrisRackauckas-Claude/DataInterpolations.jl that referenced this pull request Jul 13, 2026
Reconstructing an interpolation inside ForwardDiff promotes both the values
and the knot vector to `ForwardDiff.Dual`. On FindFirstFunctions < 3.2 the
`SearchProperties` linearity probe attempted an invalid `Float64(::Dual)`
conversion, breaking `LinearInterpolation` (and the other constructors) for
11+ knots — the v9.0.0 regression.

FindFirstFunctions 3.2 fixes the probe upstream (SciML/FindFirstFunctions.jl#100),
so no local opt-out shim is needed: bump the compat lower bound to `3.2` and
keep using `something(search_properties, FindFirstFunctions.SearchProperties(t))`
directly. Adds a regression test differentiating through both values and knots
across 15 knots.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FvBXVKGujjeaCB3iLwsDeG
ChrisRackauckas-Claude pushed a commit to ChrisRackauckas-Claude/DataInterpolations.jl that referenced this pull request Jul 13, 2026
Reconstructing an interpolation inside ForwardDiff promotes both the values
and the knot vector to `ForwardDiff.Dual`. On FindFirstFunctions < 3.2 the
`SearchProperties` linearity probe attempted an invalid `Float64(::Dual)`
conversion, breaking `LinearInterpolation` (and the other constructors) for
11+ knots — the v9.0.0 regression.

FindFirstFunctions 3.2 fixes the probe upstream (SciML/FindFirstFunctions.jl#100),
so no local opt-out shim is needed: bump the compat lower bound to `3.2` and
keep using `something(search_properties, FindFirstFunctions.SearchProperties(t))`
directly. Adds a regression test differentiating through both values and knots
across 15 knots.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FvBXVKGujjeaCB3iLwsDeG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants