Open
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>
isaacsas
commented
Feb 24, 2026
- 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>
Member
Author
|
This should be good to go once there is a StochasticDiffEq release and we can run tests to check CI here. |
… 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>
870ae0b to
d1d6beb
Compare
Co-Authored-By: Claude Opus 4.5 <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.
Needs SciML/StochasticDiffEq.jl#681 and a StochasticDiffEq release before we can fully run CI here.
Summary
Makes the integrator the single source of truth for RNG in JumpProcesses.
Previously, each aggregator struct,
JumpProblem, and variable-rate aggregator stored its ownrngfield. This caused data races withEnsembleThreads(fixed in #556 with a workaround) and made RNG control fragmented across multiple objects.Now all RNG access goes through
get_rng(integrator)at runtime, using the SciMLBasehas_rng/get_rng/set_rng!interface.Key changes
rngfield andRNGtype parameter fromAbstractSSAJumpAggregatorand all 10 concrete aggregators (Direct, FRM, NRM, CCNRM, DirectCR, RDirect, SortingDirect, RSSA, RSSACR, Coevolve) plus 2 spatial aggregators (NSM, DirectCRDirect). Allaggregate()signatures drop therngpositional arg.rngfield withhas_rng/get_rng/set_rng!implementation, so the SSAStepper pathway has the same RNG interface as ODE/SDE integrators.rngfromVR_FRMEventCallbackandVR_DirectEventCache; they now readget_rng(integrator)in their affect/initialize functions.rngstruct field. Therngkwarg no gives an error that it should instead be passed via solve.resolve_rng(rng, seed)utility. Simplify__jump_initto always forwardrng. Remove_derive_jump_seedand seed-based reseeding.rng/seedkwargs directly instead of reading fromjump_prob.rng.test/rng_kwarg_tests.jlcovering all three solve pathways (SSAStepper, ODE+VR, SDE+VR) and SimpleTauLeaping. Update ensemble tests.Dependencies
Requires:
has_rng/get_rng/set_rng!)ODEIntegrator.rng)