mirror of
https://github.com/gpujs/gpu.js.git
synced 2025-12-08 20:35:56 +00:00
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
568 lines
20 KiB
JavaScript
568 lines
20 KiB
JavaScript
const sinon = require('sinon');
|
|
const { assert, test, module: describe, only, skip } = require('qunit');
|
|
const { GPU, FunctionBuilder } = require('../../src');
|
|
|
|
describe('internal: deep types');
|
|
|
|
function oneLayerDeepFloat(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function childFunction(childFunctionArgument1) {
|
|
return childFunctionArgument1 + 1;
|
|
}
|
|
gpu.addFunction(childFunction);
|
|
|
|
const kernel = gpu.createKernel(function(kernelArgument1) {
|
|
return childFunction(kernelArgument1);
|
|
}, { output: [1] });
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
try {
|
|
const result = kernel(1.5);
|
|
assert.equal(result[0], 2.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 1);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[0][0], 'childFunction');
|
|
} finally {
|
|
FunctionBuilder.prototype.lookupReturnType.restore();
|
|
}
|
|
}
|
|
|
|
(GPU.isWebGLSupported ? test : skip)('one layer deep float WebGL', () => {
|
|
oneLayerDeepFloat('webgl');
|
|
});
|
|
(GPU.isWebGL2Supported ? test : skip)('one layer deep float WebGL2', () => {
|
|
oneLayerDeepFloat('webgl2');
|
|
});
|
|
(GPU.isHeadlessGLSupported ? test : skip)('one layer deep float HeadlessGL', () => {
|
|
oneLayerDeepFloat('headlessgl');
|
|
});
|
|
|
|
function twoLayerDeepFloat(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function child1Function(child1FunctionArgument1) {
|
|
return child2Function(child1FunctionArgument1);
|
|
}
|
|
function child2Function(child2FunctionArgument1) {
|
|
return child2FunctionArgument1 + 1;
|
|
}
|
|
gpu
|
|
.addFunction(child1Function)
|
|
.addFunction(child2Function);
|
|
const kernel = gpu.createKernel(function(kernelArgument1) {
|
|
return child1Function(kernelArgument1);
|
|
}, { output: [1] });
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
try {
|
|
const result = kernel(1.5);
|
|
assert.equal(result[0], 2.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 3);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[0][0], 'child1Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[1][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[2][0], 'child2Function');
|
|
} finally {
|
|
FunctionBuilder.prototype.lookupReturnType.restore();
|
|
}
|
|
}
|
|
|
|
(GPU.isWebGLSupported ? test : skip)('two layer deep float WebGL', () => {
|
|
twoLayerDeepFloat('webgl');
|
|
});
|
|
(GPU.isWebGL2Supported ? test : skip)('two layer deep float WebGL2', () => {
|
|
twoLayerDeepFloat('webgl2');
|
|
});
|
|
(GPU.isHeadlessGLSupported ? test : skip)('two layer deep float HeadlessGL', () => {
|
|
twoLayerDeepFloat('headlessgl');
|
|
});
|
|
|
|
function twoArgumentLayerDeepFloat(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function child1Function(child1FunctionArgument1) {
|
|
return child1FunctionArgument1 + 1;
|
|
}
|
|
function child2Function(child2FunctionArgument1) {
|
|
return child2FunctionArgument1 + 1;
|
|
}
|
|
gpu
|
|
.addFunction(child1Function)
|
|
.addFunction(child2Function);
|
|
const kernel = gpu.createKernel(function(kernelArgument1) {
|
|
return child1Function(child2Function(kernelArgument1));
|
|
}, { output: [1] });
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
try {
|
|
const result = kernel(1.5);
|
|
assert.equal(kernel.returnType, 'Float');
|
|
assert.equal(result[0], 3.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 3);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[0][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[1][0], 'child1Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[2][0], 'child2Function');
|
|
} finally {
|
|
FunctionBuilder.prototype.lookupReturnType.restore();
|
|
}
|
|
}
|
|
|
|
(GPU.isWebGLSupported ? test : skip)('two argument layer deep float WebGL', () => {
|
|
twoArgumentLayerDeepFloat('webgl');
|
|
});
|
|
(GPU.isWebGL2Supported ? test : skip)('two argument layer deep float WebGL2', () => {
|
|
twoArgumentLayerDeepFloat('webgl2');
|
|
});
|
|
(GPU.isHeadlessGLSupported ? test : skip)('two argument layer deep float HeadlessGL', () => {
|
|
twoArgumentLayerDeepFloat('headlessgl');
|
|
});
|
|
|
|
|
|
function threeLayerDeepFloat(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function child1Function(child1FunctionArgument1) {
|
|
return child2Function(child1FunctionArgument1);
|
|
}
|
|
function child2Function(child2FunctionArgument1) {
|
|
return child3Function(child2FunctionArgument1 + 1);
|
|
}
|
|
function child3Function(child3FunctionArgument1) {
|
|
return child3FunctionArgument1 + 1;
|
|
}
|
|
gpu
|
|
.addFunction(child1Function)
|
|
.addFunction(child2Function)
|
|
.addFunction(child3Function);
|
|
const kernel = gpu.createKernel(function(kernelArgument1) {
|
|
return child1Function(kernelArgument1);
|
|
}, { output: [1] });
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
try {
|
|
const result = kernel(1.5);
|
|
assert.equal(result[0], 3.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[0][0], 'child1Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[1][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[2][0], 'child3Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[3][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[4][0], 'child3Function');
|
|
} finally {
|
|
FunctionBuilder.prototype.lookupReturnType.restore();
|
|
}
|
|
}
|
|
|
|
(GPU.isWebGLSupported ? test : skip)('three layer deep float WebGL', () => {
|
|
threeLayerDeepFloat('webgl');
|
|
});
|
|
(GPU.isWebGL2Supported ? test : skip)('three layer deep float WebGL2', () => {
|
|
threeLayerDeepFloat('webgl2');
|
|
});
|
|
(GPU.isHeadlessGLSupported ? test : skip)('three layer deep float HeadlessGL', () => {
|
|
threeLayerDeepFloat('headlessgl');
|
|
});
|
|
|
|
function threeArgumentLayerDeepFloat(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function child1Function(child1FunctionArgument1) {
|
|
return child1FunctionArgument1 + 1;
|
|
}
|
|
function child2Function(child2FunctionArgument1) {
|
|
return child2FunctionArgument1 + 1;
|
|
}
|
|
function child3Function(child3FunctionArgument1) {
|
|
return child3FunctionArgument1 + 1;
|
|
}
|
|
gpu
|
|
.addFunction(child1Function)
|
|
.addFunction(child2Function)
|
|
.addFunction(child3Function);
|
|
const kernel = gpu.createKernel(function(kernelArgument1) {
|
|
return child1Function(child2Function(child3Function(kernelArgument1)));
|
|
}, { output: [1] });
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
try {
|
|
const result = kernel(1.5);
|
|
assert.equal(result[0], 4.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[0][0], 'child3Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[1][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[2][0], 'child1Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[3][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[4][0], 'child3Function');
|
|
} finally {
|
|
FunctionBuilder.prototype.lookupReturnType.restore();
|
|
}
|
|
}
|
|
|
|
(GPU.isWebGLSupported ? test : skip)('three argument layer deep float WebGL', () => {
|
|
threeArgumentLayerDeepFloat('webgl');
|
|
});
|
|
(GPU.isWebGL2Supported ? test : skip)('three argument layer deep float WebGL2', () => {
|
|
threeArgumentLayerDeepFloat('webgl2');
|
|
});
|
|
(GPU.isHeadlessGLSupported ? test : skip)('three argument layer deep float HeadlessGL', () => {
|
|
threeArgumentLayerDeepFloat('headlessgl');
|
|
});
|
|
|
|
function threeArgumentLayerDeepNumberTexture1(mode) {
|
|
const gpu = new GPU({ mode });
|
|
const texture = gpu.createKernel(function() {
|
|
return 1.5;
|
|
}, { output: [1], pipeline: true, precision: 'single' })();
|
|
function child1Function(child1FunctionArgument1) {
|
|
return child1FunctionArgument1 + 1;
|
|
}
|
|
function child2Function(child2FunctionArgument1) {
|
|
return child2FunctionArgument1 + 1;
|
|
}
|
|
function child3Function(child3FunctionArgument1) {
|
|
return child3FunctionArgument1[this.thread.x] + 1;
|
|
}
|
|
gpu
|
|
.addFunction(child1Function)
|
|
.addFunction(child2Function)
|
|
.addFunction(child3Function);
|
|
const kernel = gpu.createKernel(function(kernelArgument1) {
|
|
return child1Function(child2Function(child3Function(kernelArgument1)));
|
|
}, { output: [1] });
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
try {
|
|
const result = kernel(texture);
|
|
assert.equal(result[0], 4.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[0][0], 'child3Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[1][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[2][0], 'child1Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[3][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[4][0], 'child3Function');
|
|
} finally {
|
|
FunctionBuilder.prototype.lookupReturnType.restore();
|
|
}
|
|
}
|
|
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('three argument layer deep NumberTexture(1) WebGL', () => {
|
|
threeArgumentLayerDeepNumberTexture1('webgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('three argument layer deep NumberTexture(1) WebGL2', () => {
|
|
threeArgumentLayerDeepNumberTexture1('webgl2');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('three argument layer deep NumberTexture(1) HeadlessGL', () => {
|
|
threeArgumentLayerDeepNumberTexture1('headlessgl');
|
|
});
|
|
|
|
function circlicalLogic(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function child1Function(child1FunctionArgument1) {
|
|
return child1Function(child1FunctionArgument1);
|
|
}
|
|
gpu
|
|
.addFunction(child1Function);
|
|
const kernel = gpu.createKernel(function(kernelArgument1) {
|
|
return child1Function(kernelArgument1);
|
|
}, { output: [1] });
|
|
assert.throws(() => {
|
|
kernel(1.5);
|
|
});
|
|
}
|
|
|
|
(GPU.isWebGLSupported ? test : skip)('circlical logic webgl', () => {
|
|
circlicalLogic('webgl');
|
|
});
|
|
(GPU.isWebGL2Supported ? test : skip)('circlical logic webgl2', () => {
|
|
circlicalLogic('webgl2');
|
|
});
|
|
(GPU.isHeadlessGLSupported ? test : skip)('circlical logic headlessgl', () => {
|
|
circlicalLogic('headlessgl');
|
|
});
|
|
|
|
function arrayTexture1(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function addOne(functionValue) {
|
|
return functionValue[this.thread.x] + 1;
|
|
}
|
|
gpu.addFunction(addOne);
|
|
const texture1 = gpu.createKernel(function() {
|
|
return 1;
|
|
}, {
|
|
output: [1],
|
|
precision: 'single',
|
|
pipeline: true,
|
|
})();
|
|
if (mode !== 'cpu') {
|
|
assert.equal(texture1.type, 'ArrayTexture(1)');
|
|
}
|
|
|
|
const kernel = gpu.createKernel(function(kernelValue) {
|
|
return addOne(kernelValue);
|
|
}, { output: [1] });
|
|
const result = kernel(texture1);
|
|
assert.equal(result[0], 2);
|
|
gpu.destroy();
|
|
}
|
|
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(1) auto', ()=> {
|
|
arrayTexture1();
|
|
});
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(1) gpu', ()=> {
|
|
arrayTexture1('gpu');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('ArrayTexture(1) webgl', ()=> {
|
|
arrayTexture1('webgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('ArrayTexture(1) webgl2', ()=> {
|
|
arrayTexture1('webgl2');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('ArrayTexture(1) headlessgl', ()=> {
|
|
arrayTexture1('headlessgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(1) cpu', ()=> {
|
|
arrayTexture1('cpu');
|
|
});
|
|
|
|
function arrayTexture2(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function addOne(functionValue) {
|
|
const declaredValue = functionValue[this.thread.x];
|
|
return declaredValue[0] + 1 + declaredValue[1] + 1;
|
|
}
|
|
gpu.addFunction(addOne);
|
|
const texture1 = gpu.createKernel(function() {
|
|
return [1,2];
|
|
}, {
|
|
output: [1],
|
|
precision: 'single',
|
|
pipeline: true,
|
|
})();
|
|
if (mode !== 'cpu') {
|
|
assert.equal(texture1.type, 'ArrayTexture(2)');
|
|
}
|
|
|
|
const kernel = gpu.createKernel(function(kernelValue) {
|
|
return addOne(kernelValue);
|
|
}, { output: [1] });
|
|
const result = kernel(texture1);
|
|
assert.equal(result[0], 5);
|
|
gpu.destroy();
|
|
}
|
|
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(2) auto', ()=> {
|
|
arrayTexture2();
|
|
});
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(2) gpu', ()=> {
|
|
arrayTexture2('gpu');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('ArrayTexture(2) webgl', ()=> {
|
|
arrayTexture2('webgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('ArrayTexture(2) webgl2', ()=> {
|
|
arrayTexture2('webgl2');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('ArrayTexture(2) headlessgl', ()=> {
|
|
arrayTexture2('headlessgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(2) cpu', ()=> {
|
|
arrayTexture2('cpu');
|
|
});
|
|
|
|
function arrayTexture3(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function addOne(functionValue) {
|
|
const declaredValue = functionValue[this.thread.x];
|
|
return declaredValue[0] + 1
|
|
+ declaredValue[1] + 1
|
|
+ declaredValue[2] + 1;
|
|
}
|
|
gpu.addFunction(addOne);
|
|
const texture1 = gpu.createKernel(function() {
|
|
return [1,2,3];
|
|
}, {
|
|
output: [1],
|
|
precision: 'single',
|
|
pipeline: true,
|
|
})();
|
|
if (mode !== 'cpu') {
|
|
assert.equal(texture1.type, 'ArrayTexture(3)');
|
|
}
|
|
|
|
const kernel = gpu.createKernel(function(kernelValue) {
|
|
return addOne(kernelValue);
|
|
}, { output: [1] });
|
|
const result = kernel(texture1);
|
|
assert.equal(result[0], 9);
|
|
gpu.destroy();
|
|
}
|
|
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(3) auto', ()=> {
|
|
arrayTexture3();
|
|
});
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(3) gpu', ()=> {
|
|
arrayTexture3('gpu');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('ArrayTexture(3) webgl', ()=> {
|
|
arrayTexture3('webgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('ArrayTexture(3) webgl2', ()=> {
|
|
arrayTexture3('webgl2');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('ArrayTexture(3) headlessgl', ()=> {
|
|
arrayTexture3('headlessgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(3) cpu', ()=> {
|
|
arrayTexture3('cpu');
|
|
});
|
|
|
|
function arrayTexture4(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function addOne(functionValue) {
|
|
const declaredValue = functionValue[this.thread.x];
|
|
return declaredValue[0] + 1
|
|
+ declaredValue[1] + 1
|
|
+ declaredValue[2] + 1
|
|
+ declaredValue[3] + 1;
|
|
}
|
|
gpu.addFunction(addOne);
|
|
const texture1 = gpu.createKernel(function() {
|
|
return [1,2,3,4];
|
|
}, {
|
|
output: [1],
|
|
precision: 'single',
|
|
pipeline: true,
|
|
})();
|
|
if (mode !== 'cpu') {
|
|
assert.equal(texture1.type, 'ArrayTexture(4)');
|
|
}
|
|
|
|
const kernel = gpu.createKernel(function(kernelValue) {
|
|
return addOne(kernelValue);
|
|
}, { output: [1] });
|
|
const result = kernel(texture1);
|
|
assert.equal(result[0], 14);
|
|
gpu.destroy();
|
|
}
|
|
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(4) auto', ()=> {
|
|
arrayTexture4();
|
|
});
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(4) gpu', ()=> {
|
|
arrayTexture4('gpu');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('ArrayTexture(4) webgl', ()=> {
|
|
arrayTexture4('webgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('ArrayTexture(4) webgl2', ()=> {
|
|
arrayTexture4('webgl2');
|
|
});
|
|
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('ArrayTexture(4) headlessgl', ()=> {
|
|
arrayTexture4('headlessgl');
|
|
});
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('ArrayTexture(4) cpu', ()=> {
|
|
arrayTexture4('cpu');
|
|
});
|
|
|
|
function testTortureTest(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function addFloatArray(addFloatArrayArgument1, addFloatArrayArgument2) {
|
|
return addFloatArrayArgument1 + addFloatArrayArgument2[this.thread.x];
|
|
}
|
|
function addArrayFloat(addArrayFloatArgument1, addArrayFloatArgument2) {
|
|
return addArrayFloatArgument1[this.thread.x] + addArrayFloatArgument2;
|
|
}
|
|
function addArrayArray(addArrayArrayArgument1, addArrayArrayArgument2) {
|
|
return addArrayArrayArgument1[this.thread.x] + addArrayArrayArgument2[this.thread.x];
|
|
}
|
|
function addFloatFloat(addFloatFloatArgument1, addFloatFloatArgument2) {
|
|
return addFloatFloatArgument1 + addFloatFloatArgument2;
|
|
}
|
|
gpu
|
|
.addFunction(addFloatArray)
|
|
.addFunction(addArrayFloat)
|
|
.addFunction(addArrayArray)
|
|
.addFunction(addFloatFloat);
|
|
|
|
const texture = gpu.createKernel(function() { return 2; }, { output: [1], precision: 'single' })();
|
|
// sinon.spy(FunctionBuilder.prototype, 'lookupArgumentType');
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
|
|
try {
|
|
const kernel = gpu.createKernel(function (v1, v2, v3, v4, v5) {
|
|
return addFloatFloat(v4, addArrayFloat(v3, addFloatArray(addArrayArray(v1, v5), v2)));
|
|
}, {output: [1]});
|
|
|
|
const result = kernel([1], texture, [3], 4, new Float32Array([5]));
|
|
assert.equal(result[0], 1 + 2 + 3 + 4 + 5);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 7);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.returnValues.length, 7);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[0][0], 'addArrayArray');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.returnValues[0], 'Number');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[1][0], 'addFloatArray');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.returnValues[1], 'Number');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[2][0], 'addArrayFloat');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.returnValues[2], 'Number');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[3][0], 'addFloatFloat');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.returnValues[3], 'Float');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[4][0], 'addArrayFloat');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.returnValues[4], 'Number');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[5][0], 'addFloatArray');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.returnValues[5], 'Number');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[6][0], 'addArrayArray');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.returnValues[6], 'Number');
|
|
} finally {
|
|
FunctionBuilder.prototype.lookupReturnType.restore();
|
|
}
|
|
}
|
|
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('torture test auto', () => {
|
|
testTortureTest();
|
|
});
|
|
|
|
(GPU.isSinglePrecisionSupported ? test : skip)('torture test gpu', () => {
|
|
testTortureTest('gpu');
|
|
});
|
|
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGLSupported ? test : skip)('torture test webgl', () => {
|
|
testTortureTest('webgl');
|
|
});
|
|
|
|
(GPU.isSinglePrecisionSupported && GPU.isWebGL2Supported ? test : skip)('torture test webgl2', () => {
|
|
testTortureTest('webgl2');
|
|
});
|
|
|
|
(GPU.isSinglePrecisionSupported && GPU.isHeadlessGLSupported ? test : skip)('torture test headlessgl', () => {
|
|
testTortureTest('headlessgl');
|
|
});
|
|
|
|
test('torture test cpu', () => {
|
|
testTortureTest('cpu');
|
|
});
|
|
|
|
function testKernelMap(mode) {
|
|
const gpu = new GPU({ mode });
|
|
function calc1(v1, v2) {
|
|
return v2[this.thread.x] - v1;
|
|
}
|
|
function calc2(v1, v2) {
|
|
return v1 * v2;
|
|
}
|
|
const kernelMap = gpu.createKernelMap({
|
|
calc1,
|
|
calc2,
|
|
}, function (outputs, targets) {
|
|
const output = outputs[this.thread.x];
|
|
return calc2(calc1(output, targets), output);
|
|
}, { output: [1], pipeline: true });
|
|
try {
|
|
const result = kernelMap([1], [3]);
|
|
assert.equal(result.calc1.toArray()[0], 2);
|
|
assert.equal(result.calc2.toArray()[0], 2);
|
|
assert.equal(result.result.toArray()[0], 2);
|
|
} finally {
|
|
gpu.destroy();
|
|
}
|
|
}
|
|
|
|
|
|
(GPU.isWebGLSupported ? test : skip)('kernel map webgl', () => {
|
|
testKernelMap('webgl');
|
|
});
|
|
|
|
(GPU.isWebGL2Supported ? test : skip)('kernel map webgl2', () => {
|
|
testKernelMap('webgl2');
|
|
});
|
|
|
|
(GPU.isHeadlessGLSupported ? test : skip)('kernel map headlessgl', () => {
|
|
testKernelMap('headlessgl');
|
|
});
|