Chapter 12

WebCL

Enabling OpenCL acceleration of Web applications

Mikaël Bourges-Sévenier; Rémi Arnaud

Abstract

With the rapid advance in graphics and computing power of devices, and in particular mobile devices, new application programming interfaces such as WebGL and WebCL are making their way into Web browsers. This chapter covers programming for OpenCL running in a Web browser using WebCL. WebCL is a JavaScript representation of the OpenCL application programming interface. This chapter also covers compute and graphics interoperability using WebCL and WebGL, how WebCL can be used in stand-alone applications, and how JavaScript servers use the node.js module for WebCL (node-webcl).

Keywords

WebCL

WebGL

node.js

Web applications

JavaScript

node-webcl

Compute and graphics interoperability

12.1 Introduction

Web applications are gaining popularity as ubiquitous Web browsers and cloud servers are becoming the main way we access our personal and professional data. The ability to update and maintain Web applications without distributing and installing software on millions of client computers is very attractive to developers, as is the Inherent cross-platform support. Thanks to wide availability of fast Internet access, and constant mobile connectivity, end users are able to access their data and applications from anywhere, on any device.

With the rapid advance in graphics and computing power of devices, and in particular mobile devices, new application programming interfaces (APIs) such as WebGL and WebCL are making their way into Web browser. Those API are very important as they provide access to hardware acceleration on the device itself, providing the end user with faster rendering and computing, as well as longer battery life. This also enables better experience in general as the interactivity of the Web application does not rely solely on the quality of the network connection, and enables off-line Web applications. Thanks to WebGL and WebCL, the Web browser is able to reach a level of performance that was before accessible only to native applications, opening up a whole new era of Web applications.

12.2 Programming with WebCL

WebCL 1.0 is a JavaScript representation of OpenCL 1.2. WebCL exposes the underlying object-oriented nature of OpenCL in JavaScript. This allows a simplified programming of OpenCL while maintaining the very same API design, semantic, and runtime. We will often compare the relationship of WebCL with browsers with that of since the integration is similar. However, WebCL does not require knowledge or usage of WebGL.

As with OpenCL, programming with WebCL is composed of two parts:

1. The host side (e.g. in the Web browser) that sets up and controls the execution of the JavaScript program

2. The device side (e.g. on a GPU) that runs computations—that is, kernels in OpenCL

As with WebGL, WebCL is a property of a Window object. First, we need to check if WebCL is available, and then if a context can be created:

// First check if the WebCL extension is installed at all

if (window.webcl == undefined) {

 alert(’’Unfortunately your system does not support WebCL. ’’ +

 ’’Make sure that you have both the OpenCL driver ’’ +

 ’’and the WebCL browser extension installed.’’);

}

// Get a list of available CL platforms, and another list of the

// available devices on each platform. If there are no platforms,

// or no available devices on any platform, then we can conclude

// that WebCL is not available.

webcl = window.webcl

try {

 var platforms = webcl.getPlatforms();

 var devices = [];

 for (var i in platforms) {

 var p = platforms[i];

 devices[i] = p.getDevices();

 }

 alert(’’Excellent! Your system does support WebCL.’’);

} catch (e) {

alert(’’Unfortunately platform or device inquiry failed.’’);

}

// Setup WebCL context using the default device

var ctx = webcl.createContext ();

Figure 12.1 illustrates the WebCL objects. Note that WebCL is the name of the interface, while webcl is the name of the JavaScript object. For more information please consult the WebCL specification [1].

f12-01-9780128014141
Figure 12.1 WebCL objects.

The application can not only query the platforms to list the available devices, but can also query devices for additional information and make a specific choice of platform and/or device.

// find appropriate device

for (var j = 0, jl = devices.length; j < jl; ++j) {

 var d = devices[j];

 var devExts = d.getInfo(cl.DEVICE:EXTENSIONS);

 var devGMem = d.getInfo(cl.DEVICE:GLOBAL_MEM_SIZE);

 var devLMem = d.getInfo(cl.DEVICE:LOCAL_MEM_SIZE);

 var devCompUnits = d.getInfo(cl.DEVICE:MAX_COMPUTE_UNITS);

 var devHasImage = d.getInfo(cl.DEVICE:IMAGE_SUPPORT);

 // select device that matches your requirements

 platform = ...

 device = ...

}

// assuming we found the best device, we can create the context

var context = webcl.createContext( platform, device );

The application runtime manages OpenCL objects such as command-queues, memory objects, program objects. and kernel objects in a program and calls that allow you to enqueue commands to a command-queue. such as executing a kernel, reading a memory object, or writing a memory object.

WebCL defines the following objects:

 Command-queues

 Memory objects (buffers and images)

 Sampler objects, which describe how to sample an image being read by a kernel

 Program objects, which contain a set of kernel functions identified with the _ _kernel qualifier in the program source

 Kernel objects, which encapsulate the specific _ _kernel functions declared in a program source and its argument values to be used when executing the _ _ kernel function

 Event objects, which are used to track the execution status of a command as well as to profile a command

 Command synchronization objects such as markers and barriers

The first thing to do is to create a program. WebCL, like WebGL 1.0, assumes a program is provided in source code form (a string). Currently, a WebCL device is required to have an internal compiler. The source code is first loaded to the device, and then compiled. As with any compiler, the OpenCL compiler defines standard compilation options.

// Create the compute program from the source strings

program = context.createProgram(source);

// Build the program executable with relaxed math flag

try {

 program.build(device, ’’-cl-fast-relaxed-math’’);

} catch (err) {

throw ‘Error building program: ’ + err

 + program.getBuildInfo(device, cl.PROGRAM_BUILD_LOG));

}

At this point, our program is compiled, and contains one or more kernel functions. These kernel functions are the entry points of our program, and are similar to the entry points of a shared library. To refer to each kernel function, we create a WebCLKernel object:

// Create the compute kernels from within the program

var kernel = program.createKernel(‘kernel_function_name’);

A kernel function may have one or more arguments, like any function. Since JavaScript offers only the type Number for numerical values, typed arrays [2] are used to pass function arguments of various numerical types (see Table 12.1). For other types of values, we must use WebCL objects:

Table 12.1

Relationships Between C Types Used in Kernels and setArg()’s webcl.type

Kernel Argument TypesetArg() ValuesetArg() Typed ArrayRemarks
char, ucharscalarUint8Array, Int8Array1 byte
short, ushortscalarUint16Array, Int16Array2 bytes
int, uintscalarUint32Array, Int32Array4 bytes
long, ulongscalarUint64Array, Int64Array8 bytes
floatscalarFloat32Array4 bytes
half, doublescalarFloat32Array, Float64ArrayNot on all implementations
2 bytes (half), 8 bytes (double)
<char…double>NvectorInt8Array for (u)charNN = 2,3,4,8,16
Int16Array for (u)shortN
Int32Array for (u)intN
Int64Array for (u)longN Float32Array
for floatNand halfN
Float64Array for doubleN
char,… , double *WebCLBuffer
image2d_tWebCLImage
sampler_tWebCLSampler
_ _localInt32Array ([size_in_bytes])Size initialized in kernel

t0010

 WebCLBuffer and WebCLImage, which in-turn wrap a typed array

 WebCLSampler for sampling an image

A WebCLBuffer object stores a one-dimensional collection of elements. Elements of a buffer can be of scalar type (e.g. int, float), of vector data type, or have a user-defined structure.

// create a 1D buffer

var buffer = webcl.createBuffer(flags, sizeInBytes, optional

srcBuffer);

// flags:

//webcl.MEM_READ_WRITE Default. Memory object is read and written by kernel

//webcl.MEM_WRITE_ONLY Memory object only written by kernel

//webcl.MEM_READ_ONLY Memory object only read by kernel

//webcl.MEM_USE_HOST_PTR Implementation uses storage memory in srcBuffer.

 srcBuffer must be specified.

//webcl.MEM_ALLOC_HOST_PTR Implementation requests OpenCL to allocate

host memory.

//webcl.MEM_COPY_HOST_PTR Implementation request OpenCL to allocate host

memory and copy

data from srcBuffer memory. srcBuffer must be specified.

Note that only reading from a buffer object and its subbuffer objects or reading from multiple overlapping subbuffer objects is defined. All other concurrent reading or writing is undefined.

A WebCL image is used to store a one-, two-, or three-dimensional texture, render-buffer, or image. The elements of an image object are selected from a predefined list of image formats. However, currently, WebCL supports only two-dimensional images.

// create a 32-bit RGBA WebCLImage object

// first, we define the format of the image

var imageFormat = {

// memory layout in which pixel data channels are stored in the image.

‘channelOrder’ : webcl.RGBA,

// type of the channel data

‘channelType’ : webcl.UNSIGNED_INT8,

// image size

‘width’: image_width,

‘height’: image_height,

// scan-line pitch in bytes.

// If imageBuffer is null, it must be 0. Otherwise, it must be at least image_ width *

sizeInBytesOfChannelElement, which is the default if rowPitch is not specified.

‘rowPitch’: image_pitch

};

// Image on device

// imageBuffer is a typed array that contain the image data already allocated by the

application.

// imageBuffer.byteLength >= rowPitch * image_height. The size of each element

in bytes must be a

power of 2.

var image = context.createImage(webcl.MEM_READ_ONLY |

webcl.MEM_

USE_ HOST_PTR,

imageFormat, imageBuffer);

A WebCLSampler describes how to sample an image when the image is read in a kernel function. It is similar to WebGL samplers.

// create a sampler object

var sampler = context.createSampler(normalizedCoords,

addressingMode, filterMode);

// normalizedCoords indicates if image coordinates specified are normalized.

// addressingMode indicated how out-of-range image coordinates are handled when

reading an image.

// This can be set to webcl.ADDRESS_MIRRORED_REPEAT,

webcl.ADDRESS_REPEAT, webcl.ADDRESS_CLAMP_TO_EDGE,

webcl.ADDRESS_CLAMP and webcl.ADDRESS_NONE.

// filterMode specifies the type of filter to apply when reading an image. This can be

webcl.FILTER_NEAREST or webcl.FILTER_LINEAR

Passing arguments is done using WebCLKernel.setArg(), with scalars, vectors, or memory objects. When passing values referring to local memory, we use an Int32Array of length 1 with the number of bytes to be allocated because local variables cannot be initialized by the host or the device but the host can tell the device how many bytes to allocate for a kernel argument.

As a rule of thumb, all values passed to a kernel by setArg() are objects. Scalars must be wrapped into a typed array of size 1. Vectors are typed arrays with size of the number of elements in the vector. Buffers, images, and samplers are WebCL objects. Memory object (buffers and images) content must be transferred from host memory to device memory by enqueue commands before execution of the kernel.

Here are some examples:

// Sets value of kernel argument idx with value as memory object or sampler

kernel.setArg(idx, a_buffer);

kernel.setArg(idx, a_image);

kernel.setArg(idx, a_sampler);

// Sets value of argument 0 to the integer value 5

kernel.setArg(0, new Int32Array([5]));

// Sets value of argument 1 to the float value 1.34

kernel.setArg(1, new Float32Array([1.34]));

// Sets value of argument 2 as a 3-float vector

// buffer should be a Float32Array with 3 floats

kernel.setArg(2, new Float32Array([1.0,2.0,3.0]));

// Allocate 4096 bytes of local memory for argument 4

kernel.setArg(4, new Int32Array([4096]));

When a scalar is passed, the type is used to tell what specific type is expected by the program. JavaScript has only one type—Number—so we need to provide the information in the setArg call using typed arrays.

Notes:

 Long integers are 64-bit integers that have no representation in JavaScript. They must be represented as two 32-bit integers: the low-order 32 bits are stored in the first element of each pair, and the high-order 32 bits are stored in the second element.

 If the argument of a kernel function is declared with the _ _constant qualifier, the size in bytes of the memory object cannot exceed webcl.DEVIce:MAX_CONSTANT_BUFFER_SIZE.

 OpenCL allows the passing of structures as byte arrays to kernels but, for portability, WebCL currently does not allow this. The main reason is that endianness between the host and devices may be different, and this would require developers to format their data for each device’s endianness even on the same machine.

 All WebCL API calls are thread-safe, except kernel.setArg(). However, kernel.setArg() is safe as long as concurrent calls operate on different WebCLKernel objects. Behavior is undefined if multiple threads call on the same WebCLKernel object at the same time.

Operations on WebCL objects such as memory, program, and kernel objects are performed using command-queues. A command-queue contains a set of operations or commands. Applications may use multiple independent command-queues without synchronization as long as commands do not apply on shared objects between command-queues. Otherwise, synchronization is required.

Commands are queued in order, but execution may be in order (default) or out of order on the devices that support it (it is optional in OpenCL). Out of order means that if a command-queue contains command A and command B, an in-order command-queue object guarantees that command B is executed when command A finishes. If an application configures a command-queue to be out of order, there is no guarantee that commands finish in the order they were queued. For out-of-order queues, a wait for events or a barrier command can be enqueued in the command-queue to guarantee previous commands finish before the next batch of commands is executed. Out-of-order queues are an advanced topic we will not cover in this chapter. Interested readers should refer to [3]. Beware that many underlying OpenCL implementations do not support out-of-order queues. You should first test if you can create a command-queue with QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE flag. If the INVALID_QUEUE_PROPERTIES exception is thrown, the device does not support out-of-order queues.

// Create an in-order command-queue (default)

var queue = context.createCommandQueue(device);

// Create an in-order command-queue with profiling of commands enabled

var queue = context.createCommandQueue(device,

webcl.QUEUE_PROFILING_

ENABLE);

// Create an out-of-order command-queue

var queue = context.createCommandQueue(device,

webcl.QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE);

A command-queue is attached to a specific device. Multiple command-queues can be used per device. One application is to overlap kernel execution with data transfers between the host and the device. Figure 12.2 shows the timing benefit if a problem can be separated in half:

f12-02-9780128014141
Figure 12.2 Using multiple command-queues for overlapped data transfer.

 The first half of the data is transferred from the host to the device, taking half the time needed for the full data set. Then, the kernel is executed, possibly in half the time needed with the full data set. Finally, the result is transferred back to the device in half the time needed for the full result set.

 Just after the first half has been transferred, the second half is transferred from the host to the device, and the same process is repeated.

Once a set of commands have been queued, WebCL provides enqueue- NDRange(kernel, offsets, globals, locals) to execute them:

 kernel—the kernel to be executed.

 offsets—offsets to apply to globals. If null, then offsets=[0, 0, 0].

 globals—the problem size per dimension.

 locals—the number of work-items per work-group per dimension. If null, the device will choose the appropriate number of work-items.

For example, if we want to execute a kernel over an image of size (width, height), then globals may be [width, height] and locals may be [16, 16]. Note that enqueue NDRange() will fail if the locals size is more than webcl.KERNEL_WORK_GROUP_SIZE.

12.3 Synchronization

Just like C/C+ + OpenCL programs, the device can process the commands in the queue in an asynchronous manner. The host submits commands to the command-queue and can then wait for the completion of all the enqueued commands by using a clFinish.

Nearly all commands available in the WebCLCommandQueue class have two final parameters:

1. event_list—an array of WebCLEvents

2. event—an event returned by the device to monitor the execution status of a command

By default, the event_list and event parameters are null for any command. However, if an event is passed to a command, then the host can wait for the execution of the particular command using clWaitForEvents. The programmer can also use event callback functions to be notified when a certain command completes. The host code would need to register a callback function in order to be notified once the command completes. If an event_list is passed to the command, then the command will not start executing until all the commands corresponding to each event have reached webcl.COMPLETE.

For the commands an application wishes to be notified of their webcl.COMPLETE status, we first create a WebCLEvent object, pass it to the command, then register a JavaScript callback function. Note that the last argument of WebCLEvent.setCallback() can be anything, as this argument is passed untouched as the last argument of the callback function. Also note that in the case of enqueue read/write WebCLBuffers or WebCLImages, clBuffer ownership is transferred from the host to the device. Thus, when the read_complete() callback is called, clBuffer ownership is transferred back from the device to the host. This means that once the ownership of clBuffer has been transferred, the host cannot access or use this buffer anymore. Once the callback has been called, the host can use the buffer again. See the example code below:

// Enqueue kernel

try {

kernel_event=new cl.WebCLEvent();

queue.enqueueNDRange(kernel, 2, null, globals, locals, null,

kernel_event);

} catch(ex) {

throw ’’Couldn’t enqueue the kernel. ’’+ex;

}

// Set kernel event handling routines: call kernel_complete()

try {

kernel_event.setCallback(webcl.COMPLETE,

kernel_complete, ’’The kernel

finished successfully.’’);

} catch(ex) {

throw ’’Couldn’t set callback for event. ’’+ex;

}

// Read the buffer

var data=new Float32Array(4096);

try {

read_event=new webcl.WebCLEvent();

queue.enqueueReadBuffer(clBuffer, false, 0, 4096*4, data, null,

read_event);

} catch(ex) {

throw ’’Couldn’t read the buffer. ’’+ex;

}

// register a callback on completion of read_event: calls read_complete()

read_event.setCallback(webcl.COMPLETE,

read_complete, ’’Read complete’’);

// wait for both events to complete

queue.waitForEvents([kernel_event,

read_event]);

// kernel callback

function kernel_complete(event, data) {

// event.status = webcl.COMPLETE or error if negative

// event.data is null

// data should contain ’’The kernel finished successfully.’’

}

// read buffer callback

function read_complete(event, data) {

// event.status = cl.COMPLETE or error if negative

// event.data contains a WebCLMemoryObject with values from device

// data contains ’’Read complete’’

}

12.4 Interoperability with WebGL

Recall that WebCL is for computing, not for rendering. However, if your data already resides in the graphics processing unit (GPU) and you need to render it, would it not be faster to tell OpenGL to use it rather than reading it from the GPU memory to central processing unit (CPU) memory and send it again to OpenGL on your GPU? This is where the WebGL interoperability extension comes in.

Since WebCL is using data from WebGL, the WebGL context must be created first. Then, a shared WebCL context can be created. This WebGL shared group object manages shared WebGL and WebCL resources such as the following (Figure 12.3):

f12-03-9780128014141
Figure 12.3 Typical runtime involving WebCL and WebCL.

 Textures objects—contain texture data in image form,

 Vertex buffers objects—contain vertex data such as coordinates, colors, and normal vectors,

 Renderbuffer objects—contain images used with WebGL framebuffer objects [4].

12.5 Example Application

Applications such as image processing and ray tracing produce an output image whose pixels are drawn onto the screen. For such applications, it suffices to map the output image onto two unlit screen-aligned triangles rendered by WebGL. A compute kernel provides more flexible ways to optimize generic computations than a fragment shader. More importantly, texture memory is cached and thus provides a faster way to access data than regular (global) CPU memory. However, in devices without image memory support, one should use WebCLBuffers and update WebGL textures with pixel buffer objects.

In this section, we use Iñigo Quilez’s excellent ShaderToy’s Mandelbulb fragment shader [5] converted as a WebCL kernel, depicted in Figure 12.4. The whole WebGL scene consists of two textured triangles filling a canvas. WebCL generates the texture at each frame. Therefore, for a canvas of dimension (width, height), WebCL will generate width × height pixels.

f12-04-9780128014141
Figure 12.4 Two triangles in WebGL to draw a WebCL-generated image.

Since WebCL uses WebGL buffers for compute, WebGL context must first be initialized, and then WebCL context is created by sharing that WebGL context. Once both contexts have been initialized, it is possible to create shared objects by creating first the WebGL object, and then the corresponding WebCL object from the WebGL object. The following illustrates how a WebGL texture is created and can be used as target by WebCL:

// retrieve a <canvas> object with id glcanvas in HTML page

var canvas = document.getElementById(’’glcanvas’’);

// Try to grab the standard context. If it fails, fallback to experimental.

var gl = canvas.getContext(’’webgl’’) || canvas.getContext(’’experimental-webgl’’);

// Create OpenGL texture object

Texture = gl.createTexture();

gl.bindTexture(gl.TEXTURE_2D, Texture);

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,

TextureWidth, TextureHeight, 0,

gl.RGBA,

gl.UNSIGNED_BYTE, null);

gl.bindTexture(gl.TEXTURE_2D, null);

// Create OpenCL representation (a WebCLImage) of OpenGL texture

try {

clTexture = context.createFromGLTexture2D(cl.MEM_

WRITE_ONLY, gl.TEXTURE_2D, 0, Texture);

}

catch(ex) {

throw ’’Error: Failed to create WebCLImage. ’’+ex;

}

// To use this texture, somewhere in your code, do as usual:

glBindTexture(gl.TEXTURE_2D, Texture)

Simply use this texture as an argument to the program

kernel.setArg(0, clTexture);

kernel.setArg(1, new Uint32Array([TextureWidt]));

kernel.setArg(2, new Uint32Array([TextureHeight]));

Finally, here is how to use this WebCLImage inside the kernel code:

__kernel

void compute(__write_only image2d_t pix, uint width, uint height)

{

const int x = get_global_id(0);

const int y = get_global_id(1);

// compute pixel color as a float4

write_imagef(pix, (int2)(x,y), color);

}

12.6 Security Enhancement

Security is at the forefront of concerns for Web browser vendors. Remember when nobody had JavaScript turned on in their Web browser by default? The justified fear is that an unknown program, hiding inside a webpage may be able to access operating system resources and, for example, steal data from your computer, or install viruses and other trojans. A malicious script could also bring a computer down by utilizing all the resources, or crashing the computer.

In the case of WebGL and WebCL, the code is destined to run on the GPU to get maximum performance, and currently GPUs are lacking hardware mechanisms to make sure a program cannot access anything other than what it is supposed to: memory protection and reading uninitialized data are required.

A mechanism has been created to make sure the kernels sent to WebCL cannot access data outside their boundaries. Recall that WebCL mandates kernels are sent in text form, which enables the WebCL compiler to analyze and annotate a kernel before it is sent to the compiler. Alternatively, it would also have been possible to allow for precompiled programs provided there is a way to validate the safety of a program and a digital signature process, but there are no binary standard formats for compile kernels at this point in time.

The two principles of this protection are that the memory allocated in the program has to be initialized (prevent access to old data from other programs) and that untrusted code must not access invalid memory.

The mechanism to guarantee this level of security is as follows:

 Keep track of memory allocations (also in runtime if the platform supports dynamic allocation)

 Trace valid ranges for reads and writes

 Validate them efficiently while compiling the program or at runtime

The kernels are passed through a validator, which annotates the code to make sure that there is no possible out-of-bounds access, which does impact performance (measurements suggest less than 30% performance degradation), but ensure safety. For more information, please read [6].

12.7 WebCL on the Server

Since WebCL is all about computing, it can be used on Web browsers as well as by stand-alone applications and servers programmed with JavaScript. Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast and scalable network applications. Node.js uses an event-driven, nonblocking input/output model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices [7]. Node.js is very modular, and more than 80,000 modules exist, one of which is node-webcl [8], a cross-platform module implementing the WebCL specification on top of OpenCL. node-webcl also extends the specification with features specific to node.js (e.g. using node.js’s buffers as well as typed arrays) and other features that may be considered in future releases of the WebCL specification.

Installing node-webcl is more complex than installing a browser. This is a development tool, and it requires third-party libraries and it needs to be recompiled.

 First, make sure the OpenCL software development kit (SDK) is installed for your GPU and/or your CPU:

 For Intel GPUs, install it from https://software.intel.com/en-us/vcsource/tools/opencl-sdk.

 For AMD GPUs, install it from http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/.

 For NVIDIA GPUs, install it from https://developer.nvidia.com/opencl.

 Install node.js from http://nodejs.org.

 Install node-gyp: npm install -g node-gyp.

 Install node-image:

 Download the FreeImage library and headers from http://freeimage.sourceforge.net/.

 npm install node-image.

If you want to develop applications with the WebGL interoperability extension, you need to install node-webgl and node-glfw:

 Install GLEW from http://glew.sourceforge.net/.

 Install GLFW 3.x from http://www.glfw.org/.

 Install the AntTweakBar library and headers from http://anttweakbar.sourceforge.net/.

 npm install node-glfw node-webgl.

Finally, compile and install node-webcl:

 npm install node-webcl

We recommend installation of GLEW, AntTweakBar, FreeImage, and GLFW in your include and library paths so node-gyp can find them easily while building each node.js module, otherwise you will need to edit each module’s binding.gyp file. These four libraries are available on all desktop platforms (Mac, Windows, Linux) and can be installed on Linux and Mac machines using package managers such as apt-get and Homebrew [9].

To use node-webcl in your code, open your favorite JavaScript text editor. You require node-webcl so that the WebCL API is added to the global namespace. The webcl object below is exactly the same as a browser’s window.webcl object.

// add WebCL API

var webcl = require(‘node-webcl’);

// rest of the code is identical to that in a browser

Removing the “require” line and using webcl = window.webcl will make your code work on any WebCL-enabled browser. With node-webcl, one can now take advantage of operating system access and all node.js modules.

One possible use case is to use node.js with node-webcl to perform accelerated computations on a server and communicate the results to browsers via Web sockets [10], which in turn can render it in a meaningful way [11].

Likewise, many numerical applications require the use of various frameworks, such as Python, R, and MATLAB. These scripting languages provide similar features also available in JavaScript. And, given the speed of the JavaScript runtime and that many of these numerical libraries have already been ported to JavaScript (even tools to transcode these languages directly to JavaScript), JavaScript with node.js becomes a much faster platform unifying frameworks and languages.

Because node-webcl is less restrictive than browsers, applications can be developed more quickly and typically run faster. Enhanced with the node.js fast evented runtime, very dynamic and multithreaded applications can be developed in JavaScript that may not be possible in browsers. This is ideal for server-side applications that need to schedule complex workloads on all OpenCL-enabled devices in a platform.

With node.js and node-webcl, JavaScript-based applications can be developed and deployed rapidly on the server side and on the client side. Complex, data-intensive real-time applications are now possible from JavaScript.

Recently, a new node.js module appeared, called node-opencl [18]. While developed by the same authors as node-webcl, node-opencl is a complete rewrite. node-opencl is lower-level than node-webcl and is a direct representation of OpenCL features in JavaScript. Contrary to WebCL that supports OpenCL 1.1, node-opencl supports all versions of OpenCL. One could make a pure JavaScript representation of WebCL on top of node-opencl. While all other WebCL implementations have sporadic maintenance, node-opencl and node-webcl are actively supported.

12.8 Status and Future of WebCL

WebCL 1.0 was released on March 14, 2014, and the group has been developing the conformance tests [12], white papers, and tutorials [13]. At the time of writing, there are four implementations of WebCL 1.0:

1. Nokia’s WebCL implementation for the Firefox browser [14]

2. Samsung’s WebCL implementation for WebKit-based browsers [15]

3. AMD’s WebCL implementation for Chromium-based browsers [16]

4. Motorola Mobility’s WebCL implementation for node.js (not a browser) [17], [19]

5. AMD’s node-opencl, a node.js wrapper to OpenCL for servers [18]

The conformance was finalized by the end of 2014, which should help Web browser vendors release updated versions of their browsers with WebCL support.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.248.162