Add loopMaxIterations option

This commit is contained in:
Fazli Sapuan 2016-02-28 16:03:01 +08:00
parent 3e65ed4d41
commit ec9c3304e2
6 changed files with 51 additions and 26 deletions

View File

@ -167,6 +167,11 @@
return ret;
};
ret.loopMaxIterations = function(max) {
opt.loopMaxIterations = max;
return ret;
};
ret.wraparound = function() {
opt.wraparound = false;
return ret;

View File

@ -64,7 +64,7 @@ var functionBuilder = (function() {
///
/// Returns:
/// {[String,...]} Returning list of function names that is traced. Including itself.
function traceFunctionCalls( functionName, retList ) {
function traceFunctionCalls( functionName, retList, opt ) {
functionName = functionName || "kernel";
retList = retList || [];
@ -76,9 +76,9 @@ var functionBuilder = (function() {
} else {
retList.push(functionName);
fNode.getWebglFunctionString(); //ensure JS trace is done
fNode.getWebglFunctionString(opt); //ensure JS trace is done
for(var i=0; i<fNode.calledFunctions.length; ++i) {
this.traceFunctionCalls( fNode.calledFunctions[i], retList );
this.traceFunctionCalls( fNode.calledFunctions[i], retList, opt );
}
}
}
@ -96,12 +96,12 @@ var functionBuilder = (function() {
/// Returns:
/// {String} The full webgl string, of all the various functions. Trace optimized if functionName given
///
function webglString_fromFunctionNames(functionList) {
function webglString_fromFunctionNames(functionList, opt) {
var ret = [];
for(var i=0; i<functionList.length; ++i) {
var node = this.nodeMap[functionList[i]];
if(node) {
ret.push( this.nodeMap[functionList[i]].getWebglFunctionString() );
ret.push( this.nodeMap[functionList[i]].getWebglFunctionString(opt) );
}
}
return ret.join("\n");
@ -117,11 +117,15 @@ var functionBuilder = (function() {
/// Returns:
/// {String} The full webgl string, of all the various functions. Trace optimized if functionName given
///
function webglString(functionName) {
if(functionName) {
return this.webglString_fromFunctionNames( this.traceFunctionCalls(functionName, []).reverse() );
function webglString(functionName, opt) {
if (opt == undefined) {
opt = {};
}
return this.webglString_fromFunctionNames(Object.keys(this.nodeMap));
if(functionName) {
return this.webglString_fromFunctionNames( this.traceFunctionCalls(functionName, [], opt).reverse(), opt );
}
return this.webglString_fromFunctionNames( Object.keys(this.nodeMap), opt );
}
functionBuilder.prototype.webglString = webglString;

View File

@ -248,12 +248,12 @@ var functionNode = (function() {
/// Returns:
/// {String} webgl function string, result is cached under this.webglFunctionString
///
function getWebglFunctionString() {
function getWebglFunctionString(opt) {
if( this.webglFunctionString ) {
return this.webglFunctionString;
}
return this.webglFunctionString = functionNode_webgl(this);
return this.webglFunctionString = functionNode_webgl(this, opt);
}
functionNode.prototype.getWebglFunctionString = getWebglFunctionString;

View File

@ -1,7 +1,7 @@
// Closure capture for the ast function, prevent collision with existing AST functions
var functionNode_webgl = (function() {
var gpu, jsFunctionString;
var gpu, opt, jsFunctionString;
function isIdentifierKernelParam(paramName, ast, funcParam) {
return funcParam.paramNames.indexOf(paramName) != -1;
@ -31,8 +31,9 @@ var functionNode_webgl = (function() {
/// Returns:
/// the converted webGL function string
///
function functionNode_webgl( inNode ) {
function functionNode_webgl( inNode, _opt ) {
gpu = inNode.gpu;
opt = _opt;
jsFunctionString = inNode.jsFunctionString;
inNode.webglFunctionString_array = ast_generic( inNode.getJS_AST(), [], inNode );
inNode.webglFunctionString = webgl_regex_optimize(
@ -344,15 +345,26 @@ var functionNode_webgl = (function() {
}
if (forNode.test && forNode.test.type == "BinaryExpression") {
if (forNode.test.right.type != "Literal") {
retArr.push("{\n");
retArr.push("float ");
ast_generic(forNode.init, retArr, funcParam);
retArr.push(";\n");
retArr.push("for (float i=0.0; i<LOOP_MAX; i++, ");
ast_generic(forNode.update, retArr, funcParam);
retArr.push(") {\n");
if (forNode.test.right.type == "Identifier"
&& forNode.test.operator == "<") {
console.log(opt.loopMaxIterations);
if (opt.loopMaxIterations === undefined) {
console.warn("Warning: loopMaxIterations is not set! Using default of 100 which may result in unintended behavior.");
console.warn("Set loopMaxIterations or use a for loop of fixed length to silence this message.");
}
retArr.push("for (float ");
ast_generic(forNode.init, retArr, funcParam);
retArr.push(";");
ast_generic(forNode.test.left, retArr, funcParam);
retArr.push(forNode.test.operator);
retArr.push("LOOP_MAX");
retArr.push(";");
ast_generic(forNode.update, retArr, funcParam);
retArr.push(")");
retArr.push("{\n");
retArr.push("if (");
ast_generic(forNode.test.left, retArr, funcParam);
retArr.push(forNode.test.operator);
@ -363,8 +375,6 @@ var functionNode_webgl = (function() {
}
retArr.push("} else {\n");
retArr.push("break;\n");
retArr.push("}\n");
retArr.push("}\n");
retArr.push("}\n");

View File

@ -242,7 +242,7 @@
'precision highp float;',
'precision highp int;',
'',
'#define LOOP_MAX 10000000.0',
'#define LOOP_MAX '+ (opt.loopMaxIterations ? parseInt(opt.loopMaxIterations)+'.0' : '100.0'),
'',
opt.hardcodeConstants ? 'vec3 uOutputDim = vec3('+threadDim[0]+','+threadDim[1]+', '+ threadDim[2]+');' : 'uniform vec3 uOutputDim;',
opt.hardcodeConstants ? 'vec2 uTexSize = vec2('+texSize[0]+','+texSize[1]+');' : 'uniform vec2 uTexSize;',
@ -315,7 +315,7 @@
'}',
'',
paramStr,
builder.webglString("kernel"),
builder.webglString("kernel", opt),
'',
'void main(void) {',
' index = floor(vTexCoord.s * float(uTexSize.x)) + floor(vTexCoord.t * float(uTexSize.y)) * uTexSize[0];',
@ -511,6 +511,11 @@
opt.graphical = flag;
return ret;
};
ret.loopMaxIterations = function(max) {
opt.loopMaxIterations = max;
return ret;
};
ret.wraparound = function(flag) {
opt.wraparound = flag;

View File

@ -58,7 +58,8 @@ QUnit.test( "for_loop (CPU)", function( assert ) {
var evil_while_cpuRef = new GPU();
var evil_while_cpuRef_f = evil_while_cpuRef.createKernel(evil_while_kernalFunction, {
dimensions : [6],
mode : "cpu"
mode : "cpu",
loopMaxIterations: 10000
});
var evil_while_exp = evil_while_cpuRef_f(evil_while_a,evil_while_b);