diff --git a/src/backend/base-function-builder.js b/src/backend/base-function-builder.js index 580e3810..6db5cd93 100644 --- a/src/backend/base-function-builder.js +++ b/src/backend/base-function-builder.js @@ -18,6 +18,7 @@ module.exports = class BaseFunctionBuilder { constructor(gpu) { this.nodeMap = {}; this.gpu = gpu; + this.rootKernel = null; } /// @@ -46,6 +47,12 @@ module.exports = class BaseFunctionBuilder { /// addFunctionNode(inNode) { this.nodeMap[inNode.functionName] = inNode; + if (inNode.isRootKernel) { + if (this.rootKernel) { + throw new Error('root kernel already defined'); + } + this.rootKernel = inNode; + } } /// @@ -65,7 +72,7 @@ module.exports = class BaseFunctionBuilder { traceFunctionCalls(functionName, retList) { functionName = functionName || 'kernel'; retList = retList || []; - + const fNode = this.nodeMap[functionName]; if(fNode) { // Check if function already exists @@ -145,6 +152,7 @@ module.exports = class BaseFunctionBuilder { /// {String} The full webgl string, of all the various functions. Trace optimized if functionName given /// webGlPrototypeString(functionName) { + this.rootKernel.build(); if(functionName) { return this.webGlPrototypeStringFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); } diff --git a/src/backend/base-function-node.js b/src/backend/base-function-node.js index 88b618f0..3c7e553b 100644 --- a/src/backend/base-function-node.js +++ b/src/backend/base-function-node.js @@ -48,6 +48,7 @@ module.exports = class BaseFunctionNode { this.initVariables = []; this.readVariables = []; this.writeVariables = []; + this.addFunction = null; // // Missing jsFunction object exception @@ -87,7 +88,7 @@ module.exports = class BaseFunctionNode { // Extract parameter name, and its argument types // this.paramNames = utils.getParamNamesFromString(this.jsFunctionString); - if(paramTypeArray != null) { + if(paramTypeArray) { if(paramTypeArray.length !== this.paramNames.length) { throw 'Invalid argument type array length, against function length -> ('+ paramTypeArray.length+','+ @@ -108,6 +109,11 @@ module.exports = class BaseFunctionNode { this.returnType = returnType || 'float'; } + setAddFunction(fn) { + this.addFunction = fn; + return this; + } + // // Core function //---------------------------------------------------------------------------------------------------- @@ -153,7 +159,7 @@ module.exports = class BaseFunctionNode { } inParser = inParser || parser; - if(inParser == null) { + if(inParser === null) { throw 'Missing JS to AST parser'; } @@ -193,4 +199,8 @@ module.exports = class BaseFunctionNode { setFunctionString(functionString) { this.functionString = functionString; } + + build(options) { + throw new Error('build not defined on BaseFunctionNode'); + } }; diff --git a/src/backend/base-kernel.js b/src/backend/base-kernel.js index 4e9f95d8..b6c9e88d 100644 --- a/src/backend/base-kernel.js +++ b/src/backend/base-kernel.js @@ -20,6 +20,7 @@ module.exports = class BaseKernel { this.floatTextures = null; this.floatOutput = null; this.floatOutputForce = null; + this.addFunction = null; for (let p in settings) { if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue; @@ -31,6 +32,11 @@ module.exports = class BaseKernel { throw new Error('"build" not defined on Base'); } + setAddFunction(cb) { + this.addFunction = cb; + return this; + } + setDimensions(dimensions) { this.dimensions = dimensions; return this; diff --git a/src/backend/base-runner.js b/src/backend/base-runner.js index ded471c3..318ce069 100644 --- a/src/backend/base-runner.js +++ b/src/backend/base-runner.js @@ -66,6 +66,10 @@ module.exports = class BaseRunner { throw 'Unable to get body of kernel function'; } + if (!settings.functionBuilder) { + settings.functionBuilder = this.functionBuilder; + } + return kernelRunShortcut(new this.Kernel(fnString, settings)); } }; diff --git a/src/backend/cpu/cpu-function-builder.js b/src/backend/cpu/cpu-function-builder.js index a2006b8f..fcb2bc47 100644 --- a/src/backend/cpu/cpu-function-builder.js +++ b/src/backend/cpu/cpu-function-builder.js @@ -3,6 +3,9 @@ const CPUFunctionNode = require('./cpu-function-node'); module.exports = class CPUFunctionBuilder extends BaseFunctionBuilder { addFunction(functionName, jsFunction, paramTypeArray, returnType) { - this.addFunctionNode(new CPUFunctionNode(functionName, jsFunction, paramTypeArray, returnType)); + this.addFunctionNode( + new CPUFunctionNode(functionName, jsFunction, paramTypeArray, returnType) + .setAddFunction(this.addFunction.bind(this)) + ); } }; \ No newline at end of file diff --git a/src/backend/gpu/gpu-function-builder.js b/src/backend/gpu/gpu-function-builder.js index 7616cb22..7682c2a7 100644 --- a/src/backend/gpu/gpu-function-builder.js +++ b/src/backend/gpu/gpu-function-builder.js @@ -3,6 +3,9 @@ const GPUFunctionNode = require('./gpu-function-node'); module.exports = class GPUFunctionBuilder extends BaseFunctionBuilder { addFunction(functionName, jsFunction, paramTypeArray, returnType) { - this.addFunctionNode(new GPUFunctionNode(functionName, jsFunction, paramTypeArray, returnType)); + this.addFunctionNode( + new GPUFunctionNode(functionName, jsFunction, paramTypeArray, returnType) + .setAddFunction(this.addFunction.bind(this)) + ); } }; \ No newline at end of file diff --git a/src/backend/gpu/gpu-function-node.js b/src/backend/gpu/gpu-function-node.js index 41c6e845..24cea5d7 100644 --- a/src/backend/gpu/gpu-function-node.js +++ b/src/backend/gpu/gpu-function-node.js @@ -190,7 +190,9 @@ module.exports = class GPUFunctionNode extends BaseFunctionNode { funcArr.push(lines[end.line-1].slice(0, end.column)); const funcStr = funcArr.join('\n'); - this.gpu.addFunction(funcStr); + if (this.addFunction) { + this.addFunction(funcStr); + } return retArr; } @@ -857,4 +859,8 @@ module.exports = class GPUFunctionNode extends BaseFunctionNode { } return this.webGlFunctionPrototypeString = this.generate(options); } + + build(options) { + return this.getFunctionPrototypeString(options).length > 0; + } }; \ No newline at end of file diff --git a/src/backend/gpu/gpu-kernel.js b/src/backend/gpu/gpu-kernel.js index d2e7f8b0..be34a44c 100644 --- a/src/backend/gpu/gpu-kernel.js +++ b/src/backend/gpu/gpu-kernel.js @@ -14,7 +14,7 @@ module.exports = class GPUKernel extends BaseKernel { this.framebufferCache = {}; this.buffer = null; this.program = null; - this.functionBuilder = new GPUFunctionBuilder(); + this.functionBuilder = settings.functionBuilder; this.endianness = utils.systemEndianness; } @@ -125,6 +125,7 @@ module.exports = class GPUKernel extends BaseKernel { } const kernelNode = new GPUFunctionNode('kernel', this.fnString); + kernelNode.setAddFunction(builder.addFunction.bind(builder)); kernelNode.paramNames = paramNames; kernelNode.paramType = paramType; kernelNode.isRootKernel = true; @@ -320,7 +321,6 @@ void main(void) { } } }`; - console.log(builder.webGlPrototypeString('kernel')); const fragShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(vertShader, vertShaderSrc); diff --git a/test/src/features/mult_AB.js b/test/src/features/mult_AB.js index ef50ae7c..0b6010ba 100644 --- a/test/src/features/mult_AB.js +++ b/test/src/features/mult_AB.js @@ -1,5 +1,5 @@ function mult_AB_test( assert, mode ) { - var gpu = new GPU(); + var gpu = new GPU({ mode }); var f = gpu.createKernel(function(a, b) { var sum = 0; sum += a[this.thread.y][0] * b[0][this.thread.x]; @@ -7,8 +7,7 @@ function mult_AB_test( assert, mode ) { sum += a[this.thread.y][2] * b[2][this.thread.x]; return sum; }, { - dimensions : [3, 3], - mode: mode + dimensions : [3, 3] }); assert.ok( f !== null, "function generated test"); @@ -27,7 +26,7 @@ function mult_AB_test( assert, mode ) { [30, 36, 42], [66, 81, 96], [102, 126, 150] - ], + ], "basic mult function test" ); }