1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright 2024-2026 Jonathan Shook
// SPDX-License-Identifier: Apache-2.0
//! # polydat (formerly nbrs-variates)
//!
//! Deterministic variate generation kernel (GK) for workload testing.
//!
//! Transforms named `u64` coordinate tuples into typed output variates
//! via a compiled DAG of composable function nodes. The same coordinate
//! always produces the same outputs — deterministic, reproducible, and
//! parallelizable with zero shared mutable state.
//!
//! ## Quick Start
//!
//! ### From DSL source
//!
//! The simplest way to build a kernel is from Polydat DSL source:
//!
//! ```rust
//! use polydat::dsl::compile_polydat;
//!
//! let mut kernel = compile_polydat(r#"
//! input cycle: u64
//! hashed := hash(cycle)
//! user_id := mod(hashed, 1000000)
//! "#).unwrap();
//!
//! kernel.set_inputs(&[42]);
//! let user_id = kernel.pull("user_id").as_u64();
//! assert!(user_id < 1_000_000);
//! ```
//!
//! ### From the assembler API
//!
//! For programmatic construction:
//!
//! ```rust
//! use polydat::compile::assembly::{PolydatAssembler, WireRef};
//! use polydat::library::hash::Hash;
//! use polydat::library::arithmetic::Mod;
//!
//! let mut asm = PolydatAssembler::new(vec!["cycle".into()]);
//! asm.add_node("hashed", Box::new(Hash::new()), vec![WireRef::input("cycle")]);
//! asm.add_node("user_id", Box::new(Mod::new(1_000_000)), vec![WireRef::node("hashed")]);
//! asm.add_output("user_id", WireRef::node("user_id"));
//!
//! let mut kernel = asm.compile().unwrap();
//! kernel.set_inputs(&[42]);
//! assert!(kernel.pull("user_id").as_u64() < 1_000_000);
//! ```
//!
//! ## Architecture
//!
//! ```text
//! coordinates (u64 tuple)
//! │
//! ▼
//! ┌─────────────────────────┐
//! │ PolydatProgram (immutable) │ Shared via Arc across threads
//! │ - nodes: Vec<PolydatNode> │
//! │ - wiring: Vec<Vec<..>> │
//! │ - output_map │
//! └──────────┬──────────────┘
//! │
//! ┌──────┴──────┐
//! │ PolydatState │ One per thread — no locks
//! │ - buffers │
//! │ - coords │
//! └──────┬──────┘
//! │
//! ▼
//! pull("user_id") → Value::U64(527897)
//! ```
//!
//! ## Compilation Levels
//!
//! The kernel supports four compilation levels:
//!
//! - **Phase 1** (default): Pull-through interpreter. ~70ns/node.
//! - **Phase 2**: Compiled `u64` closures. ~4.5ns/node.
//! - **Hybrid**: Per-node optimal (JIT where supported, closures elsewhere).
//! - **Phase 3**: Cranelift JIT native code. ~0.2ns/node.
//! Requires the `jit` feature (enabled by default).
//!
//! ## Features
//!
//! - **`jit`** (default): Cranelift JIT compilation for Phase 3.
//! Disable with `default-features = false` for a lighter build.
//! - **`vectordata`**: Vector dataset access nodes for ML/AI workloads.
//!
//! ## Modules
//!
//! - [`ast`]: Core types — [`ast::Value`], [`ast::PolydatNode`] trait,
//! [`ast::Port`], [`ast::PortType`]
//! - [`kernel`]: Runtime — [`kernel::PolydatProgram`], [`kernel::PolydatKernel`],
//! [`kernel::PolydatState`]
//! - [`compile`]: DAG construction + compilation strategies —
//! [`compile::assembly::PolydatAssembler`], [`compile::fusion`],
//! [`compile::closures`] (Phase 2), [`compile::hybrid`]
//! (per-node optimal), [`compile::jit`] (Phase 3 Cranelift,
//! feature-gated)
//! - [`dsl`]: Polydat language — [`dsl::compile_polydat`], lexer, parser, registry
//! - [`library`]: 250+ built-in function nodes (hash, arithmetic, string,
//! math, distributions, datetime, noise, etc.) plus [`library::sampling`]
//! (alias tables, LUT interpolation, ICD) and [`library::support`]
//! (library-internal cache + audit infrastructure)
//! - [`viz`]: DAG visualization (DOT, Mermaid)
// Unit tests use round-number float literals (`3.14`, `1.57`,
// `2.71`, …) as arbitrary fixture data. clippy's `approx_constant`
// is a deny-by-default correctness lint that reads those as
// fat-fingered `std::f*::consts::*` — true for production code,
// noise for test data. Scope the allowance to `cfg(test)` so the
// lint still guards real code.
// SRD-80 PR B.3 — let the `#[polydat_node]` macro's emitted
// `polydat::...` paths resolve when the macro is invoked from
// INSIDE the polydat crate itself (library nodes migrating to
// the macro form). External callers don't need this — they
// reference `polydat` via the regular crate-name lookup.
extern crate self as polydat;
// SRD-104 — dependency-inverted resource-accessor bridge. A
// type-erased trait + process-global install point by which a
// kernel node reaches a live, host-owned resource by fingerprint,
// without polydat depending on the host runtime.
// SRD-80 — proc-macro trait surface. The `polydat-derive`
// crate emits paths like `polydat::derive_support::FromValue` /
// `IntoValue` that resolve here.
// SRD-80 PR B.5 — `Const<T>` wrapper re-exported at crate root
// for ergonomic use in `#[polydat_node]` function signatures.
pub use Const;
// SRD-105 — engine-mix surface: the process-default JIT mode and
// its accessors. `kernel.jit: auto|off|force` maps here.
pub use ;
// SRD-82 §"Panic reporting: one full render" — host runtimes with
// their own panic reporting declare it so the eval-panic hook
// prints a short notice instead of the full diagnostic.
pub use set_panic_reporting_downstream;
// SRD-80 — re-export the `#[polydat_node]` attribute so
// library callers can write `#[polydat::polydat_node]` without
// a separate `use polydat_derive::polydat_node;` line.
pub use polydat_node;
// SRD-80 — re-export `inventory` so the macro's emitted
// `::polydat::inventory::submit!` path resolves at every call
// site without users having to add `inventory` to their own
// dependencies.
pub use inventory;
/// Re-exported for `#[polydat_node]`-generated Phase-2 buffer
/// casts on `half::f16`-typed wires (the generated code spells
/// `polydat::half::f16`, which `extern crate self as polydat`
/// resolves inside this crate too).
pub use half;
/// SRD-104 — the resource-accessor bridge at the crate root so the
/// host installs via `polydat::RESOURCE_ACCESSOR` and nodes resolve
/// via `polydat::resource_lookup`, without reaching a deep module
/// path (D6).
pub use ;
/// Host-log sink bridge — the sanctioned public path for installing
/// a leveled log sink into the kernel (`set_log_fn`) and for emitting
/// through it (`warn` / `info` / …). The activity runner installs its
/// `observer::log` here so polydat's cycle-time data-source audit lines
/// land in `session.log`. This is the one public entry point for the
/// audit channel; the implementation lives under `library::support`,
/// which is library-internal and must not be reached directly.
pub use audit;