Skip to content
This repository has been archived by the owner on Aug 16, 2018. It is now read-only.

Commit

Permalink
make tests es5 and add the kernel .toString() method, so we can hav…
Browse files Browse the repository at this point in the history
…e the entire kernel, and nothing else.
  • Loading branch information
robertleeplummerjr committed Jun 29, 2017
1 parent c5db5b0 commit 81275b5
Show file tree
Hide file tree
Showing 14 changed files with 388 additions and 173 deletions.
4 changes: 2 additions & 2 deletions src/alias.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const utils = require('./utils');
module.exports = function alias(name, fn) {
const fnString = fn.toString();
return new Function(`return function ${ name } (${ utils.getParamNamesFromString(fnString).join(', ') }) {${ utils.getFunctionBodyFromString(fnString) }}`)();
const fnString = fn.toString();
return new Function(`return function ${ name } (${ utils.getParamNamesFromString(fnString).join(', ') }) {${ utils.getFunctionBodyFromString(fnString) }}`)();
};
56 changes: 56 additions & 0 deletions src/backend/cpu/kernel-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const utils = require('../../utils');
const kernelRunShortcut = require('../kernel-run-shortcut');

module.exports = function(cpuKernel, name) {
return `() => {
${ kernelRunShortcut.toString() };
const utils = {
allPropertiesOf: function ${ utils.allPropertiesOf.toString() },
clone: function ${ utils.clone.toString() },
/*splitArray: function ${ utils.splitArray.toString() },
getArgumentType: function ${ utils.getArgumentType.toString() },
getDimensions: function ${ utils.getDimensions.toString() },
dimToTexSize: function ${ utils.dimToTexSize.toString() },
copyFlatten: function ${ utils.copyFlatten.toString() },
flatten: function ${ utils.flatten.toString() },
systemEndianness: '${ utils.systemEndianness }',
initWebGl: function ${ utils.initWebGl.toString() },
isArray: function ${ utils.isArray.toString() }*/
};
class ${ name || 'Kernel' } {
constructor() {
this.argumentsLength = 0;
this._canvas = null;
this._webGl = null;
this.built = false;
this.program = null;
this.paramNames = ${ JSON.stringify(cpuKernel.paramNames) };
this.paramTypes = ${ JSON.stringify(cpuKernel.paramTypes) };
this.texSize = ${ JSON.stringify(cpuKernel.texSize) };
this.dimensions = ${ JSON.stringify(cpuKernel.dimensions) };
this._kernelString = \`${ cpuKernel._kernelString }\`;
this.run = function() {
this.run = null;
this.build();
return this.run.apply(this, arguments);
}.bind(this);
this.thread = {
x: 0,
y: 0,
z: 0
};
this.runDimensions = {
x: null,
y: null,
z: null
};
}
setCanvas(canvas) { this._canvas = canvas; return this; }
setWebGl(webGl) { this._webGl = webGl; return this; }
${ cpuKernel.build.toString() }
run () { ${ cpuKernel.kernelString } }
getKernelString() { return this._kernelString; }
};
return kernelRunShortcut(new Kernel());
};`;
};
197 changes: 106 additions & 91 deletions src/backend/cpu/kernel.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const KernelBase = require('../kernel-base');
const utils = require('../../utils');
const kernelString = require('./kernel-string');

module.exports = class CPUKernel extends KernelBase {
constructor(fnString, settings) {
Expand All @@ -11,6 +12,7 @@ module.exports = class CPUKernel extends KernelBase {
this._canvasCtx = null;
this._imageData = null;
this._colorData = null;
this._kernelString = null;
this.thread = {
x: 0,
y: 0,
Expand Down Expand Up @@ -48,8 +50,6 @@ module.exports = class CPUKernel extends KernelBase {

build() {
const kernelArgs = [];
const builder = this.functionBuilder;
const paramNames = this.paramNames;
for (let i = 0; i < arguments.length; i++) {
const argType = utils.getArgumentType(arguments[i]);
if (argType === 'Array' || argType === 'Number') {
Expand All @@ -61,28 +61,7 @@ module.exports = class CPUKernel extends KernelBase {
}
}

if (this.subKernels !== null) {
this.subKernelOutputTextures = [];
this.subKernelOutputVariableNames = [];
for (let i = 0; i < this.subKernels.length; i++) {
const subKernel = this.subKernels[i];
builder.addSubKernel(subKernel);
this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
}

} else if (this.subKernelProperties !== null) {
this.subKernelOutputVariableNames = [];
let i = 0;
for (let p in this.subKernelProperties) {
if (!this.subKernelProperties.hasOwnProperty(p)) continue;
const subKernel = this.subKernelProperties[p];
builder.addSubKernel(subKernel);
this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
i++;
}
}

const threadDim = this.threadDim = utils.clone(this.dimensions);
const threadDim = this.threadDim || (this.threadDim = utils.clone(this.dimensions));

while (threadDim.length < 3) {
threadDim.push(1);
Expand All @@ -97,73 +76,7 @@ module.exports = class CPUKernel extends KernelBase {
this._colorData = new Uint8ClampedArray(threadDim[0] * threadDim[1] * 4);
}

const kernelString = `
${ this.constants ? Object.keys(this.constants).map((key) => { return `var ${ key } = ${ this.constants[key] }`; }).join(';\n') + ';\n' : '' }
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` var ${ name } = null;\n`).join('')
}
${ builder.getPrototypeString() }
var fn = function fn(${ this.paramNames.join(', ') }) { ${ this._fnBody } }.bind(this);
return function (${ this.paramNames.join(', ') }) {
var ret = new Array(${ threadDim[2] });
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name } = new Array(${ threadDim[2] });\n`).join('')
}
for (this.thread.z = 0; this.thread.z < ${ threadDim[2] }; this.thread.z++) {
ret[this.thread.z] = new Array(${ threadDim[1] });
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name }[this.thread.z] = new Array(${ threadDim[1] });\n`).join('')
}
for (this.thread.y = 0; this.thread.y < ${ threadDim[1] }; this.thread.y++) {
ret[this.thread.z][this.thread.y] = new Array(${ threadDim[0] });
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name }[this.thread.z][this.thread.y] = new Array(${ threadDim[0] });\n`).join('')
}
for (this.thread.x = 0; this.thread.x < ${ threadDim[0] }; this.thread.x++) {
ret[this.thread.z][this.thread.y][this.thread.x] = fn(${ this.paramNames.join(', ') });
}
}
}
if (this.graphical) {
this._imageData.data.set(this._colorData);
this._canvasCtx.putImageData(this._imageData, 0, 0);
return;
}
if (this.dimensions.length === 1) {
ret = ret[0][0];
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name } = ${ name }[0][0];\n`).join('')
}
} else if (this.dimensions.length === 2) {
ret = ret[0];
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name } = ${ name }[0];\n`).join('')
}
}
${ this.subKernelOutputVariableNames === null
? 'return ret;\n'
: this.subKernels !== null
? `var result = [
${ this.subKernelOutputVariableNames.map((name) => `${ name }`).join(',\n') }
];
result.result = ret;
return result;\n`
: `return {
result: ret,
${ Object.keys(this.subKernelProperties).map((name, i) => `${ name }: ${ this.subKernelOutputVariableNames[i] }`).join(',\n') }
};`
}
}.bind(this);`;
const kernelString = this.getKernelString();

if (this.debug) {
console.log('Options:');
Expand All @@ -172,6 +85,7 @@ ${ this.subKernelOutputVariableNames === null
console.log(kernelString);
}

this.kernelString = kernelString;
this.run = new Function([], kernelString).bind(this)();
}

Expand All @@ -198,4 +112,105 @@ ${ this.subKernelOutputVariableNames === null
this._colorData[index * 4 + 2] = b;
this._colorData[index * 4 + 3] = a;
}

getKernelString() {
if (this._kernelString !== null) return this._kernelString;

const paramNames = this.paramNames;
const threadDim = this.threadDim;
const builder = this.functionBuilder;

if (this.subKernels !== null) {
this.subKernelOutputTextures = [];
this.subKernelOutputVariableNames = [];
for (let i = 0; i < this.subKernels.length; i++) {
const subKernel = this.subKernels[i];
builder.addSubKernel(subKernel);
this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
}

} else if (this.subKernelProperties !== null) {
this.subKernelOutputVariableNames = [];
let i = 0;
for (let p in this.subKernelProperties) {
if (!this.subKernelProperties.hasOwnProperty(p)) continue;
const subKernel = this.subKernelProperties[p];
builder.addSubKernel(subKernel);
this.subKernelOutputVariableNames.push(subKernel.name + 'Result');
i++;
}
}

return this._kernelString = `
${ this.constants ? Object.keys(this.constants).map((key) => { return `var ${ key } = ${ this.constants[key] }`; }).join(';\n') + ';\n' : '' }
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` var ${ name } = null;\n`).join('')
}
${ builder.getPrototypeString() }
var fn = function fn(${ this.paramNames.join(', ') }) { ${ this._fnBody } }.bind(this);
return function (${ this.paramNames.join(', ') }) {
var ret = new Array(${ threadDim[2] });
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name } = new Array(${ threadDim[2] });\n`).join('')
}
for (this.thread.z = 0; this.thread.z < ${ threadDim[2] }; this.thread.z++) {
ret[this.thread.z] = new Array(${ threadDim[1] });
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name }[this.thread.z] = new Array(${ threadDim[1] });\n`).join('')
}
for (this.thread.y = 0; this.thread.y < ${ threadDim[1] }; this.thread.y++) {
ret[this.thread.z][this.thread.y] = new Array(${ threadDim[0] });
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name }[this.thread.z][this.thread.y] = new Array(${ threadDim[0] });\n`).join('')
}
for (this.thread.x = 0; this.thread.x < ${ threadDim[0] }; this.thread.x++) {
ret[this.thread.z][this.thread.y][this.thread.x] = fn(${ this.paramNames.join(', ') });
}
}
}
if (this.graphical) {
this._imageData.data.set(this._colorData);
this._canvasCtx.putImageData(this._imageData, 0, 0);
return;
}
if (this.dimensions.length === 1) {
ret = ret[0][0];
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name } = ${ name }[0][0];\n`).join('')
}
} else if (this.dimensions.length === 2) {
ret = ret[0];
${ this.subKernelOutputVariableNames === null
? ''
: this.subKernelOutputVariableNames.map((name) => ` ${ name } = ${ name }[0];\n`).join('')
}
}
${ this.subKernelOutputVariableNames === null
? 'return ret;\n'
: this.subKernels !== null
? `var result = [
${ this.subKernelOutputVariableNames.map((name) => `${ name }`).join(',\n') }
];
result.result = ret;
return result;\n`
: `return {
result: ret,
${ Object.keys(this.subKernelProperties).map((name, i) => `${ name }: ${ this.subKernelOutputVariableNames[i] }`).join(',\n') }
};`
}
}.bind(this);`;
}

toString() {
return kernelString(this);
}
};
6 changes: 3 additions & 3 deletions src/backend/kernel-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const utils = require('../utils');
/// subKernelOutputVariableNames - {Array} Names of the variables outputted by the subkerls

module.exports = class BaseKernel {

///
/// Function: BaseKernel
///
Expand Down Expand Up @@ -148,7 +148,7 @@ module.exports = class BaseKernel {
this.outputToTexture = flag;
return this;
}

///
/// Function: setFloatTextures
///
Expand Down Expand Up @@ -257,7 +257,7 @@ module.exports = class BaseKernel {
}
});
}

/// Function: addSubKernel
///
/// Add a sub kernel to the root kernel instance.
Expand Down
16 changes: 4 additions & 12 deletions src/backend/kernel-run-shortcut.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const utils = require('../utils');

module.exports = function kernelRunShortcut(kernel) {
const shortcut = function() {
return kernel.run.apply(kernel, arguments);
};

allPropertiesOf(kernel).forEach((key) => {
utils.allPropertiesOf(kernel).forEach((key) => {
if (key[0] === '_' && key[1] === '_') return;
if (typeof kernel[key] === 'function') {
if (key.substring(0, 3) === 'set') {
Expand All @@ -27,14 +29,4 @@ module.exports = function kernelRunShortcut(kernel) {
shortcut.kernel = kernel;

return shortcut;
};

function allPropertiesOf(obj) {
const props = [];

do {
props.push.apply(props, Object.getOwnPropertyNames(obj));
} while (obj = Object.getPrototypeOf(obj));

return props;
}
};
4 changes: 2 additions & 2 deletions src/backend/runner-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const kernelRunShortcut = require('./kernel-run-shortcut');
///

module.exports = class BaseRunner {

///
/// Function: BaseRunner
///
Expand Down Expand Up @@ -88,7 +88,7 @@ module.exports = class BaseRunner {
///
/// Get and returns the Synchronous executor, of a class and kernel
/// Which returns the result directly after passing the arguments.
///
///
buildKernel(fn, settings) {
settings = Object.assign({}, settings || {});
const fnString = fn.toString();
Expand Down
Loading

0 comments on commit 81275b5

Please sign in to comment.