This is a part of Node3D project.
npm i opencl-raub
Node.js addon with OpenCL bindings.
Note: this addon uses N-API, and therefore is ABI-compatible across different Node.js versions. Addon binaries are precompiled and there is no compilation step during the
npm i
command.
- Exposes low-level OpenCL interface, native-like functions.
The API is very close to the low-level one, although there are minor changes when it comes to lengths and, of course, pointers.
This is a rather low level interface, where most of the stuff is directly reflecting OpenCL interfaces.
- Import the module:
const cl = require('opencl-raub');
- Fetch the CL control objects:
const platform = cl.getPlatformIDs()[0]; const devices = cl.getDeviceIDs(platform, cl.DEVICE_TYPE_ALL); const context = cl.createContext([cl.CONTEXT_PLATFORM, platform], devices); const device = cl.getContextInfo(context, cl.CONTEXT_DEVICES)[0]; const queue = cl.createCommandQueue(context, device, null);
- 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) return; c[i] = a[i] + b[i]; } `); cl.buildProgram(program);
- Fetch and setup a kernel from within the program:
// Create a kernel object let 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], null); 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); cl.releaseContext(context);
See examples
for more details. The full code of the above example is available
here.
The methods, returning cl_int
values of CL error codes, would return a number
to JS.
That number
may be checked against cl.SUCCESS
and other error codes.
The returned object types (Platform
, Context
, Event
, etc.) are wrappers around CL
resource ids, that can be passed to further CL method calls.
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 the length. The specific set of parameters for each method is documented below, so it can be compared to the original spec, when in doubt.
For enqueueXXX()
methods, you can pass hasEvent = true
(the last argument).
In this case an Event
is returned, it can be used to coordinate calls, profiling etc.
-
cl.getPlatformIDs(): [Platform]
- clGetPlatformIDs. -
cl.getPlatformInfo(platform: Platform, param_name: string): string
- clGetPlatformInfo. -
cl.createContext(properties: [number | Platform], devices: [Device]): Context
- clCreateContext. -
cl.createContextFromType(properties: [number | Platform], device_type: number): Context
- clCreateContext. -
cl.retainContext(context: Context): number
- clRetainContext. -
cl.releaseContext(context: Context): number
- clReleaseContext. -
cl.getContextInfo(context: Context, param_name: string): [Device] | number | [number | Platform]
- clGetContextInfo. -
cl.getDeviceIDs(platform: Platform, device_type: number): [Device]
- clGetDeviceIDs. -
cl.getDeviceInfo(device: Device, param_name: number): string | number | boolean | Platform | [number] | null
- clGetDeviceInfo. -
cl.createSubDevices(device: Device, properties: [number | Platform]): [Device]
- . -
cl.retainDevice(device: Device): number
- clRetainDevice. -
cl.releaseDevice(device: Device): number
- clReleaseDevice. -
cl.createCommandQueue(context: Context, device: Device, properties: number): Queue
- clCreateCommandQueue. -
cl.retainCommandQueue(queue: Queue): number
- clRetainCommandQueue. -
cl.releaseCommandQueue(queue: Queue): number
- clReleaseCommandQueue. -
cl.getCommandQueueInfo(queue: Queue, param_name: number): number
- clGetCommandQueueInfo. -
cl.flush(queue: Queue): number
- clFlush. -
cl.finish(queue: Queue): number
- clFinish. -
cl.enqueueReadBuffer(queue: Queue, buffer: Memory, blocking_read: boolean, offset: number, size: number, buffer: Buffer | TypedArray, event_wait_list: [Event], hasEvent: boolean): number | Event
- clEnqueueReadBuffer. -
cl.enqueueReadBufferRect(queue: Queue, buffer: Memory, blocking_read: boolean, buffer_offset: [number], host_offset: [number], region: [number], buffer_row_pitch: number, buffer_slice_pitch: number, host_row_pitch: number, host_slice_pitch: number, buffer: Buffer | TypedArray, event_wait_list: [Event], hasEvent: boolean): number | Event
- clEnqueueReadBufferRect. -
cl.enqueueWriteBuffer(): number | Event
- clEnqueueWriteBuffer. -
cl.enqueueWriteBufferRect(): number | Event
- clEnqueueWriteBufferRect. -
cl.enqueueCopyBuffer(): number | Event
- clEnqueueCopyBuffer. -
cl.enqueueCopyBufferRect(): number | Event
- clEnqueueCopyBufferRect. -
cl.enqueueReadImage(): number | Event
- clEnqueueReadImage. -
cl.enqueueWriteImage(): number | Event
- clEnqueueWriteImage. -
cl.enqueueCopyImage(): number | Event
- clEnqueueCopyImage. -
cl.enqueueCopyImageToBuffer(): number | Event
- clEnqueueCopyImageToBuffer. -
cl.enqueueCopyBufferToImage(): number | Event
- clEnqueueCopyBufferToImage. -
cl.enqueueMapBuffer(): number | Event
- clEnqueueMapBuffer. -
cl.enqueueMapImage(): number | Event
- clEnqueueMapImage. -
cl.enqueueUnmapMemObject(): number | Event
- clEnqueueUnmapMemObject. -
cl.enqueueNDRangeKernel(): number | Event
- clEnqueueNDRangeKernel. -
cl.enqueueTask(): number | Event
- clEnqueueTask. -
cl.enqueueNativeKernel(): number | Event
- clEnqueueNativeKernel. -
cl.enqueueMarkerWithWaitList(): number | Event
- clEnqueueMarkerWithWaitList. -
cl.enqueueBarrierWithWaitList(): number | Event
- clEnqueueBarrierWithWaitList. -
cl.enqueueFillBuffer(): number | Event
- clEnqueueFillBuffer. -
cl.enqueueFillImage(): number | Event
- clEnqueueFillImage. -
cl.enqueueMigrateMemObjects(): number | Event
- clEnqueueMigrateMemObjects. -
cl.enqueueAcquireGLObjects(): number | Event
- clEnqueueAcquireGLObjects. -
cl.enqueueReleaseGLObjects(): number | Event
- clEnqueueReleaseGLObjects. -
cl.createKernel(): Kernel
- clCreateKernel. -
cl.createKernelsInProgram(): number
- clCreateKernelsInProgram. -
cl.retainKernel(): number
- clRetainKernel. -
cl.releaseKernel(): number
- clReleaseKernel. -
cl.setKernelArg(): number
- clSetKernelArg. -
cl.getKernelInfo(): number
- clGetKernelInfo. -
cl.getKernelArgInfo(): number
- clGetKernelArgInfo. -
cl.getKernelWorkGroupInfo(): number
- clGetKernelWorkGroupInfo. -
cl.createBuffer(): number
- clCreateBuffer. -
cl.createSubBuffer(): number
- clCreateSubBuffer. -
cl.createImage(): number
- clCreateImage. -
cl.retainMemObject(): number
- clRetainMemObject. -
cl.releaseMemObject(): number
- clReleaseMemObject. -
cl.getSupportedImageFormats(): number
- clGetSupportedImageFormats. -
cl.getMemObjectInfo(): number
- clGetMemObjectInfo. -
cl.getImageInfo(): number
- clGetImageInfo. -
cl.createFromGLBuffer(): number
- clCreateFromGLBuffer. -
cl.createProgramWithSource(): number
- clCreateProgramWithSource. -
cl.createProgramWithBinary(): number
- clCreateProgramWithBinary. -
cl.createProgramWithBuiltInKernels(): number
- clCreateProgramWithBuiltInKernels. -
cl.retainProgram(): number
- clRetainProgram. -
cl.releaseProgram(): number
- clReleaseProgram. -
cl.buildProgram(): number
- clBuildProgram. -
cl.compileProgram(): number
- clCompileProgram. -
cl.linkProgram(): number
- clLinkProgram. -
cl.unloadPlatformCompiler(): number
- clUnloadPlatformCompiler. -
cl.getProgramInfo(): number
- clGetProgramInfo. -
cl.getProgramBuildInfo(): number
- clGetProgramBuildInfo. -
cl.retainSampler(): number
- clRetainSampler. -
cl.releaseSampler(): number
- clReleaseSampler. -
cl.getSamplerInfo(): number
- clGetSamplerInfo. -
cl.createSampler(): number
- clCreateSampler. -
cl.waitForEvents(): number
- clWaitForEvents. -
cl.getEventInfo(): number
- clGetEventInfo. -
cl.createUserEvent(): number
- clCreateUserEvent. -
cl.retainEvent(): number
- clRetainEvent. -
cl.releaseEvent(): number
- clReleaseEvent. -
cl.setUserEventStatus(): number
- clSetUserEventStatus. -
cl.setEventCallback(): number
- clSetEventCallback. -
cl.getEventProfilingInfo(): number
- clGetEventProfilingInfo.