This is a part of Node3D project.
npm i -s opencl-raub
This addon is ABI-compatible across Node.js versions. There is no compilation during
npm i
.
Node.js addon with OpenCL 1.2 bindings. This is not WebCL.
The API directly reflects the low-level OpenCL interface. There are minor changes similar to how WebGL is different from OpenGL.
- All
cl*
methods are available ascl.*
starting lowercase, e.g:clCreateKernel -> cl.createKernel
. - All
CL_*
constants are available ascl.*
, e.g.:CL_TRUE -> cl.TRUE
. - The CL resource pointers are wrapped in JS objects, such as
TClPlatform
,TClContext
,TClEvent
. - For
cl.enqueue*()
methods, you can passhasEvent = true
, in that case aTClEvent
is returned. - The CL status is not returned, instead a JS exception is thrown in case of a CL error.
Most of the method arguments comply to the original C-style spec, some parameters are omitted due to JS specifics. For example, passing an array, you don't need to specify its length.
See TypeScript declarations for more details.
- Import the module:
import cl from 'opencl-raub';
- Fetch the CL control objects:
const { context, device } = cl.quickStart(); // see /index.js const queue = cl.createCommandQueue(context, device);
- Prepare the data input/output buffers:
const BUFFER_SIZE = 10; const BYTE_SIZE = BUFFER_SIZE * Uint32Array.BYTES_PER_ELEMENT; const arrayA = new Uint32Array(BUFFER_SIZE); const arrayB = new Uint32Array(BUFFER_SIZE); const arrayC = new Uint32Array(BUFFER_SIZE); for (let i = 0; i < BUFFER_SIZE; i++) { arrayA[i] = i; arrayB[i] = i * 2; } // Create buffer for arrayA and arrayB and copy host contents const bufferA = cl.createBuffer(context, cl.MEM_READ_ONLY, BYTE_SIZE); const bufferB = cl.createBuffer(context, cl.MEM_READ_ONLY, BYTE_SIZE); // Create buffer for arrayC to read results const bufferC = cl.createBuffer(context, cl.MEM_WRITE_ONLY, BYTE_SIZE);
- Create a valid CL program, e.g. from source:
const program = cl.createProgramWithSource(context, ` __kernel void vadd(__global int *a, __global int *b, __global int *c, uint num) { size_t i = get_global_id(0); if (i < num) { c[i] = a[i] + b[i]; } } `); cl.buildProgram(program);
- Fetch and setup a kernel from within the program:
// Create a kernel object const kernel = cl.createKernel(program, 'vadd'); // Set kernel args cl.setKernelArg(kernel, 0, 'uint*', bufferA); cl.setKernelArg(kernel, 1, 'uint*', bufferB); cl.setKernelArg(kernel, 2, 'uint*', bufferC); cl.setKernelArg(kernel, 3, 'uint', BUFFER_SIZE);
- Launch the kernel and then read the results:
// Do the work cl.enqueueWriteBuffer(queue, bufferA, true, 0, BYTE_SIZE, arrayA); cl.enqueueWriteBuffer(queue, bufferB, true, 0, BYTE_SIZE, arrayB); cl.enqueueNDRangeKernel(queue, kernel, 1, null, [BUFFER_SIZE]); cl.enqueueReadBuffer(queue, bufferC, true, 0, BYTE_SIZE, arrayC);
- See if it worked:
console.log(`A = [${arrayA.join(', ')}]`); console.log(`B = [${arrayB.join(', ')}]`); console.log(`C = [${arrayC.join(', ')}]`);
- Release the CL objects:
cl.releaseCommandQueue(queue); cl.releaseKernel(kernel); cl.releaseProgram(program); cl.releaseMemObject(bufferA); cl.releaseMemObject(bufferB); cl.releaseMemObject(bufferC);
See examples
for more details. The full code of the above example is available
here.