gpujs / gpu.js

GPU Accelerated JavaScript
https://gpu.rocks
MIT License
15.08k stars 650 forks source link

Using `input` arguments causes strangeness #701

Open rotu opened 3 years ago

rotu commented 3 years ago

The goddamn pixel is blue

What is wrong?

When passing an input using the Input class, a texture can be mapped to memory in strange ways, resulting in different outputs for essentially the same inputs.

Where does it happen?

On my Linux machine running Ubuntu 20.04

How do we replicate the issue?

Here is a small reproducible codepen: https://codepen.io/rotu-the-bold/pen/WNpmVWm

kernels = []
for (let i=0;i<3;++i)
 {
  const kernel = (new GPU()).createKernel(function(a) {
  const {x,y} = this.thread
  this.color(a[x][y][0], a[x][y][1], a[x][y][2])
}, {output:[2,2], graphical:true})
  document.getElementsByTagName('body')[0].appendChild(kernel.canvas);
   kernels.push(kernel)
}

kernels[0]([
  [[0,0,1],[0,0,0]],
  [[0,0,0],[0,0,0]]])

kernels[1](GPU.input(new Float32Array([ 
  0,0,1, 0,0,0,
  0,0,0, 0,0,0]), [2,2,3]))

kernels[2](GPU.input(new Int16Array([ 
  0,0,1, 0,0,0,
  0,0,0, 0,0,0]), [2,2,3]))

image

How important is this (1-5)?

4

Expected behavior (i.e. solution)

I expect the input tool for passing data to vary most quickly with the first index and least quickly with the last index.

In my example, output images should be the same: a single blue cell and 3 black cells.

Other Comments

This bug affects multiple browsers on my machine.

It seems selecting mode: 'cpu' makes Int16Array behave as a Float32Array-backed input, though still differently from the nested array, not using input.

This was especially confusing to me because the index order of the input array is not well-documented. It should probably be explicitly stated how the indices map to the memory values. It might be nice to make the per-axis memory strides into an exposed property on Input objects and/or accessor methods to make it simpler to manipulate their data.