# IntelLabs/RiverTrail

updated static webpages

1 parent 4a84eb4 commit f8234bc95b8c55f3e017f7109b78001c27c7486e Stephan Herhut committed May 21, 2012
 @@ -74,9 +74,9 @@
Some more idioms to play with:

-increment: var result = first.map(function f() {return this+1;})
+increment: var result = first.map(function f(val) {return val+1;})
add: var result = first.combine(function f(idx,snd) {return this.get(idx)+snd.get(idx);}, second)
-sum: var result = first.reduce(function f(acc) {return this+acc;})
+sum: var result = first.reduce(function f(a, b) {return a + b;})

Enjoy!

 @@ -316,16 +316,28 @@ var ParallelArray = function () { // Flatten a multidimensional array to a single dimension. var createFlatArray = function createFlatArray (arr) { - var localShape = arrShape(arr); - var resultLength = shapeToLength(localShape); - var flatArray = new Array(resultLength); + // we build localShape and localRank as we go + var localShape = []; + var localRank = undefined; + var flatArray = new Array(); var flatIndex = 0; var flattenFlatParallelArray = function flattenFlatParallelArray (level, pa) { // We know we have a parallel array, we know it is flat. // Flat arrays are flat all the way down. - if (!localShape.slice(level).every(function (v, idx) {return v === pa.shape[idx];})) { - throw "wrong shape of nested PA " + localShape.slice(level) + " and " + pa.shape; + // update/check localShape and localRank + pa.shape.forEach( function (v, idx) { + if (localShape[level+idx] === undefined) { + localShape[level+idx] = v; + } else if (localShape[level+idx] !== v) { + //throw "wrong shape of nested PA at " + idx + " local " + v + "/global " + localShape[level+idx]; + throw "shape mismatch: level " + (level+idx) + " expected " + localShape[level+idx] + " found " + v; + } + }); + if (localRank === undefined) { + localRank = level + pa.shape.length; + } else if (localRank !== level + pa.shape.length) { + throw "dimensionality mismatch; expected " + localRank + " found " + (level + pa.shape.length); } var i; var size = shapeToLength(pa.shape); @@ -344,43 +356,41 @@ var ParallelArray = function () { return; } } - if (localShape[level] != arr.length) { + if (localShape[level] === undefined) { + localShape[level] = arr.length; + } else if (localShape[level] !== arr.length) { // We do not have a regular array. - console.log("createFlatArray: array is not regular - shape[level] != arr.length"); - console.log(" shape: ", localShape, " level: ", level, " arr.length: ". arr.length); - throw ("Array is not regular."); + throw "shape mismatch: level " + (level) + " expected " + localShape[level] + " found " + arr.length; } for (thisLevelIndex=0;thisLevelIndex level) { - throw "irregular array -- too few dimensions"; - } flattenInner(level+1, arr[thisLevelIndex].get(i)); } } else { // it's not an array or ParallelArray so it is just an element. flatArray[flatIndex] = arr[thisLevelIndex]; flatIndex++; + // check for rank uniformity + if (localRank === undefined) { + localRank = level; + } else if (localRank !== level) { + throw "dimensionality mismatch; expected " + localRank + " found " + level; + } } } }; // flattenInner try { flattenInner(0, arr); } catch (err) { console.log("flattenArray:", err); - console.log("returning null instead of a vector."); return null; }; - if (flatArray.length != resultLength) { - console.log ("bummer .. (flatArray.length (", flatArray.length, ") != resultLength(", resultLength, ")"); - } return flatArray; }; @@ -871,7 +881,7 @@ var ParallelArray = function () { var paResult; var extraArgs; var extraArgOffset = 2; - if (typeof(depth) === 'function') { + if ((typeof(depth) === 'function') || (depth instanceof low_precision.wrapper)) { f = depth; depth = 1; extraArgOffset = 1; @@ -1920,7 +1930,7 @@ var ParallelArray = function () { result = createSimpleParallelArray.call(this, arguments[1], arguments[0]); } else if (useFF4Interface && (arguments[0] instanceof Components.interfaces.dpoIData)) { result = createOpenCLMemParallelArray.apply(this, arguments); - } else if (arguments[1] instanceof Function) { + } else if (typeof(arguments[1]) === 'function') { var extraArgs; if (arguments.length > 2) { extraArgs = new Array(arguments.length -2); // skip the size vector and the function
 @@ -81,7 +81,6 @@ RiverTrail.compiler = (function () { var kernelString; var lowPrecision; var ast; - var rawArgs = args; var i; // If f is a low_precision wrapped function, unwrap it first if (f instanceof low_precision.wrapper) { @@ -92,16 +91,18 @@ RiverTrail.compiler = (function () { } const defaultNumberType = lowPrecision ? "float": "double"; - // First convert all arguments to ParallelArray representation. As we need to have shape and type - // information anyhow, this has little overhead to only converting the data to a typed array. - // I use the prototype here as args might not be a real array. + // First convert all array arguments into suitable flat representations that can be passed to + // the OpenCL side args = Array.prototype.map.call(args, function (object) { if (object instanceof Array) { - var result = new ParallelArray( lowPrecision ? Float32Array : Float64Array, object); - result._wasArray = true; - return result; + if ((typeof(openCLContext.canBeMapped) === 'function') && (openCLContext.canBeMapped(object))) { + // we have found a JavaScript array that can be directly mapped, so we keep it + return object; + } else { + return new RiverTrail.Helper.FlatArray( lowPrecision ? Float32Array : Float64Array, object); + } } else { return object; }}); @@ -133,7 +134,7 @@ RiverTrail.compiler = (function () { } try { - ast = parse(paSource, construct, rankOrShape, f.toString(), rawArgs, lowPrecision); // parse, no code gen + ast = parse(paSource, construct, rankOrShape, f.toString(), args, lowPrecision); // parse, no code gen kernelString = RiverTrail.compiler.codeGen(ast, paSource, rankOrShape, construct); // Creates an OpenCL kernel function } catch (e) { RiverTrail.Helper.debugThrow(e); @@ -236,10 +237,16 @@ RiverTrail.compiler = (function () { var argument = args[i]; if (argument instanceof ParallelArray) { argumentTypes.push(inferPAType(argument)); + } else if (argument instanceof RiverTrail.Helper.FlatArray) { + argumentTypes.push({ inferredType: defaultNumberType, dimSize: argument.shape}); } else if (argument instanceof Array) { - // SAH: treating all non-PA arrays as float requires a check for regularity and - // homogeneity! This is done in the transfer code. - argumentTypes.push({ inferredType: defaultNumberType, dimSize: [argument.length] }); + // SAH: if an array makes it here without being transformed into a flat array, it + // must be a dense, homogeneous JavaScript array. Those are always double arrays + // and we assume the shape can be derived by looking at the first element in + // each dimension. + // NOTE: I use /* jsval */ double as type to make sure these are not confused with + // ordinary arrays when checking for matching signatures. + argumentTypes.push({ inferredType: "/* jsval */ double", dimSize: function makeShape(a, r) { if (a instanceof Array) { r.push(a.length); makeShape(a[0], r); } return r;}(argument, []) }); } else if (RiverTrail.Helper.isTypedArray(argument)) { argumentTypes.push({ inferredType: RiverTrail.Helper.inferTypedArrayType(argument), dimSize: [argument.length] }); } else if (argument instanceof RiverTrail.Helper.Integer) { @@ -252,7 +259,7 @@ RiverTrail.compiler = (function () { // numbers are floats argumentTypes.push({ inferredType: defaultNumberType, dimSize: [] }); } else { - throw new CompilerBug("Type derivation for argument not implemented yet"); + throw new Error("Type derivation for argument not implemented yet"); } } return argumentTypes; @@ -268,7 +275,7 @@ RiverTrail.compiler = (function () { if (key === 'tokenizer' ) { return '-- hidden --'; } - if ((key === 'flowTo') || (key === 'flowFrom')) { + if (key === 'flowTo') { return '-- cyclic --'; } return value; @@ -291,16 +298,6 @@ RiverTrail.compiler = (function () { Array.prototype.every.call(shapeA, function (a,idx) { return a == shapeB[idx];})); }; - // I create three names for Error here so that we can, should we ever wish - // distinguish both or have our own implementation for exceptions - var errorHelper = function errorHelper(e) { - throw (e); - }; - - var CompilerError = errorHelper; - var CompilerBug = errorHelper; // something went wrong although it should not - var CompilerAbort = errorHelper; // exception thrown to influence control flow, e.g., misspeculation - // end code from parallel array return { verboseDebug: false,