[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 / outputRole
Default inputstests/fixtures/parity/pine/*.pine (first-party)
Tolerancesrtol=1e-5, atol=1e-6 (nan-aware)
Report.cache/interp_compile_parity.json
Exit 0No 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

TestScope
tests/test_dividend_yield_parity.pyHost-series copy-on-assign + time history (interpret/compile)
tests/test_compiler_numba.pyKernel-level numeric correctness
tests/test_parity.pyStrategy 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

  1. Common plot keys — float series after Nonenan normalization.
  2. Warm-up na — leading missing samples align (interpret None / compile nan).
  3. time / bar-open ms — when OHLCV includes time, or both use the synthetic i * 60_000 fallback.
  4. 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

TopicPolicy
SentinelsInterpret: None; Numba: np.nan. Compare with nan-aware equality, not ==.
Hline / fill / bgcolor keysMay appear on one mode only; ignore with harness flags unless you need strict key sets.
Unresolved imports / stubsNon-numeric plot cells serialize as na (null)—not string stubs.
Outside compile surfaceUDT-heavy / full request.* / rich strategy analytics stay interpret-first; auto falls back.
Disk / Numba cachesStale IR after kernel edits can fake mismatches—clear compile + Numba caches (see harness docstring).

Internals

PathRole
scripts/compare_interp_compile.pyEnd-to-end series compare
tests/test_interp_compile_parity.pyAlways-on smoke + harness flag tests
src/pynescript/runtime/host.py_run_compiled, OHLCV + time_arr packing
backend/runtime.pyCompat re-export of the package host
src/pynescript/compiler/engine.pyCompile façade + result normalize
src/pynescript/compiler/numba_builtins.pyJIT 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

SymptomLikely cause
Systematic offset after warm-upEMA/RSI seed or window clamp drift in a kernel
Only-compile empty plotsScript still object-mode / plot not lowered; or cache corruption
time divergesHost omitted times on one path only; check time_arr packing
Structural-only keyshline/fill/background naming — use ignore flags or align collectors

See also