Repository navigation
ssa: count the run's clock from a far t_start, and read held rates inside their interval (#1059) - #1381
Open
Montana wants to merge 1 commit into
Open
ssa: count the run's clock from a far t_start, and read held rates inside their interval (#1059)#1381Montana wants to merge 1 commit into
Montana wants to merge 1 commit into
Conversation
…side their interval (lanl#1059) lanl#1075 fixed the discrete loops; the continuous loop (a rate that reads the clock, or rate rules) still placed its firings on panels in absolute time, and from t_start = 1e12 a decay came back at z = -289. A rate held between breakpoints also went back to 0 after its first firing, the firing's clock rounding onto the breakpoint. Above |t_start| = 2^20 the run now counts its clock from t_start and hands the model origin + elapsed where it reads the clock; rows get the times asked for (Result::set_time), and the state and event carry the next run reads keep their exact absolute times. At origin 0 every run is bit-identical.
This branch has not been deployed
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.
Closes #1059 (the SSA/PSA half; see "Not in this PR").
What was wrong
#1075 fixed the two discrete SSA loops, which draw a waiting time from a constant total propensity and now carry what
t + taurounds away. The continuous loop never got that fix. That is the loop for a model whose rate reads the clock, or that has rate rules. It integrates the propensity over error-controlled panels in absolute time. Near t = 1e12 the doubles are 1.2e-4 apart, and the panel step floor there,64·eps·|t|, is 1.4e-2. A firing placed attp + th·hhloses what is below that spacing.A decay of 1e5 copies,
k*A*(1 + 1e-30*time())at k = 0.5 (it reads the clock but does not move with it). The exact mean at t0 + 2 is 36788. Ten seeds, on main c0877fa:t_startA second failure on main, found while testing this, has the same cause. A rate held constant between breakpoints,
k*A*piecewise(1, time() > t0 + 1, 0), is switched on at the breakpoint. The refresh reads it at the interval's midpoint, correctly. But after each firing the propensities are updated at the firing's time, and from 1e12 a firing just pastt0 + 1rounds back ontot0 + 1. There the condition is still false, so the rate went back to 0 after its first firing: 99999 of 100000 left, where e⁻¹ of them should be.The fix (
src/ssa_simulator.cpp)The run keeps its own clock as time elapsed since
t_start. It hands the modelorigin + elapsedwherever the model reads the clock, so panels, step floors and waiting times are as fine at 1e12 as at 0. Every change is insiderun_internal(the SSA and PSA body):The origin.
ssa_clock_origin(times)ist_startwhere|t_start| >= 2^20, where the doubles are 1.2e-10 apart, and 0 below. The run'sTimeSpec(t_start,t_end,sample_times) and its breakpoints and time-table knots are shifted onto the run's clock.The clock reads. All 19
model.evaluate_functions(x)and 9model.set_current_time(x)calls in the body readorigin + x. At origin 0,0.0 + x == xfor every finite x, so every run below 2^20 is the run it was, to the bit. No call site needs judging individually.Rows are given the exact times asked for afterwards, through a new
Result::set_time, notorigin + elapsed.What goes to the next run:
t_end;origin + (t_end − origin)ist_endwhenevert_end <= 2·t_start(Sterbenz), but not for a longer run, which a test covers.Error messages that print a time print the absolute one.
A held rate is read where
pc_refresh_atread it, inside its interval, where the origin has moved. That is the second failure above.Tests (
test_ssa_elapsed_clock.py, 7)test_a_decay_from_a_far_start_keeps_its_rate[continuous loop (reads the clock)]: t0 = 1e12, 10 seeds, |z| < 5…[discrete loop (#1075)]: the loop #1075 fixed, still righttest_a_rate_that_switches_at_an_absolute_time_switches_there: no decay before t0 + 1, then e⁻¹ (breakpoints on the run's clock; the held rate)test_an_event_at_an_absolute_time_fires_there: the trigger reads the absolute clocktest_the_rows_are_the_times_asked_for:result.time == sample_timesexactly at 1e12test_a_run_continues_from_where_the_last_one_ended: a delayed event pending across two runs applies at t0 + 3 in the secondtest_a_long_run_hands_on_its_exact_end: t_end > 2·t_start, wheret0 + (te − t0) != te; the next run still finds the pending executionFour pass on main because they check what must not regress under the new clock.
Mutations (C++ rebuilt for each)
origin + elapsedMeasured
t_start0, 5, 1e5 and 1048575 (= 2^20 − 1) × SSA and PSA, at one seed: 40 of 40 identical to main's core, times and states.pre-commit run --all-files(new files staged; clang-format included) andsphinx -Wwithdocs/requirements-ci.txtare clean.Not in this PR
method="rm") on a model that reads the clock runs on absolute model time (Re-vendor RuleMonkey 3.11.0: lift method='rm''s time() and time-TFUN refusals, run rm on absolute model time, and pick up the RuleMonkey fixes since 3.10.1 #1022), and has the same limit (the issue measured z = −291 at 1e12; not rerun here). Its clock is RuleMonkey's own, so the fix belongs upstream: an origin plus elapsed time, as here. This PR does not touch it.