Task 1 of 5
Until now, every kernel call ended the same way: the GPU finished computing, then the whole result was downloaded back to JavaScript as a typed array. That download is the expensive part — for a 512×512 grid it's a megabyte crossing the bus on every single call.
pipeline: true changes the ending. The kernel still runs the same, but the
result stays in GPU memory, and what you get back is a texture —
a lightweight handle to data that never left the card. Log one and you'll see an object,
not numbers. When you actually want the values, you ask for the download explicitly with
.toArray() — and since the download is a real trip across the bus, it is
asynchronous like the kernel call itself: await result.toArray().
One backend wrinkle to know: the CPU backend has no textures, so there a pipeline
kernel hands back a plain array — which has no .toArray at all. Mode-safe code
uses the same guard gpu.js uses internally, with the await in front of the call it guards:
result.toArray ? await result.toArray() : result. (Awaiting a plain array is a
no-op, so that one line is correct on every backend.)
boost kernel a pipeline kernel, then
download its result explicitly and log the first sample.pipeline: true to the kernel settingsawait .toArray(), using the mode-safe guardconsole.log('first sample:', values[0])pipeline: true sits in the settings object, right next to
output. Nothing about the kernel function itself changes.
const values = result.toArray ? await result.toArray() : result;
On a GPU backend this awaits toArray(); on the CPU backend
result is already an array and passes through untouched.
GPUBuffer you never map in
WebGPU, or device memory behind a pointer in CUDA and ROCm: the data has an address on
the card, and JavaScript only holds the ticket stub. .toArray() is the
explicit "map it back to the host" step.
This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.