mirror of
https://github.com/gpujs/gpu.js.git
synced 2026-01-25 16:08:02 +00:00
feat: `switch` statements
feat: `kernel.toString()` has as well `.getPixels()`
fix: Proper fallback when arguments or constants are not supported
fix: Removal of infamous `|| 'Number'` for argument types and return types
fix: detect circlical logic in `FunctionBuilder.lookupReturnType()` and tests
fix: Allow subKernels to get their type detected as well
fix: `FunctionNode`'s `typeLookupMap` didn't have 'Float' or 'Integer'
feat: Turn off context checking in kernel, via `{ checkContext: false }`, used for `kernel.toString()`
fix: `GPU.upgradeDeprecatedCreateKernelSettings` to have a default return value
fix: Typings
fix: `kernelRunShortcut()` to better switch kernel when replacing
feat: It order to flatten methods, for `kernel.toString()` `utils.flattenFunctionToString()` and light unit testing of it
fix: Added sinon for testing
fix: Bump gl-wiretap
250 lines
10 KiB
JavaScript
250 lines
10 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, 'lookupArgumentType');
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
const result = kernel(1.5);
|
|
assert.equal(result[0], 2.5);
|
|
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.callCount, 1);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[0][0], 'childFunctionArgument1');
|
|
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 1);
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[0][0], 'childFunction');
|
|
|
|
FunctionBuilder.prototype.lookupArgumentType.restore();
|
|
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, 'lookupArgumentType');
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
const result = kernel(1.5);
|
|
assert.equal(result[0], 2.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.callCount, 2);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[0][0], 'child2FunctionArgument1');
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[1][0], 'child1FunctionArgument1');
|
|
|
|
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');
|
|
|
|
FunctionBuilder.prototype.lookupArgumentType.restore();
|
|
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, 'lookupArgumentType');
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
const result = kernel(1.5);
|
|
assert.equal(kernel.returnType, 'Float');
|
|
assert.equal(result[0], 3.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.callCount, 2);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[0][0], 'child1FunctionArgument1');
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[1][0], 'child2FunctionArgument1');
|
|
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 4);
|
|
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');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[3][0], 'child2Function');
|
|
|
|
FunctionBuilder.prototype.lookupArgumentType.restore();
|
|
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, 'lookupArgumentType');
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
const result = kernel(1.5);
|
|
assert.equal(result[0], 3.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.callCount, 3);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[0][0], 'child3FunctionArgument1');
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[1][0], 'child2FunctionArgument1');
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[2][0], 'child1FunctionArgument1');
|
|
|
|
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');
|
|
|
|
FunctionBuilder.prototype.lookupArgumentType.restore();
|
|
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, 'lookupArgumentType');
|
|
sinon.spy(FunctionBuilder.prototype, 'lookupReturnType');
|
|
const result = kernel(1.5);
|
|
assert.equal(result[0], 4.5);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.callCount, 3);
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[0][0], 'child1FunctionArgument1');
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[1][0], 'child2FunctionArgument1');
|
|
assert.equal(FunctionBuilder.prototype.lookupArgumentType.args[2][0], 'child3FunctionArgument1');
|
|
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.callCount, 8);
|
|
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');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[3][0], 'child3Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[4][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[5][0], 'child3Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[6][0], 'child2Function');
|
|
assert.equal(FunctionBuilder.prototype.lookupReturnType.args[7][0], 'child3Function');
|
|
|
|
FunctionBuilder.prototype.lookupArgumentType.restore();
|
|
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 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 webgl', () => {
|
|
circlicalLogic('webgl2');
|
|
});
|
|
(GPU.isHeadlessGLSupported ? test : skip)('circlical logic webgl', () => {
|
|
circlicalLogic('headlessgl');
|
|
});
|