Adopt the input and source vocabulary

This commit is contained in:
Dennis Kobert
2026-09-06 16:57:14 +00:00
parent c93395bb8f
commit 5d967a6a17
+12 -12
View File
@@ -310,7 +310,7 @@ not. The tuple form composes with laziness: a lazy input declared
each evaluation, so a kernel can branch on another input's attribute each evaluation, so a kernel can branch on another input's attribute
without evaluating the branch it rejects. It is a read declaration without evaluating the branch it rejects. It is a read declaration
only: the lazy input's fields do not pass through to the output, since only: the lazy input's fields do not pass through to the output, since
the kernel controls whether and how often the edge is evaluated; the kernel controls whether and how often the input is evaluated;
forwarding a lazy input's attributes is routing. forwarding a lazy input's attributes is routing.
The rest of the authoring surface composes. Categories, per-parameter The rest of the authoring surface composes. Categories, per-parameter
@@ -561,18 +561,18 @@ every lift, one copy per invocation.
| Signature form | Meaning | Lowering | | Signature form | Meaning | Lowering |
| --- | --- | --- | | --- | --- | --- |
| first non-context param | primary input | carrier record | | first non-context param | primary input | carrier record |
| `_: ()` | no primary input | no carrier edge | | `_: ()` | no primary input | no carrier input |
| `element: T` (unbounded, returned first) | explicit passthrough | erased byte carry, where `T` is instantiated with a zero-sized token, so the routing is checked by the type system and costs nothing | | `element: T` (unbounded, returned first) | explicit passthrough | erased byte carry, where `T` is instantiated with a zero-sized token, so the routing is checked by the type system and costs nothing |
| `element: Concrete` / bound | element read | field read at offset 0, monomorphized per implementations list, binds level 0 | | `element: Concrete` / bound | element read | field read at offset 0, monomorphized per implementations list, binds level 0 |
| `(x, a): (X, Attr<A>)` | input with attribute reads | the value as its ordinary lowering; each `Attr` an offset read into that input's record, or the default constant | | `(x, a): (X, Attr<A>)` | input with attribute reads | the value as its ordinary lowering; each `Attr` an offset read into that input's record, or the default constant |
| `(_, a): ((), Attr<A>)` | attribute-only input | wired record edge with unit element; the attribute is the payload | | `(_, a): ((), Attr<A>)` | attribute-only input | a wired record input with unit element; the attribute is the payload |
| `Attr<A>` in the return tuple | attribute write | offset write into the output record | | `Attr<A>` in the return tuple | attribute write | offset write into the output record |
| `RemoveAttr<A>` in the return tuple | attribute delete | the name leaves the output layout; functionally a write of the default | | `RemoveAttr<A>` in the return tuple | attribute delete | the name leaves the output layout; functionally a write of the default |
| `OwnedAttr<A>` in an async source's return tuple | owned attribute write | the value crosses the future boundary as a deep copy taken before the first await, and parks into the serving arena at every lift; exhaustion surfaces as a poll | | `OwnedAttr<A>` in an async source's return tuple | owned attribute write | the value crosses the future boundary as a deep copy taken before the first await, and parks into the serving arena at every lift; exhaustion surfaces as a poll |
| `keys: IList<K>` | whole-extent input | wired edge, evaluated over its extent into a view | | `keys: IList<K>` | whole-extent input | a wired input, evaluated over its extent into a view |
| plain parameters | wired value inputs | ordinary wired edges; attributes on their wires do not flow | | plain parameters | wired value inputs | ordinary wired value inputs; attributes on their wires do not flow |
| `impl Node<Context<'_>, Output = Concrete>` | lazy value input | the value flows, attributes do not | | `impl Node<Context<'_>, Output = Concrete>` | lazy value input | the value flows, attributes do not |
| `impl Node<Context<'_>, Output = (T, Attr<A>, ..)>` | lazy input with attribute reads | each eval yields the element plus the declared reads, offsets resolved against that edge's layout; a read declaration only, and no field pass-through | | `impl Node<Context<'_>, Output = (T, Attr<A>, ..)>` | lazy input with attribute reads | each eval yields the element plus the declared reads, offsets resolved against that input's layout; a read declaration only, and no field pass-through |
| `impl Node<Context<'_>, Output = T>` (unbounded) | source of an opaque record family | routing, see below | | `impl Node<Context<'_>, Output = T>` (unbounded) | source of an opaque record family | routing, see below |
| `-> IList<W>` with a lazy subject and `DeriveCtx` | per-copy level production | the kernel splits the index and evaluates the subject at the pushed level | | `-> IList<W>` with a lazy subject and `DeriveCtx` | per-copy level production | the kernel splits the index and evaluates the subject at the pushed level |
| `-> IList<W>` with a carrier subject | per-lane level production | the carrier binds once for the run; the kernel computes each lane's own fields | | `-> IList<W>` with a carrier subject | per-lane level production | the carrier binds once for the run; the kernel computes each lane's own fields |
@@ -640,10 +640,10 @@ sources are the lazy inputs whose `Output` is the generic; the element
passthrough is the same mechanism with the carrier as the family's only passthrough is the same mechanism with the carrier as the family's only
source. Wiring computes the union of the sources' layouts and a source. Wiring computes the union of the sources' layouts and a
translation plan per source (field moves plus default fills). The translation plan per source (field moves plus default fills). The
kernel-facing handles wrap the edges the same way the error dialect kernel-facing handles wrap the inputs the same way the error dialect
wraps status plumbing: evaluating a source evaluates its edge at the wraps status plumbing: evaluating a source evaluates its input at the
unchanged context and yields a value carrying the resulting record, unchanged context and yields a value carrying the resulting record,
either through the plan into that source's own buffer, or, when the either through the plan into a claim of that source's own, or, when the
source's layout already equals the union, by forwarding the record source's layout already equals the union, by forwarding the record
pointer untouched. The forwarding case compiles to a conditional move pointer untouched. The forwarding case compiles to a conditional move
plus a tail call; the +4.7ns per lane of a two-branch switch is the plus a tail call; the +4.7ns per lane of a two-branch switch is the
@@ -652,12 +652,12 @@ costs +6.5ns per lane at eight attributes.
The kernel routes these values as ordinary Rust values. It can evaluate The kernel routes these values as ordinary Rust values. It can evaluate
any source any number of times, hold several results at once (per-source any source any number of times, hold several results at once (per-source
buffers keep them valid side by side), pass them through helper claims keep them valid side by side), pass them through helper
functions, and return any of them. The returned value's record is the functions, and return any of them. The returned value's record is the
node's output, so provenance is carried by the value itself: element and node's output, so provenance is carried by the value itself: element and
attributes travel together, and returning a result obtained before some attributes travel together, and returning a result obtained before some
later evaluation is well-defined. A value is live until its own source later evaluation is well-defined. A value is live until its own source
is evaluated again, which overwrites that source's buffer; a kernel that is evaluated again, which reclaims that source's claim; a kernel that
needs two results of one input side by side declares the input twice. needs two results of one input side by side declares the input twice.
The values are opaque and unforgeable, and inspecting one requires The values are opaque and unforgeable, and inspecting one requires
bounds on the generic, which is element access and monomorphization as bounds on the generic, which is element access and monomorphization as
@@ -810,7 +810,7 @@ the wiring-computed byte plans, where it is irreducible.
convergence (merge unions them, defaults answer switch mismatches) and convergence (merge unions them, defaults answer switch mismatches) and
the resolver is untouched. the resolver is untouched.
- The numbers cited throughout come from a reference prototype with - The numbers cited throughout come from a reference prototype with
type-erased node edges (the indirect calls were verified in the type-erased node inputs (the indirect calls were verified in the
disassembly), thin LTO, 64k-lane workloads, and best-of-nine timing. disassembly), thin LTO, 64k-lane workloads, and best-of-nine timing.
Chain results use ten nodes and eight f64 attributes. Chain results use ten nodes and eight f64 attributes.