gpu.js/test/features/dynamic-arguments.js
Robert Plummer 86af54efef fix: Node support for v8+
fix: Move `make` cli command to gulp so it runs in parallel
fix: Add official support for `Array1D(2|3|4)`, `Array2D(2|3|4)`, and `Array3D(2|3|4)` and unit tests
fix: Add offical support for `Array(2)`, `Array(3)`, and `Array(4)` and unit tests
fix: Mandelbulb constant used a constant, so moved to appropriate location
fix: Failing unit test for Safari
fix: When not falling back in HeadlessGL, call `STACKGL_resize_drawingbuffer`
fix: Remove `xyz` variable from glsl
fix: Add `uniform4fv` and `uniform4iv` to WebGL implementation
fix: Check for kernel settings `constantTypes` and `argumentTypes`
fix: Inherit type from kernel in KernelValue constructors
fix: Add some typescript details for `GPUVariableType`, `IKernelSettings`, and `ITypesList`
fix: Add support for 4d array in `utils.getMemoryOptimizedFloatTextureSize` for the special use case of `Array3D(2|3|4)`
fix: Add `utils.flatten4dArrayTo` for the special use case of `Array3D(2|3|4)`
fix: Add support for 4d array in `utils.flattenTo`
fix: Bump and build
2019-07-24 12:56:05 -04:00

1294 lines
33 KiB
JavaScript

const { assert, skip, test, module: describe, only } = require('qunit');
const { GPU, input } = require('../../src');
describe('features: dynamic arguments');
function testHTMLImage(done, mode) {
const image1 = new Image();
const image2 = new Image();
image1.src = 'jellyfish.jpeg';
image2.src = 'jellyfish-1.jpeg';
let loadedCount = 0;
image1.onload = image2.onload = () => {
loadedCount++;
if (loadedCount === 2) loaded();
};
function loaded() {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(image) {
const pixel = image[this.thread.y][this.thread.x];
return (pixel[0] + pixel[1] + pixel[2]) / 3;
})
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([276, 183]);
const pixels1 = kernel(image1);
kernel.setOutput([138, 91]);
const pixels2 = kernel(image2);
assert.ok(pixels1[0][0] > .43);
assert.ok(pixels1[0][0] < .45);
assert.equal(pixels1.length, image1.height);
assert.equal(pixels1[0].length, image1.width);
assert.ok(pixels2[0][0] > .82);
assert.ok(pixels2[0][0] < .83);
assert.equal(pixels2.length, image2.height);
assert.equal(pixels2[0].length, image2.width);
gpu.destroy();
done();
}
}
(typeof Image !== 'undefined' ? test : skip)('HTML Image auto', t => {
testHTMLImage(t.async());
});
(typeof Image !== 'undefined' && GPU.isWebGLSupported ? test : skip)('HTML Image webgl', t => {
testHTMLImage(t.async(), 'webgl');
});
(typeof Image !== 'undefined' && GPU.isWebGL2Supported ? test : skip)('HTML Image webgl2', t => {
testHTMLImage(t.async(), 'webgl2');
});
(typeof Image !== 'undefined' ? test : skip)('HTML Image cpu', t => {
testHTMLImage(t.async(), 'cpu');
});
function testMemoryOptimizedNumberTexture(mode) {
const gpu = new GPU({ mode });
const matrix4X4 = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16],
];
const texture4X4 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([4, 4])
.setPrecision('single')
.setOptimizeFloatMemory(true)
.setPipeline(true)
)(matrix4X4);
const matrix3X3 = [
[1,2,3],
[4,5,6],
[7,8,9]
];
const texture3X3 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([3, 3])
.setPrecision('single')
.setOptimizeFloatMemory(true)
.setPipeline(true)
)(matrix3X3);
const matrix2X2 = [
[1,2],
[3,4]
];
const texture2X2 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([2, 2])
.setPrecision('single')
.setOptimizeFloatMemory(true)
.setPipeline(true)
)(matrix2X2);
const kernel = gpu.createKernel(function(texture) {
return texture[this.thread.y][this.thread.x];
})
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOptimizeFloatMemory(true)
.setOutput([4,4]);
assert.deepEqual(kernel(texture4X4), [
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
]);
kernel.setOutput([3, 3]);
assert.deepEqual(kernel(texture3X3), [
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
new Float32Array([7,8,9]),
]);
kernel.setOutput([2, 2]);
assert.deepEqual(kernel(texture2X2), [
new Float32Array([1,2]),
new Float32Array([3,4]),
]);
assert.ok(kernel.kernelArguments[0].constructor.name.match('DynamicMemoryOptimizedNumberTexture'));
gpu.destroy();
}
(GPU.isSinglePrecisionSupported ? test : skip)('MemoryOptimizedNumberTexture (GPU only) auto', () => {
testMemoryOptimizedNumberTexture();
});
(GPU.isSinglePrecisionSupported ? test : skip)('MemoryOptimizedNumberTexture (GPU only) gpu', () => {
testMemoryOptimizedNumberTexture('gpu');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('MemoryOptimizedNumberTexture (GPU only) webgl', () => {
testMemoryOptimizedNumberTexture('webgl');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('MemoryOptimizedNumberTexture (GPU only) webgl2', () => {
testMemoryOptimizedNumberTexture('webgl2');
});
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('MemoryOptimizedNumberTexture (GPU only) headlessgl', () => {
testMemoryOptimizedNumberTexture('headlessgl');
});
function testNumberTexture(mode) {
const gpu = new GPU({ mode });
const matrix4X4 = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16],
];
const texture4X4 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([4, 4])
.setPrecision('single')
.setPipeline(true)
)(matrix4X4);
const matrix3X3 = [
[1,2,3],
[4,5,6],
[7,8,9]
];
const texture3X3 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([3, 3])
.setPrecision('single')
.setPipeline(true)
)(matrix3X3);
const matrix2X2 = [
[1,2],
[3,4]
];
const texture2X2 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([2, 2])
.setPrecision('single')
.setPipeline(true)
)(matrix2X2);
const kernel = gpu.createKernel(function(texture) {
return texture[this.thread.y][this.thread.x];
})
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([4,4]);
assert.deepEqual(kernel(texture4X4), [
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
]);
kernel.setOutput([3, 3]);
assert.deepEqual(kernel(texture3X3), [
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
new Float32Array([7,8,9]),
]);
kernel.setOutput([2, 2]);
assert.deepEqual(kernel(texture2X2), [
new Float32Array([1,2]),
new Float32Array([3,4]),
]);
assert.ok(kernel.kernelArguments[0].constructor.name.match('NumberTexture'));
gpu.destroy();
}
(GPU.isSinglePrecisionSupported ? test : skip)('NumberTexture (GPU only) auto', () => {
testNumberTexture();
});
(GPU.isSinglePrecisionSupported ? test : skip)('NumberTexture (GPU only) gpu', () => {
testNumberTexture('gpu');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('NumberTexture (GPU only) webgl', () => {
testNumberTexture('webgl');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('NumberTexture (GPU only) webgl2', () => {
testNumberTexture('webgl2');
});
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('NumberTexture (GPU only) headlessgl', () => {
testNumberTexture('headlessgl');
});
function testMixedNumberTexture(mode) {
const gpu = new GPU({ mode });
const matrix4X4 = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16],
];
const texture4X4 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([4, 4])
.setPrecision('single')
.setOptimizeFloatMemory(true)
.setPipeline(true)
)(matrix4X4);
const matrix3X3 = [
[1,2,3],
[4,5,6],
[7,8,9]
];
const texture3X3 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([3, 3])
.setPrecision('single')
.setOptimizeFloatMemory(true)
.setPipeline(true)
)(matrix3X3);
const matrix2X2 = [
[1,2],
[3,4]
];
const texture2X2 = (
gpu.createKernel(function(value) {
return value[this.thread.y][this.thread.x];
})
.setOutput([2, 2])
.setPrecision('single')
.setPipeline(true)
)(matrix2X2);
const kernel = gpu.createKernel(function(texture) {
return texture[this.thread.y][this.thread.x];
})
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([4,4]);
assert.deepEqual(kernel(texture4X4), [
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
]);
kernel.setOutput([3, 3]);
assert.deepEqual(kernel(texture3X3), [
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
new Float32Array([7,8,9]),
]);
kernel.setOutput([2, 2]);
assert.deepEqual(kernel(texture2X2), [
new Float32Array([1,2]),
new Float32Array([3,4]),
]);
assert.ok(kernel.kernelArguments[0].constructor.name.match('NumberTexture'));
gpu.destroy();
}
(GPU.isSinglePrecisionSupported ? test : skip)('Mixed NumberTexture (GPU only) auto', () => {
testMixedNumberTexture();
});
(GPU.isSinglePrecisionSupported ? test : skip)('Mixed NumberTexture (GPU only) gpu', () => {
testMixedNumberTexture('gpu');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('Mixed NumberTexture (GPU only) webgl', () => {
testMixedNumberTexture('webgl');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('Mixed NumberTexture (GPU only) webgl2', () => {
testMixedNumberTexture('webgl2');
});
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('Mixed NumberTexture (GPU only) headlessgl', () => {
testMixedNumberTexture('headlessgl');
});
function testSingleArray1D2(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.x];
}, {
argumentTypes: { v: 'Array1D(2)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
new Float32Array([1,2]),
new Float32Array([3,4]),
];
kernel.setOutput([expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
new Float32Array([1,2]),
new Float32Array([3,4]),
new Float32Array([5,6]),
new Float32Array([7,8]),
];
kernel.setOutput([expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array1D2 auto', () => {
testSingleArray1D2();
});
test('Single Array1D2 gpu', () => {
testSingleArray1D2('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array1D2 webgl', () => {
testSingleArray1D2('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array1D2 webgl2', () => {
testSingleArray1D2('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array1D2 headlessgl', () => {
testSingleArray1D2('headlessgl');
});
test('Single Array1D2 cpu', () => {
testSingleArray1D2('cpu');
});
function testSingleArray1D3(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.x];
}, {
argumentTypes: { v: 'Array1D(3)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
];
kernel.setOutput([expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
new Float32Array([7,8,9]),
new Float32Array([10,11,12]),
];
kernel.setOutput([expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array1D3 auto', () => {
testSingleArray1D3();
});
test('Single Array1D3 gpu', () => {
testSingleArray1D3('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array1D3 webgl', () => {
testSingleArray1D3('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array1D3 webgl2', () => {
testSingleArray1D3('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array1D3 headlessgl', () => {
testSingleArray1D3('headlessgl');
});
test('Single Array1D3 cpu', () => {
testSingleArray1D3('cpu');
});
function testSingleArray1D4(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.x];
}, {
argumentTypes: { v: 'Array1D(4)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
];
kernel.setOutput([expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
];
kernel.setOutput([expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array1D4 auto', () => {
testSingleArray1D4();
});
test('Single Array1D4 gpu', () => {
testSingleArray1D4('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array1D4 webgl', () => {
testSingleArray1D4('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array1D4 webgl2', () => {
testSingleArray1D4('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array1D4 headlessgl', () => {
testSingleArray1D4('headlessgl');
});
test('Single Array1D4 cpu', () => {
testSingleArray1D4('cpu');
});
function testSingleArray2D2(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.y][this.thread.x];
}, {
argumentTypes: { v: 'Array2D(2)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
[
new Float32Array([1,2]),
new Float32Array([3,4]),
],[
new Float32Array([5,6]),
new Float32Array([7,8]),
]
];
kernel.setOutput([expected1[0].length, expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
[
new Float32Array([1,2]),
new Float32Array([3,4]),
new Float32Array([5,6]),
new Float32Array([7,8]),
],[
new Float32Array([9,10]),
new Float32Array([11,12]),
new Float32Array([13,14]),
new Float32Array([15,16]),
]
];
kernel.setOutput([expected2[0].length, expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array2D2 auto', () => {
testSingleArray2D2();
});
test('Single Array2D2 gpu', () => {
testSingleArray2D2('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array2D2 webgl', () => {
testSingleArray2D2('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array2D2 webgl2', () => {
testSingleArray2D2('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array2D2 headlessgl', () => {
testSingleArray2D2('headlessgl');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array2D2 cpu', () => {
testSingleArray2D2('cpu');
});
function testSingleArray2D3(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.y][this.thread.x];
}, {
argumentTypes: { v: 'Array2D(3)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
[
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
],[
new Float32Array([7,8,9]),
new Float32Array([10,11,12]),
]
];
kernel.setOutput([expected1[0].length, expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
[
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
new Float32Array([7,8,9]),
new Float32Array([10,11,12]),
],[
new Float32Array([13,14,15]),
new Float32Array([16,17,18]),
new Float32Array([19,20,21]),
new Float32Array([22,23,24]),
]
];
kernel.setOutput([expected2[0].length, expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array2D3 auto', () => {
testSingleArray2D3();
});
test('Single Array2D3 gpu', () => {
testSingleArray2D3('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array2D3 webgl', () => {
testSingleArray2D3('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array2D3 webgl2', () => {
testSingleArray2D3('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array2D3 headlessgl', () => {
testSingleArray2D3('headlessgl');
});
test('Single Array2D3 cpu', () => {
testSingleArray2D3('cpu');
});
function testSingleArray2D4(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.y][this.thread.x];
}, {
argumentTypes: { v: 'Array2D(4)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
[
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
],[
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
]
];
kernel.setOutput([expected1[0].length, expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
[
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
],[
new Float32Array([17,18,19,20]),
new Float32Array([21,22,23,24]),
new Float32Array([25,26,27,28]),
new Float32Array([29,30,31,32]),
]
];
kernel.setOutput([expected2[0].length, expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array2D4 auto', () => {
testSingleArray2D4();
});
test('Single Array2D4 gpu', () => {
testSingleArray2D4('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array2D4 webgl', () => {
testSingleArray2D4('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array2D4 webgl2', () => {
testSingleArray2D4('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array2D4 headlessgl', () => {
testSingleArray2D4('headlessgl');
});
test('Single Array2D4 cpu', () => {
testSingleArray2D4('cpu');
});
function testSingleArray3D2(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.z][this.thread.y][this.thread.x];
}, {
argumentTypes: { v: 'Array3D(2)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
[
[
new Float32Array([1,2]),
new Float32Array([3,4]),
],[
new Float32Array([5,6]),
new Float32Array([7,8]),
]
],[
[
new Float32Array([9,10]),
new Float32Array([11,12]),
],[
new Float32Array([13,14]),
new Float32Array([15,16]),
]
]
];
kernel.setOutput([expected1[0][0].length, expected1[0].length, expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
[
[
new Float32Array([1,2]),
new Float32Array([3,4]),
new Float32Array([5,6]),
new Float32Array([7,8]),
],[
new Float32Array([9,10]),
new Float32Array([11,12]),
new Float32Array([13,14]),
new Float32Array([15,16]),
]
],[
[
new Float32Array([17,18]),
new Float32Array([19,20]),
new Float32Array([21,22]),
new Float32Array([23,24]),
],[
new Float32Array([25,26]),
new Float32Array([27,28]),
new Float32Array([29,30]),
new Float32Array([31,32]),
]
]
];
kernel.setOutput([expected2[0][0].length, expected2[0].length, expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array3D2 auto', () => {
testSingleArray3D2();
});
test('Single Array3D2 gpu', () => {
testSingleArray3D2('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array3D2 webgl', () => {
testSingleArray3D2('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array3D2 webgl2', () => {
testSingleArray3D2('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array3D2 headlessgl', () => {
testSingleArray3D2('headlessgl');
});
test('Single Array3D2 cpu', () => {
testSingleArray3D2('cpu');
});
function testSingleArray3D3(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.z][this.thread.y][this.thread.x];
}, {
argumentTypes: { v: 'Array3D(3)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
[
[
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
],[
new Float32Array([7,8,9]),
new Float32Array([10,11,12]),
]
],[
[
new Float32Array([13,14,15]),
new Float32Array([16,17,18]),
],[
new Float32Array([19,20,21]),
new Float32Array([22,23,24]),
]
]
];
kernel.setOutput([expected1[0][0].length, expected1[0].length, expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
[
[
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
new Float32Array([7,8,9]),
new Float32Array([10,11,12]),
],[
new Float32Array([13,14,15]),
new Float32Array([16,17,18]),
new Float32Array([19,20,21]),
new Float32Array([22,23,24]),
]
],[
[
new Float32Array([25,26,27]),
new Float32Array([28,29,30]),
new Float32Array([31,32,33]),
new Float32Array([34,35,36]),
],[
new Float32Array([37,38,39]),
new Float32Array([40,41,42]),
new Float32Array([43,44,45]),
new Float32Array([46,47,48]),
]
]
];
kernel.setOutput([expected2[0][0].length, expected2[0].length, expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array3D3 auto', () => {
testSingleArray3D3();
});
test('Single Array3D3 gpu', () => {
testSingleArray3D3('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array3D3 webgl', () => {
testSingleArray3D3('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array3D3 webgl2', () => {
testSingleArray3D3('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array3D3 headlessgl', () => {
testSingleArray3D3('headlessgl');
});
test('Single Array3D3 cpu', () => {
testSingleArray3D3('cpu');
});
function testSingleArray3D4(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(v) {
return v[this.thread.z][this.thread.y][this.thread.x];
}, {
argumentTypes: { v: 'Array3D(4)' },
dynamicArguments: true,
dynamicOutput: true
});
const expected1 = [
[
[
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
],[
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
]
],[
[
new Float32Array([17,18,19,20]),
new Float32Array([21,22,23,24]),
],[
new Float32Array([25,26,27,28]),
new Float32Array([29,30,31,32]),
]
]
];
kernel.setOutput([expected1[0][0].length, expected1[0].length, expected1.length]);
assert.deepEqual(kernel(expected1), expected1);
const expected2 = [
[
[
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
],[
new Float32Array([17,18,19,20]),
new Float32Array([21,22,23,24]),
new Float32Array([25,26,27,28]),
new Float32Array([29,30,31,32]),
]
],[
[
new Float32Array([33,34,35,36]),
new Float32Array([37,38,39,40]),
new Float32Array([41,42,43,44]),
new Float32Array([45,46,47,48]),
],[
new Float32Array([49,50,51,52]),
new Float32Array([53,54,56,57]),
new Float32Array([58,59,60,61]),
new Float32Array([62,63,64,65]),
]
]
];
kernel.setOutput([expected2[0][0].length, expected2[0].length, expected2.length]);
assert.deepEqual(kernel(expected2), expected2);
gpu.destroy();
}
test('Single Array3D4 auto', () => {
testSingleArray3D4();
});
test('Single Array3D4 gpu', () => {
testSingleArray3D4('gpu');
});
(GPU.isWebGLSupported ? test : skip)('Single Array3D4 webgl', () => {
testSingleArray3D4('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('Single Array3D4 webgl2', () => {
testSingleArray3D4('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('Single Array3D4 headlessgl', () => {
testSingleArray3D4('headlessgl');
});
test('Single Array3D4 cpu', () => {
testSingleArray3D4('cpu');
});
function testUnsignedPrecisionArray(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(input) {
return input[this.thread.x];
})
.setPrecision('unsigned')
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([5]);
assert.deepEqual(kernel([1,2,3,4,5]), new Float32Array([1,2,3,4,5]));
kernel.setOutput([4]);
assert.deepEqual(kernel([1,2,3,4]), new Float32Array([1,2,3,4]));
kernel.setOutput([3]);
assert.deepEqual(kernel([1,2,3]), new Float32Array([1,2,3]));
kernel.setOutput([2]);
assert.deepEqual(kernel([1,2]), new Float32Array([1,2]));
gpu.destroy();
}
test('unsigned precision Array auto', () => {
testUnsignedPrecisionArray();
});
test('unsigned precision Array gpu', () => {
testUnsignedPrecisionArray('gpu');
});
(GPU.isWebGLSupported ? test : skip)('unsigned precision Array webgl', () => {
testUnsignedPrecisionArray('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('unsigned precision Array webgl2', () => {
testUnsignedPrecisionArray('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('unsigned precision Array headlessgl', () => {
testUnsignedPrecisionArray('headlessgl');
});
test('unsigned precision Array cpu', () => {
testUnsignedPrecisionArray('cpu');
});
function testSinglePrecisionArray(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(input) {
return input[this.thread.x];
})
.setPrecision('single')
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([5]);
assert.deepEqual(kernel([1,2,3,4,5]), new Float32Array([1,2,3,4,5]));
kernel.setOutput([4]);
assert.deepEqual(kernel([1,2,3,4]), new Float32Array([1,2,3,4]));
kernel.setOutput([3]);
assert.deepEqual(kernel([1,2,3]), new Float32Array([1,2,3]));
kernel.setOutput([2]);
assert.deepEqual(kernel([1,2]), new Float32Array([1,2]));
gpu.destroy();
}
(GPU.isSinglePrecisionSupported ? test : skip)('single precision Array auto', () => {
testSinglePrecisionArray();
});
(GPU.isSinglePrecisionSupported ? test : skip)('single precision Array gpu', () => {
testSinglePrecisionArray('gpu');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('single precision Array webgl', () => {
testSinglePrecisionArray('webgl');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('single precision Array webgl2', () => {
testSinglePrecisionArray('webgl2');
});
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('single precision Array headlessgl', () => {
testSinglePrecisionArray('headlessgl');
});
test('single precision Array cpu', () => {
testSinglePrecisionArray('cpu');
});
function testUnsignedPrecisionMatrix(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(input) {
return input[this.thread.y][this.thread.x];
})
.setPrecision('unsigned')
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([4,4]);
let matrix = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]
];
assert.deepEqual(kernel(matrix), matrix.map(row => new Float32Array(row)));
kernel.setOutput([3,3]);
matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
];
assert.deepEqual(kernel(matrix), matrix.map(row => new Float32Array(row)));
kernel.setOutput([2,2]);
matrix = [
[1,2],
[3,4]
];
assert.deepEqual(kernel(matrix), matrix.map(row => new Float32Array(row)));
gpu.destroy();
}
test('unsigned precision Matrix auto', () => {
testUnsignedPrecisionMatrix();
});
test('unsigned precision Matrix gpu', () => {
testUnsignedPrecisionMatrix('gpu');
});
(GPU.isWebGLSupported ? test : skip)('unsigned precision Matrix webgl', () => {
testUnsignedPrecisionMatrix('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('unsigned precision Matrix webgl2', () => {
testUnsignedPrecisionMatrix('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('unsigned precision Matrix headlessgl', () => {
testUnsignedPrecisionMatrix('headlessgl');
});
test('unsigned precision Matrix cpu', () => {
testUnsignedPrecisionMatrix('cpu');
});
function testSinglePrecisionMatrix(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(input) {
return input[this.thread.y][this.thread.x];
})
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([4,4]);
let matrix = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]
];
assert.deepEqual(kernel(matrix), matrix.map(row => new Float32Array(row)));
kernel.setOutput([3,3]);
matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
];
assert.deepEqual(kernel(matrix), matrix.map(row => new Float32Array(row)));
kernel.setOutput([2,2]);
matrix = [
[1,2],
[3,4]
];
assert.deepEqual(kernel(matrix), matrix.map(row => new Float32Array(row)));
gpu.destroy();
}
(GPU.isSinglePrecisionSupported ? test : skip)('single precision Matrix auto', () => {
testSinglePrecisionMatrix();
});
(GPU.isSinglePrecisionSupported ? test : skip)('single precision Matrix gpu', () => {
testSinglePrecisionMatrix('gpu');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('single precision Matrix webgl', () => {
testSinglePrecisionMatrix('webgl');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('single precision Matrix webgl2', () => {
testSinglePrecisionMatrix('webgl2');
});
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('single precision Matrix headlessgl', () => {
testSinglePrecisionMatrix('headlessgl');
});
test('single precision Matrix cpu', () => {
testSinglePrecisionMatrix('cpu');
});
function testUnsignedPrecisionInputMatrix(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(input) {
return input[this.thread.y][this.thread.x];
})
.setPrecision('unsigned')
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([4,4]);
let matrix = input([
1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16
], [4, 4]);
assert.deepEqual(kernel(matrix), [
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16]),
]);
kernel.setOutput([3,3]);
matrix = input([
1,2,3,
4,5,6,
7,8,9
], [3,3]);
assert.deepEqual(kernel(matrix), [
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
new Float32Array([7,8,9])
]);
kernel.setOutput([2,2]);
matrix = input([
1,2,
3,4
], [2,2]);
assert.deepEqual(kernel(matrix), [
new Float32Array([1,2]),
new Float32Array([3,4])
]);
gpu.destroy();
}
test('unsigned precision Input Matrix auto', () => {
testUnsignedPrecisionInputMatrix();
});
test('unsigned precision Input Matrix gpu', () => {
testUnsignedPrecisionInputMatrix('gpu');
});
(GPU.isWebGLSupported ? test : skip)('unsigned precision Input Matrix webgl', () => {
testUnsignedPrecisionInputMatrix('webgl');
});
(GPU.isWebGL2Supported ? test : skip)('unsigned precision Input Matrix webgl2', () => {
testUnsignedPrecisionInputMatrix('webgl2');
});
(GPU.isHeadlessGLSupported ? test : skip)('unsigned precision Input Matrix headlessgl', () => {
testUnsignedPrecisionInputMatrix('headlessgl');
});
test('unsigned precision Input Matrix cpu', () => {
testUnsignedPrecisionInputMatrix('cpu');
});
function testSinglePrecisionInputMatrix(mode) {
const gpu = new GPU({ mode });
const kernel = gpu.createKernel(function(input) {
return input[this.thread.y][this.thread.x];
})
.setDynamicArguments(true)
.setDynamicOutput(true)
.setOutput([4,4]);
let matrix = input([
1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16
], [4, 4]);
assert.deepEqual(kernel(matrix), [
new Float32Array([1,2,3,4]),
new Float32Array([5,6,7,8]),
new Float32Array([9,10,11,12]),
new Float32Array([13,14,15,16])
]);
kernel.setOutput([3,3]);
matrix = input([
1,2,3,
4,5,6,
7,8,9
], [3, 3]);
assert.deepEqual(kernel(matrix), [
new Float32Array([1,2,3]),
new Float32Array([4,5,6]),
new Float32Array([7,8,9])
]);
kernel.setOutput([2,2]);
matrix = input([
1,2,
3,4
], [2,2]);
assert.deepEqual(kernel(matrix), [
new Float32Array([1,2]),
new Float32Array([3,4])
]);
gpu.destroy();
}
(GPU.isSinglePrecisionSupported ? test : skip)('single precision Input Matrix auto', () => {
testSinglePrecisionInputMatrix();
});
(GPU.isSinglePrecisionSupported ? test : skip)('single precision Input Matrix gpu', () => {
testSinglePrecisionInputMatrix('gpu');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('single precision Input Matrix webgl', () => {
testSinglePrecisionInputMatrix('webgl');
});
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('single precision Input Matrix webgl2', () => {
testSinglePrecisionInputMatrix('webgl2');
});
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('single precision Input Matrix headlessgl', () => {
testSinglePrecisionInputMatrix('headlessgl');
});
test('single precision Input Matrix cpu', () => {
testSinglePrecisionInputMatrix('cpu');
});