Skip to content

Fix HashedRandom guess in SCCNonlinearProblem (stable_eachindex MethodError)#4606

Open
baggepinnen wants to merge 2 commits into
SciML:masterfrom
baggepinnen:fix-scc-hashedrandom-eachindex
Open

Fix HashedRandom guess in SCCNonlinearProblem (stable_eachindex MethodError)#4606
baggepinnen wants to merge 2 commits into
SciML:masterfrom
baggepinnen:fix-scc-hashedrandom-eachindex

Conversation

@baggepinnen

Copy link
Copy Markdown
Contributor

Fixes #4603

The MissingGuessValue.HashedRandom() branch in the SCC init-problem builder (src/problems/sccnonlinearproblem.jl) had two bugs on one line:

newval = [hash(var,hash(i)) for i in SU.stable_eachindex(symbolic_idxs)]./0x1p64
  1. symbolic_idxs is a plain Vector{Int64} (from findall), but stable_eachindex is only defined for BasicSymbolic, producing the reported MethodError: no method matching stable_eachindex(::Vector{Int64}). This was introduced by a blanket eachindexstable_eachindex rename that wrongly caught this loop over a regular vector.
  2. var is undefined in this (non-LinearFunction) branch — it only exists in the LinearFunction branch. The line was a faulty copy of the array-symbolic HashedRandom code in problem_utils.jl.

For the SCC case, the missing-guess value for index j should derive from the corresponding scalar unknown dvs[vscc[j]], matching the scalar HashedRandom form hash(var)/0x1p64 and consistent with the sibling Random branch:

newval = [hash(dvs[vscc[j]]) for j in symbolic_idxs]./0x1p64

This branch only became reachable once HashedRandom became the default missing-guess strategy (#4445), which is why it surfaced as a regression.

Verification

Reproduced with the ParallelKinematicRobot model from MultibodyComponents.jl (the case in #4603):

  • Without the fix: MethodError: no method matching stable_eachindex(::Vector{Int64}) during ODEProblem construction.
  • With the fix: ODEProblem builds and solve returns retcode: Success.

🤖 Generated with Claude Code

The `MissingGuessValue.HashedRandom()` branch in the SCC init-problem
builder called `stable_eachindex` on `symbolic_idxs`, a plain
`Vector{Int64}` returned by `findall`. `stable_eachindex` is only defined
for `BasicSymbolic`, so this threw `MethodError: no method matching
stable_eachindex(::Vector{Int64})`. The line also referenced `var`, which
is undefined in this branch (it only exists in the `LinearFunction`
branch) — the line was a faulty copy of the array-symbolic code in
`problem_utils.jl`.

For the SCC case the missing-guess value for index `j` should be derived
from the corresponding scalar unknown `dvs[vscc[j]]`, matching the scalar
`HashedRandom` form `hash(var)/0x1p64` and consistent with the sibling
`Random` branch. This branch only became reachable once HashedRandom
became the default missing-guess strategy (SciML#4445).

Fixes SciML#4603

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a self-contained test where the initialization problem decomposes
into multiple SCCs with no user-provided guesses, exercising the default
`HashedRandom` missing-guess branch in `SCCNonlinearProblem`. Without the
fix this errors with `MethodError: no method matching
stable_eachindex(::Vector{Int64})`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baggepinnen

Copy link
Copy Markdown
Contributor Author

good to merge? This is keeping MBC CI red and dyad-lang wants to add MBC as downstream test

@oscardssmith

Copy link
Copy Markdown
Member

CI seems mad at you, but in principle looks good

@baggepinnen

Copy link
Copy Markdown
Contributor Author

I haven't learned how to interpret MTK CI, it seems about half are red all the time? Are there any actions needed before merge?

@oscardssmith

Copy link
Copy Markdown
Member

very much an @AayushSabharwal question.

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.

regression: no method matching stable_eachindex(::Vector{Int64})

3 participants