Invoking Operations
Both kernel() and plan() define callable operations. Calling an operation
with its bindings creates a context-free node:
const scale = kernel({ shader: `fn main(gid: vec3u) { output[gid.x] = input[gid.x] * 2.0; }`, threads: 'input'});
const node = scale({ input, output });Operation invocation does not access WebGPU or submit work. The node is
materialized for a device when it reaches v.run(), v.wait(), or a read.
Signature
Section titled “Signature”const node = operation(bindings, options);| Argument | Meaning |
| ---------- | ---------------------------------------------------- |
| bindings | Buffer, RawBuffer, Uniform, or Handle values |
| options | Optional invocation-level overrides |
const node = scale( { input, output }, { label: 'scale node', threads: input.count });debug enables shader debugging for a primitive kernel invocation:
const node = scale({ input, output }, { debug: true });plan() defines an operation that can build several kernel nodes after a
Volten context is known. Its output names come from the returned handle map:
const reduce = plan((context, inputs) => { const A = reduceStep({ input: inputs.input, output: tempA }); const B = reduceStep({ input: A.output, output: tempB });
return { result: B.output };});
const A = reduce({ input });const B = consume({ input: A.result, output });The builder runs once, during materialization. Every branch represented by a returned handle belongs to the plan invocation and is scheduled together. A builder that returns no handles schedules no work.
The order of properties in the returned object is not an execution order. Connect kernels through handles whenever one must wait for another:
const A = update({ data: inputs.data });const B = update({ data: A.data });
return { data: B.data };