Repository navigation
Enhancement-559: a loop command's -seed pins the model-declared draws, and the f-string edges
a loop command's -seed pins the model-declared draws, and the f-string edges
Scope: F13 and F12 of the
bug hunt of 2026-09-05:
the osdimc draw key and its verbose line (src/osdi/osdisetup.c,
src/include/ngspice/osdiitf.h), the loop commands' seed bracket
(src/frontend/com_sweep.c), the f-string pass (src/frontend/control.c)
and the lexer's prefixed single-quoted string (src/frontend/parser/lexical.c).
ngspice only; the compiler is unchanged.
Suites: mcpolicy_examples 41 → 46
(one existing one-sided limit widened to a two-sided band, since it happened
to sit above both re-keyed draws), rawfstring_examples
19 → 23, both solvers; the Monte Carlo, high-sigma, wcd, osdimc and
distribution suites pass; full sweep 459 of 459. Handbook
§3.6 (the osdimc keying and the
E-537 paragraph) and §3.10 (the
f-string row), README_OSDI, the two suite READMEs.
What was wrong
F13. E-537 mixed a loop command's -seed into the osdimc draw key so that
replications would be independent, but left the session-wide trial counter in
the key too. So montecarlo 3 -seed 1 … run twice reproduced the netlist
agauss values exactly and not the model-declared draws (1020.17 / 815.62 /
719.15, then 1213.59 / 1198.65 / 1133.03); highsigma 1000 -scale 2 -seed 3
gave 0.0594 and 0.0481 for one seed; the published montecarlo_seed could
not regenerate an ensemble; and a reset between two runs made them repeat
only when the commands before them matched too — what the draws depended on
was how many run-class commands had happened earlier in the session. On a
never-run deck, montecarlo's fast path (no per-sample reset) spent its
first sample on the nominal baseline as well: the first run's new circuit
pointer restarted the count that E-537's baseline skip had just set.
F12. Small edges of the f-string pass. {1e20:d} printed
9223372036854775807 with no note — the cast to long is undefined for it
and saturates on arm64; {{1+1}} failed, rightly, but the message named a
vector {1; { } was reported as an expression that does not evaluate;
{1+1:.3} — a precision without a conversion letter — was handed to the
expression evaluator with no hint that a format needs the letter; and an
unterminated r'abc came out of the lexer re-quoted as r"abc.
What changed
- A loop command's draws are a function of
(-seed, sample number).
Insidemontecarlo,highsigmaandwcdthe draw key carries the seed and
the sample number counted from the command's start instead of the trial
counter; the seed defaults to 1, exactly as the netlist half's always has,
so an unseeded run repeats itself whole and equals-seed 1, and the
unseeded NOTE says so. The counter itself still advances, so the plain run
after a loop command is a fresh trial as before. Setting the seed steps past
the baseline and blesses a never-run deck's first circuit pointer, so the
fast path draws on sample 0..option osdimc_verboseshows the pair:
osdimc: trial 3: mm:r = 966.375 (nominal 1000) [sample 2 of -seed 1]. - The f-string edges.
:dand:iprint a whole number beyond along
exactly (through%.0f, flags and width kept);:x,:Xand:urefuse a
negative or too-large value naming it — {-1:x}: -1 cannot be shown as hex
(use :d for a whole number or :g for any);{{1+1}}is told braces do not
nest — an expression cannot start with '{' (write { for a literal
brace);{ }is an empty {}; a colon tail with a format's shape but no
conversion letter gets if ':.3' was meant as a format, it needs a
conversion letter (e, f, g, d, i, u, x, X): :.3f, a wrong letter is named,
and a ternary's colon gets no hint; an unterminatedr'abcpasses through
as typed.
Verification
| check | result |
|---|---|
montecarlo 3 -seed 1 -analysis op -expr ro=@mm[r] twice, two ops between |
ro 1005.891 / 1020.166 / 815.617 both times (the ops between draw differently) |
the same with -seed 2 |
803.53 / 729.98 / 1016.27 |
the same without -seed |
the seed-1 values; NOTE: the random .params and the model-declared statistics are drawn from the default seed 1, so running this montecarlo again repeats them |
highsigma 800 -scale 2 -seed 3 before and after a reset |
P(fail) 0.0918484 both times (it was 0.0874 and 0.0968) |
| a never-run deck with a netlist random (fast path armed) | trials 2, 3 = samples 1, 2 of seed 1; sample 0 is a draw, not the nominal |
echo f"{1e20:d} {-1e20:d} {255:08X}" |
100000000000000000000 -100000000000000000000 000000FF |
{-1:x}, {{1+1}}, { }, {1+1:.3}, {1+1:.3q}, {1 > 0 ? 2 : 3} |
refused naming the value; braces do not nest; an empty {}; the hint :.3f; 'q' is not a conversion letter; 2 with no hint |
echo r'abc |
r'abc |
mcpolicy_examples, rawfstring_examples; full sweep |
46 / 46, 23 / 23; 459 of 459 |
Write-up: enhancements_doc/Enhancement-559.md.