Skip to content

Commit

Permalink
add new feature combineKernels
Browse files Browse the repository at this point in the history
and fix a return on cpu when in graphic mode
  • Loading branch information
robertleeplummerjr committed May 17, 2017
1 parent acc3651 commit 323a4e1
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/backend/cpu/kernel.js
Expand Up @@ -95,6 +95,7 @@ module.exports = class CPUKernel extends KernelBase {
if (this.graphical) {
this._imageData.data.set(this._colorData);
this._canvasCtx.putImageData(this._imageData, 0, 0);
return;
}

if (this.dimensions.length === 1) {
Expand Down
45 changes: 45 additions & 0 deletions src/gpu.js
Expand Up @@ -81,6 +81,51 @@ module.exports = class GPU {
return this._kernelSynchronousExecutor = this._runner.buildKernel(fn, settings || {});
}

combineKernels() {
const lastKernel = arguments[arguments.length - 2];
const combinedKernel = arguments[arguments.length - 1];
if (this.mode === 'cpu') return combinedKernel;

const canvas = arguments[0].canvas;
let webGl = arguments[0].webGl;

for (let i = 0; i < arguments.length - 1; i++) {
arguments[i]
.setCanvas(canvas)
.setWebGl(webGl)
.setOutputToTexture(true);
}

return function() {
combinedKernel.apply(null, arguments);
const texSize = lastKernel.texSize;
const gl = lastKernel.webGl;
const threadDim = lastKernel.threadDim;
let result;
if (lastKernel.floatOutput) {
result = new Float32Array(texSize[0] * texSize[1] * 4);
gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result);
} else {
const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);
gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
result = Float32Array.prototype.slice.call(new Float32Array(bytes.buffer));
}

result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);

if (lastKernel.dimensions.length === 1) {
return result;
} else if (lastKernel.dimensions.length === 2) {
return utils.splitArray(result, lastKernel.dimensions[0]);
} else if (lastKernel.dimensions.length === 3) {
const cube = utils.splitArray(result, lastKernel.dimensions[0] * lastKernel.dimensions[1]);
return cube.map(function(x) {
return utils.splitArray(x, lastKernel.dimensions[0]);
});
}
};
}

get mode() {
return this._runner.mode;
}
Expand Down
17 changes: 17 additions & 0 deletions test/html/features/combine-kernels.html
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GPU.JS : Combine Kernels</title>
<link rel="stylesheet" href="../../../node_modules/qunitjs/qunit/qunit.css">

<!-- gpu.js scripts -->
<script src="../../../bin/gpu.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="../../../node_modules/qunitjs/qunit/qunit.js"></script>
<script src="../../src/features/combine-kernels.js"></script>
</body>
</html>
1 change: 1 addition & 0 deletions test/html/test-all.html
Expand Up @@ -24,6 +24,7 @@
<script src="../src/features/add-custom-function.js"></script>
<script src="../src/features/nested-function.js"></script>
<script src="../src/features/get-canvas.js"></script>
<script src="../src/features/combine-kernels.js"></script>

<!-- internal -->
<script src="../src/internal/utils.js"></script>
Expand Down
35 changes: 35 additions & 0 deletions test/src/features/combine-kernels.js
@@ -0,0 +1,35 @@
function combineKernels(mode) {
var gpu = new GPU({ mode: mode });

var kernel1 = gpu.createKernel(function(a, b) {
return a[this.thread.x] + b[this.thread.x];
}, { dimensions: [5] });

var kernel2 = gpu.createKernel(function(c, d) {
return c[this.thread.x] * d[this.thread.x];
}, { dimensions: [5] });

return gpu.combineKernels(kernel1, kernel2, function(array1, array2, array3) {
return kernel2(kernel1(array1, array2), array3);
});
}

QUnit.test( "combineKernels (auto)", function() {
var superKernel = combineKernels(null);
var result = QUnit.extend([], superKernel([1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]));
QUnit.assert.deepEqual(result, [2, 8, 18, 32, 50]);
});

QUnit.test( "combineKernels (WebGL)", function() {
var superKernel = combineKernels('webgl');
var result = QUnit.extend([], superKernel([1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]));
QUnit.assert.deepEqual(result, [2, 8, 18, 32, 50]);
});

QUnit.test( "combineKernels (CPU)", function() {
var superKernel = combineKernels('cpu');
var result = QUnit.extend([], superKernel([1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]));
QUnit.assert.deepEqual(result, [2, 8, 18, 32, 50]);
});

console.log(combineKernels('gpu')([1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]));

0 comments on commit 323a4e1

Please sign in to comment.