fix addFunction so that root kernel is built

This commit is contained in:
Robert Plummer 2017-05-07 07:26:18 -04:00
parent e04b35a0b9
commit cb4d78e10b
9 changed files with 51 additions and 12 deletions

View File

@ -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());
}

View File

@ -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');
}
};

View File

@ -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;

View File

@ -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));
}
};

View File

@ -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))
);
}
};

View File

@ -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))
);
}
};

View File

@ -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;
}
};

View File

@ -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);

View File

@ -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"
);
}