Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

README.md

walk

One thread per walker running steps dependent steps: each walker's start state goes in, its end state and the state after every step come out, with the number of steps it ran. A state is 1 to 8 floats (width).

The step is a Field, handed to the kernel the way map takes its template: the fields package fuses the Field into WGSL expressions and the kernel is specialized with them. A node holds no WGSL.

SpecializationTypeMeaning
WALK_STEPvec4<f32> expressionlanes 0 to 3 of the next state; default zero_walk_advance(s), the constant step
WALK_STEP_HIvec4<f32> expressionlanes 4 to 7 of the next state; default s_hi
WALK_DONEbool expressionwhether the walker stops before step k; default false
WALK_PRELUDEmodule-scope WGSLthe functions the expressions call, and #include lines for the rand, noise and color preludes

The expressions read the state leaves s (lanes 0 to 3) and s_hi (lanes 4 to 7), the step number k (u32) and the walker number id (u32), the numbers of u (u_get(n)) and the columns of the cols table (cols_f32(slot, i, lane), cols_vec3(slot, i)), which is how a step reads a raster, a field column or a per-walker attribute. The constant step needs no Field: its vector is the params dx, dy, dz and dw.

Bind cols (a table from compute_abi.table), u, start (width floats a walker). Outputs: finish (n * width), path (n * steps * width, row k of walker i at (i * steps + k) * width) and steps_run.

local variant = ref:program():variant({ specialize = {
    WALK_STEP = "vec4<f32>(s.x + 1.0, s.y * 0.5, 0.0, 0.0)",
    WALK_DONE = "s.x > 8.0",
} })
local run = variant:run({ n = walkers, inputs = { cols = emptyTable, u = numbers, start = startBuffer },
    params = { steps = 8, width = 2 } })

fieldc.walkSpec(step, opts) writes the specializations from a step Field over the leaves field.walk_state and field.walk_index, and fieldc.bindSpec(spec) the cols and u to bind; device.kernel runs the kernel with them (the abi README states the form).

Exact: each walker writes its own path rows, so the result does not depend on thread order.