Repository navigation
JumpProcess v10 Attempt 2 - #680
Merged
isaacsas merged 62 commits intoOct 11, 2026
Merged
Conversation
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>
use integrator rng API
- 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>
Closed
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>
6 tasks done
…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>
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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
Summary of major changes
rngorseedtosolve/init;JumpProblem(...; rng)now errors.remakeno longer mutates shared rate coefficients.update_parameters!is removed, and custom parameter mappers have a new contract.SSAStepperand the OrdinaryDiffEq paths reuse aJumpProblem's jump state, re-initializing it at everyinit, and never copy it. AJumpProblemsupports one active solve at a time.alias_jumpis removed.SSASteppergains the commonaliaskeyword foru0,p, andtstops.SSAStepperintegrator evaluation: evaluating the integrator at a time it can't represent now raises an error instead of silently returning the current state. A newSSAStepper(; save_uprev = true)option allows exact evaluation within the current step.init:initwith an SDE/RODE solver now reaches StochasticDiffEqCore's ownJumpProbleminitializers, through upstream fixes (OrdinaryDiffEq.jl #4707 and the WIP #4836). JumpProcesses has no StochasticDiffEqCore extension or weak dependency.ltsfor the Interface groups and ThreadSafety, and the downgrade job.JumpProblemcallbacks ran twice per step underiniton ODE, DAE, andFunctionMapintegrators.JumpProblemwraps are now rejected with an informative error. Previously some solvers ran them and others ignored them.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
rngorseedtosolve/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 (
SSAStepperand the OrdinaryDiffEq ODE/DAE pathways) now always reuse theJumpProblem's jump aggregator and callbacks, re-initializing them at everyinit. They never copy them, on any thread; previously, solves off thread 1 copied this state. Consequences:JumpProblemsupports one active solve or integrator at a time.deepcopy(jprob)or anEnsembleProblem.EnsembleThreadscopies the problem once per spawned task, andsafetycopy = truecopies it for every trajectory.remakeshare the original's jump state.The removed copy shows up directly. For a small SIR model,
initon a spawned task allocated 5,952 bytes before this change and 2,912 after, the same as on the main thread.Keyword changes
alias_jumpis removed. Any supplied value raises a migration error, whether it is passed tosolve,init,JumpProblem, or a multi-trajectoryEnsembleGPUKernelsolve, or stored on the wrapped problem.alias_jumpswas never a solver keyword. SciMLBase's keyword validation rejects it onsolve/init, and multi-trajectory kernel solves, which bypass that validation, reject it explicitly.SSASteppernow supports the commonaliaskeyword foru0,p, andtstops.Bool, aSciMLBase.DiscreteAliasSpecifier, or anODEAliasSpecifier. The last is the specifier OrdinaryDiffEq'sFunctionMapalready uses for DiscreteProblems, and the one that also controlststops.u0is copied withrecursivecopy,pis reused, and a caller'ststopsis never modified.truepermits aliasing.tstopsgiven as a number, a tuple, or anAbstractVectorother than aVectorof the time type is copied into aVectoratinit.aliasnever controls jump state.aliasis forwarded unchanged.SDEAliasSpecifier(alias_jumps)policy; this is documented.Evaluating an
SSAIntegratorat a timeUntil now,
integrator(t)andintegrator(out, t)ignoredtand returned the current state. That is silently wrong for callbacks that evaluate the integrator at earlier times, such as DiffEqCallbacks'SavingCallbackwithsaveat. The in-place form also errored, becauseget_tmp_cachewas missing.The new
save_uprevoption (SSAStepper(; save_uprev = true), off by default) keeps the state at the start of each step inintegrator.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], andget_tmp_cacheprovides scratch space for in-place callbacks. With the default, evaluation is valid only atintegrator.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:
SSASteppernow saves pendingsaveattimes 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
solvekeyword.SSAStepper()is unchanged for callers, but its type is nowSSAStepper{false}; theisdenseplotmethod is updated to match.Supported state types are now documented:
Vectors andSVectors of integers or floats, and species × sites matrices for spatial problems.NSMandDirectCRDirectkeep the matrix; other aggregators flatten it to aVector. BoundedVariableRateJumps requireCoevolve;RSSA/RSSACR, and bounded variable-rate jumps withCoevolve;Tests cover each supported type.
StochasticDiffEq initialization and dependencies
Released StochasticDiffEqCore (through 2.2.3) defines an
__initmethod for jump problems that is ambiguous with JumpProcesses' own, soinit(jprob, sde_alg)could not reach Core's initializer.__init(::JumpProblem, ...)methods.__inittoAbstractRODEProblem, and updates StochasticDiffEqCore for v10's RNG and jump-state ownership.initfollowed bysolve!matchessolve, and JumpProcesses needs no StochasticDiffEqCore extension or weak dependency.initthrough aJumpProcessesStochasticDiffEqCoreExtextension; it has been removed.[sources]pins StochasticDiffEqCore, StochasticDiffEqImplicit, and StochasticDiffEqLeaping, as test extras, to an exact commit of its branch.[sources]only for the active project.[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 skiplts, and the downgrade job is disabled, until the pins are removed.ltsbenchmarks do not load StochasticDiffEq and still run. QA runs on Julia 1 only.JumpProblemno longer run twice per step when an ODE, DAE, orFunctionMapintegrator is created withinit, and are no longer reintroduced undermerge_callbacks = false.Callbacks on the wrapped problem
Callbacks stored on the problem a
JumpProblemwraps, for exampleODEProblem(f, u0, tspan, p; callback), were run by OrdinaryDiffEq solvers, includingFunctionMap, but silently ignored bySSAStepperand StochasticDiffEq solvers.JumpProblemconstructors, andremakewith a new wrapped problem, now raise an informativeArgumentErrorwhen the wrapped problem stores a callback.JumpProblem(...; callback)or tosolve/initinstead;remake(prob; callback = nothing)removes them from an existing problem.JumpProblem, so the problems they build are unaffected.JumpProblemdocstring, the docs, and the migration guide state the rule.Other changes
SSASteppersave paths andintegrator(t)now use OrdinaryDiffEq'scopyat_or_push!/recursivecopysemantics, so nested states are saved as independent snapshots.EnsembleGPUKernelsolves rejectaliasvalues other thannothing. They also rejectalias_jump,alias_jumps, andaliaswhether passed tosolveor stored on the wrapped problem.SSAStepperno longer errors when only the final state is saved (save_end = truewith nothing saved earlier);masterhas the same bug.Documentation
These rules are documented throughout, with emphasis on the lack of safety in non-serial contexts and with
remake:HISTORY.md;JumpProblemthread-safety docstring and a newremake(::JumpProblem)docstring;SSAStepper,SortingDirect, andEnsembleGPUKerneldocstrings;remake, and problem reuse", showing patterns that balance performance and safety. It needs no Catalyst or ModelingToolkit dependency.SortingDirectdeliberately 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.
docs/Project.tomlpins them through[sources]to exact commits of their JumpProcesses 10 branches: WIP: Support JumpProcesses 10 in ModelingToolkitBase jump problems ModelingToolkit.jl#5269, WIP: Support JumpProcesses 10 in tests, benchmarks, and docs Catalyst.jl#1572, and #4836.JumpProblemdocstring links the new tutorial's stable URL, whichlinkcheckignores until the 10.0 docs are deployed.History and relation to #570
This branch preserves the feature history from #570. Its changes since #570's head are in this comparison.
masterthrough1816ee40(Type RDirectJumpAggregation.counter_threshold as Int #676) and migrates master's new tests to v10's solve-time RNG ownership.Release plan
ltsInterface and ThreadSafety jobs and the downgrade job stay off.9.x, 10so that the pins resolve on either side of this bump. Each one then requires"10", removes its pins, merges, and releases, in this order:ltsand the downgrade job;linkcheck_ignoreentry once the 10.0 docs are deployed.Local validation
These are results from local runs.
JumpProblemtests pass against this branch, 141/141;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
mastermerge. That merge (#676) changes one field type and adds one test; the affected tests, strict QA, and the style checks pass after it.Pkg.testQA 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.Allgroup passes, 5,540/5,540.init/solvecallback checks and the wrapped-callback rejection pass.save_uprev = trueis 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])