Persist sim options before StartSimul so the seed is honored (AB#2742) - #2
Merged
Conversation
run_simulation(seed=N) packed the seed correctly ([SeedFixed]:1 / [seed0]:N, matching ModelRisk's PackToStringList), and the array marshalled fine — verified by reading back ModelRisk's own parsed SimOpt_SeedFixed=1 / SimOpt_Seed0=N after feeding the exact payload to VoseSetSimulOptions12. But the simulation still ran non-reproducibly. Root cause: ModelRisk's per-cell-twister Manual-Seed mode sources its base seed from the WORKBOOK-persisted SimOpt_SeedFixed / SimOpt_Seed0 defined-names (written by SaveOptionsToWorkbook), NOT from the per-call options passed to VoseStartSimulCustom12. The bridge set the per-call [seed0] (ignored by the twister) but never persisted it to the workbook, so Manual Seed stayed OFF -> Random mode -> different stream every run. Fix: call VoseSetSimulOptions12 with the same options payload before VoseStartSimulCustom12. That runs SaveOptionsToWorkbook, persisting SimOpt_SeedFixed=1 / SimOpt_Seed0=N, which the twister then honors. Verified end-to-end against the engine oracle (single-cell VoseUniform): - two runs at seed=12345 -> byte-identical streams (was: differing) - seed=12345 vs seed=555 -> different reproducible streams (seed now drives it) - the seed=12345 stream matches mrengine's per-cell twister-0 reference (0.929616, 0.890155, 0.316376, 0.130707, 0.183919, 0.039759, ...) exactly, validating the byte-identical parity path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…B#2742) The seed-persist fix inserts VoseSetSimulOptions12 before VoseStartSimulCustom12, so run_simulation now issues 3 Run() calls (persist, start, save) instead of 2. Update the order/index assertions accordingly and add an invariant that the persist call receives the same options payload as the start call. Co-Authored-By: Claude Opus 4.8 (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.
Problem
run_simulation(seed=N)ran non-reproducibly even with a fixed seed — two runs at the same seed produced different streams.The seed packing was never the issue: the bridge packs
[SeedFixed]:1/[seed0]:Ncorrectly (matching ModelRisk'sPackToStringList), and the options array marshals fine — both verified by reading back ModelRisk's own parsedSimOpt_SeedFixed=1/SimOpt_Seed0=Nafter feeding the exact payload toVoseSetSimulOptions12.Root cause
ModelRisk's per-cell-twister Manual-Seed mode sources its base seed from the workbook-persisted
SimOpt_SeedFixed/SimOpt_Seed0defined-names (written bySaveOptionsToWorkbook), not from the per-call options passed toVoseStartSimulCustom12.The bridge set the per-call
[seed0](parsed intom_Seedsbut ignored by the twister) and never persisted it to the workbook, so Manual Seed stayed OFF → Random mode → a different stream every run.Proof: persist
SimOpt_Seed0=999viaVoseSetSimulOptions12, then run the sim passing per-callseed=12345→ the stream tracks 999, not 12345.Fix
Call
VoseSetSimulOptions12with the same options payload beforeVoseStartSimulCustom12. That runsSaveOptionsToWorkbook, persistingSimOpt_SeedFixed=1/SimOpt_Seed0=N, which the twister then honors.Side effect (acceptable, matches ModelRisk's own ribbon Simulate): the MCP's sim settings are now written into the workbook.
Verification (end-to-end against the engine oracle, single-cell
=VoseOutput("U")+VoseUniform(0,1))seed=12345→ byte-identical streams (was: differing)seed=12345vsseed=555→ different reproducible streams (the seed now drives it)seed=12345stream matches mrengine's per-cell twister-0 reference[0.929616, 0.890155, 0.316376, 0.130707, 0.183919, 0.039759, ...]exactly, validating the byte-identical parity pathNote
The running MCP server must be reloaded (Claude Desktop restart) before the live
run_simulationtool picks up this change.🤖 Generated with Claude Code