Use this WebCL test to see if your system supports WebCL.
<script id="clRand" type="text/x-opencl">
__kernel void kRand( global uint* rand ){
uint x = get_global_id(0);
rand[x] = 1664525u*rand[x] + 1013904223u;
}
</script>
Common for all scripts the loadKernel function reads the kernel source
<script type="text/javascript">
function loadKernel ( id ){
var shaderScript = document.getElementById ( id );
var str = "";
var k = shaderScript.firstChild;
while ( k ){
if ( k.nodeType == 3 ) str += k.textContent;
k = k.nextSibling;
}
return str;
}
The main function get the WebCL context
function CL_rand () {
var output = document.getElementById("output");
output.innerHTML = "";
try {
if (window.WebCL == undefined) {
alert("Unfortunately your system does not support WebCL");
return false;
}
var platforms = WebCL.getPlatformIDs();
var ctx = WebCL.createContextFromType ([WebCL.CL_CONTEXT_PLATFORM,
platforms[0]], WebCL.CL_DEVICE_TYPE_DEFAULT);
var devices = ctx.getContextInfo(WebCL.CL_CONTEXT_DEVICES);
prepares data
var n = 8;
var UIrand = new Uint32Array(n);
for ( var i = 0; i < n; i++)
UIrand[i] = Math.floor(Math.random() * 4294967295);
var bufSize = n * 4;
var bufRand = ctx.createBuffer (WebCL.CL_MEM_READ_WRITE, bufSize);
loads, compiles kernel and set its arguments
var kernelSrc = loadKernel("clRand");
var program = ctx.createProgramWithSource(kernelSrc);
try {
program.buildProgram ([devices[0]], "");
} catch(e) {
alert ("Failed to build WebCL program. Error "
+ program.getProgramBuildInfo (devices[0],
WebCL.CL_PROGRAM_BUILD_STATUS) + ": "
+ program.getProgramBuildInfo (devices[0],
WebCL.CL_PROGRAM_BUILD_LOG));
throw e;
}
var kernel = program.createKernel ("kRand");
kernel.setKernelArg (0, bufRand);
creates command queue, writes buffer, runs kernel reads and prints result
var cmdQueue = ctx.createCommandQueue (devices[0], 0);
cmdQueue.enqueueWriteBuffer (bufRand, true, 0, 4*n, UIrand, []);
cmdQueue.enqueueNDRangeKernel(kernel, 1, [], [n], [n], []);
cmdQueue.finish();
cmdQueue.enqueueReadBuffer(bufRand, true, 0, bufSize, UIrand, []);
output.innerHTML += "<br>Result = ";
for (var i = 0; i < n; i = i + 1)
output.innerHTML += UIrand[i] + ", ";
} catch(e) {
document.getElementById("output").innerHTML
+= "<h3>ERROR:</h3><pre style=\"color:red;\">" + e.message + "</pre>";
throw e;
}
}
</script>
Note that the try block is used to catch WebCL errors. See the Nokia Research
WebCL
Tutorial for more comments.
cmdQueue.enqueueNDRangeKernel(kRelax, 2, [], [n,n], [8,8], []); cmdQueue.finish(); ...or Flush function and EventWaitList
var ev = cmdQueue.enqueueNDRangeKernel(kRelax2, 2, [], [n,n], [8,8], []);
cmdQueue.flush();
for(var i = 0; i < it; i++){
kRelax.setKernelArg(0, img0);
kRelax.setKernelArg(2, img1);
ev = cmdQueue.enqueueNDRangeKernel(kRelax, 2, [], [n,n], [8,8], [ev]);
cmdQueue.flush();
kRelax.setKernelArg(0, img1);
kRelax.setKernelArg(2, img0);
ev = cmdQueue.enqueueNDRangeKernel(kRelax, 2, [], [n,n], [8,8], [ev]);
cmdQueue.flush();
}
cmdQueue.enqueueNDRangeKernel(kShow, 2, [], [n,n], [8,8], [ev]);
...
The first construction was ~2 times slower on AMD E-350 processor.
This 2d ink droplet script uses HTML5 Canvas2d to show pictures. It is a litle slower than the script with WebGL based output (fps is 25 and 30 correspondingly).