GPU.js 3D Kernel Dimension Traversal Order

This article explains the execution hierarchy and dimension traversal order used by GPU.js when computing with a three-dimensional kernel. Understanding how this.thread.x, this.thread.y, and this.thread.z are ordered is essential for correctly mapping 3D arrays, flattening data structures, and ensuring optimal memory access patterns in WebGL compute shaders.

The Dimension Traversal Order

When configuring a 3D kernel in GPU.js using an output array such as output: [width, height, depth], the library maps the dimensions sequentially to this.thread.x, this.thread.y, and this.thread.z.

Although the GPU executes thousands of threads concurrently, the logical data ordering and underlying memory layout traverse dimensions from the outermost dimension to the innermost dimension in the following order:

  1. this.thread.z (Outermost / Slowest-changing dimension)
  2. this.thread.y (Middle dimension)
  3. this.thread.x (Innermost / Fastest-changing dimension)

Loop Analogy and Memory Flattening

If represented as traditional, nested JavaScript for loops, a 3D GPU.js kernel operates logically equivalent to:

for (let z = 0; z < depth; z++) {
  for (let y = 0; y < height; y++) {
    for (let x = 0; x < width; x++) {
      // Kernel body executes here
    }
  }
}

Because this.thread.x is the innermost dimension, it increments on every adjacent memory element. When multidimensional output is packed or flattened into a standard 1D linear array or texture buffer, the linear index corresponding to a thread can be calculated as:

\[\text{Index} = x + (y \times \text{width}) + (z \times \text{width} \times \text{height})\]

Implications for 3D Data Handling