Skip to content

JumpProcess v10 Attempt 2 - #680

Merged
isaacsas merged 62 commits into
SciML:masterfrom
isaacsas:integration/v10-master-2026-09-22
Oct 11, 2026
Merged

isaacsas merged 62 commits into
SciML:masterfrom
isaacsas:integration/v10-master-2026-09-22

Conversation

@isaacsas

@isaacsas isaacsas commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

This PR supersedes #570. It contains the JumpProcesses 10 work from that PR, keeps its commit history, merges current master, and adds the remaining v10 changes.

It is set up for a transitional 10.0.0 release.

  • StochasticDiffEq, ModelingToolkit, and Catalyst do not support JumpProcesses 10 yet. Every registered version of them caps JumpProcesses below 10, so environments that include them keep JumpProcesses 9.x.
  • The README, the docs home page, and HISTORY say so, and recommend waiting for 10.0.1 unless JumpProcesses is used on its own. They also say jump problems coupled to DDEs are not supported in 10.0 at this time.
  • The downstream updates follow the release, then 10.0.1 removes the notices and the temporary pins. See "Release plan" below.

Summary of major changes

  • RNG ownership: jumps draw random numbers from the integrator's RNG. Pass rng or seed to solve/init; JumpProblem(...; rng) now errors.
  • Mass-action rates: solvers and aggregators own the working rate buffers. Parameter-mapped rates are filled from the current parameters at initialization and reset, so remake no longer mutates shared rate coefficients. update_parameters! is removed, and custom parameter mappers have a new contract.
  • Jump-state ownership: SSAStepper and the OrdinaryDiffEq paths reuse a JumpProblem's jump state, re-initializing it at every init, and never copy it. A JumpProblem supports one active solve at a time.
    • alias_jump is removed.
    • SSAStepper gains the common alias keyword for u0, p, and tstops.
  • SSAStepper integrator evaluation: evaluating the integrator at a time it can't represent now raises an error instead of silently returning the current state. A new SSAStepper(; save_uprev = true) option allows exact evaluation within the current step.
  • StochasticDiffEq init: init with an SDE/RODE solver now reaches StochasticDiffEqCore's own JumpProblem initializers, through upstream fixes (OrdinaryDiffEq.jl #4707 and the WIP #4836). JumpProcesses has no StochasticDiffEqCore extension or weak dependency.
    • Until #4836 is released, the tests pin StochasticDiffEqCore, StochasticDiffEqImplicit, and StochasticDiffEqLeaping to a commit of its branch, and CI temporarily skips lts for the Interface groups and ThreadSafety, and the downgrade job.
    • Also fixed: stored JumpProblem callbacks ran twice per step under init on ODE, DAE, and FunctionMap integrators.
  • Callbacks on the wrapped problem: callbacks stored on the problem a JumpProblem wraps are now rejected with an informative error. Previously some solvers ran them and others ignored them.
  • Documentation: a v10 migration guide, a new tutorial on ensembles and problem reuse, and updated docstrings, FAQ, and HISTORY.

The details follow.

RNG and mass-action rate ownership

Jump callbacks now draw from the integrator's RNG, and each solver or aggregator owns its mass-action working-rate buffer. Supply rng or seed to solve/init; JumpProblem(...; rng) now errors. Parameter-mapped mass-action rates are filled from the current parameters at initialization and reset, so rate coefficients shared by jump definitions are never mutated. The migration guide documents the breaking APIs and the custom mapper contract.

Jump-state ownership

Solvers owned by JumpProcesses (SSAStepper and the OrdinaryDiffEq ODE/DAE pathways) now always reuse the JumpProblem's jump aggregator and callbacks, re-initializing them at every init. They never copy them, on any thread; previously, solves off thread 1 copied this state. Consequences:

  • A JumpProblem supports one active solve or integrator at a time.
  • Concurrent solves, and integrators alive at the same time, need deepcopy(jprob) or an EnsembleProblem. EnsembleThreads copies the problem once per spawned task, and safetycopy = true copies it for every trajectory.
  • Problems created with remake share the original's jump state.

The removed copy shows up directly. For a small SIR model, init on a spawned task allocated 5,952 bytes before this change and 2,912 after, the same as on the main thread.

Keyword changes

  • alias_jump is removed. Any supplied value raises a migration error, whether it is passed to solve, init, JumpProblem, or a multi-trajectory EnsembleGPUKernel solve, or stored on the wrapped problem.
    • The plural alias_jumps was never a solver keyword. SciMLBase's keyword validation rejects it on solve/init, and multi-trajectory kernel solves, which bypass that validation, reject it explicitly.
  • SSAStepper now supports the common alias keyword for u0, p, and tstops.
    • It accepts a Bool, a SciMLBase.DiscreteAliasSpecifier, or an ODEAliasSpecifier. The last is the specifier OrdinaryDiffEq's FunctionMap already uses for DiscreteProblems, and the one that also controls tstops.
    • The defaults match OrdinaryDiffEq: u0 is copied with recursivecopy, p is reused, and a caller's tstops is never modified. true permits aliasing.
    • tstops given as a number, a tuple, or an AbstractVector other than a Vector of the time type is copied into a Vector at init.
    • alias never controls jump state.
  • On coupled ODE/DAE paths, alias is forwarded unchanged.
  • StochasticDiffEq SDE/RODE solvers keep their own SDEAliasSpecifier(alias_jumps) policy; this is documented.

Evaluating an SSAIntegrator at a time

Until now, integrator(t) and integrator(out, t) ignored t and returned the current state. That is silently wrong for callbacks that evaluate the integrator at earlier times, such as DiffEqCallbacks' SavingCallback with saveat. The in-place form also errored, because get_tmp_cache was missing.

  • The new save_uprev option (SSAStepper(; save_uprev = true), off by default) keeps the state at the start of each step in integrator.uprev. The buffer is updated each step without allocating.

  • What each setting allows: with the option on, evaluation is exact anywhere in [integrator.tprev, integrator.t], and get_tmp_cache provides scratch space for in-place callbacks. With the default, evaluation is valid only at integrator.t, and other times raise an informative error.

  • Alternatively, pass a callback's evaluation times as tstops. That also gives exact results and avoids the per-step state copy, at the cost of a stop and callback pass at each time. The docs, a new tutorial section, and the FAQ show both approaches.

  • Not yet supported: DiffEqCallbacks' integrating callbacks still don't work with SSAStepper, since they need an algorithm order. That is left to an upstream follow-up and documented.

  • End-time fix: SSAStepper now saves pending saveat times before its final callback pass at the end time. Previously a callback that changed the state at the end time altered those earlier saved values, and the saved times came out of order.

  • Why the option is on the algorithm: SciMLBase's keyword check rejects a new solve keyword. SSAStepper() is unchanged for callers, but its type is now SSAStepper{false}; the isdenseplot method is updated to match.

  • Supported state types are now documented:

    • fully supported: Vectors and SVectors of integers or floats, and species × sites matrices for spatial problems. NSM and DirectCRDirect keep the matrix; other aggregators flatten it to a Vector. Bounded VariableRateJumps require Coevolve;
    • still working: scalar states, for models without mass-action jumps. That covers constant-rate jumps with every non-spatial aggregator except RSSA/RSSACR, and bounded variable-rate jumps with Coevolve;
    • other types are unsupported.

    Tests cover each supported type.

StochasticDiffEq initialization and dependencies

Released StochasticDiffEqCore (through 2.2.3) defines an __init method for jump problems that is ambiguous with JumpProcesses' own, so init(jprob, sde_alg) could not reach Core's initializer.

  • The fix is upstream:
    • OrdinaryDiffEq.jl #4707 (merged, unreleased) added per-algorithm __init(::JumpProblem, ...) methods.
    • OrdinaryDiffEq.jl #4836 (WIP) narrows Core's remaining union __init to AbstractRODEProblem, and updates StochasticDiffEqCore for v10's RNG and jump-state ownership.
    • With both, init followed by solve! matches solve, and JumpProcesses needs no StochasticDiffEqCore extension or weak dependency.
    • An earlier revision of this PR forwarded stochastic init through a JumpProcessesStochasticDiffEqCoreExt extension; it has been removed.
  • Temporary test pins and CI limits:
    • Until #4836 is released, [sources] pins StochasticDiffEqCore, StochasticDiffEqImplicit, and StochasticDiffEqLeaping, as test extras, to an exact commit of its branch.
    • Implicit and Leaping are pinned because the test environment's registered StochasticDiffEq pulls in their registered versions, which do not admit JumpProcesses 10.
    • The pins only affect running the tests. Installing or loading JumpProcesses ignores them, since Pkg honors [sources] only for the active project.
    • Julia 1.10 ignores [sources], and the downgrade action discards URL sources. Registered StochasticDiffEq packages do not admit JumpProcesses 10, so the test environment cannot resolve there. InterfaceI, InterfaceII, and ThreadSafety therefore skip lts, and the downgrade job is disabled, until the pins are removed.
    • The lts benchmarks do not load StochasticDiffEq and still run. QA runs on Julia 1 only.
  • Callback fix: callbacks stored in a JumpProblem no longer run twice per step when an ODE, DAE, or FunctionMap integrator is created with init, and are no longer reintroduced under merge_callbacks = false.

Callbacks on the wrapped problem

Callbacks stored on the problem a JumpProblem wraps, for example ODEProblem(f, u0, tspan, p; callback), were run by OrdinaryDiffEq solvers, including FunctionMap, but silently ignored by SSAStepper and StochasticDiffEq solvers.

  • New behavior: the JumpProblem constructors, and remake with a new wrapped problem, now raise an informative ArgumentError when the wrapped problem stores a callback.
  • Migration: pass callbacks to JumpProblem(...; callback) or to solve/init instead; remake(prob; callback = nothing) removes them from an existing problem.
  • Downstream: ModelingToolkitBase and Catalyst attach their events to the outer JumpProblem, so the problems they build are unaffected.
  • Documentation: HISTORY, the JumpProblem docstring, the docs, and the migration guide state the rule.

Other changes

  • SSAStepper save paths and integrator(t) now use OrdinaryDiffEq's copyat_or_push!/recursivecopy semantics, so nested states are saved as independent snapshots.
  • Multi-trajectory EnsembleGPUKernel solves reject alias values other than nothing. They also reject alias_jump, alias_jumps, and alias whether passed to solve or stored on the wrapped problem.
  • SSAStepper no longer errors when only the final state is saved (save_end = true with nothing saved earlier); master has the same bug.
  • The SciMLBase floor is now 3.34, an existing registered release.
  • No SciMLBase source change is required. This is unrelated to the obsolete RNG fork.

Documentation

These rules are documented throughout, with emphasis on the lack of safety in non-serial contexts and with remake:

  • HISTORY.md;
  • the JumpProblem thread-safety docstring and a new remake(::JumpProblem) docstring;
  • the SSAStepper, SortingDirect, and EnsembleGPUKernel docstrings;
  • a new API section, the v10 migration guide, and FAQ entries;
  • a new tutorial, "Ensembles, remake, and problem reuse", showing patterns that balance performance and safety. It needs no Catalyst or ModelingToolkit dependency.
  • the docs now load the specific solver packages they use (OrdinaryDiffEqTsit5, OrdinaryDiffEqRosenbrock, OrdinaryDiffEqFunctionMap, and StochasticDiffEqHighOrder) instead of DifferentialEquations.jl and the OrdinaryDiffEq and StochasticDiffEq umbrella packages. The installation instructions now recommend JumpProcesses plus a solver package.

SortingDirect deliberately retains its learned search order across solves, for repeated-sampling performance. This is documented, along with the conditions for exact replay.

Documentation CI runs again.

History and relation to #570

This branch preserves the feature history from #570. Its changes since #570's head are in this comparison.

Release plan

  1. Merge this PR and register 10.0.0, with CI and docs green on the pinned commits. The lts Interface and ThreadSafety jobs and the downgrade job stay off.
  2. Downstream updates. The WIP PRs currently admit JumpProcesses 9.x, 10 so that the pins resolve on either side of this bump. Each one then requires "10", removes its pins, merges, and releases, in this order:
    1. StochasticDiffEq, #4836 (Core, Implicit, and Leaping);
    2. ModelingToolkitBase, WIP: Support JumpProcesses 10 in ModelingToolkitBase jump problems ModelingToolkit.jl#5269;
    3. Catalyst, WIP: Support JumpProcesses 10 in tests, benchmarks, and docs Catalyst.jl#1572.
  3. 10.0.1:
    • remove the notices and all test and docs pins;
    • restore lts and the downgrade job;
    • drop the linkcheck_ignore entry once the 10.0 docs are deployed.

Local validation

These are results from local runs.

  • At 10.0.0, with the exact-commit pins, on Julia 1.12.7:
    • the test environment resolves with registered StochasticDiffEq 7.2.0 and the pinned Core, Implicit, and Leaping, and stochastic dispatch passes 287/287;
    • the docs environment resolves with the pinned Catalyst, ModelingToolkitBase, and StochasticDiffEqCore;
    • a full docs build runs every doctest and example, including the Catalyst tutorial. Its link check failed only on curl timeouts to existing external links, all of which respond normally on recheck.
  • The previous head (9.33.1, extension removed, StochasticDiffEqCore pinned to #4836's branch), on Julia 1.12.7:
    • stochastic dispatch 287/287, RNG keyword 36/36, callbacks 162/162, variable-rate 76/76, and strict QA 20/20 pass;
    • #4836's JumpProblem tests pass against this branch, 141/141;
    • a full docs build against the Catalyst, ModelingToolkitBase, and StochasticDiffEqCore branches runs every doctest and example, including the Catalyst tutorial, and renders the site. The link check fails only on the not-yet-deployed tutorial URL, now ignored, and on transient external timeouts or rate limits.

The full matrix below ran earlier, with the previous forwarding extension. All of its dependency graphs were resolved freshly from the registry, with no source overrides, on the tree just before the final master merge. That merge (#676) changes one field type and adds one test; the affected tests, strict QA, and the style checks pass after it.

  • Latest registered dependencies: InterfaceI 1,861/1,861 and InterfaceII 3,344/3,344 on both Julia 1.12.7 and 1.10.12. Four-thread ThreadSafety passes 333/333 and strict native Pkg.test QA passes 20/20, both on Julia 1.12.7. The versions were SciMLBase 3.57.0, DiffEqBase 7.21.3, OrdinaryDiffEqCore 4.18.1, StochasticDiffEq 7.2.0, and StochasticDiffEqCore 2.2.3.
  • The downgrade action's minimum graph (Julia 1.10, four threads; SciMLBase 3.39.0, DiffEqBase 7.5.0, OrdinaryDiffEq 7.0.0, StochasticDiffEq 7.0.0, StochasticDiffEqCore 2.2.1): the All group passes, 5,540/5,540.
  • A package-only graph at JumpProcesses' floors (SciMLBase 3.34.0, DiffEqBase 7.0.0, OrdinaryDiffEqCore 4.0.0): the init/solve callback checks and the wrapped-callback rejection pass.
  • Precompilation and formatting: strict precompilation and every extension load order pass on both Julia versions. JuliaFormatter, typos, and whitespace checks are clean.
  • Documentation: the new tutorial section's examples and the FAQ and migration snippets run, and a Documenter build of the changed pages succeeds.
  • Benchmarks: SSA allocations are identical to before. save_uprev = true is within noise for a three-species model and about 1.9 times slower on a 2,500-site spatial model, which is why it is off by default.

Not run locally: actual CUDA (the kernel tests run on the CPU KernelAbstractions backend) and Julia prerelease. The unseeded adaptive ThreadSafety warning remains an explicitly deferred investigation.

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

isaacsas and others added 30 commits February 23, 2026 22:05
Make the integrator the single source of truth for RNG (Phase 1 Step 4).
Remove rng field from all aggregator structs, JumpProblem, and variable-rate
callback structs. All code now reads get_rng(integrator) at runtime.

Key changes:
- Remove RNG type param from AbstractSSAJumpAggregator and all concrete aggregators
- Remove rng from build_jump_aggregation and all aggregate() signatures
- Add rng field to SSAIntegrator with has_rng/get_rng/set_rng! interface
- Add resolve_rng utility for rng/seed/fallback priority resolution
- Remove rng from VR_FRMEventCallback and VR_DirectEventCache
- JumpProblem rng kwarg now forwards to solver via solkwargs
- Simplify solve.jl: remove _derive_jump_seed, simplify __jump_init
- Update SimpleTauLeaping/SimpleExplicitTauLeaping to use rng kwarg
- Add rng_kwarg_tests.jl covering all three solve pathways
- Update docs with RNG control section and FAQ entry
- Bump version to 9.23.0, SciMLBase compat to 2.144

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Breaking: JumpProblem no longer accepts an `rng` keyword argument.
Passing `rng` now throws an ArgumentError directing users to pass
it to `solve` or `init` instead. This fixes inconsistent RNG
priority ordering across solver pathways (SSAStepper, ODE/SDE,
tau-leaping) and makes the integrator the single source of truth
for RNG state.

- Simplify resolve_rng to 2-arg form (remove fallback_rng)
- Remove jump_prob.kwargs rng fallback from tau-leaping solvers
- Update all tests to pass rng to solve/init instead of JumpProblem
- Update docs and HISTORY.md with breaking change notes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ecking

- Revert <:Any back to named type params in ssajump.jl (minimize diff from master)
- Revert solkwargs to simpler ternary form in problem.jl (rng removal made filter unnecessary)
- Add type checking to SSAIntegrator set_rng! to match StochasticDiffEq pattern

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The GPU tau-leaping kernel uses PassthroughRNG internally; the
StableRNG was never consumed by the EnsembleGPUKernel path.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
solve(; rng = nothing) falls through to default_rng() via resolve_rng,
so the ternary guards are redundant.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comparing continuous-valued jump times is more robust than discrete
final state values, which could collide by chance.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Check jump_u thresholds directly via init, and verify both event times
and post-event thresholds from ensemble solve.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolves conflicts by combining integrator RNG (get_rng) with
u_modified!(true) fix, and using robust first_jump_time helpers
in tests that account for the initialization save.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove StochasticDiffEq from [deps] (test-only, belongs in [extras])
- Move EnsembleThreads data race tests from ensemble_problems.jl to
  thread_safety.jl with stronger assertions (400 trajectories, allunique
  on first reaction times, all 3 VR aggregators, adaptive SDE solver)
- Renumber remaining ensemble_problems.jl sections

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ensemble_problems.jl: check initial jump_u threshold (u[2]) instead
  of post-event (u[3]) now that u_modified!(true) produces init save
- extended_jump_array_remake.jl: rework to solve → remake → init →
  compare jump_u, verifying fresh thresholds after remake
- geneexpr_test.jl: remove unnecessary isnothing(rng) branch
- linearreaction_test.jl: make rng const for type stability
- variable_rate.jl: switch getmean from seed integer to StableRNG
- rng_kwarg_tests.jl: add SDE+VR different seeds test, SDE+VR no-rng
  functional test, seed kwarg reproducibility and different-seeds tests
  for all pathways (SSAStepper, ODE+VR, SDE+VR), use first_jump_time
  helper for robust event time extraction

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… strengthen thread_safety assertions

- docs/advanced_point_process.md: move rng from JumpProblem to solve
- rng_kwarg_tests.jl: add seed kwarg tests for SimpleTauLeaping (tests 13-14), renumber 15-20
- thread_safety.jl: SSAStepper EnsembleThreads now runs 400 trajectories and asserts allunique first jump times

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create ThreadSafety.yml workflow: runs thread_safety.jl with --threads=4
- Add ThreadSafety group to Tests.yml matrix (serial) and runtests.jl
- Move thread_safety.jl from InterfaceII to ThreadSafety group
- Fix shared rng data race: SSAStepper ensemble tests now use task-local
  default_rng() instead of a shared StableRNG across threads

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…-scaling

When MTKBase/Catalyst constructs MassActionJumps, the symbolic rate expressions
already include stoichiometric scaling (e.g. k/3! for 3X → Y), so they pass
scale_rates=false. However, update_parameters! defaulted to scale_rates=true,
causing every subsequent parameter update path (reset_aggregated_jumps!, remake,
finalize_parameters_hook!) to double-scale the rates.

The fix stores the intended scaling behavior on the struct as
rescale_rates_on_update, which update_parameters! now reads as its default.
This field is propagated through all merge/combine paths and validated for
consistency when merging multiple MassActionJumps.

Also fixes SpatialMassActionJump conversion constructor to default
scale_rates=false since it receives already-scaled rates.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The mapper now conditionally applies scalerates! based on scale_rates,
matching MTKBase JumpSysMajParamMapper behavior. Previously it ignored
scale_rates entirely, so the test would pass even with the old buggy
default of scale_rates=true.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document that JumpProblem contains mutable state and is not thread-safe
for concurrent solve calls. Note that EnsembleProblem handles isolation
automatically via SciMLBase per-task deepcopy and per-trajectory RNG.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…structs

Move mutable rate working-copy (maj_rates) out of MassActionJump and into
all 10 aggregation structs + RxRates. Rates are now lazily materialized via
fill_scaled_rates! during initialize! instead of eagerly in the JumpProblem
constructor. This fixes aliasing bugs where multiple JumpProblems sharing
the same MAJ could silently corrupt each others rates.

Key changes:
- Add maj_rates field to all aggregation structs and RxRates
- Add fill_scaled_rates! dispatcher for parameterized vs explicit MAJs
- Update evalrxrate to 4-arg signature taking explicit maj_rates
- Propagate maj_rates through calculate_jump_rate, rejectrx, bracketing
- Remove update_parameters!, finalize_parameters_hook!
- Simplify reset_aggregated_jumps! (remove update_jump_params kwarg)
- JumpProblem constructor keeps original parameterized MAJ
- Add merge guards for mapper-backed MAJs
- Add SpatialMassActionJump guard for parameterized MAJs
- Remove dead 1-arg mapper callables
- Update all tests for lazy rate materialization pattern

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Narrow MAJ merge guards to only block custom (non-MassActionJumpParamMapper)
  mapper types. Built-in parameterized MAJ merges via varargs and JumpSet
  vectors work correctly and are tested in ssa_callback_test.jl.
- Fix 3-arg evalrxrate call in test/spatial/reaction_rates.jl to use
  eval_massaction_rate which handles both MassActionJump and
  SpatialMassActionJump correctly.
- Add fill_scaled_rates! call before spatial rate tests to populate maj_rates.
- Update scale_rates_field_test.jl merge test to verify built-in merges
  succeed and custom mapper merges error.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- setup_majump_to_merge now copies arrays before creating the merge
  accumulator, preventing in-place mutation from corrupting the original
  MAJ net_stoch/reactant_stoch arrays
- massaction_jump_combine(::Nothing, ::MassActionJump) now creates a safe
  copy via setup_majump_to_merge instead of returning the original MAJ
- Remove scale_rates and useiszero as JumpProblem kwargs; they are now
  properties of the MassActionJump itself. Passing them raises an
  informative ArgumentError

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Merge master into revamp_maj_initialization, bringing in:
- OrdinaryDiffEqCore package extension for __init ambiguity fix
- ExtendedJumpArray lmul!/ldiv! bug fix
- SDE+jump callback duplication test
- Doc updates for Catalyst v16

Reverted master update_jump_params kwarg addition to SSAIntegrator
reset_aggregated_jumps! and removed associated test, since this branch
removes that kwarg entirely (throws ArgumentError if passed).

Dropped OrdinaryDiffEqCore =3.15 pin in favor of master compat bound.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move rng kwarg from JumpProblem to solve/init in merged test files
  (extended_jump_array.jl, callbacks.jl)
- Remove stale seed! import from JumpProcesses.jl (QA failure)
- Add fill_scaled_rates! in spatial bracketing test to populate maj_rates
- Remove old prob_func(prob, i, repeat) signature in thread_safety.jl
  (use default EnsembleProblem which already deepcopies)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… update bracketing test

- Add fill_scaled_rates! no-op for SpatialMassActionJump (rates stored in
  struct, no working copy needed). Placed in spatial_massaction_jump.jl since
  the type is defined after jumps.jl in the include order.
- Update test/bracketing.jl: pass maj_rates to get_majump_brackets, add
  maj_rates field to DummyAggregator, call fill_scaled_rates! to init rates.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Merge master through 1816ee4 (SciML#676), which types
RDirectJumpAggregation.counter_threshold as Int. The test added there
passed rng to JumpProblem, which v10 rejects. The test only builds the
aggregator, so the keyword is dropped.

Validation on registered dependencies, Julia 1.12.7: the affected test
files (allocations.jl and ssa_aggregator_smoke.jl), strict QA, and the
formatting, spelling and whitespace checks pass.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@isaacsas isaacsas mentioned this pull request Oct 10, 2026
isaacsas and others added 3 commits October 10, 2026 10:45
The benchmark job runs benchmark/benchmarks.jl against both the PR and
master. The script used v10's solve-time rng, which master's SSAStepper
rejects, so both benchmark jobs failed while benchmarking master. The
script now detects which API it runs against, since JumpProblem(...; rng)
raises an ArgumentError under v10. On master it reseeds the problem's
StableRNG with seed in every sample, so both branches simulate the same
trajectory and their timings are comparable.

On CUDA, the explicit tau-leaping kernel fails to compile for Float32
rates. pois_rand uses PoissonRandom's procf for larger rates, and procf
is not type-stable for Float32: two of its results are
Union{Float32, Float64}. Master's kernel makes the same call, but v10's
new kernel rate test is the first to run it with Float32 on a GPU, and
the error also stopped that testset before its Float64 pass. The Float32
GPU solve is now @test_broken, so the Float64 pass runs and an upstream
fix shows up as an unexpected pass.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tions

The docs depended on the DifferentialEquations, OrdinaryDiffEq, and
StochasticDiffEq umbrella packages, but the examples use only Tsit5,
Rodas4P, FunctionMap, and SRIW1. Depend on OrdinaryDiffEqTsit5,
OrdinaryDiffEqRosenbrock, OrdinaryDiffEqFunctionMap, and
StochasticDiffEqHighOrder instead, and load them in the tutorials.
JumpProcesses re-exports the problem types and solve, and the solver
packages bring in OrdinaryDiffEqCore and StochasticDiffEqCore, which
activate JumpProcesses' extensions.

The README and docs home page now say to install JumpProcesses plus a
solver package. They no longer describe JumpProcesses as part of
DifferentialEquations.jl, since DifferentialEquations 8 no longer
includes it. The advanced point-process helper now defaults to
Rodas4P(), because the solver packages alone provide no default ODE
algorithm.

The changed pages build locally. The only failing examples are the
Catalyst tutorial blocks that need the pending ModelingToolkitBase
migration.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
massaction_jump_combine checked both jumps for custom parameter mappers
by looping over a tuple of two differently typed jumps, which allocated
128 bytes on every merge. It now checks each jump explicitly. Merging
10,000 scalar MassActionJumps allocates 0.73 MB again, as in released
9.33.1, rather than 2.0 MB.

Merging a jump with fixed rates and one with a parameter mapping, in
either order, now raises an informative error instead of a MethodError.

New tests merge scalar-form MassActionJumps in any order with scalar or
collection-form jumps, through JumpSet and JumpProblem. They check the
merged stoichiometry, parameter indices, and rates, that the problem
solves, and that the user's jumps are unchanged. They also cover the
mixed-merge error.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas and others added 3 commits October 10, 2026 15:44
…anch

OrdinaryDiffEq.jl#4707 gave StochasticDiffEqCore per-algorithm
__init(::JumpProblem, ...) methods, and OrdinaryDiffEq.jl#4836 narrows
Core's remaining union __init to AbstractRODEProblem. With both,
stochastic init of a JumpProblem dispatches to Core without ambiguity,
so JumpProcessesStochasticDiffEqCoreExt and the StochasticDiffEqCore
weak dependency are removed. The OrdinaryDiffEqCore extension keeps its
four-family method, which covers the intersection with
OrdinaryDiffEqCore's initializer.

Until #4836 is released, tests pin StochasticDiffEqCore to that branch
through [sources]. Julia 1.10 ignores [sources], and the downgrade
action discards URL sources; registered StochasticDiffEqCore's init is
ambiguous without the extension. So InterfaceI and InterfaceII drop lts,
and the downgrade job is off, until the pin is removed. QA,
ThreadSafety, and benchmarks keep lts: they do not call stochastic init.

stochastic_dispatch.jl now checks that SDE, RODE, and TauLeaping init
dispatch to Core's methods, and runs the filtered ambiguity check over
JumpProcesses, Core, and the OrdinaryDiffEqCore extension. HISTORY and
the solver-dispatch docs are updated.

Validation, Julia 1.12.7 with the pinned branch: stochastic_dispatch.jl
(287), rng_kwarg_tests.jl (36), callbacks.jl (162), variable_rate.jl
(76), and QA (20) pass.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
solve! checked integrator.sol.t[end] before saving the end state, which
threw a BoundsError when nothing had been saved yet: save_start = false,
save_positions = (false, false), no saveat, and save_end = true. The
check now treats an empty solution as needing the end save, so the
solution holds just the final time and state. The same line is on
master.

saveat_regression.jl gains a "Final-only saving" testset: no jumps,
jumps (the final state equals the number of jumps that fired), and an
end time already saved by a callback in the final pass, which must not
be saved twice.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The temporary [sources] pin now follows the sdecore/jumpprocesses-v10
branch of OrdinaryDiffEq.jl#4836, so this PR's CI tests its latest
state without a pin bump for every change there. Exact commits will be
pinned for the 10.0 release validation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/OrdinaryDiffEq.jl that referenced this pull request Oct 10, 2026
Pin JumpProcesses through [sources] in StochasticDiffEqCore,
StochasticDiffEqImplicit, StochasticDiffEqLeaping, and the
StochasticDiffEq umbrella, which tests with it, to the branch of
SciML/JumpProcesses.jl#680. That branch is still at version 9.33.1, so
it satisfies the current 9.26.0 compat, and CI now runs the new
JumpProblem tests against the JumpProcesses 10 code instead of the
registered 9.x release. Julia 1.10 ignores [sources], so LTS jobs still
resolve registered JumpProcesses.

Remove the pins, and require JumpProcesses "10", before merging.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas and others added 3 commits October 11, 2026 07:34
The ensembles and problem reuse tutorial seeded every example, which
suggested that repeated serial solves need a seed. The serial-solves
section now shows two examples: solves drawing from Julia's default RNG,
and one generator passed to every solve for reproducible samples, with
a warning against creating a new same-seed generator per solve, which
makes every solve follow the same path.

Seeds that only made the rendered output reproducible are now hidden
Random.seed! lines, or dropped where the output is deterministic. The
SortingDirect replay section keeps its seeds, since reproducibility is
its subject.

docs/make.jl ignores the stable-docs URL of this tutorial in linkcheck:
the JumpProblem docstring links it, and the page exists only once the
10.0 docs are deployed. Remove the entry then.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Catalyst tutorial needs ModelingToolkitBase and Catalyst versions
that support the JumpProcesses 10 mapper and solve-time RNG APIs. Their
branches now exist, so docs/Project.toml pins Catalyst,
ModelingToolkitBase, and StochasticDiffEqCore to them through [sources],
with ModelingToolkitBase and StochasticDiffEqCore as direct docs
dependencies so the pins apply. The pins track branches; exact commits
will be pinned for the 10.0 release build, and the pins removed once
those releases are registered. The asset copy of the docs project is
kept in sync.

The Documentation workflow runs on pushes and pull requests again, as on
master.

A local build against these branches ran every doctest and example,
including the Catalyst tutorial, and rendered the full site.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
remake now zeroes jump_u rather than resampling it, relying on the
VR_FRM callback initializers to draw new thresholds from the
integrator's RNG at every init. A new testset checks this for ODE
(Tsit5) and SDE (SOSRI, EM) problems when solving the remade problem,
solving the original problem (whose aliased jump_u remake also zeroes),
and re-solving one integrator with reinit!. For a single constant-rate
jump, every solve must succeed, the threshold saved at t = 0 after
initialization must be nonzero and give the first jump time, and the
first jump times must be distinct and pass a Kolmogorov-Smirnov test
against the exponential distribution.

Also corrects the remake comment that still described jump_u as
resampled.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Commit 33b86e9 dropped the final-value uniqueness checks from the
serial ensemble testset, and swapped them for first jump times in the
different-seeds testset, on the grounds that discrete final states
could collide by chance. In this ODE model the state decays
continuously and jumps subtract one, so the final value depends
continuously on every jump time; collisions are no more likely than for
first jump times. Unlike first jump times, final values also cover the
jumps after the first, so both checks are kept, as in the sequential
solves testset.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/OrdinaryDiffEq.jl that referenced this pull request Oct 11, 2026
Temporary: JumpProcesses' PR branch (SciML/JumpProcesses.jl#680) moves to version 10.0.0
for release, and its test and documentation environments pin this
branch, so its compat must admit 10. Admitting 9 too keeps the pins
resolving while that branch is at 9.33.1. Narrow the bound to "10" before merging: under JumpProcesses 9 these changes would skip the reseeding the transitional helpers did.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/ModelingToolkit.jl that referenced this pull request Oct 11, 2026
Temporary: JumpProcesses' PR branch (SciML/JumpProcesses.jl#680) moves to version 10.0.0
for release, and its test and documentation environments pin this
branch, so its compat must admit 10. Admitting 9 too keeps the pins
resolving while that branch is at 9.33.1. Narrow the bounds to "10" before merging, together with removing the pins.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/Catalyst.jl that referenced this pull request Oct 11, 2026
Temporary: JumpProcesses' PR branch (SciML/JumpProcesses.jl#680) moves to version 10.0.0
for release, and its test and documentation environments pin this
branch, so its compat must admit 10. Admitting 9 too keeps the pins
resolving while that branch is at 9.33.1. Narrow the bounds to "10" before merging, together with removing the pins.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bump the version to 10.0.0. StochasticDiffEq, ModelingToolkit, and
Catalyst do not support JumpProcesses 10 yet, so environments with
them keep JumpProcesses 9.x until their updates and 10.0.1 are
released. The README, the docs home page, and HISTORY say so, and that
jump problems coupled to DDEs are not supported in 10.0 at this time.

The temporary test and docs pins stay, now at exact commits: the
StochasticDiffEq branch (SciML/OrdinaryDiffEq.jl#4836) for
StochasticDiffEqCore and, since registered versions of them do not
admit JumpProcesses 10, StochasticDiffEqImplicit and
StochasticDiffEqLeaping as test extras; and the Catalyst
(SciML/Catalyst.jl#1572) and ModelingToolkitBase
(SciML/ModelingToolkit.jl#5269) branches for the docs, whose
JumpProcesses compat becomes "10". Those branches now admit
JumpProcesses 10. The pins only affect running the tests and building
the docs; they are removed in 10.0.1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/ModelingToolkit.jl that referenced this pull request Oct 11, 2026
SciML/JumpProcesses.jl#680 is now at version 10.0.0. The test
environments include registered StochasticDiffEq, which pulls in
registered StochasticDiffEqImplicit and StochasticDiffEqLeaping; those
do not admit JumpProcesses 10, so the tests could not resolve. Pin both
to the StochasticDiffEq branch for JumpProcesses 10
(SciML/OrdinaryDiffEq.jl#4836) as test extras, like
StochasticDiffEqCore. Temporary: remove with the other pins before
merging.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
At 10.0.0 the test environment cannot resolve on Julia 1.10: it ignores
[sources], and registered StochasticDiffEq packages do not admit
JumpProcesses 10. The lts ThreadSafety job failed for this reason, so
skip it like the lts InterfaceI and InterfaceII jobs, whose comments now
give the same reason. Restore all three when the pins are removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/Catalyst.jl that referenced this pull request Oct 11, 2026
SciML/JumpProcesses.jl#680 is now at version 10.0.0. The test
environment includes registered StochasticDiffEq, which pulls in
registered StochasticDiffEqImplicit and StochasticDiffEqLeaping; those
do not admit JumpProcesses 10, so the tests could not resolve. Pin both
to the StochasticDiffEq branch for JumpProcesses 10
(SciML/OrdinaryDiffEq.jl#4836) as test extras, like
StochasticDiffEqCore. Temporary: remove with the other pins before
merging.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/OrdinaryDiffEq.jl that referenced this pull request Oct 11, 2026
SciML/JumpProcesses.jl#680 is now at version 10.0.0. The umbrella
StochasticDiffEq test environment loads ModelingToolkit
(reversal_tests.jl), and registered ModelingToolkit does not admit
JumpProcesses 10, so the tests could not resolve. Pin ModelingToolkit
and ModelingToolkitBase to the ModelingToolkit branch for JumpProcesses
10 (SciML/ModelingToolkit.jl#5269), with ModelingToolkitBase as a test
extra. Temporary: remove with the JumpProcesses pin before merging.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@isaacsas
isaacsas merged commit 69fedc0 into SciML:master Oct 11, 2026
21 of 22 checks passed
isaacsas added a commit to isaacsas/OrdinaryDiffEq.jl that referenced this pull request Oct 11, 2026
JumpProcesses 10.0.0 is registered. StochasticDiffEqCore,
StochasticDiffEqImplicit, and StochasticDiffEqLeaping now require it:
under JumpProcesses 9 these changes would skip the reseeding the removed
helpers did. The JumpProcesses [sources] pins to the
SciML/JumpProcesses.jl#680 branch, in those three and the
StochasticDiffEq umbrella, are no longer needed and are removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/ModelingToolkit.jl that referenced this pull request Oct 11, 2026
JumpProcesses 10.0.0 is registered. Require it ("10") and remove the
temporary JumpProcesses [sources] pins to the SciML/JumpProcesses.jl#680
branch. The StochasticDiffEq pins (SciML/OrdinaryDiffEq.jl#4836) remain
until those releases are registered.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
isaacsas added a commit to isaacsas/Catalyst.jl that referenced this pull request Oct 11, 2026
JumpProcesses 10.0.0 is registered. Require it ("10") in the root,
docs, and test/extensions projects, and remove the temporary
JumpProcesses [sources] pins to the SciML/JumpProcesses.jl#680 branch.
The ModelingToolkitBase (SciML/ModelingToolkit.jl#5269) and
StochasticDiffEq (SciML/OrdinaryDiffEq.jl#4836) pins remain until those
releases are registered.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.

1 participant