pub struct NOf {
pub n: u64,
pub m: u64,
/* private fields */
}Expand description
N-of-M deterministic fractional selection.
Signature: n_of(input: u64, n: u64, m: u64) -> u64
Returns 1 for exactly n out of every m consecutive inputs, 0
otherwise. Which specific inputs are selected within each window
is determined by hashing, so the pattern is not simply “first n”.
This differs from unfair_coin(input, n/m): unfair_coin is
probabilistic (each input independently has probability n/m),
while n_of guarantees exact counts over each window of m inputs.
Use for precise fraction control: exactly 3 out of every 10 cycles are “special”, exactly 1 out of every 100 is an error, etc.
is_special := n_of(cycle, 3, 10)Both n and m are init-time constant parameters, and both of
their rules are checked when the node is built: 1 <= m <= 65536 by
the per-parameter range constraint, and n <= m by the node-level
validator, which is where a relation between two parameters belongs.
Neither rule depends on the body running, so both hold on every
engine.
The window is at most 65 536 positions because each call ranks its
position against every other one in the window, m hashes per
cycle. At the bound that is about a tenth of a millisecond a cycle;
unbounded, a large m was a hang, one call taking longer than any
run. The bound keeps every output of an m that was usable as it
was.
JIT level: P3 (JitOp::NOfConst).
Fields§
§n: u64The n argument, as given at construction.
m: u64The m argument, as given at construction.
Implementations§
Trait Implementations§
Source§impl PolydatNode for NOf
impl PolydatNode for NOf
Source§fn compiled_u64(&self) -> Option<CompiledU64Op>
fn compiled_u64(&self) -> Option<CompiledU64Op>
Source§fn jit_constants(&self) -> Vec<u64>
fn jit_constants(&self) -> Vec<u64>
Source§fn scratch_layout(&self) -> Vec<ScratchElem>
fn scratch_layout(&self) -> Vec<ScratchElem>
Self::eval_in. Empty for a node that evaluates over
Values alone, which is every node but a native cone.Source§fn eval_in(
&self,
scratch: &mut [ScratchBuf],
inputs: &[Value],
outputs: &mut [Value],
)
fn eval_in( &self, scratch: &mut [ScratchBuf], inputs: &[Value], outputs: &mut [Value], )
Self::eval with the node’s scratch, which the evaluating
state owns and hands in: storage belongs to the state, never to
the node, which is shared by every state of the program.Source§fn commutativity(&self) -> Commutativity
fn commutativity(&self) -> Commutativity
Source§fn accepts_none_inputs(&self) -> bool
fn accepts_none_inputs(&self) -> bool
Value::None inputs
directly rather than have the kernel propagate None through
it. Default: false — most nodes follow none_semantics.md Rule 1
(None in → None out, no eval invocation). Read moreSource§fn compiled_slot(
&self,
_wire_types: &[PortType],
_engine: Engine,
) -> Option<CompiledSlotKit>
fn compiled_slot( &self, _wire_types: &[PortType], _engine: Engine, ) -> Option<CompiledSlotKit>
(ptr, len) slot
pairs; vector outputs write into kernel-owned scratch.
Checked by the compiled-kernel builders AFTER
Self::compiled_u64 — pure-scalar nodes never need it.
Default None: the node stays on typed eval. Read moreSource§fn purity(&self) -> Purity
fn purity(&self) -> Purity
runtime_model.md’s D2 axiom. Default:
Purity::Pure. Override to declare an observable
side channel (Purity::SideChannel) or
eval-call-spanning state (Purity::Nondeterministic). Read moreSource§fn simd_variant(&self) -> Option<SimdVariant>
fn simd_variant(&self) -> Option<SimdVariant>
Source§fn fusion_subgraph(&self) -> Option<FusionSubgraph<'_>>
fn fusion_subgraph(&self) -> Option<FusionSubgraph<'_>>
PolydatProgram::canonical_hash) walks THROUGH fusion
nodes into this subgraph, so identity is invariant to the
engine mix: jit=off and jit=auto compiles of the same
source hash identically, and resume-skip matching survives
mode changes. Default None: ordinary nodes hash as
themselves.