Skip to main content

GPU Evaluators

@luma.gl/gpgpu has two evaluator layers:

  • GPUDataEvaluator runs one lazy transform over one fixed-width GPUData chunk or GPUDataView.
  • GPUVectorEvaluator applies one lazy GPUDataEvaluator transform independently to every ordered GPUData chunk in a GPUVector.

There is no GPUTable evaluator input path. Streaming code should pass an incoming GPUData chunk or borrowed GPUDataView directly to GPUDataEvaluator operations, or wrap a GPUVector with GPUVectorEvaluator when the same transform should preserve every existing chunk boundary.

GPU evaluator split

Usage

One incoming GPUData

import {GPUDataEvaluator, add} from '@luma.gl/gpgpu';

const offset = GPUDataEvaluator.fromConstant([1, 2, 3]);
const translatedChunk = add(incomingGPUData, offset);

const translatedVector = await translatedChunk.evaluate(device);

One GPUVector

import {GPUDataEvaluator, GPUVectorEvaluator, add} from '@luma.gl/gpgpu';

const offset = GPUDataEvaluator.fromConstant([1, 2, 3]);
const translatedVector = GPUVectorEvaluator.fromGPUVector(vector).mapGPUData(data =>
add(data, offset)
);

const outputVector = await translatedVector.evaluate(device);

GPUVectorEvaluator preserves vector.data[] order and chunk boundaries. It does not combine streaming batches or pack buffers implicitly.

Interleaved attribute input

import {add} from '@luma.gl/gpgpu';
import {makeGPUDataViewFromAttribute} from '@luma.gl/tables';

const positions = makeGPUDataViewFromAttribute({
buffer: interleavedBuffer,
bufferLayout,
attributeName: 'positions',
length: instanceCount
});

const translatedPositions = add(positions, [10, 0, 0]);
const packedOutput = await translatedPositions.evaluate(device);

Input views retain their offset and stride, so multiple attributes may borrow the same interleaved buffer. Operation results remain newly materialized packed outputs; evaluating into an interleaved destination is not implicit.

GPUDataEvaluator

GPUDataEvaluator describes a 2D row layout backed by CPU values, one borrowed GPUData chunk, borrowed GPUDataView, another GPUDataEvaluator, or a lazy Operation output. Each row contains size scalar elements of the same numeric type.

GPUDataEvaluatorProps

PropertyTypeDescription
id?stringOptional debug name used by toString().
typeSignedDataTypeScalar element type, such as 'float32' or 'uint32'.
sizenumberNumber of scalar elements in each row.
offset?numberByte offset to the first element of the first row. Defaults to 0.
stride?numberByte distance between adjacent rows. Defaults to ValueType.BYTES_PER_ELEMENT * size.
normalized?booleanWhether integer values are normalized when exposed as vertex formats.
value?TypedArrayCPU-side data for the evaluator.
buffer?Buffer | DynamicBufferBorrowed GPU buffer backing this evaluator.
gpuData?GPUDataBorrowed fixed-width GPUData chunk backing this evaluator.
format?GPUVectorFormatOptional memory format preserved for GPUVector interop.
source?Operation | GPUDataEvaluator | nullLazy source for this evaluator.
isConstant?booleanWhether every row shares the same value. Defaults to false.
length?numberRow count. Optional when isConstant is true or value is provided.

Static Methods

GPUDataEvaluator.fromArray(value, props?): GPUDataEvaluator

Creates one evaluator from a typed array or numeric array. Plain JavaScript arrays use props.type or 'float32' by default. Float64Array inputs are reinterpreted as uint32 pairs for GPU-oriented operations such as fround().

GPUDataEvaluator.fromConstant(value, type?): GPUDataEvaluator

Creates one constant evaluator with a shared row value. A scalar becomes a one-element row, and an array becomes a row with value.length elements.

GPUDataEvaluator.fromGPUData(data, options?): GPUDataEvaluator

Creates one evaluator view over a fixed-width GPUData chunk. The input must have a fixed-width GPUData.format and matching rowByteLength. Strided rows are preserved. The evaluator borrows data.buffer and does not destroy it.

GPUDataEvaluator.fromGPUDataView(view, options?): GPUDataEvaluator

Creates an evaluator over a borrowed fixed-width GPUDataView, preserving its format, length, byte offset, and byte stride. Existing operations accept views directly through GPUDataEvaluatorInput.

CPU, WebGL, and WebGPU support strided 32-bit component formats. Other formats remain subject to backend capabilities; unsupported WebGPU storage types fail explicitly rather than being repacked. Offsets and strides must be aligned to the stored scalar component width.

Methods

evaluate(device: Device, options?): Promise<GPUVector>

Materializes one single-chunk GPUVector on the provided device. Lazy dependencies are evaluated before the operation handler writes the output.

evaluateSync(device: Device, options?): GPUVector

Materializes one single-chunk GPUVector synchronously. This is useful for call sites that must stay synchronous, but it is stricter than evaluate():

  • backend lookup must already be resolved
  • dependencies are evaluated recursively without awaiting
  • any required CPU value must already be available

If those conditions are not met, evaluateSync() throws.

readValue(startRow?: number, endRow?: number): Promise<TypedArray>

Reads evaluator contents back to the CPU. This is intended for debugging or inspection and may be slower than staying on the GPU.

destroy(): void

Releases cached GPU storage owned by this evaluator and prevents future evaluation.

GPUVectorEvaluator

GPUVectorEvaluator is the official GPUVector path. It wraps ordered GPUDataEvaluator chunks and materializes one output GPUVector with the same chunk boundaries.

Static Methods

GPUVectorEvaluator.fromGPUVector(vector): GPUVectorEvaluator

Creates one chunk-preserving evaluator over a fixed-width GPUVector. The vector must have at least one GPUData chunk and must not be interleaved.

GPUVectorEvaluator.fromGPUDataEvaluators(evaluators, options?): GPUVectorEvaluator

Creates one vector evaluator from already-built ordered chunk evaluators.

Methods

mapGPUData(transform): GPUVectorEvaluator

Applies one lazy GPUDataEvaluator transform independently to each preserved chunk. Use this for row-local streaming transforms that should not repack source batches.

evaluate(device: Device, options?): Promise<GPUVector>

Materializes every chunk evaluator and returns one GPUVector with preserved chunk order and boundaries.

evaluateSync(device: Device, options?): GPUVector

Synchronously materializes every chunk evaluator and returns one GPUVector with preserved chunk order and boundaries. This has the same synchronous requirements as GPUDataEvaluator.evaluateSync().

destroy(): void

Releases cached GPU resources owned through child GPUDataEvaluator instances.

Remarks

  • Leaf operations accept GPUDataEvaluator, GPUData, or GPUDataView, not GPUVector.
  • Use GPUVectorEvaluator.fromGPUVector(vector).mapGPUData(...) for vector-wide transforms that should preserve streaming chunks.
  • GPUDataEvaluator operation outputs own their materialized single-chunk GPUVector backing resource.
  • Borrowed GPUData chunks are not destroyed by GPUDataEvaluator.destroy().
  • Borrowed GPUDataView buffers are not destroyed by GPUDataEvaluator.destroy().
  • Synchronous evaluation is intended for already-prepared graphs where backend registration and any required CPU values are available up front.