GPU.js - GPU Accelerated JavaScript
GPU.js is a JavaScript library designed for General Purpose computing on Graphics Processing Units (GPGPU), enabling high-performance numerical computations in both web browsers and Node.js environments. It achieves this by automatically transpiling ordinary JavaScript functions into shader language (e.g., GLSL for WebGL) which then executes directly on the GPU, leveraging parallel processing capabilities for significant speedups, often 1-15x faster than CPU-bound operations. The library includes a robust fallback mechanism, ensuring that if a GPU is unavailable, computations seamlessly revert to standard JavaScript execution on the CPU. The current stable version is 2.16.0, with recent releases primarily focusing on maintenance, bug fixes (including security and memory leak issues in earlier 2.x versions), and performance enhancements. A key differentiator is its abstraction over complex shader programming, allowing developers to write GPU-accelerated code using familiar JavaScript syntax and a `this.thread.x/y/z` model for accessing thread indices within the kernel.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'x')
cause Attempting to access `this.thread.x` (or `y`/`z`) outside of a GPU.js kernel function, or when `this` context is incorrectly bound.fixEnsure `this.thread` is only accessed within the callback function passed to `gpu.createKernel()` or a function called by it that was added via `gpu.addFunction()`. -
WebGL: INVALID_VALUE: texImage2D: width or height is 0
cause The output dimensions specified in `.setOutput()` resulted in a zero-dimension texture, or input arrays were empty/invalid.fixVerify that the arguments passed to `.setOutput([width, height, depth])` are positive integers reflecting the desired output size of the computation. Also, check input array dimensions. -
Error: Function 'someFunction' is not supported.
cause A JavaScript function or method called inside the kernel could not be transpiled into an equivalent GLSL shader function by GPU.js.fixReview the list of supported Math methods and language features in the GPU.js documentation. For custom functions, use `gpu.addFunction()` to provide a transpilable implementation or refactor the logic to use supported operations. -
Error: GLSL failed to compile
cause The transpiled GLSL code for the kernel contains syntax errors or uses unsupported features for the target WebGL environment, often due to complex JavaScript logic that can't be directly translated.fixSimplify the kernel logic. Avoid complex closures, object manipulations, or unsupported data structures within the kernel. Enable debugging (`gpu.setDebug(true)`) and check browser console logs for detailed GLSL compilation errors.
Warnings
- breaking GPU.js v2 introduced new concepts around 'pipelining' for chaining kernels efficiently and explicit texture cloning/cleanup. While these were performance features, they implied new memory management considerations for users chaining kernels, specifically regarding `cleanupPipelineTextureMemory()`.
- gotcha External functions (functions not defined within the kernel's scope) cannot be directly called from within a `createKernel` function. The kernel's body is transpiled to GLSL, which does not have access to the surrounding JavaScript scope.
- gotcha The `this` context inside a GPU.js kernel function (`createKernel` callback) refers to the GPU thread's properties (`this.thread.x`, `this.thread.y`, `this.thread.z`) and not the surrounding JavaScript context. Accessing external variables directly from `this` will fail.
- breaking Versions 2.8.4 and 2.8.5 addressed significant memory leaks related to texture deallocation. Earlier versions could consume excessive GPU memory, especially with frequent kernel runs or pipeline usage, potentially leading to performance degradation or crashes.
- breaking Version 2.8.3 included a fix for a security issue. Details are not publicly disclosed beyond 'Fix Security Issue' in the release notes, but users on older versions are advised to upgrade for security patching.
Install
-
npm install gpu.js -
yarn add gpu.js -
pnpm add gpu.js
Imports
- GPU
const GPU = require('gpu.js');import { GPU } from 'gpu.js'; - GPU (browser global)
import { GPU } from 'gpu.js';const gpu = new GPU();
- IKernelFunction
import { IKernelFunction } from 'gpu.js';
Quickstart
import { GPU } from 'gpu.js';
// Initialize GPU.js
const gpu = new GPU();
// Define two 512x512 matrices for multiplication
const matrixA = Array(512).fill(0).map(() => Array(512).fill(Math.random()));
const matrixB = Array(512).fill(0).map(() => Array(512).fill(Math.random()));
// Create a GPU accelerated kernel function for matrix multiplication
const multiplyMatrix = gpu.createKernel(function(a: number[][], b: number[][]) {
let sum = 0;
for (let i = 0; i < 512; i++) {
// this.thread.x and this.thread.y represent the current thread's coordinates
sum += a[this.thread.y][i] * b[i][this.thread.x];
}
return sum;
}).setOutput([512, 512]); // Define the output dimensions of the kernel
// Run the kernel with the input matrices
const c = multiplyMatrix(matrixA, matrixB) as number[][];
console.log('Matrix multiplication completed on GPU (or CPU fallback).');
console.log('Resulting matrix dimensions:', c.length, 'x', c[0].length);
// For a real application, you'd inspect 'c' for results.