deepbox/core
Config & Backends
Global defaults for dtype, device and seed, and the backend registry that decides where tensors can live.
- Config
- Backends
Overview
getConfig()returns{ defaultDtype, defaultDevice, seed }, which start asfloat32,cpuandnull.setConfigvalidates every key before it changes anything and rejects unknown keys.resetConfig()restores the defaults and clears the seed.- The seed belongs to the global random generator, so
setSeedhere andsetSeedindeepbox/randomset the same stream.setConfigreseeds only when you passseed. Changing the dtype or device does not disturb a running stream. With no seed set,getSeed()returnsnullhere andundefinedindeepbox/random. - Only the CPU backend is registered at load time.
WasmBackendandWebGpuBackendare opt-in: create the backend,await backend.init(), checkbackend.info().available, then callregisterBackend.init()does not throw when the runtime lacks support. setDeviceandsetConfig({ defaultDevice })throwDeviceErrorunless that device has a registered backend that reports itself available.listBackends,getBackendandisBackendAvailableinspect the registry, andunregisterBackendremoves an entry.- Tensors change device only through explicit moves,
await t.to(device)andawait t.cpu(). Which operations run on a device is covered in Devices & Execution.
Backend
interfaceThe interface every Deepbox execution backend must implement.
Backends additionally implementing KernelBackend (device-memory kernels, e.g. WebGpuBackend) or HostAcceleratorBackend (host-memory SIMD kernels, e.g. WasmBackend) are picked up automatically by the ndarray dispatch layer once registered. The CPU backend ships as the always-available reference implementation.
info(): BackendInfoReturns static information about this backend.
supports(cap: BackendCapability): booleanReturns
trueif the backend supports the given capability.init(): Promise<void>Perform any async initialisation the backend requires.
dispose(): voidRelease any resources held by the backend.
BackendCapability
typeCapability flags that a backend may support.
Consumers can query these before dispatching work to avoid runtime surprises on unsupported devices.
type BackendCapability = "matmul" | "conv2d" | "fft" | "reduction" | "elementwise" | "blas" | "random";BackendInfo
typeInformation about a registered backend.
readonly device: DeviceThe device this backend serves.
readonly name: stringHuman-readable name (e.g.
readonly available: booleanWhether this backend is currently available in the runtime.
readonly capabilities: readonly BackendCapability[]Capabilities this backend supports.
BinaryKernelOp
typeBinary element-wise kernels a backend may execute.
type BinaryKernelOp = "add" | "sub" | "mul" | "div" | "pow" | "maximum" | "minimum";CompiledWasmModule
typeA compiled WASM SIMD module with its exports.
readonly name: WasmModuleNamereadonly instance: WebAssembly.Instancereadonly memory: WebAssembly.Memory
DeviceBuffer
typeOpaque handle to memory owned by a KernelBackend.
The handle is created by the backend (upload, fill, or as a kernel output) and must be released with free when no longer referenced. Tensors wrap these handles and free them automatically via a finalization registry, but deterministic release via Tensor.dispose() is recommended for large buffers.
readonly device: DeviceDevice that owns this buffer.
readonly byteLength: numberSize of the buffer's payload in bytes.
readonly size: numberNumber of elements in the buffer.
readonly dtype?: DeviceDTypeElement type of the buffer.
DeviceDType
typeElement type of a DeviceBuffer.
float32 is the default (an absent/undefined dtype on a buffer means float32, so all existing code keeps working). float16 is true on-device IEEE-754 half precision (2 bytes/element, requires the WebGPU shader-f16 feature). bfloat16 gives correct bfloat16 numerics to the user via rounding at upload/download while computing on-device in float32, so the WebGPU backend stores it in 4 bytes/element (see Devices & execution).
type DeviceDType = "float32" | "float16" | "bfloat16";GpuPipelineInfo
typeInformation about a compiled GPU pipeline.
readonly name: ShaderNamereadonly workgroupSize: number
HostAcceleratorBackend
interfaceExecution interface for host-accelerator backends (e.g. WASM SIMD).
Host accelerators share the CPU address space: tensors on their device keep ordinary TypedArray storage, eligible ops run through the accelerator, and everything else uses the normal CPU implementation. That fallback is safe as long as the accelerator's results are bit-identical IEEE-754 float32 arithmetic, which element-wise add, sub, mul and div are.
binaryContiguous(op: HostBinaryOp, a: Float32Array, b: Float32Array): Float32Array | nullElement-wise
a OP bover contiguous float32 arrays.
HostBinaryOp
typeBinary ops a host accelerator may run over contiguous float32 data.
type HostBinaryOp = "add" | "sub" | "mul" | "div";Im2ColParams
typeGeometry of a 2-D convolution unfold/fold (im2col/col2im), all in elements. The input is [batch, channels, height, width]; the unfolded columns are [batch, outH*outW, channels*kH*kW], laid out for a [channels*kH*kW, outChannels] weight matmul.
readonly batch: numberreadonly channels: numberreadonly height: numberreadonly width: numberreadonly outH: numberreadonly outW: numberreadonly kH: numberreadonly kW: numberreadonly strideH: numberreadonly strideW: numberreadonly padH: numberreadonly padW: number
KernelBackend
interfaceExecution interface for accelerated (non-CPU) backends.
Implementations execute kernels over DeviceBuffer memory. All kernels are synchronous from the caller's perspective: they enqueue device work and return a handle immediately. The only asynchronous operation is download, which must wait for in-flight work targeting the buffer to complete before resolving (WebGPU readback is inherently async, which is why Tensor.to('cpu') returns a promise).
Register an implementation with registerBackend(device, backend); the ndarray dispatch layer picks it up automatically for tensors created on (or moved to) that device.
upload(data: Float32Array, dtype?: DeviceDType): DeviceBufferCopy host data into new device memory.
download(buffer: DeviceBuffer): Promise<Float32Array>Copy device memory back to the host.
free(buffer: DeviceBuffer): voidRelease device memory.
fill(value: number, size: number, dtype?: DeviceDType): DeviceBufferAllocate a buffer of
sizeelements filled withvalue.binary(op: BinaryKernelOp, a: DeviceBuffer, aLayout: KernelLayout, b: DeviceBuffer, bLayout: KernelLayout, outShape: readonly number[]): DeviceBufferBroadcast-aware binary element-wise kernel.
unary(op: UnaryKernelOp, x: DeviceBuffer, layout: KernelLayout): DeviceBufferStrided unary element-wise kernel.
matmul(a: DeviceBuffer, aLayout: KernelLayout, b: DeviceBuffer, bLayout: KernelLayout): DeviceBuffer2-D matrix multiply:
[m, k] @ [k, n] -> [m, n].reduce(op: ReduceKernelOp, x: DeviceBuffer, layout: KernelLayout): DeviceBufferFull reduction over all elements.
reduceAxis(op: ReduceKernelOp, x: DeviceBuffer, layout: KernelLayout, axis: number): DeviceBufferReduction along a single axis.
matmulBatched(a: DeviceBuffer, aLayout: KernelLayout, b: DeviceBuffer, bLayout: KernelLayout, batch: number, m: number, k: number, n: number): DeviceBufferBatched matrix multiply:
[..., m, k] @ [..., k, n] -> [..., m, n]where the leading batch dimensions match.ternary(op: TernaryKernelOp, cond: DeviceBuffer, condLayout: KernelLayout, a: DeviceBuffer, aLayout: KernelLayout, b: DeviceBuffer, bLayout: KernelLayout, outShape: readonly number[]): DeviceBufferBroadcast-aware ternary select.
im2col(x: DeviceBuffer, layout: KernelLayout, params: Im2ColParams): DeviceBuffer2-D convolution unfold.
col2im(cols: DeviceBuffer, params: Im2ColParams): DeviceBufferAdjoint of im2col: scatter-adds a contiguous
[batch, outH*outW, channels*kH*kW]column buffer back into a contiguous[batch, channels, height, width]image, summing overlapping window contributions.pool2d(x: DeviceBuffer, layout: KernelLayout, op: PoolKernelOp, params: Im2ColParams): DeviceBuffer2-D pooling over a
[batch, channels, height, width]input, producing a contiguous[batch, channels, outH, outW]buffer.pool2dBackward(x: DeviceBuffer, xLayout: KernelLayout, gradOut: DeviceBuffer, op: PoolKernelOp, params: Im2ColParams): DeviceBufferBackward of pool2d.
KernelLayout
typeExplicit memory layout of one kernel operand.
Strides and offset are measured in elements (not bytes). A dimension broadcast to the output shape is expressed with stride 0.
readonly shape: readonly number[]readonly strides: readonly number[]readonly offset: number
PoolKernelOp
type2-D pooling kernels a backend may execute.
type PoolKernelOp = "max" | "avg";ReduceKernelOp
typeFull-tensor reduction kernels a backend may execute.
type ReduceKernelOp = "sum" | "mean" | "max" | "min";ShaderName
typeAvailable shader names.
type ShaderName = keyof typeof WGSL_SHADERS;TernaryKernelOp
typeTernary element-wise kernels a backend may execute. where selects a where the condition (first operand) is non-zero, else b.
type TernaryKernelOp = "where";UnaryKernelOp
typeUnary element-wise kernels a backend may execute. copy materializes a strided view; step is the Heaviside step (1 where x > 0, else 0), used by autograd for the relu backward mask.
type UnaryKernelOp = "copy" | "step" | "neg" | "abs" | "exp" | "log" | "sqrt" | "square" | "relu" | "sigmoid" | "tanh" | "gelu" | "erf" | "rsqrt" | "reciprocal" | "sign" | "expm1" | "log1p" | "softplus";WasmModuleName
typeAvailable WASM module names.
type WasmModuleName = keyof typeof WAT_MODULES;WASM_BINARIES
constconst WASM_BINARIES: Record<WasmModuleName, string>;WAT_MODULES
constconst WAT_MODULES: { readonly simdAdd: "(module\n (import \"env\" \"memory\" (memory 1))\n (func (export \"run\") (param $a i32) (param $b i32) (param $out i32) (param $count i32)\n (local $i i32)\n (loca…WGSL_SHADERS
constconst WGSL_SHADERS: Record<string, string>;DeepboxConfig
typeGlobal configuration for Deepbox.
readonly defaultDtype: DTypereadonly defaultDevice: Devicereadonly seed: number | null
CpuBackend
The built-in CPU execution backend.
Supports all capabilities and requires no async initialisation. It holds no resources, so it stays available after CpuBackend.dispose: disposing it only sets CpuBackend.isDisposed. Otherwise one stray dispose() call on the registered CPU backend would make every tensor operation fail.
Members (5)
isDisposed: booleanReturns
trueafter dispose has been called.info(): BackendInfosupports(cap: BackendCapability): booleaninit(): Promise<void>dispose(): voidMarks the backend as disposed.
WasmBackend
WASM SIMD execution backend.
init() feature-detects WASM SIMD and instantiates the embedded kernel binaries over one shared memory; afterwards info().available is true and registering the backend (registerBackend('wasm', backend)) lets contiguous float32 arithmetic on wasm-device tensors run through the SIMD kernels.
import { WasmBackend, registerBackend } from 'deepbox/core';import { tensor, add } from 'deepbox/ndarray'; const wasm = new WasmBackend();await wasm.init();if (wasm.info().available) { registerBackend('wasm', wasm); const a = tensor([1, 2, 3, 4], { device: 'wasm' }); const b = add(a, a); // eligible ops use WASM SIMD}Members (13)
isInitialized: booleanWhether the backend has been successfully initialized.
isDisposed: booleanWhether WasmBackend.dispose has been called.
info(): BackendInfosupports(cap: BackendCapability): booleaninit(): Promise<void>Compile and instantiate the embedded SIMD kernel modules.
binaryContiguous(op: HostBinaryOp, a: Float32Array, b: Float32Array): Float32Array | nullElement-wise
a OP bover contiguous float32 data using SIMD.dotContiguous(a: Float32Array, b: Float32Array): number | nullSIMD dot product over contiguous float32 data.
sumContiguous(a: Float32Array): number | nullSIMD sum over contiguous float32 data (same accumulation caveats as WasmBackend.dotContiguous).
hasModule(name: WasmModuleName): booleanCheck if a specific WASM module is compiled and ready.
getModule(name: WasmModuleName): CompiledWasmModule | undefinedGet a compiled WASM module by name.
listModules(): WasmModuleName[]List all available WAT module names.
isSimdSupported(): booleanCheck if the current runtime supports WASM with SIMD.
dispose(): voidRelease the compiled modules and the shared memory.
WebGpuBackend
WebGPU execution backend.
Detects WebGPU availability during init() and executes the built-in float32 tensor kernels (KernelBackend) on the GPU. Buffers are pooled and reused; call WebGpuBackend.dispose to release everything.
import { WebGpuBackend, registerBackend } from 'deepbox/core';import { dot, tensor } from 'deepbox/ndarray'; const gpu = new WebGpuBackend();await gpu.init();if (gpu.info().available) { registerBackend('webgpu', gpu); const a = tensor([[1, 2], [3, 4]], { device: 'webgpu' }); const b = dot(a, a); // executes on the GPU const host = await b.cpu(); // read the result back}Members (28)
constructor(options?: { readonly gpu?: GpuLike; })isDisposed: booleanWhether WebGpuBackend.dispose has been called.
info(): BackendInfosupports(cap: BackendCapability): booleaninit(): Promise<void>Initialize the WebGPU backend.
supportsF16(): booleanWhether this backend can execute true on-device float16 kernels.
upload(data: Float32Array, dtype?: DeviceDType): DeviceBufferdownload(buffer: DeviceBuffer): Promise<Float32Array>free(buffer: DeviceBuffer): voidfill(value: number, size: number, dtype?: DeviceDType): DeviceBufferbinary(op: BinaryKernelOp, a: DeviceBuffer, aLayout: KernelLayout, b: DeviceBuffer, bLayout: KernelLayout, outShape: readonly number[]): DeviceBufferunary(op: UnaryKernelOp, x: DeviceBuffer, layout: KernelLayout): DeviceBuffermatmul(a: DeviceBuffer, aLayout: KernelLayout, b: DeviceBuffer, bLayout: KernelLayout): DeviceBufferreduce(op: ReduceKernelOp, x: DeviceBuffer, layout: KernelLayout): DeviceBufferreduceAxis(op: ReduceKernelOp, x: DeviceBuffer, layout: KernelLayout, axis: number): DeviceBuffermatmulBatched(a: DeviceBuffer, aLayout: KernelLayout, b: DeviceBuffer, bLayout: KernelLayout, batch: number, m: number, k: number, n: number): DeviceBufferternary(op: TernaryKernelOp, cond: DeviceBuffer, condLayout: KernelLayout, a: DeviceBuffer, aLayout: KernelLayout, b: DeviceBuffer, bLayout: KernelLayout, outShape: readonly number[]): DeviceBufferim2col(x: DeviceBuffer, layout: KernelLayout, params: Im2ColParams): DeviceBuffercol2im(cols: DeviceBuffer, params: Im2ColParams): DeviceBufferpool2d(x: DeviceBuffer, layout: KernelLayout, op: PoolKernelOp, params: Im2ColParams): DeviceBufferpool2dBackward(x: DeviceBuffer, xLayout: KernelLayout, gradOut: DeviceBuffer, op: PoolKernelOp, params: Im2ColParams): DeviceBuffergetPipeline(name: ShaderName): GpuComputePipeline | nullGet or create a compute pipeline for the given shader.
createBuffer(data: Float32Array, usage: number): GpuBuffer | nullCreate a GPU buffer from a Float32Array (advanced usage).
readBuffer(buffer: GpuBuffer, size: number): Promise<Float32Array>Read data back from a GPU buffer (advanced usage).
getDevice(): GpuDevice | nullGet the underlying GPU device (for advanced usage).
listPipelines(): GpuPipelineInfo[]List all compiled shader pipelines.
listShaders(): ShaderName[]List all available built-in shader names.
dispose(): voidDestroy the pooled buffers and the GPU device.
getBackend
function getBackend(device: Device): Backend;Retrieve the backend for the given device.
Parameters
deviceDevice- Target device
Returns
BackendThe registered backend
Throws
DeviceErrorIf no backend is registered for the device
import { getBackend } from 'deepbox/core'; const cpu = getBackend('cpu');console.log(cpu.info().name); // "Deepbox CPU Backend"getHostAccelerator
function getHostAccelerator(device: Device): HostAcceleratorBackend | null;Retrieve the host-accelerator backend for a device, or null when the device has no registered, available backend implementing that surface.
Parameters
deviceDevice- Target device
Returns
HostAcceleratorBackend | nullThe host-accelerator backend, or null
getKernelBackend
function getKernelBackend(device: Device): KernelBackend | null;Retrieve the kernel-capable backend for a device, or null when the device has no registered backend, the backend is unavailable, or it does not implement the KernelBackend execution surface.
Used by the ndarray dispatch layer to route ops on non-CPU tensors.
Parameters
deviceDevice- Target device
Returns
KernelBackend | nullThe kernel backend, or null
isBackendAvailable
function isBackendAvailable(device: Device): boolean;Check whether a backend is registered and available for the device.
Parameters
deviceDevice- Device to check
Returns
booleantrue if a backend is registered and reports itself as available
isHostAcceleratorBackend
function isHostAcceleratorBackend(backend: Backend): backend is HostAcceleratorBackend;Type guard for the HostAcceleratorBackend surface.
Parameters
backendBackend- Backend to test
Returns
backend is HostAcceleratorBackendtrue if the backend exposes host-accelerator kernels
isKernelBackend
function isKernelBackend(backend: Backend): backend is KernelBackend;Type guard for the KernelBackend execution surface.
Parameters
backendBackend- Backend to test
Returns
backend is KernelBackendtrue if the backend exposes device kernels
listBackends
function listBackends(): Device[];List all currently registered devices with backends.
Returns
Device[]Array of device identifiers
registerBackend
function registerBackend(device: Device, backend: Backend): void;Register a new backend for a device.
If a backend was previously registered for the same device it is replaced (the old backend is not automatically disposed). Register the backend after await backend.init(): tensors can only be created on a device whose backend reports info().available === true.
Parameters
deviceDevice- Device the backend serves
backendBackend- Backend implementation
Throws
InvalidParameterErrorIfdeviceis not a known device orbackenddoes not implement the Backend interface
import { WasmBackend, registerBackend } from 'deepbox/core'; const wasm = new WasmBackend();await wasm.init();registerBackend('wasm', wasm);unregisterBackend
function unregisterBackend(device: Device): boolean;Remove a registered backend.
The backend is not disposed. Call backend.dispose() yourself if it holds resources. The CPU backend is mandatory and cannot be unregistered.
Parameters
deviceDevice- Device whose backend should be removed
Returns
booleantrue if a backend was removed, false if none was registered
Throws
DeviceErrorWhen attempting to unregister the CPU backend
getConfig
function getConfig(): Readonly<DeepboxConfig>;Get the current global configuration.
Returns a copy of the configuration to prevent external mutation.
Returns
Readonly<DeepboxConfig>Current configuration object
import { getConfig } from 'deepbox/core'; const config = getConfig();console.log(config.defaultDtype); // 'float32'getDevice
function getDevice(): Device;Get the current default device.
Returns
DeviceCurrent default device
getDtype
function getDtype(): DType;Get the current default data type.
Returns
DTypeCurrent default dtype
getSeed
function getSeed(): number | null;Get the current random seed.
Returns
number | nullCurrent seed value or null if not set
resetConfig
function resetConfig(): void;Reset configuration to default values.
Also clears the global random seed.
import { resetConfig } from 'deepbox/core'; resetConfig(); // Back to defaultssetConfig
function setConfig(next: Partial<DeepboxConfig>): void;Update global configuration.
Merges provided settings with current configuration. Only specified fields are updated. All values are validated before any of them is applied, so a failing call leaves the configuration unchanged. The random generator is re-seeded only when seed is part of the update; changing the dtype or device does not disturb a running random stream.
Parameters
nextPartial<DeepboxConfig>- Partial configuration to merge
Throws
DataValidationErrorIf config is invalid or contains unknown keys
import { setConfig } from 'deepbox/core'; setConfig({ defaultDtype: 'float64', seed: 42});setDevice
function setDevice(device: Device): void;Set the default compute device for new tensors and other device-aware APIs.
Parameters
deviceDevice- Device to use ('cpu', 'webgpu', or 'wasm')
Throws
DataValidationErrorIf device is not a supported identifierDeviceErrorIf no backend is registered for the device or it reports unavailable
import { registerBackend, setDevice, WebGpuBackend } from 'deepbox/core'; setDevice('cpu'); // Use CPU for all operations (default) // With a registered GPU backend, new tensors default to GPU memory:const gpu = new WebGpuBackend();await gpu.init();if (gpu.info().available) { registerBackend('webgpu', gpu); setDevice('webgpu');}setDtype
function setDtype(dtype: DType): void;Set the default data type for new tensors.
Parameters
dtypeDType- Data type to use as default
Throws
DataValidationErrorIf dtype is not supported
import { setDtype } from 'deepbox/core'; setDtype('float64'); // Use double precision by defaultsetSeed
function setSeed(seed: number): void;Set the global random seed for reproducibility.
Parameters
seednumber- Integer seed value (negative values and zero are allowed)
Throws
DataValidationErrorIf seed is not a safe integer
import { setSeed } from 'deepbox/core'; setSeed(42); // All random operations now reproducibleimport { getBackend, getConfig, isBackendAvailable, listBackends, resetConfig, setConfig, setSeed,} from "deepbox/core"; setConfig({ defaultDtype: "float64", seed: 42 });console.log(getConfig()); // { defaultDtype: "float64", defaultDevice: "cpu", seed: 42 } setSeed(7); // the same seed that deepbox/random usesconsole.log(getConfig().seed); // 7 console.log(listBackends()); // ["cpu"]console.log(isBackendAvailable("webgpu")); // false until a backend is registeredconsole.log(getBackend("cpu").info().name); resetConfig();Found a mistake? Open an issue.