[Interpret ↔ compile parity]
Plot-series parity between Runtime interpret and compile modes: harness, tolerances, and known sentinel differences.
Interpret ↔ compile parity
Abstract
PYNE ships two bar engines that should agree on numeric plot series for scripts in the compile surface: the AST interpreter and the generated Numba/object-mode loop. This page is the short contract for that agreement—how to measure it, what “equal” means, and where intentional differences live (None vs nan, host time_arr, structural keys).
Strategy event parity (Python vs TypeScript worker) is a separate oracle (tests/test_parity.py + fixtures). Here the focus is plot values on one host: pynescript.runtime.Runtime.
Conceptual model
Both modes receive the same synthetic (or host) OHLCV. Compile additionally builds time_arr from bar time fields so time / calendar expressions line up with the interpret time series.
Interface surface
Corpus harness
# From repo root — first-party fixtures by default
python scripts/compare_interp_compile.py --bars 1000 --limit 50
python scripts/compare_interp_compile.py --files tests/fixtures/parity/pine/strategy_01_entry_long.pine
| Flag / output | Role |
|---|---|
| Default inputs | tests/fixtures/parity/pine/*.pine (first-party) |
| Tolerances | rtol=1e-5, atol=1e-6 (nan-aware) |
| Report | .cache/interp_compile_parity.json |
| Exit 0 | No value/nan mismatches on common series keys |
Buckets: OK, fill_background_only, both_error_same, expected_error, both_error, MISMATCH, interp_error, compile_error, structural_only. Matched errors on both backends (both_error_same) and intentional demo failures (expected_error, e.g. auto-fib / pivot-depth) count as success unless --strict-errors. First-party hline/fill/bgcolor/plotshape keys match interpret (0.3.11). --ignore-hline-keys / --ignore-fill-keys remain optional for leftover corpus key noise; --strict-keys fails on any one-sided key.
Focused unit tests
| Test | Scope |
|---|---|
tests/test_dividend_yield_parity.py | Host-series copy-on-assign + time history (interpret/compile) |
tests/test_compiler_numba.py | Kernel-level numeric correctness |
tests/test_parity.py | Strategy event fixtures (not plot allclose) |
Product path
Pro API /run defaults to mode=auto: compile when _compile_eligible passes (no top-level import, no request. token), otherwise interpret with compile_fallback_reason. Parity harness always forces explicit interpret vs compile so fallbacks do not hide drift.
What must match
- Common plot keys — float series after
None↔nannormalization. - Warm-up
na— leading missing samples align (interpretNone/ compilenan). time/ bar-open ms — when OHLCV includestime, or both use the synthetici * 60_000fallback.- Structured errors — scripts that
runtime.error(e.g. insufficient pivots) should fail on both with messages that normalize equal (both_error_same).
Intentional / soft differences
| Topic | Policy |
|---|---|
| Sentinels | Interpret: None; Numba: np.nan. Compare with nan-aware equality, not ==. |
| Hline / fill / bgcolor keys | May appear on one mode only; ignore with harness flags unless you need strict key sets. |
| Unresolved imports / stubs | Non-numeric plot cells serialize as na (null)—not string stubs. |
| Outside compile surface | UDT-heavy / full request.* / rich strategy analytics stay interpret-first; auto falls back. |
| Disk / Numba caches | Stale IR after kernel edits can fake mismatches—clear compile + Numba caches (see harness docstring). |
Internals
| Path | Role |
|---|---|
scripts/compare_interp_compile.py | End-to-end series compare |
tests/test_interp_compile_parity.py | Always-on smoke + harness flag tests |
src/pynescript/runtime/host.py | _run_compiled, OHLCV + time_arr packing |
backend/runtime.py | Compat re-export of the package host |
src/pynescript/compiler/engine.py | Compile façade + result normalize |
src/pynescript/compiler/numba_builtins.py | JIT kernels under test |
Worked example
python scripts/compare_interp_compile.py \
--files tests/fixtures/parity/pine/strategy_01_entry_long.pine \
--bars 500
# → OK (or MISMATCH with first differing bar/key in the JSON report)
Failure modes
| Symptom | Likely cause |
|---|---|
| Systematic offset after warm-up | EMA/RSI seed or window clamp drift in a kernel |
| Only-compile empty plots | Script still object-mode / plot not lowered; or cache corruption |
time diverges | Host omitted times on one path only; check time_arr packing |
| Structural-only keys | hline/fill/background naming — use ignore flags or align collectors |
See also
- Compiler overview
- Numba path
- Series & history
- Runtime hub
- Numerical validation
- PyneTS parity — TypeScript vs Python plots