Skip to content

AICL-Lab/gpu-fft

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

62 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

WebGPU FFT Library

npm version TypeScript WebGPU License: MIT CI Docs

English | ็ฎ€ไฝ“ไธญๆ–‡

High-performance GPU-accelerated Fast Fourier Transform library for JavaScript/TypeScript. The package combines a WebGPU FFT core, real-input RFFT/IRFFT APIs, and CPU-based utilities for spectrum analysis and frequency-domain image filtering, all with zero runtime dependencies.

โšก Why WebGPU FFT?

webgpu-fft cpu-only libs Python (numpy)
GPU Acceleration โœ… WebGPU shaders โŒ CPU only โŒ CPU only
Real-input FFT APIs โœ… RFFT / IRFFT / 2D RFFT Varies Varies
Frequency Filtering โœ… Built-in (CPU utility) Manual Manual
Spectrum Analysis โœ… Built-in (CPU utility) Manual Manual
Browser Native โœ… No WASM โœ… โŒ Server
Zero Dependencies โœ… โœ… โŒ
TypeScript โœ… Strict mode Varies โŒ

Measured performance depends on your hardware and runtime. Use the repository benchmark to collect CPU and WebGPU results in your current environment.

๐Ÿš€ Quick Start

Installation

npm install webgpu-fft

Basic 1D FFT

import { createFFTEngine } from 'webgpu-fft';

const engine = await createFFTEngine();

// Input: interleaved [real, imag, real, imag, ...]
const signal = new Float32Array(8 * 2);
for (let i = 0; i < 8; i++) {
  signal[i * 2] = Math.sin(i);   // Real
  signal[i * 2 + 1] = 0;         // Imag
}

const spectrum = await engine.fft(signal);
const recovered = await engine.ifft(spectrum);

engine.dispose(); // Release GPU resources

CPU Fallback (No GPU Required)

import { cpuFFT, cpuIFFT } from 'webgpu-fft';

const spectrum = cpuFFT(signal);
const recovered = cpuIFFT(spectrum);

Real-Valued FFT (RFFT / IRFFT)

import { createFFTEngine, createRealFFTBackend, CPUFFTBackend } from 'webgpu-fft';

const realSignal = new Float32Array([0, 1, 0, -1, 0, 1, 0, -1]);

// CPU path
const cpuRealFFT = createRealFFTBackend(new CPUFFTBackend());
const cpuSpectrum = cpuRealFFT.rfft(realSignal); // N / 2 + 1 complex bins
const cpuRecovered = cpuRealFFT.irfft(cpuSpectrum);

// GPU path
const engine = await createFFTEngine();
const gpuSpectrum = await engine.rfft(realSignal);
const gpuRecovered = await engine.irfft(gpuSpectrum);
engine.dispose();

๐Ÿ“Š Performance

Run the repository benchmark to collect measured results for your current runtime:

npm run benchmark

The benchmark reports:

  • measured CPU FFT results in every environment
  • measured WebGPU FFT results only when WebGPU is actually available
  • no speculative or static โ€œexpected performanceโ€ section

๐ŸŽฏ Use Cases

Audio Spectrum Analysis

import { createSpectrumAnalyzer, WindowType } from 'webgpu-fft';

const analyzer = createSpectrumAnalyzer({
  fftSize: 2048,
  windowType: WindowType.Hann,
  sampleRate: 44100,
});

const audioBuffer = new Float32Array(2048);
// ... fill from Web Audio API ...

const spectrum = analyzer.analyze(audioBuffer); // dB values per bin
const frequencies = analyzer.getFrequencies();  // Hz per bin

Note: createSpectrumAnalyzer() is currently CPU-only and does not use the GPU FFT path internally.

Frequency-Domain Image Filtering

import { createImageFilter } from 'webgpu-fft';

const filter = await createImageFilter({
  type: 'lowpass',
  shape: 'gaussian',
  cutoffFrequency: 0.3,
});

// Low-pass filter (blur)
const blurred = await filter.apply(imageData, 512, 512);

// High-pass filter (edge detection)
const edgeFilter = await createImageFilter({
  type: 'highpass',
  shape: 'gaussian',
  cutoffFrequency: 0.1,
});
const edges = await edgeFilter.apply(imageData, 512, 512);

filter.dispose();

Note: createImageFilter() is currently CPU-only and uses the CPU 2D FFT implementation internally.

๐Ÿ“– API Overview

Core Engine

Method Description Max Size
fft(data) 1D forward FFT 65,536
ifft(data) 1D inverse FFT 65,536
rfft(data) 1D real-input FFT 65,536 real samples
irfft(data) 1D inverse real-input FFT 65,536 real samples
fft2d(data, w, h) 2D forward FFT 2048ร—2048
ifft2d(data, w, h) 2D inverse FFT 2048ร—2048
rfft2d(data, w, h) 2D real-input FFT 2048ร—2048 real samples
irfft2d(data, w, h) 2D inverse real-input FFT 2048ร—2048 real samples
dispose() Release GPU resources -

Utilities

API Purpose
cpuFFT() / cpuIFFT() CPU-based FFT fallback
createRealFFTBackend() Upgrade any complex FFT backend to the RealFFTBackend seam
cpuRFFT() / cpuIRFFT() CPU real-input FFT shortcuts
cpuRFFT2D() / cpuIRFFT2D() CPU 2D real-input FFT shortcuts
createSpectrumAnalyzer() Real-time audio analysis (CPU-only utility)
createImageFilter() Frequency-domain filtering (CPU-only utility)
isWebGPUAvailable Check GPU support
Window functions Hann, Hamming, Blackman, FlatTop, Rectangular
Complex utilities Add, Mul, Magnitude, Twiddle factors

Input Formats

Complex FFT APIs expect interleaved complex data:

// [realโ‚€, imagโ‚€, realโ‚, imagโ‚, realโ‚‚, imagโ‚‚, ...]
const data = new Float32Array([1, 0, 2, 0, 3, 0, 4, 0]);
// Represents: 1+0i, 2+0i, 3+0i, 4+0i

Real-input FFT APIs accept plain real-valued Float32Array samples and return compressed half-spectrum complex data.

Error Handling

import { FFTError } from 'webgpu-fft';

try {
  await engine.fft(invalidData);
} catch (error) {
  if (error instanceof FFTError) {
    console.error(`[${error.code}] ${error.message}`);
  }
}

๐Ÿ“š Complete API Reference: See the documentation site for detailed function signatures, types, and examples.

๐ŸŒ Browser Compatibility

Browser Version GPU CPU
Chrome 113+ โœ… Stable โœ…
Edge 113+ โœ… Stable โœ…
Firefox 128+ โœ… Stable โœ…
Safari 17+ โš ๏ธ Preview โœ…

Tip: Use isWebGPUAvailable to detect support at runtime and gracefully fallback to CPU when needed.

๐Ÿ“ฆ Package Info

Metric Value
Bundle Size (ESM) ~27 kB
Bundle Size (CJS) ~22 kB
Runtime Deps 0
Node Version โ‰ฅ18.0.0
Exports ESM + CJS + Types

๐Ÿงช Development

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Run with coverage
npm run test:coverage

# Lint & format
npm run lint:fix
npm run format

# Run benchmarks
npm run benchmark

# Local docs
npm run docs:dev

# Local demo
npx serve examples/web

๐Ÿ” Troubleshooting

Issue Solution
WebGPU is not available Update browser, or use cpuFFT fallback
Input size must be power of 2 Pad or truncate to nearest power of 2
Input size exceeds maximum Split data or use CPU implementation
Slow first run Shader compilation overhead โ€” reuse engine

๐Ÿ“– Full troubleshooting guide: Documentation โ†’ Troubleshooting

๐Ÿ—บ๏ธ Roadmap

  • 3D FFT support
  • Real-valued FFT APIs (initial contract-first implementation)
  • GPU-native image filtering
  • Convolution operations
  • WASM fallback

๐Ÿค Contributing

Contributions welcome! Read the Contributing Guide and Code of Conduct.

This project follows OpenSpec-driven development โ€” see openspec/specs/ for the canonical repository specifications and change workflow.

๐Ÿ“„ License

MIT ยฉ WebGPU FFT Library Contributors

๐Ÿ™ Acknowledgments

About

WebGPU FFT core for JavaScript/TypeScript with 1D/2D and real-input transforms, plus CPU utilities. Zero runtime dependencies.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors