Skip to content

Comp for js pb#3

Open
caumond wants to merge 28 commits into
mainfrom
comp-for-js-pb
Open

Comp for js pb#3
caumond wants to merge 28 commits into
mainfrom
comp-for-js-pb

Conversation

@caumond

@caumond caumond commented Apr 13, 2025

Copy link
Copy Markdown
Member

---Summary

Brings branch comp-for-js-pb to a steady state. The headline work is a rework of the PRNG subsystem into a portable + fast-per-platform design, plus a sweep of the tasks.org checklist (comprehensive tests, security docs, runnable examples). The branch also carries earlier refactoring commits that diverge from main (e.g. the time_based → tb_var rename, routings, eval).

PRNG: portable + fast-per-platform variants

  • :xoroshiro128 — portable, identical values on JVM and JS (.cljc).
  • :xoroshiro128-jvm / :xoroshiro256-jvm (JVM-only), :xoroshiro128-js (JS-only) — the fastest impl on each platform; only the host-matching key is
    registered.
  • The JVM-fast and JS-fast cores match the canonical C reference bit-for-bit (test/c/xoro_test.cpp, xoro256_test.cpp; asserted in
    reference-implementation-test).
  • Fast variants implement the full PRNG protocol (incl. jump) and are documented as not thread-safe (use duplicate per thread). Shared bit-ops + generic
    next-*-fn factories live in xoro-common.

Steady-state checklist (tasks.org)

  • Correctness/tests — xoshiro256 zero-state guard + :state-bits meta; benchmark assertions fixed and tagged ^:benchmark; lazy test-state-independence
    realized; xoro-common mix/long->unit-float:alt tests; protocol lifecycle assertions factored into one shared suite.
  • Coverage — new tests for eval, tb-var protocol/storage-strategy/var-aggregated, plus crit-comp/routings edge cases. Fixed a real eval/registry-schema
    bug (bare invalid Malli :function + unqualified keys → fn? + ::opti-qualified, so the registry validates against its own schema).
  • Security — prng docstring warns the generators are not cryptographically secure and flags the fixed-default-seed footgun; PRNG thread-safety contract
    made honest; seed input validated (->uuid throws a clear error instead of a downstream NPE).
  • iterative.descent quarantined as experimental (stochastic throws "not implemented yet"; unfinished loop kept as a documented sketch; contract pinned
    by a test).
  • Runnable docs — docs/examples/ with a runnable .clj per feature (+ end-to-end) mirrored by .org, run by a new bb examples task.

Build/CI wiring

:paths includes src/clj; :test-clj discovers test/clj (excluding ^:benchmark); :cljs-deps carries src/cljs + test/cljs; bb lint covers all source roots.

Test plan

  • bb bp (format → lint → clj-test all → cljs-node-test all) — green.
  • bb examples — 9/9 green.

Notes / follow-ups

  • Mirror the PRNG security warning onto the prng wiki page (docs/wiki/, a separate repo, not touched here).
  • The scrambler-as-parameter enhancement for the fast variants was deferred (TODO removed, not implemented).

@caumond
caumond force-pushed the comp-for-js-pb branch 3 times, most recently from 0b30576 to 1ae3166 Compare December 17, 2025 14:28
@caumond
caumond force-pushed the comp-for-js-pb branch 3 times, most recently from f603242 to ddd59ef Compare December 17, 2025 15:10
@caumond
caumond force-pushed the comp-for-js-pb branch 3 times, most recently from 61981a7 to 0331d94 Compare December 17, 2025 15:39
@caumond
caumond force-pushed the comp-for-js-pb branch 4 times, most recently from c7614c4 to 68c63fe Compare December 17, 2025 21:00
@caumond
caumond force-pushed the comp-for-js-pb branch 4 times, most recently from e28a684 to af750de Compare December 22, 2025 21:00
@caumond
caumond force-pushed the comp-for-js-pb branch 2 times, most recently from 7a43d76 to 14e4632 Compare December 22, 2025 23:17
@caumond
caumond force-pushed the comp-for-js-pb branch 2 times, most recently from 4702ecf to 4939150 Compare December 30, 2025 17:14
caumond and others added 10 commits January 5, 2026 22:33
Resolve the namespace collision where src/clj and src/cljc both defined
auto-opti.prng.impl.xoroshiro128, which silently shadowed the portable
implementation on the JVM and broke bb clj-test / CI.

The registry now exposes platform-explicit variants:
- :xoroshiro128       portable, identical values on JVM and JS (cljc)
- :xoroshiro128-jvm   fast JVM (primitive longs, mutable long-array)
- :xoroshiro256-jvm   fast JVM, larger xoshiro256+ state
- :xoroshiro128-js    fast JS (64-bit math emulated on 32-bit lanes)

Only the entries matching the host platform are registered. The JVM-fast
and JS-fast cores match the canonical C reference bit for bit (reference
and JS-core tests). Fast variants implement the full PRNG protocol
(including jump) and are documented as not thread-safe; xoro-common now
holds the shared bit ops and the generic next-*-fn factories.

Build: the clj test runner discovers test/clj (excluding :benchmark-
tagged tests), the cljs build picks up src/cljs + test/cljs. bb bp green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generate canonical xoshiro256+ values from a C reference (state
[1,2,3,4]) and assert the JVM implementation reproduces them exactly, as
the xoroshiro128+ variant already does. Adds test/c/xoro256_test.cpp and
run256; also tracks the pre-existing xoro_test.cpp / run that back the
128-bit reference test. Compiled binaries stay gitignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PRNG cluster:
- xoshiro256: non-zero-state guard checks all four words; :meta uses the
  unambiguous :state-bits (128 too); :next-raw shape unified (task 4).
- Tests: xoro-advanced-test drops the redundant outer `is`;
  test-state-independence forces its lazy seq with dorun (task 7).
- xoro-common gains direct mix / long->unit-float:alt tests; the protocol
  lifecycle assertions are factored into a shared
  test-suites/run-prng-protocol-tests used by the 128-jvm, 256-jvm and js
  test namespaces (task 8).
- stateful/PRNG docstring made honest about per-impl thread-safety; prng
  warns it is not cryptographically secure and flags the fixed default seed;
  ->uuid validates the seed and throws a clear error on malformed input
  (tasks 11, 12).

Coverage + fixes (task 9):
- New tests for eval, tb-var protocol/storage-strategy/var-aggregated, plus
  crit-comp/routings edge cases. Fixed a real eval/registry-schema bug: bare
  (invalid) malli :function and unqualified keys -> fn? + ::opti-qualified,
  so the registry validates against its own schema.

iterative.descent quarantined as experimental: stochastic throws
"not implemented yet", the unfinished loop kept as a documented sketch,
with a test pinning the contract (task 10).

Runnable docs (tasks 13, 14): docs/examples/ with a runnable .clj per
feature (+ end-to-end) mirrored by .org, and a `bb examples` task that runs
them all and fails on any throw.

bb bp (format/lint/clj/cljs) and bb examples are green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rename the JVM-only common helpers (and their test) to *_jvm to mark them platform-specific, and remove the now-unnecessary (:refer-clojure :exclude [next]) from the cljc built-in and xoroshiro128 impls.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gamma now guards the non-positive integers (0, -1, -2, ...) where Γ is undefined and returns ##NaN there, matching the Apache Commons Math reference, rather than throwing an ArithmeticException. Fix the inv-gamma-1pm1 / log-gamma-1p docstrings ([-0.5;1.5]) and add a gamma-is-nan-at-poles test (green on clj and cljs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New auto-opti.rep namespace: a registry mapping a rep-type keyword (e.g. :seed) to a Malli schema, with valid-rep to validate a representation against its type. eval registry entries now use ::opti/rep-type and ::opti/eval-fn (was ::rep/::eval), and eval/eval-map validates the model and builds the evaluation. montecarlo/eval guards a non-numeric model.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Delete the duplicate per-example .clj files. bb examples now extracts the #+begin_src clojure block(s) from each docs/examples/*.org, runs all of a file's blocks in one JVM (shared session, like org-babel against one REPL), and checks each block's stdout against the #+RESULTS: that follows it (lines containing ... are wildcards). Supports multiple blocks per file. Update README to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant