WebCL
Software
- 6 min read
- 4 chapters
Related on Lably
Through JavaScript, Web browser and Augmented reality
Implementation
Currently, no browsers natively support WebCL. However, non-native add-ons are used to implement WebCL. For example, Nokia developed a WebCL extension. Mozilla does not plan to implement WebCL in favor of WebGL Compute Shaders, which were in turn scrapped in favor of WebGPU.
- Mozilla (Firefox) - hg.mozilla.org/projects/webcl/ Archived 2016-03-03 at the Wayback Machine
WebCL working draft
- Samsung (WebKit) - github.com/SRA-SiliconValley/webkit-webcl Archived 2014-08-01 at the Wayback Machine
- Nokia (Firefox) - github.com/toaarnio/webcl-firefox (last Version for Firefox 34) Archived 2018-06-11 at the Wayback Machine
- Intel (Crosswalk) - www.crosswalk-project.org Archived 2013-09-27 at the Wayback Machine
Example C code
The basic unit of a parallel program is kernel. A kernel is any parallelizable task used to perform a specific job. More often functions can be realized as kernels. A program can be composed of one or more kernels. In order to realize a kernel, it is essential that a task is parallelizable. Data dependencies and order of execution play a vital role in producing efficient parallelized algorithms. A simple example can be thought of the case of loop unrolling performed by C compilers, where a statement like:
<span id="mwTA"></span><span class="k" id="mwTQ">for</span><span class="w" id="mwTg"> </span><span class="p" id="mwTw">(</span><span class="n" id="mwUA">i</span><span class="w" id="mwUQ"> </span><span class="o" id="mwUg">=</span><span class="w" id="mwUw"> </span><span class="mi" id="mwVA">0</span><span class="p" id="mwVQ">;</span><span class="w" id="mwVg"> </span><span class="n" id="mwVw">i</span><span class="o" id="mwWA"><</span><span class="w" id="mwWQ"> </span><span class="mi" id="mwWg">3</span><span class="w" id="mwWw"> </span><span class="p" id="mwXA">;</span><span class="w" id="mwXQ"> </span><span class="n" id="mwXg">i</span><span class="o" id="mwXw">++</span><span class="p" id="mwYA">)</span> <span class="w" id="mwYQ"> </span><span class="n" id="mwYg">c</span><span class="p" id="mwYw">[</span><span class="n" id="mwZA">i</span><span class="p" id="mwZQ">]</span><span class="w" id="mwZg"> </span><span class="o" id="mwZw">=</span><span class="w" id="mwaA"> </span><span class="n" id="mwaQ">a</span><span class="p" id="mwag">[</span><span class="n" id="mwaw">i</span><span class="p" id="mwbA">]</span><span class="w" id="mwbQ"> </span><span class="o" id="mwbg">+</span><span class="w" id="mwbw"> </span><span class="n" id="mwcA">b</span><span class="p" id="mwcQ">[</span><span class="n" id="mwcg">i</span><span class="p" id="mwcw">];</span>
can be unrolled into:
<span id="mwdw"></span><span class="n" id="mweA">c</span><span class="p" id="mweQ">[</span><span class="mi" id="mweg">0</span><span class="p" id="mwew">]</span><span class="w" id="mwfA"> </span><span class="o" id="mwfQ">=</span><span class="w" id="mwfg"> </span><span class="n" id="mwfw">a</span><span class="p" id="mwgA">[</span><span class="mi" id="mwgQ">0</span><span class="p" id="mwgg">]</span><span class="w" id="mwgw"> </span><span class="o" id="mwhA">+</span><span class="w" id="mwhQ"> </span><span class="n" id="mwhg">b</span><span class="p" id="mwhw">[</span><span class="mi" id="mwiA">0</span><span class="p" id="mwiQ">];</span> <span class="n" id="mwig">c</span><span class="p" id="mwiw">[</span><span class="mi" id="mwjA">1</span><span class="p" id="mwjQ">]</span><span class="w" id="mwjg"> </span><span class="o" id="mwjw">=</span><span class="w" id="mwkA"> </span><span class="n" id="mwkQ">a</span><span class="p" id="mwkg">[</span><span class="mi" id="mwkw">1</span><span class="p" id="mwlA">]</span><span class="w" id="mwlQ"> </span><span class="o" id="mwlg">+</span><span class="w" id="mwlw"> </span><span class="n" id="mwmA">b</span><span class="p" id="mwmQ">[</span><span class="mi" id="mwmg">1</span><span class="p" id="mwmw">];</span> <span class="n" id="mwnA">c</span><span class="p" id="mwnQ">[</span><span class="mi" id="mwng">2</span><span class="p" id="mwnw">]</span><span class="w" id="mwoA"> </span><span class="o" id="mwoQ">=</span><span class="w" id="mwog"> </span><span class="n" id="mwow">a</span><span class="p" id="mwpA">[</span><span class="mi" id="mwpQ">2</span><span class="p" id="mwpg">]</span><span class="w" id="mwpw"> </span><span class="o" id="mwqA">+</span><span class="w" id="mwqQ"> </span><span class="n" id="mwqg">b</span><span class="p" id="mwqw">[</span><span class="mi" id="mwrA">2</span><span class="p" id="mwrQ">];</span>
Above statements can be parallelized and can be made to run simultaneously. A kernel follows a similar approach where only the snapshot of the ith iteration is captured inside kernel.
Rewriting the above code using a kernel:
<span id="mwsw"></span><span class="n" id="mwtA">__kernel</span><span class="w" id="mwtQ"> </span><span class="nf" id="mwtg">add</span><span class="p" id="mwtw">(</span><span class="n" id="mwuA">__global</span><span class="w" id="mwuQ"> </span><span class="kt" id="mwug">float</span><span class="o" id="mwuw">*</span><span class="w" id="mwvA"> </span><span class="n" id="mwvQ">a</span><span class="p" id="mwvg">,</span><span class="w" id="mwvw"> </span><span class="n" id="mwwA">__global</span><span class="w" id="mwwQ"> </span><span class="kt" id="mwwg">float</span><span class="o" id="mwww">*</span><span class="w" id="mwxA"> </span><span class="n" id="mwxQ">b</span><span class="p" id="mwxg">,</span><span class="w" id="mwxw"> </span><span class="n" id="mwyA">__global</span><span class="w" id="mwyQ"> </span><span class="kt" id="mwyg">float</span><span class="o" id="mwyw">*</span><span class="n" id="mwzA">c</span><span class="p" id="mwzQ">)</span> <span class="p" id="mwzg">{</span> <span class="w" id="mwzw"> </span><span class="kt" id="mw0A">int</span><span class="w" id="mw0Q"> </span><span class="n" id="mw0g">i</span><span class="w" id="mw0w"> </span><span class="o" id="mw1A">=</span><span class="w" id="mw1Q"> </span><span class="n" id="mw1g">get_global_id</span><span class="p" id="mw1w">(</span><span class="mi" id="mw2A">0</span><span class="p" id="mw2Q">);</span> <span class="w" id="mw2g"> </span><span class="k" id="mw2w">if</span><span class="w" id="mw3A"> </span><span class="p" id="mw3Q">(</span><span class="n" id="mw3g">i</span><span class="o" id="mw3w"><</span><span class="mi" id="mw4A">3</span><span class="p" id="mw4Q">)</span> <span class="w" id="mw4g"> </span><span class="n" id="mw4w">c</span><span class="p" id="mw5A">[</span><span class="n" id="mw5Q">i</span><span class="p" id="mw5g">]</span><span class="w" id="mw5w"> </span><span class="o" id="mw6A">=</span><span class="w" id="mw6Q"> </span><span class="n" id="mw6g">a</span><span class="p" id="mw6w">[</span><span class="n" id="mw7A">i</span><span class="p" id="mw7Q">]</span><span class="w" id="mw7g"> </span><span class="o" id="mw7w">+</span><span class="w" id="mw8A"> </span><span class="n" id="mw8Q">b</span><span class="p" id="mw8g">[</span><span class="n" id="mw8w">i</span><span class="p" id="mw9A">];</span> <span class="p" id="mw9Q">}</span>Running a WebCL application involves the following steps:
- Allow access to devices and provide context
- Hand over the kernel to a device
- Cause the device to execute the kernel
- Retrieve results from the device
- Use the data inside JavaScript
Further details about the same can be found at
Sign in to keep reading
3 more chapters are free with a Lably account.
Exceptions List
WebCL, being a JavaScript based implementation, doesn't return an error code when errors occur. Instead, it throws an exception such as OUT_OF_RESOURCES, OUT_OF_HOST_MEMORY, or the WebCL-specific WEBCL_IMPLEMENTATION_FAILURE. The exception object describes the machine-readable name and human-readable message describing the error. The syntax is as follows:
<span id="mwAQ0"></span><span class="nx" id="mwAQ4">exception</span><span class="w" id="mwAQ8"> </span><span class="nx" id="mwARA">WebCLException</span><span class="w" id="mwARE"> </span><span class="o" id="mwARI">:</span><span class="w" id="mwARM"> </span><span class="nx" id="mwARQ">DOMException</span><span class="w" id="mwARU"> </span><span class="p" id="mwARY">{</span> <span class="w" id="mwARc"> </span><span class="nx" id="mwARg">DOMString</span><span class="w" id="mwARk"> </span><span class="nx" id="mwARo">name</span><span class="p" id="mwARs">;</span><span class="w" id="mwARw"> </span><span class="c1" id="mwAR0">// A string representation of the numeric error code, e.g. "INVALID_VALUE"</span> <span class="w" id="mwAR4"> </span><span class="nx" id="mwAR8">DOMString</span><span class="o" id="mwASA">?</span><span class="w" id="mwASE"> </span><span class="nx" id="mwASI">message</span><span class="p" id="mwASM">;</span><span class="w" id="mwASQ"> </span><span class="c1" id="mwASU">// An implementation-specific description of what caused the exception</span> <span class="p" id="mwASY">};</span>From the code above, it can be observed that the message field can be a NULL value. Other exceptions include:
INVALID_OPERATION– if the blocking form of this function is called from aWebCLCallbackINVALID_VALUE– ifeventWaitListis emptyINVALID_CONTEXT– if events specified ineventWaitListdo not belong to the same contextINVALID_DEVICE_TYPE– ifdeviceTypeis given, but is not one of the valid enumerated valuesDEVICE_NOT_FOUND– if there is noWebCLDeviceavailable that matches the givendeviceType
More information on exceptions can be found in the specs document.
There is another exception that is raised upon trying to call an object that is ‘released’. On using the release method, the object doesn't get deleted permanently but it frees the resources associated with that object. In order to avoid this exception, releaseAll method can be used, which not only frees the resources but also deletes all the associated objects created.
Security
WebCL, being an open-ended software developed for web applications, has lots of scope for vulnerabilities in the design and development fields too. This forced the developers working on WebCL to give security the utmost importance. Few concerns that were addressed are:
- Out-of-bounds Memory Access: This occurs by accessing the memory locations, outside the allocated space. An attacker can rewrite or erase all the important data stored in those memory locations. Whenever there arises such a case, an error must be generated at the compile time, and zero must be returned at run-time, not letting the program override the memory. A project WebCL Validator, was initiated by the Khronos Group (developers) on handling this vulnerability.
- Memory Initialization: This is done to prevent the applications to access the memory locations of previous applications. WebCL ensures that this doesn't happen by initializing all the buffers, variables used to zero before it runs the current application. OpenCL 1.2 has an extension ‘cl_khr_initialize_memory’, which enables this.
- Denial of Service: The most common attack on web applications cannot be eliminated by WebCL or the browser. OpenCL can be provided with watchdog timers and pre-emptive multitasking, which can be used by WebCL in order to detect and terminate the contexts that are taking too long or consume lot of resources. There is an extension of OpenCL 1.2 ‘cl_khr_terminate_context’ like for the previous one, which enables to terminate the process that might cause a denial of service attack.
Related browser bugs
- Bug 664147 - [WebCL] add openCL in gecko, Mozilla
- Bug 115457: [Meta] WebCL support for WebKit, WebKit Bugzilla

