Skip to content

Latest commit

 

History

History
445 lines (331 loc) · 11.8 KB

File metadata and controls

445 lines (331 loc) · 11.8 KB

TypeScript + WASM + Parallel Computing Architecture

This document describes the refactored mathjs architecture that supports TypeScript, WebAssembly (WASM), and parallel/multicore computing.

Overview

The refactored architecture provides three tiers of performance optimization:

  1. JavaScript Fallback - Compatible with all environments
  2. WASM Acceleration - 2-10x performance improvement for large operations
  3. Parallel/Multicore - Additional 2-4x speedup on multi-core systems

Architecture Components

1. TypeScript Infrastructure

Configuration Files

  • tsconfig.json - Type checking only (existing)
  • tsconfig.build.json - Compilation configuration for TypeScript source
  • tsconfig.wasm.json - AssemblyScript configuration for WASM compilation

Directory Structure

src/
  ├── parallel/          # Parallel computing infrastructure
  │   ├── WorkerPool.ts      # Web Worker pool manager
  │   ├── ParallelMatrix.ts  # Parallel matrix operations
  │   └── matrix.worker.ts   # Matrix computation worker
  ├── wasm/              # WASM integration layer
  │   ├── WasmLoader.ts      # WASM module loader
  │   └── MatrixWasmBridge.ts # Bridge between JS and WASM
  └── [existing JS files]

src-wasm/              # WASM source (AssemblyScript)
  ├── matrix/
  │   └── multiply.ts      # WASM matrix operations
  ├── algebra/
  │   └── decomposition.ts # WASM linear algebra
  ├── signal/
  │   └── fft.ts          # WASM signal processing
  └── index.ts           # WASM entry point

lib/                   # Compiled output
  ├── cjs/             # CommonJS (existing)
  ├── esm/             # ES Modules (existing)
  ├── typescript/      # Compiled TypeScript
  ├── wasm/            # Compiled WASM modules
  │   ├── index.wasm       # Release build
  │   └── index.debug.wasm # Debug build
  └── browser/         # Browser bundle (existing)

2. WASM Compilation Pipeline

Build Process

src-wasm/*.ts
    ↓ (AssemblyScript compiler)
lib/wasm/index.wasm
    ↓ (WasmLoader.ts)
JavaScript/TypeScript code

WASM Modules

Matrix Operations (src-wasm/matrix/multiply.ts)

  • multiplyDense - Cache-optimized blocked matrix multiplication
  • multiplyDenseSIMD - SIMD-accelerated multiplication (2x faster)
  • multiplyVector - Matrix-vector multiplication
  • transpose - Cache-friendly blocked transpose
  • add, subtract, scalarMultiply - Element-wise operations
  • dotProduct - Vector dot product

Linear Algebra (src-wasm/algebra/decomposition.ts)

  • luDecomposition - LU decomposition with partial pivoting
  • qrDecomposition - QR decomposition using Householder reflections
  • choleskyDecomposition - Cholesky decomposition for symmetric positive-definite matrices
  • luSolve - Linear system solver using LU
  • luDeterminant - Determinant computation from LU

Signal Processing (src-wasm/signal/fft.ts)

  • fft - Cooley-Tukey radix-2 FFT
  • fft2d - 2D FFT for matrices/images
  • convolve - FFT-based convolution
  • rfft / irfft - Real FFT (optimized for real-valued data)

3. Parallel Computing Architecture

WorkerPool (src/parallel/WorkerPool.ts)

  • Manages a pool of Web Workers (browser) or worker_threads (Node.js)
  • Auto-detects optimal worker count based on CPU cores
  • Task queue with automatic load balancing
  • Support for transferable objects (zero-copy)

ParallelMatrix (src/parallel/ParallelMatrix.ts)

  • Automatic parallelization for large matrices
  • Row-based work distribution for matrix multiplication
  • SharedArrayBuffer support for zero-copy memory sharing
  • Configurable thresholds for parallel execution

Configuration

import { ParallelMatrix } from './parallel/ParallelMatrix.js'

ParallelMatrix.configure({
  minSizeForParallel: 1000,  // Minimum size for parallel execution
  workerScript: './matrix.worker.js',
  maxWorkers: 4,  // 0 = auto-detect
  useSharedMemory: true  // Use SharedArrayBuffer if available
})

4. Integration Bridge

MatrixWasmBridge (src/wasm/MatrixWasmBridge.ts)

The bridge automatically selects the optimal implementation:

import { MatrixWasmBridge } from './wasm/MatrixWasmBridge.js'

// Initialize WASM (call once at startup)
await MatrixWasmBridge.init()

// Automatic optimization selection
const result = await MatrixWasmBridge.multiply(
  aData, aRows, aCols,
  bData, bRows, bCols
)

Selection Strategy:

  1. Size < minSizeForWasm → JavaScript
  2. Size >= minSizeForWasm && WASM available → WASM SIMD
  3. Size >= minSizeForParallel → Parallel (multi-threaded)
  4. WASM not available → JavaScript fallback

Configuration

MatrixWasmBridge.configure({
  useWasm: true,
  useParallel: true,
  minSizeForWasm: 100,
  minSizeForParallel: 1000
})

Performance Characteristics

Benchmark Results (Expected)

Matrix Multiplication (1000x1000)

  • JavaScript: ~1000ms
  • WASM: ~150ms (6.7x faster)
  • WASM SIMD: ~75ms (13x faster)
  • Parallel (4 cores): ~40ms (25x faster)

LU Decomposition (500x500)

  • JavaScript: ~200ms
  • WASM: ~50ms (4x faster)

FFT (8192 points)

  • JavaScript: ~100ms
  • WASM: ~15ms (6.7x faster)

Memory Efficiency

SharedArrayBuffer Mode

  • Zero-copy data transfer between workers
  • Reduces memory usage by 50-70% for large matrices
  • Requires secure context (HTTPS or localhost)

Standard Mode

  • Data copying between workers
  • Compatible with all environments
  • Slightly higher memory usage

Build System

Build Commands

# Full build (JavaScript + TypeScript + WASM)
npm run build

# TypeScript only
npm run compile:ts

# WASM only
npm run build:wasm
npm run build:wasm:debug  # With debug symbols

# Watch mode
npm run watch:ts

# Clean build
npm run build:clean

Gulp Tasks

gulp                    // Full build
gulp compile           // Compile all sources
gulp compileTypeScript // TypeScript only
gulp compileWasm       // WASM only
gulp clean             // Clean build artifacts

Integration with Existing Code

Gradual Migration Strategy

The architecture is designed for gradual migration:

  1. Phase 1: Infrastructure

    • TypeScript configuration
    • WASM build pipeline
    • Parallel computing framework
  2. Phase 2: Core Operations (In Progress)

    • Matrix multiplication
    • Linear algebra decompositions
    • Signal processing (FFT)
  3. Phase 3: Extended Operations

    • All matrix operations
    • Statistical functions
    • Symbolic computation
  4. Phase 4: Full Migration

    • All source files to TypeScript
    • Complete WASM coverage
    • Parallel optimization for all suitable operations

Backward Compatibility

  • All existing JavaScript APIs remain unchanged
  • WASM and parallel execution are opt-in via configuration
  • Automatic fallback to JavaScript if WASM fails to load
  • No breaking changes to public API

Usage Examples

Example 1: Basic Matrix Multiplication

import { MatrixWasmBridge } from 'mathjs/lib/typescript/wasm/MatrixWasmBridge.js'

// Initialize (once per application)
await MatrixWasmBridge.init()

// Create matrices
const a = new Float64Array(100 * 100).map(() => Math.random())
const b = new Float64Array(100 * 100).map(() => Math.random())

// Multiply (automatically uses best implementation)
const result = await MatrixWasmBridge.multiply(a, 100, 100, b, 100, 100)

Example 2: LU Decomposition

import { MatrixWasmBridge } from 'mathjs/lib/typescript/wasm/MatrixWasmBridge.js'

await MatrixWasmBridge.init()

const matrix = new Float64Array([
  4, 3,
  6, 3
])

const { lu, perm, singular } = await MatrixWasmBridge.luDecomposition(matrix, 2)

if (!singular) {
  console.log('LU decomposition successful')
  console.log('L and U:', lu)
  console.log('Permutation:', perm)
}

Example 3: Parallel Matrix Operations

import { ParallelMatrix } from 'mathjs/lib/typescript/parallel/ParallelMatrix.js'

// Configure
ParallelMatrix.configure({
  minSizeForParallel: 500,
  maxWorkers: 0  // Auto-detect
})

// Large matrix multiplication (will use parallel execution)
const a = new Float64Array(2000 * 2000).map(() => Math.random())
const b = new Float64Array(2000 * 2000).map(() => Math.random())

const result = await ParallelMatrix.multiply(a, 2000, 2000, b, 2000, 2000)

// Cleanup when done
await ParallelMatrix.terminate()

Example 4: FFT with WASM

import { MatrixWasmBridge } from 'mathjs/lib/typescript/wasm/MatrixWasmBridge.js'

await MatrixWasmBridge.init()

// Create complex signal [real0, imag0, real1, imag1, ...]
const n = 1024
const signal = new Float64Array(n * 2)
for (let i = 0; i < n; i++) {
  signal[i * 2] = Math.sin(2 * Math.PI * i / n)  // Real part
  signal[i * 2 + 1] = 0  // Imaginary part
}

// Compute FFT
const spectrum = await MatrixWasmBridge.fft(signal, false)

// Compute inverse FFT
const reconstructed = await MatrixWasmBridge.fft(spectrum, true)

Testing

Running Tests

# All tests
npm run test:all

# Unit tests only
npm test

# Browser tests
npm run test:browser

# Type tests
npm run test:types

Writing Tests for WASM/Parallel Code

import { MatrixWasmBridge } from '../src/wasm/MatrixWasmBridge.js'
import assert from 'assert'

describe('WASM Matrix Operations', () => {
  before(async () => {
    await MatrixWasmBridge.init()
  })

  it('should multiply matrices correctly', async () => {
    const a = new Float64Array([1, 2, 3, 4])
    const b = new Float64Array([5, 6, 7, 8])

    const result = await MatrixWasmBridge.multiply(a, 2, 2, b, 2, 2)

    assert.deepStrictEqual(
      Array.from(result),
      [19, 22, 43, 50]
    )
  })

  after(async () => {
    await MatrixWasmBridge.cleanup()
  })
})

Troubleshooting

WASM Not Loading

Problem: WASM module fails to load

Solutions:

  • Ensure lib/wasm/index.wasm exists (run npm run build:wasm)
  • Check browser console for security errors
  • Verify MIME type is set correctly (application/wasm)
  • For Node.js, ensure --experimental-wasm-modules flag if needed

Parallel Execution Not Working

Problem: Operations run sequentially despite parallel configuration

Solutions:

  • Check if Workers are supported (typeof Worker !== 'undefined')
  • Verify matrix size exceeds minSizeForParallel threshold
  • Check browser console for worker errors
  • Ensure worker script path is correct

SharedArrayBuffer Not Available

Problem: SharedArrayBuffer is not defined

Solutions:

  • Requires secure context (HTTPS or localhost)
  • Requires specific headers:
    Cross-Origin-Opener-Policy: same-origin
    Cross-Origin-Embedder-Policy: require-corp
    
  • Falls back to standard ArrayBuffer automatically

Future Enhancements

  1. GPU Acceleration (WebGPU)

    • Matrix multiplication using GPU compute shaders
    • Additional 10-100x speedup for very large matrices
  2. SIMD.js Polyfill

    • SIMD support for browsers without WASM SIMD
  3. Automatic Tiling

    • Adaptive block size selection based on cache size
  4. Sparse Matrix WASM

    • Specialized WASM implementations for sparse matrices
  5. Streaming Operations

    • Support for matrices larger than memory
    • Disk-backed storage with streaming computation

Contributing

When adding new operations:

  1. Implement WASM version in src-wasm/
  2. Add JavaScript fallback in bridge
  3. Add parallel version if applicable
  4. Update tests
  5. Update benchmarks
  6. Document in this file

License

Same as mathjs (Apache-2.0)

References