UNPKG

webcl

Version:

OpenCL bindings for Node.js

122 lines (99 loc) 4.08 kB
#!/usr/bin/env node var WebCL = require('webcl'); var alert = console.log; var clProgramVectorAdd = '__kernel void ckVectorAdd(__global unsigned int* vectorIn1,\n' + '__global unsigned int* vectorIn2,\n' + '__global unsigned int* vectorOut,\n' + 'unsigned int uiVectorWidth) {' + 'unsigned int x = get_global_id(0);' + 'if (x >= (uiVectorWidth)) return;' + 'vectorOut[x] = vectorIn1[x] + vectorIn2[x];' + 'return; }'; function CL_vectorAdd () { // All output is written to element by id "output" var output = ""; try { // First check if the WebCL extension is installed at all if (WebCL == undefined) { alert("Unfortunately your system does not support WebCL. " + "Make sure that you have the WebCL extension installed."); return; } // Generate input vectors var vectorLength = 30; var UIvector1 = new Uint32Array(vectorLength); var UIvector2 = new Uint32Array(vectorLength); for ( var i=0; i<vectorLength; i=i+1) { UIvector1[i] = Math.floor(Math.random() * 100); //Random number 0..99 UIvector2[i] = Math.floor(Math.random() * 100); //Random number 0..99 } output += "\nVector length = " + vectorLength; // Setup WebCL context using the default device of the first platform var platforms = WebCL.getPlatformIDs(); var ctx = WebCL.createContextFromType ([WebCL.CL_CONTEXT_PLATFORM, platforms[0]], WebCL.CL_DEVICE_TYPE_GPU); // Reserve buffers var bufSize = vectorLength * 4; // size in bytes output += "\nBuffer size: " + bufSize + " bytes"; var bufIn1 = ctx.createBuffer (WebCL.CL_MEM_READ_ONLY, bufSize); var bufIn2 = ctx.createBuffer (WebCL.CL_MEM_READ_ONLY, bufSize); var bufOut = ctx.createBuffer (WebCL.CL_MEM_WRITE_ONLY, bufSize); // Create and build program for the first device var kernelSrc = clProgramVectorAdd; var program = ctx.createProgramWithSource(kernelSrc); var devices = ctx.getContextInfo(WebCL.CL_CONTEXT_DEVICES); 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; } // Create kernel and set arguments var kernel = program.createKernel ("ckVectorAdd"); kernel.setKernelArg (0, bufIn1, WebCL.types.MEM); kernel.setKernelArg (1, bufIn2, WebCL.types.MEM); kernel.setKernelArg (2, bufOut, WebCL.types.MEM); kernel.setKernelArg (3, vectorLength, WebCL.types.UINT); // Create command queue using the first available device var cmdQueue = ctx.createCommandQueue (devices[0], 0); cmdQueue.enqueueWriteBuffer (bufIn1, false, 0, UIvector1.length*4, UIvector1, []); cmdQueue.enqueueWriteBuffer (bufIn2, false, 0, UIvector2.length*4, UIvector2, []); // Init ND-range var localWS = [8]; var globalWS = [Math.ceil (vectorLength / localWS) * localWS]; output += "\nGlobal work item size: " + globalWS; output += "\nLocal work item size: " + localWS; // Execute (enqueue) kernel cmdQueue.enqueueNDRangeKernel(kernel, globalWS.length, [], globalWS, localWS, []); // Read the result buffer from OpenCL device var outBuffer = new Uint32Array(vectorLength); cmdQueue.enqueueReadBuffer (bufOut, false, 0, outBuffer.length*4, outBuffer, []); cmdQueue.finish (); //Finish all the operations //Print input vectors and result vector output += "\nVector1 = "; for (var i = 0; i < vectorLength; i = i + 1) { output += UIvector1[i] + ", "; } output += "\nVector2 = "; for (var i = 0; i < vectorLength; i = i + 1) { output += UIvector2[i] + ", "; } output += "\nResult = "; for (var i = 0; i < vectorLength; i = i + 1) { output += outBuffer[i] + ", "; } } catch(e) { alert(e.message); throw e; } alert(output); } CL_vectorAdd ();