Algorithms: typeshade/algorithms
typeshade/algorithms is a common module: kernel functions written in "use typeshade" and published under a subpath of the package (Rule 11.20). It holds the copy, the fill, the maps, the reductions, the scan, the compaction and the histogram over arrays. Each function runs on WebGPU, on WebGL2 and on the CPU tier, and gives on each the bits the CPU oracle gives. In a fuse scope it fuses with the calls around it as far as the facts allow.
1. The host face
Host code imports the subpath as it imports any package, and calls each function over Resident arrays, alone or inside a fuse body. Each function writes every element of its output, so an array from a device pool needs no zeroing. histogram is the one exception: it adds into the bins it is given, and the caller zeroes them.
import { fuse } from 'typeshade/fuse';import { fill, add, relu, sumAxis, exclusiveScan, compact } from 'typeshade/algorithms';import { fillUniform } from 'typeshade/random';
await fuse(() => { fill(t, 1); // t[i] = 1 add(u, t, b); // u[i] = t[i] + b[i] relu(v, u); // v[i] = max(u[i], 0): one dispatch with the two before it sumAxis(rows, v, columns, 1); // a group of its own: it reads v at another index});
await fuse(() => { fillUniform(noise, 12345); exclusiveScan(offsets, flags, sums); // sums: the caller's scratch compact(kept, rows, flags, offsets);});2. The functions
An array parameter is an array<f32> unless the row says otherwise.
| Group | Functions | What each one does |
|---|---|---|
| Copy and fill | copy(out, x), fill(out, value) and sequence(out, start, step) | One loop at i. sequence writes start + f32(i) * step. |
| Binary maps | add, sub, mul and div as (out, a, b), and scale(out, x, k) | One loop at i. |
| Unary maps | abs, neg, sqrt, rsqrt, exp, log, expm1, log1p, floor, ceil, round, sign, sin, cos, tan, tanh, sigmoid and relu as (out, x), and clip(out, x, lo, hi) | One loop at i. In the shader module each one is <op>Map, such as absMap, since a kernel function cannot carry a builtin's name. |
| Whole reductions | sum(x), max(x) and min(x), each an f32 | One tree order on every tier (Rule 7.2). In the shader module they are sum, maxAll and minAll. |
| Axis reductions | sumAxis, meanAxis, prodAxis, maxAxis, minAxis, argMaxAxis and argMinAxis as (out, x, axis, inner) | x is read as [outer, axis, inner]. Each element of out is a serial fold in ascending order. |
| Scan | inclusiveScan(out, x, sums) and exclusiveScan(out, x, sums) over array<u32> | Two loops of one kernel function. sums is the caller's scratch, with at least one element and about as many as the square root of the length of x. |
| Compaction | compact(out, x, flags, offsets) | The elements whose flag is 1, in their order, where offsets is the exclusive scan of flags. |
| Histogram | histogram(bins, x, lo, hi) | Adds the count of x in each of the equal bins over [lo, hi) into bins. Each add is an atomic on WebGPU. |
3. How the calls fuse
Every map writes out at i and reads its inputs at i, so a chain of maps is one dispatch, and a whole reduction joins a chain as its last call. An axis reduction, a scan and a compaction read their input at another index, so each one starts a group of its own after a call that wrote that input. In the first scope of the sample, fill, add and relu run as one dispatch and sumAxis as a second, in one submission.
4. Where each one runs
The compiler's differential gate calls every function on WebGPU and on WebGL2 against the CPU oracle. It holds a function bit for bit where the determinism report lists no row for it, and within a bound where it lists one, such as exp or sin. WebGL2 refuses the three whole reductions, the two scans, compact and histogram, so each of those calls falls to the next tier of its selected owner's prefer policy (Rule 11.8).
5. The device face
A "use typeshade" file may import from typeshade/algorithms too, which names the shader module under the typeshade condition. Its exports are kernel functions, and no function calls a kernel function, so a shader file has nothing to call from it in this version. The helpers a kernel composes over its own workgroup memory are a later delivery.
6. Not yet
Sort, partition, a segmented reduction, reduceByKey, a nearest-neighbour search, matrix products, f64 linear algebra and a workgroup-memory scan are later deliveries.