├── .gitignore ├── LICENSES ├── README.md ├── binding.gyp ├── examples ├── BoxFilter.cl ├── BoxFilter.js ├── BoxFilterGL.js ├── DeviceQuery.js ├── ImageFilter.js ├── VectorAdd.js ├── VectorAddMapped.js ├── apple │ └── qjulia │ │ ├── qjulia.js │ │ └── qjulia_kernel.cl ├── gaussian_filter.cl ├── glMatrix-0.9.5.min.js ├── histogram.js ├── lenaRGB.jpg ├── mandelbrot │ └── mandelbrot.cl ├── mike_scooter.jpg ├── sampler.js ├── saxpy.js ├── shadertoy │ ├── 704.cl │ ├── clgl.js │ ├── compute.js │ ├── compute_julia.js │ ├── graphics.js │ ├── mandelbulb.cl │ ├── mandelbulb_AoS.cl │ └── qjulia.cl ├── sine.cl ├── sine.js └── swapRB.cl ├── lib └── clUtils.js ├── package.json ├── runner.js ├── src ├── bindings.cc ├── cl_checks.cc ├── cl_checks.h ├── commandqueue.cc ├── commandqueue.h ├── common.h ├── context.cc ├── context.h ├── device.cc ├── device.h ├── event.cc ├── event.h ├── exceptions.cc ├── exceptions.h ├── kernel.cc ├── kernel.h ├── manager.cc ├── manager.h ├── memoryobject.cc ├── memoryobject.h ├── platform.cc ├── platform.h ├── program.cc ├── program.h ├── sampler.cc ├── sampler.h ├── webcl.cc └── webcl.h ├── test ├── bandwidth.js ├── callback.js ├── callback2.js ├── callback_empty_eventList.js ├── ctypes.js ├── exit.js ├── fp64.js ├── gradient.cl ├── image.js ├── lenaRGB.jpg ├── node_buffer.js ├── perf.chai.js ├── profile_items.js ├── profile_read.js ├── sizeof.js ├── test.createQ_no_device.js ├── test.createQ_no_locals.js ├── test.exceptions.js ├── test.memory.js ├── test.platform.js ├── test.typedarrays.js ├── typedarrays.js └── user_event.js └── webcl.js /.gitignore: -------------------------------------------------------------------------------- 1 | Debug 2 | .idea 3 | .settings 4 | build 5 | conformance 6 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [ 3 | { 4 | 'target_name': 'webcl', 5 | 'defines': [ 6 | 'VERSION=0.9.1', 7 | # 'LOGGING' 8 | ], 9 | 'sources': [ 10 | 'src/bindings.cc', 11 | 'src/cl_checks.cc', 12 | 'src/commandqueue.cc', 13 | 'src/context.cc', 14 | 'src/device.cc', 15 | 'src/event.cc', 16 | 'src/exceptions.cc', 17 | 'src/kernel.cc', 18 | 'src/memoryobject.cc', 19 | 'src/platform.cc', 20 | 'src/program.cc', 21 | 'src/sampler.cc', 22 | 'src/webcl.cc', 23 | 'src/manager.cc', 24 | ], 25 | 'include_dirs' : [ 26 | "> 8) & 0xff; 21 | rgba.z = (c >> 16) & 0xff; 22 | rgba.w = (c >> 24) & 0xff; 23 | return rgba; 24 | } 25 | 26 | // Inline device function to convert floating point rgba color to 32-bit unsigned integer 27 | //***************************************************************** 28 | unsigned int rgbaFloat4ToUint(float4 rgba, float fScale) { 29 | unsigned int uiPackedPix = 0U; 30 | uiPackedPix |= 0x000000FF & (unsigned int) (rgba.x * fScale); 31 | uiPackedPix |= 0x0000FF00 & (((unsigned int) (rgba.y * fScale)) << 8); 32 | uiPackedPix |= 0x00FF0000 & (((unsigned int) (rgba.z * fScale)) << 16); 33 | uiPackedPix |= 0xFF000000 & (((unsigned int) (rgba.w * fScale)) << 24); 34 | return uiPackedPix; 35 | } 36 | 37 | // Row summation filter kernel with rescaling, using Image (texture) 38 | // USETEXTURE switch passed in via OpenCL clBuildProgram call options string at app runtime 39 | //***************************************************************** 40 | // Row summation filter kernel with rescaling, using Image (texture) 41 | __kernel void BoxRowsTex( __read_only image2d_t SourceRgbaTex, __global unsigned int* uiDest, sampler_t RowSampler, 42 | unsigned int uiWidth, unsigned int uiHeight, int iRadius, float fScale) 43 | { 44 | // Row to process (note: 1 dimensional workgroup and ND range used for row kernel) 45 | size_t globalPosY = get_global_id(0); 46 | size_t szBaseOffset = mul24(globalPosY, uiWidth); 47 | 48 | // Process the row as long as Y pos isn'f4Sum off the image 49 | if (globalPosY < uiHeight) 50 | { 51 | // 4 fp32 accumulators 52 | float4 f4Sum = (float4)0.0f; 53 | 54 | // Do the left boundary 55 | for(int x = -iRadius; x <= iRadius; x++) // (note: clamping provided by Image (texture)) 56 | { 57 | int2 pos = {x , globalPosY}; 58 | f4Sum += convert_float4(read_imageui(SourceRgbaTex, RowSampler, pos)); 59 | } 60 | uiDest[szBaseOffset] = rgbaFloat4ToUint(f4Sum, fScale); 61 | 62 | // Do the rest of the image 63 | int2 pos = {0, globalPosY}; 64 | for(unsigned int x = 1; x < uiWidth; x++) // (note: clamping provided by Image (texture)) 65 | { 66 | // Accumulate the next rgba sub-pixel vals 67 | pos.x = x + iRadius; 68 | f4Sum += convert_float4(read_imageui(SourceRgbaTex, RowSampler, pos)); 69 | 70 | // Remove the trailing rgba sub-pixel vals 71 | pos.x = x - iRadius - 1; 72 | f4Sum -= convert_float4(read_imageui(SourceRgbaTex, RowSampler, pos)); 73 | 74 | // Write out to GMEM 75 | uiDest[szBaseOffset + x] = rgbaFloat4ToUint(f4Sum, fScale); 76 | } 77 | } 78 | } 79 | 80 | // Column kernel using coalesced global memory reads 81 | //***************************************************************** 82 | __kernel void BoxColumns(__global unsigned int* uiInputImage, __global unsigned int* uiOutputImage, 83 | unsigned int uiWidth, unsigned int uiHeight, int iRadius, float fScale) 84 | { 85 | size_t globalPosX = get_global_id(0); 86 | uiInputImage = &uiInputImage[globalPosX]; 87 | uiOutputImage = &uiOutputImage[globalPosX]; 88 | 89 | // do left edge 90 | float4 f4Sum; 91 | f4Sum = rgbaUintToFloat4(uiInputImage[0]) * (float4)(iRadius); 92 | for (int y = 0; y < iRadius + 1; y++) 93 | { 94 | f4Sum += rgbaUintToFloat4(uiInputImage[y * uiWidth]); 95 | } 96 | uiOutputImage[0] = rgbaFloat4ToUint(f4Sum, fScale); 97 | for(int y = 1; y < iRadius + 1; y++) 98 | { 99 | f4Sum += rgbaUintToFloat4(uiInputImage[(y + iRadius) * uiWidth]); 100 | f4Sum -= rgbaUintToFloat4(uiInputImage[0]); 101 | uiOutputImage[y * uiWidth] = rgbaFloat4ToUint(f4Sum, fScale); 102 | } 103 | 104 | // main loop 105 | unsigned int y; 106 | for(y = iRadius + 1; y < uiHeight - iRadius; y++) 107 | { 108 | f4Sum += rgbaUintToFloat4(uiInputImage[(y + iRadius) * uiWidth]); 109 | f4Sum -= rgbaUintToFloat4(uiInputImage[((y - iRadius) * uiWidth) - uiWidth]); 110 | uiOutputImage[y * uiWidth] = rgbaFloat4ToUint(f4Sum, fScale); 111 | } 112 | 113 | // do right edge 114 | for (y = uiHeight - iRadius; y < uiHeight; y++) 115 | { 116 | f4Sum += rgbaUintToFloat4(uiInputImage[(uiHeight - 1) * uiWidth]); 117 | f4Sum -= rgbaUintToFloat4(uiInputImage[((y - iRadius) * uiWidth) - uiWidth]); 118 | uiOutputImage[y * uiWidth] = rgbaFloat4ToUint(f4Sum, fScale); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /examples/ImageFilter.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../webcl'); 30 | clu = require('../lib/clUtils'); 31 | util = require("util"), 32 | fs = require("fs"); 33 | Image = require("node-image").Image; 34 | log = console.log; 35 | } 36 | else 37 | webcl = window.webcl; 38 | 39 | //First check if the webcl extension is installed at all 40 | if (webcl == undefined) { 41 | alert("Unfortunately your system does not support webcl. " + 42 | "Make sure that you have the webcl extension installed."); 43 | process.exit(-1); 44 | } 45 | 46 | var file = __dirname+'/mike_scooter.jpg'; 47 | 48 | log('Loading image '+file); 49 | var img=Image.load(file); 50 | var image=img.convertTo32Bits(); 51 | log('Image '+file+': \n'+util.inspect(image)); 52 | 53 | image.size = image.height*image.pitch; 54 | 55 | var outBuf=ImageFilter(image); 56 | 57 | // PNG uses 32-bit images, JPG can only work on 24-bit images 58 | if(!Image.save('out.png',outBuf, image.width, image.height, image.pitch, image.bpp, 0xFF0000, 0x00FF00, 0xFF)) 59 | log("Error saving image"); 60 | image.unload(); 61 | 62 | function ImageFilter(image) { 63 | var out=new Uint8Array(image.size); 64 | 65 | // create GPU context for this platform 66 | var context=webcl.createContext(webcl.DEVICE_TYPE_GPU); 67 | 68 | // find the device for this context 69 | var devices = context.getInfo(webcl.CONTEXT_DEVICES); 70 | device=devices[0]; 71 | 72 | // Report the device vendor and device name 73 | // 74 | var vendor_name = device.getInfo(webcl.DEVICE_VENDOR); 75 | var device_name = device.getInfo(webcl.DEVICE_NAME); 76 | 77 | log("Connecting to: "+vendor_name+" "+device_name); 78 | 79 | kernelSourceCode = fs.readFileSync(__dirname+'/swapRB.cl','ascii'); 80 | 81 | //Create and program from source 82 | program=context.createProgram(kernelSourceCode); 83 | 84 | //Build program 85 | try { 86 | program.build(device); 87 | } catch (err) { 88 | log('Error building program: ' + err); 89 | log(program.getBuildInfo(device, webcl.PROGRAM_BUILD_LOG)); 90 | process.exit(-1); 91 | } 92 | 93 | // create device buffers 94 | try { 95 | cmPinnedBufIn = context.createBuffer(webcl.MEM_READ_ONLY | webcl.MEM_ALLOC_HOST_PTR, image.size); 96 | cmPinnedBufOut = context.createBuffer(webcl.MEM_WRITE_ONLY | webcl.MEM_ALLOC_HOST_PTR, image.size); 97 | } 98 | catch(err) { 99 | console.log('error creating buffers'); 100 | process.exit(-1); 101 | } 102 | 103 | //Create kernel object 104 | try { 105 | kernel= program.createKernel("swapRB"); 106 | } 107 | catch(err) { 108 | console.log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG)); 109 | } 110 | 111 | // Set the arguments to our compute kernel 112 | var aints=new Int32Array(3); 113 | aints.set([image.width, image.height, 0]); 114 | try { 115 | kernel.setArg(0, cmPinnedBufIn); 116 | kernel.setArg(1, cmPinnedBufOut); 117 | kernel.setArg(2, aints); 118 | // kernel.setArg(3, aints.subarray(1)); 119 | } 120 | catch(ex) { 121 | log(ex); 122 | process.exit(-1); 123 | } 124 | 125 | //Create command queue 126 | queue=context.createCommandQueue(device, 0); 127 | 128 | // Init ND-range 129 | // Get the maximum work group size for executing the kernel on the device 130 | var localWS=[ kernel.getWorkGroupInfo(device, webcl.KERNEL_WORK_GROUP_SIZE) ]; 131 | var globalWS = [ localWS[0] * clu.DivUp(image.size, localWS[0]) ]; 132 | 133 | log("Global work item size: " + globalWS); 134 | log("Local work item size: " + localWS); 135 | 136 | // Write our data set into the input array in device memory asynchronously 137 | queue.enqueueWriteBuffer(cmPinnedBufIn, false, 0, image.size, image.buffer); 138 | 139 | // Execute (enqueue) kernel 140 | queue.enqueueNDRangeKernel(kernel, 1, 141 | null, 142 | globalWS, 143 | localWS); 144 | 145 | queue.enqueueReadBuffer(cmPinnedBufOut, false, 0, out.length, out); 146 | 147 | queue.finish(); //Finish all the operations 148 | 149 | return out; 150 | } 151 | 152 | 153 | -------------------------------------------------------------------------------- /examples/VectorAdd.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../webcl'); 30 | clu = require('../lib/clUtils'); 31 | log=console.log; 32 | } 33 | else 34 | webcl = window.webcl; 35 | 36 | //First check if the webcl extension is installed at all 37 | if (webcl == undefined) { 38 | alert("Unfortunately your system does not support webcl. " + 39 | "Make sure that you have the webcl extension installed."); 40 | process.exit(-1); 41 | } 42 | 43 | VectorAdd(); 44 | 45 | function VectorAdd() { 46 | BUFFER_SIZE=10; 47 | var A=new Uint32Array(BUFFER_SIZE); 48 | var B=new Uint32Array(BUFFER_SIZE); 49 | 50 | for (var i = 0; i < BUFFER_SIZE; i++) { 51 | A[i] = i; 52 | B[i] = i * 2; 53 | } 54 | 55 | //Pick platform 56 | var platformList=webcl.getPlatforms(); 57 | platform=platformList[0]; 58 | log('using platform: '+platform.getInfo(webcl.PLATFORM_NAME)); 59 | 60 | //Query the set of devices on this platform 61 | devices = platform.getDevices(webcl.DEVICE_TYPE_DEFAULT); 62 | log('using device: '+devices[0].getInfo(webcl.DEVICE_NAME)); 63 | 64 | // create GPU context for this platform 65 | context=webcl.createContext(webcl.DEVICE_TYPE_DEFAULT); 66 | 67 | kernelSourceCode = [ 68 | "__kernel void vadd(__global int *a, __global int *b, __global int *c, uint iNumElements) ", 69 | "{ ", 70 | " size_t i = get_global_id(0); ", 71 | " if(i >= iNumElements) return; ", 72 | " c[i] = a[i] + b[i]; ", 73 | "} " 74 | ].join("\n"); 75 | 76 | //Create and program from source 77 | program=context.createProgram(kernelSourceCode); 78 | 79 | //Build program 80 | program.build(devices); 81 | 82 | size=BUFFER_SIZE*Uint32Array.BYTES_PER_ELEMENT; // size in bytes 83 | 84 | // Create buffer for A and B and copy host contents 85 | aBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 86 | bBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 87 | 88 | // Create buffer for C to read results 89 | cBuffer = context.createBuffer(webcl.MEM_WRITE_ONLY, size); 90 | 91 | // Create kernel object 92 | try { 93 | kernel= program.createKernel("vadd"); 94 | } 95 | catch(err) { 96 | console.log(program.getBuildInfo(devices[0],webcl.PROGRAM_BUILD_LOG)); 97 | } 98 | 99 | // Set kernel args 100 | kernel.setArg(0, aBuffer); 101 | kernel.setArg(1, bBuffer); 102 | kernel.setArg(2, cBuffer); 103 | kernel.setArg(3, new Uint32Array([BUFFER_SIZE])); 104 | 105 | // Create command queue 106 | queue=context.createCommandQueue(devices[0], 0); 107 | 108 | // Execute the OpenCL kernel on the list 109 | var localWS = [5]; // process one list at a time 110 | var globalWS = [clu.roundUp(localWS, BUFFER_SIZE)]; // process entire list 111 | 112 | log("Global work item size: " + globalWS); 113 | log("Local work item size: " + localWS); 114 | 115 | // Do the work 116 | queue.enqueueWriteBuffer (aBuffer, false, 0, A.length*Uint32Array.BYTES_PER_ELEMENT, A); 117 | queue.enqueueWriteBuffer (bBuffer, false, 0, B.length*Uint32Array.BYTES_PER_ELEMENT, B); 118 | 119 | // Execute (enqueue) kernel 120 | log("using enqueueNDRangeKernel"); 121 | queue.enqueueNDRangeKernel(kernel, 1, 122 | null, 123 | globalWS, 124 | localWS); 125 | 126 | // get results and block while getting them 127 | var C=new Uint32Array(BUFFER_SIZE); 128 | queue.enqueueReadBuffer (cBuffer, true, 0, C.length*Uint32Array.BYTES_PER_ELEMENT, C); 129 | 130 | // print results 131 | printResults(A,B,C); 132 | 133 | // cleanup 134 | // test release each CL object 135 | // queue.release(); 136 | // kernel.release(); 137 | // program.release(); 138 | // aBuffer.release(); 139 | // bBuffer.release(); 140 | // cBuffer.release(); 141 | // context.release(); 142 | 143 | // test release all CL objects 144 | // webcl.releaseAll(); 145 | 146 | // if no manual cleanup specified, webcl.releaseAll() is called at exit of program 147 | } 148 | 149 | function printResults(A,B,C) { 150 | // Print input vectors and result vector 151 | var output = "\nA = "; 152 | for (var i = 0; i < BUFFER_SIZE; i++) { 153 | output += A[i] + ", "; 154 | } 155 | output += "\nB = "; 156 | for (var i = 0; i < BUFFER_SIZE; i++) { 157 | output += B[i] + ", "; 158 | } 159 | output += "\nC = "; 160 | for (var i = 0; i < BUFFER_SIZE; i++) { 161 | output += C[i] + ", "; 162 | } 163 | 164 | log(output); 165 | } 166 | -------------------------------------------------------------------------------- /examples/VectorAddMapped.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../webcl'); 30 | clu = require('../lib/clUtils'); 31 | log=console.log; 32 | } 33 | else 34 | webcl = window.webcl; 35 | 36 | //First check if the webcl extension is installed at all 37 | if (webcl == undefined) { 38 | alert("Unfortunately your system does not support webcl. " + 39 | "Make sure that you have the webcl extension installed."); 40 | process.exit(-1); 41 | } 42 | 43 | VectorAdd(); 44 | 45 | function VectorAdd() { 46 | BUFFER_SIZE=10; 47 | var A=new Uint32Array(BUFFER_SIZE); 48 | var B=new Uint32Array(BUFFER_SIZE); 49 | var C=new Uint32Array(BUFFER_SIZE); 50 | 51 | for (var i = 0; i < BUFFER_SIZE; i++) { 52 | A[i] = i; 53 | B[i] = i * 2; 54 | C[i] = 10; 55 | } 56 | 57 | // create GPU context for this platform 58 | var context=null; 59 | try { 60 | context=webcl.createContext(webcl.DEVICE_TYPE_GPU); 61 | } 62 | catch(ex) { 63 | throw new Exception("Can't create CL context"); 64 | } 65 | 66 | var devices=context.getInfo(webcl.CONTEXT_DEVICES); 67 | device=devices[0]; 68 | 69 | log('using device: '+device.getInfo(webcl.DEVICE_VENDOR).trim()+ 70 | ' '+device.getInfo(webcl.DEVICE_NAME)); 71 | 72 | kernelSourceCode = [ 73 | "__kernel void vadd(__global int *a, __global int *b, __global int *c, uint iNumElements) ", 74 | "{ ", 75 | " size_t i = get_global_id(0); ", 76 | " if(i > iNumElements) return; ", 77 | " c[i] = a[i] + b[i]; ", 78 | "} " 79 | ].join("\n"); 80 | 81 | //Create and program from source 82 | program=context.createProgram(kernelSourceCode); 83 | 84 | //Build program 85 | program.build(devices,""); 86 | 87 | var size=BUFFER_SIZE*Uint32Array.BYTES_PER_ELEMENT; // size in bytes 88 | 89 | //Create kernel object 90 | try { 91 | kernel= program.createKernel("vadd"); 92 | } 93 | catch(err) { 94 | console.log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG)); 95 | } 96 | 97 | //Create command queue 98 | queue=context.createCommandQueue(device, 0); 99 | 100 | //Create buffer for A and copy host contents 101 | aBuffer = context.createBuffer(webcl.MEM_READ_ONLY | webcl.MEM_USE_HOST_PTR, size, A); 102 | 103 | //Create buffer for B and copy host contents 104 | bBuffer = context.createBuffer(webcl.MEM_READ_ONLY | webcl.MEM_USE_HOST_PTR, size, B); 105 | 106 | //Create buffer for that uses the host ptr C 107 | cBuffer = context.createBuffer(webcl.MEM_WRITE_ONLY | webcl.MEM_USE_HOST_PTR, size, C); 108 | 109 | //Set kernel args 110 | kernel.setArg(0, aBuffer); 111 | kernel.setArg(1, bBuffer); 112 | kernel.setArg(2, cBuffer); 113 | kernel.setArg(3, new Uint32Array([BUFFER_SIZE])); 114 | 115 | // Execute the OpenCL kernel on the list 116 | // var localWS = [5]; // process one list at a time 117 | // var globalWS = [clu.roundUp(localWS, BUFFER_SIZE)]; // process entire list 118 | var localWS=null; 119 | var globalWS=[BUFFER_SIZE]; 120 | 121 | log("Global work item size: " + globalWS); 122 | log("Local work item size: " + localWS); 123 | 124 | // Execute (enqueue) kernel 125 | queue.enqueueNDRangeKernel(kernel, 1, 126 | null, 127 | globalWS, 128 | localWS); 129 | 130 | log("using enqueueMapBuffer"); 131 | // Map cBuffer to host pointer. This enforces a sync with 132 | // the host backing space, remember we choose GPU device. 133 | var map=queue.enqueueMapBuffer( 134 | cBuffer, 135 | webcl.TRUE, // block 136 | webcl.MAP_READ, 137 | 0, 138 | size); 139 | 140 | var output; 141 | output="after map C= "; 142 | for (var i = 0; i < BUFFER_SIZE; i++) { 143 | output += C[i] + ", "; 144 | } 145 | log(output); 146 | 147 | // we are now reading values as bytes, we need to cast it to the output type we want 148 | output = "output = "; 149 | for (var i = 0; i < size; i++) { 150 | output += map[i] + ", "; 151 | } 152 | log(output); 153 | 154 | queue.enqueueUnmapMemObject(cBuffer, map); 155 | 156 | output="after unmap C= "; 157 | for (var i = 0; i < BUFFER_SIZE; i++) { 158 | output += C[i] + ", "; 159 | } 160 | log(output); 161 | 162 | queue.finish(); //Finish all the operations 163 | 164 | printResults(A,B,C); 165 | 166 | // cleanup 167 | // queue.release(); 168 | // kernel.release(); 169 | // program.release(); 170 | // aBuffer.release(); 171 | // bBuffer.release(); 172 | // cBuffer.release(); 173 | // context.release(); 174 | //webcl.releaseAll(); 175 | } 176 | 177 | function printResults(A,B,C) { 178 | //Print input vectors and result vector 179 | var output = "\nA = "; 180 | for (var i = 0; i < BUFFER_SIZE; i++) { 181 | output += A[i] + ", "; 182 | } 183 | output += "\nB = "; 184 | for (var i = 0; i < BUFFER_SIZE; i++) { 185 | output += B[i] + ", "; 186 | } 187 | output += "\nC = "; 188 | for (var i = 0; i < BUFFER_SIZE; i++) { 189 | output += C[i] + ", "; 190 | } 191 | 192 | log(output); 193 | } 194 | -------------------------------------------------------------------------------- /examples/gaussian_filter.cl: -------------------------------------------------------------------------------- 1 | /* 2 | Adapted from OpenCL Programming Guide, Aaftab Munshi, Benedict Gaster, Timothy Mattson, James Fung, Dan Ginsburg, Addison-Wesley Professional, http://www.openclprogrammingguide.com 3 | Chapter 8 - ImageFilter2D.cpp 4 | */ 5 | 6 | // Gaussian filter of image 7 | 8 | __kernel void gaussian_filter(__read_only image2d_t srcImg, 9 | __write_only image2d_t dstImg, 10 | sampler_t sampler, 11 | int width, int height) 12 | { 13 | // Gaussian Kernel is: 14 | // 1 2 1 15 | // 2 4 2 16 | // 1 2 1 17 | float kernelWeights[9] = { 1.0f, 2.0f, 1.0f, 18 | 2.0f, 4.0f, 2.0f, 19 | 1.0f, 2.0f, 1.0f }; 20 | 21 | int x0 = get_global_id(0), y0 = get_global_id(1); 22 | int2 startImageCoord = (int2) (x0 - 1, y0 - 1); 23 | int2 endImageCoord = (int2) (x0 + 1, y0 + 1); 24 | int2 outImageCoord = (int2) (x0, y0); 25 | 26 | int weight = 0; 27 | float4 outColor = (float4)(0.0f, 0.0f, 0.0f, 0.0f); 28 | for( int y = startImageCoord.y; y <= endImageCoord.y; y++) 29 | { 30 | for( int x = startImageCoord.x; x <= endImageCoord.x; x++) 31 | { 32 | outColor += (read_imagef(srcImg, sampler, (int2)(x, y)) * kernelWeights[weight]); 33 | weight += 1; 34 | } 35 | } 36 | 37 | // Write the output value to image 38 | write_imagef(dstImg, outImageCoord, outColor/16.0f); 39 | } 40 | -------------------------------------------------------------------------------- /examples/lenaRGB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikeseven/node-webcl/100ce70280e020028b72e8b80a116bcef513a355/examples/lenaRGB.jpg -------------------------------------------------------------------------------- /examples/mandelbrot/mandelbrot.cl: -------------------------------------------------------------------------------- 1 | #ifdef cl_amd_fp64 2 | #pragma OPENCL EXTENSION cl_amd_fp64 : enable 3 | #elif defined(cl_khr_fp64) 4 | #pragma OPENCL EXTENSION cl_khr_fp64 : enable 5 | #endif 6 | 7 | __constant uint nc = 30; 8 | #define nc2 (2*nc) 9 | #define maxCol (nc*3) 10 | #define st (255.0f/(float)nc) 11 | 12 | /* This could be implemented as another kernel that would be executed after 13 | the Mandelbrot rendering. By doing so we could use many color maps without 14 | redoing the calculation of the Mandelbrot image. 15 | In this case, we would have Mandelbrot 'image' are a uint16 to be mapped into 16 | a final RGBA image using a colormap. 17 | */ 18 | void colorMap(__global unsigned int* pix, unsigned int idx, 19 | unsigned int ic) 20 | { 21 | unsigned int r=0U, g=0U, b=0U; 22 | if(ic> 1, h2 = height >> 1; 55 | int x2 = x-w2, y2 = y-h2; 56 | float Cr = (x2/scale)+ cX; 57 | float Ci = (y2/scale)+ cY; 58 | float I = 0, R = 0, I2 = 0, R2 = 0; 59 | unsigned int n = 0U; 60 | 61 | while ( ((R2+I2)<4.0f) && (n0.0f) p=prp+scp*f; 65 | else f=maxd; 66 | 67 | for(int i=0;i<256;i++){ 68 | if (fabs(s)<.01f || f>maxd) break; 69 | f+=s; 70 | p=prp+scp*f; 71 | s=inObj(params,p); 72 | } 73 | 74 | float3 rgb; 75 | 76 | if (f.5f) 79 | if (_fract(p.z*.5f)>.5f) 80 | c=(float3)(0); 81 | else 82 | c=(float3)(1); 83 | else 84 | if (_fract(p.z*.5f)>.5f) 85 | c = (float3)(1); 86 | else 87 | c = (float3)(0); 88 | n=(float3)(0,1,0); 89 | } 90 | else{ 91 | const float d=length(p); 92 | c=(float3)((native_sin(d*.25f-params.time*4.0f)+1.0f), 93 | (params.stime+1.0f), 94 | (native_sin(d-params.time*4.0f)+1.0f)); //color 95 | c *= 0.5f; 96 | n=normalize( 97 | (float3)(s-inObj(params,p-e.xyy), 98 | s-inObj(params,p-e.yxy), 99 | s-inObj(params,p-e.yyx))); 100 | } 101 | const float b=dot(n,normalize(prp-p)); 102 | rgb=(b*c+native_powr(b,54.0f))*(1.0f-f*.005f); 103 | rgb=clamp(rgb,(float3)(0),(float3)(1)); 104 | } 105 | 106 | write_imagef(pix,(int2)(x,y),(float4)(rgb,1.0f)); 107 | } 108 | -------------------------------------------------------------------------------- /examples/shadertoy/clgl.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../../webcl'); 30 | clu = require('../../lib/clUtils'); 31 | util = require('util'); 32 | fs = require('fs'); 33 | WebGL = require('node-webgl'); 34 | document = WebGL.document(); 35 | Image = WebGL.Image; 36 | alert = console.log; 37 | Graphics = require('./graphics'); 38 | argv=require('optimist').argv; 39 | Compute = require(argv.compute || './compute'); 40 | //Compute = require('./compute_droplet2d'); 41 | //Compute = require('./compute_droplet3d'); 42 | } 43 | else 44 | webcl = window.webcl; 45 | 46 | log = console.log; 47 | requestAnimationFrame = document.requestAnimationFrame; 48 | 49 | var COMPUTE_KERNEL_ID = "704.cl"; 50 | // var COMPUTE_KERNEL_ID = argv.kernel || "mandelbulb_AoS.cl"; 51 | // var COMPUTE_KERNEL_ID = "qjulia.cl"; 52 | var COMPUTE_KERNEL_NAME = "compute"; 53 | var WIDTH = argv.width || 512; 54 | var HEIGHT = argv.height || 512; 55 | var Width = WIDTH; 56 | var Height = HEIGHT; 57 | var Reshaped = true; 58 | var cango=false; 59 | var canvas; 60 | 61 | /* 62 | * reshape() is called if document is resized 63 | */ 64 | function reshape(evt) { 65 | Width = evt.width; 66 | Height = evt.height; 67 | Reshaped = true; 68 | log('reshape texture to '+Width+'x'+Height); 69 | } 70 | 71 | function keydown(evt) { 72 | //log('process key: ' + evt.which); 73 | 74 | Update = true; 75 | //cango=true; 76 | } 77 | 78 | 79 | (function main() { 80 | log('Initializing'); 81 | 82 | document.setTitle("ShaderToy with Image2D"); 83 | canvas = document.createElement("mycanvas", Width, Height); 84 | 85 | // install UX callbacks 86 | document.addEventListener('resize', reshape); 87 | document.addEventListener('keydown', keydown); 88 | 89 | // init WebGL 90 | var gfx=Graphics(); 91 | try { 92 | gfx.init(canvas); 93 | } 94 | catch(err) { 95 | log('[Error] While initializing GL: '+err); 96 | gfx.clean(); 97 | return; 98 | } 99 | 100 | // init webcl 101 | var compute=Compute(); 102 | try { 103 | compute.init(gfx, COMPUTE_KERNEL_ID, COMPUTE_KERNEL_NAME); 104 | } 105 | catch(err) { 106 | log('[Error] While initializing CL: '+err); 107 | compute.clean(); 108 | return; 109 | } 110 | 111 | // render scene 112 | var startTime=-1; 113 | 114 | (function update(timestamp) { 115 | if(timestamp) { 116 | if(startTime==-1) { 117 | startTime=fpsTo=timestamp; 118 | } 119 | var ltime = timestamp-startTime; 120 | } 121 | 122 | // reinit shared data if document is resized 123 | if (Reshaped) { 124 | log('reshaping texture to '+Width+'x'+Height); 125 | try { 126 | var glTexture=gfx.configure_shared_data(Width,Height); 127 | var clTexture=compute.configure_shared_data(gfx, glTexture); 128 | Reshaped=false; 129 | } 130 | catch(ex) { 131 | log('[Error] While reshaping shared data: '+ex); 132 | return; 133 | } 134 | } 135 | 136 | // set kernel arguments 137 | compute.resetKernelArgs(ltime/1000.0, Width, Height); 138 | 139 | // compute texture for this timestamp 140 | try { 141 | compute.execute_kernel(gfx.gl()); 142 | } 143 | catch(err) { 144 | alert('[Error] While executing kernel: '+err); 145 | return; 146 | } 147 | 148 | // render scene with updated texture from CL 149 | try { 150 | gfx.display(ltime); 151 | } 152 | catch(err) { 153 | alert('[Error] While rendering scene '+err); 154 | return; 155 | } 156 | 157 | //gfx.gl().flush(); // for timing 158 | //if(!cango) 159 | // startTime=-1; 160 | requestAnimationFrame(update /*,cango ? 0 : 5000*/); 161 | })(); 162 | })(); 163 | 164 | -------------------------------------------------------------------------------- /examples/shadertoy/compute_julia.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Compute contains all webcl initializations and runtime for our kernel 3 | * that update a texture. 4 | */ 5 | function Compute() { 6 | var orig=require('./compute')(); 7 | var orig_resetKernelArgs = orig.resetKernelArgs; 8 | var orig_init = orig.init; 9 | 10 | var Epsilon = 0.003; 11 | var ColorA = [ 0.25, 0.45, 1, 1 ]; 12 | var ColorB = [ 0.25, 0.45, 1, 1 ]; 13 | var diffuse = [ 0.25, 0.45, 1, 1 ]; 14 | var MuA = [ -0.278, -0.479, 0, 0 ]; 15 | var MuB = [ 0.278, 0.479, 0, 0 ]; 16 | var mu = [ -0.278, -0.479, -0.231, 0.235 ]; 17 | var t=0; 18 | 19 | function updateMu( m, t, a, b) { 20 | m[0] = (1 - t) * a[0] + t * b[0]; 21 | m[1] = (1 - t) * a[1] + t * b[1]; 22 | m[2] = (1 - t) * a[2] + t * b[2]; 23 | m[3] = (1 - t) * a[3] + t * b[3]; 24 | 25 | t+=0.01; 26 | if(t>=1) { 27 | t=0; 28 | a[0] = b[0]; 29 | a[1] = b[1]; 30 | a[2] = b[2]; 31 | a[3] = b[3]; 32 | 33 | b[0] = 2 * Math.random() - 1; 34 | b[1] = 2 * Math.random() - 1; 35 | b[2] = 2 * Math.random() - 1; 36 | b[3] = 2 * Math.random() - 1; 37 | } 38 | return t; 39 | } 40 | 41 | function updateColor( m, t, a, b) { 42 | t=updateMu(m, t, a, b); 43 | b[3] = 1; 44 | return t; 45 | } 46 | 47 | function init(gfx, kernel_id, kernel_name) { 48 | orig_init(gfx, kernel_id, kernel_name); 49 | var ATB=gfx.getATB(); 50 | var twBar=gfx.getBar(); 51 | 52 | twBar.AddVar("epsilon", ATB.TYPE_FLOAT, { 53 | getter: function(data){ return Epsilon; }, 54 | setter: function(val,data) { Epsilon=val; }, 55 | }, 56 | " label='epsilon' min=0.001 max=0.05 step=0.001 keyIncr=s keyDecr=S help='epsilon' "); 57 | 58 | twBar.AddVar("MuC", ATB.TYPE_QUAT4F, { 59 | getter: function(data){ return mu; }, 60 | }, 61 | " label='Mu' opened=true help='Mu' "); 62 | 63 | twBar.AddVar("Color", ATB.TYPE_COLOR4F, { 64 | getter: function(data){ return diffuse; }, 65 | }, 66 | " label='Color' opened=true help='Color' "); 67 | } 68 | 69 | /* 70 | * (Re-)set kernel arguments 71 | * 72 | * @param time timestamp in ms (as given by new Date().getTime() 73 | * @param image_width width of the image 74 | * @param image_height height of the image 75 | */ 76 | function resetKernelArgs(time, image_width, image_height) { 77 | orig_resetKernelArgs(time, image_width, image_height); 78 | 79 | updateMu(mu, t, MuA, MuB); 80 | t = updateColor(diffuse, t, ColorA, ColorB); 81 | 82 | // set the kernel args 83 | var clKernel = orig.getKernel(); 84 | var amu=new Float32Array(4); amu.set(mu); 85 | var adiffuse=new Float32Array(4); adiffuse.set(diffuse); 86 | var aeps=new Float32Array(1); aeps.set(Epsilon); 87 | 88 | try { 89 | // Set the Argument values for the row kernel 90 | clKernel.setArg(2, amu); 91 | clKernel.setArg(3, adiffuse); 92 | clKernel.setArg(4, aeps); 93 | } catch (err) { 94 | throw "Failed to set Julia kernel args! " + err; 95 | } 96 | } 97 | 98 | orig.init = init; 99 | orig.resetKernelArgs = resetKernelArgs; 100 | return orig; 101 | } 102 | 103 | module.exports=Compute; 104 | -------------------------------------------------------------------------------- /examples/shadertoy/mandelbulb.cl: -------------------------------------------------------------------------------- 1 | // forward declarations 2 | bool isphere( float4 sph, float3 ro, float3 rd, float2 *t ); 3 | bool iterate( float3 q, float *resPot, float4 *resColor ); 4 | bool ifractal( float3 ro, float3 rd, float *rest, float maxt, float3 *resnor, float4 *rescol, float fov ); 5 | 6 | inline bool isphere( float4 sph, float3 ro, float3 rd, float2 *t ) 7 | { 8 | float3 oc = ro - sph.xyz; 9 | float b = dot(oc,rd); 10 | float c = dot(oc,oc) - sph.w*sph.w; 11 | 12 | float h = b*b - c; 13 | if( h<0 ) 14 | return false; 15 | 16 | float g = sqrt( h ); 17 | (*t).x = - b - g; 18 | (*t).y = - b + g; 19 | 20 | return true; 21 | } 22 | 23 | #define NumIte 7 24 | #define Bailout 100 25 | 26 | inline bool iterate( float3 q, float *resPot, float4 *resColor ) 27 | { 28 | float4 trap = (float4)(100); 29 | float3 zz = q; 30 | float m = dot(zz,zz); 31 | if( m > Bailout ) 32 | { 33 | *resPot = 0.5f*log(m); ///pow(8.0f,0.0f); 34 | *resColor = (float4)(1); 35 | return false; 36 | } 37 | 38 | for( int i=1; i Bailout ) 58 | { 59 | *resColor = trap; 60 | *resPot = 0.5f*log(m)/pow(8.0f,i); 61 | return false; 62 | } 63 | } 64 | 65 | *resColor = trap; 66 | *resPot = 0; 67 | return true; 68 | } 69 | 70 | inline bool ifractal( float3 ro, float3 rd, float *rest, float maxt, 71 | float3 *resnor, float4 *rescol, float fov ) 72 | { 73 | float4 sph = (float4)( 0.0, 0.0, 0.0, 1.25 ); 74 | float2 dis; 75 | 76 | // bounding sphere 77 | if( !isphere(sph,ro,rd,&dis) ) 78 | return false; 79 | 80 | // early skip 81 | if( dis.y<0.001f ) return false; 82 | 83 | // clip to near! 84 | if( dis.x<0.001f ) dis.x = 0.001f; 85 | 86 | if( dis.y>maxt) dis.y = maxt; 87 | 88 | float dt; 89 | float3 gra; 90 | float4 color; 91 | float4 col2; 92 | float pot1; 93 | float pot2, pot3, pot4; 94 | 95 | float fovfactor = 1.0f/sqrt(1+fov*fov); 96 | 97 | // raymarch! 98 | for( float t=dis.x; t0.001f ) { 193 | float lt1; 194 | float3 ln; 195 | float4 lc; 196 | if( ifractal(xyz,light1,<1,1e20,&ln,&lc,fov) ) 197 | dif1 = 0.1f; 198 | } 199 | 200 | // material color 201 | rgb = (float3)(1); 202 | rgb = mix( rgb, (float3)(0.8,0.6,0.2), (float3)(sqrt(col.x)*1.25f) ); 203 | rgb = mix( rgb, (float3)(0.8,0.3,0.3), (float3)(sqrt(col.y)*1.25f) ); 204 | rgb = mix( rgb, (float3)(0.7,0.4,0.3), (float3)(sqrt(col.z)*1.25f) ); 205 | 206 | // lighting 207 | rgb *= (0.5f+0.5f*nor.y)* 208 | (float3)(.14,.15,.16)*0.8f + 209 | dif1*(float3)(1.0,.85,.4) + 210 | 0.5f*dif2*(float3)(.08,.10,.14); 211 | rgb *= (float3)( pow(ao,0.8f), pow(ao,1.00f), pow(ao,1.1f) ); 212 | 213 | // gamma 214 | rgb = 1.5f*(rgb*0.15f + 0.85f*sqrt(rgb)); 215 | } 216 | 217 | float2 uv = 0.5f*(p+1.f); 218 | rgb *= 0.7f + 0.3f*16.0f*uv.x*uv.y*(1.0f-uv.x)*(1.0f-uv.y); 219 | rgb = clamp( rgb, (float3)(0), (float3)(1) ); 220 | 221 | write_imagef(pix,(int2)(x,y),(float4)(rgb,1.0f)); 222 | } 223 | -------------------------------------------------------------------------------- /examples/shadertoy/mandelbulb_AoS.cl: -------------------------------------------------------------------------------- 1 | #define MAX_WORKGROUP_SIZE 256 2 | 3 | typedef struct { 4 | float3 origin; 5 | float r; 6 | float2 dis; 7 | } Sphere; // 4*(3+1+2)=24 bytes aligned to 32 bytes 8 | 9 | typedef struct { 10 | float3 origin; 11 | float3 dir; 12 | float3 nor; 13 | float4 col; 14 | float fovfactor; 15 | float t; 16 | float3 rgb; 17 | Sphere sph; 18 | } __attribute__((aligned(16))) Ray; // aligned to 128 bytes 19 | 20 | // forward declarations 21 | bool isphere( __local Ray *ray ); 22 | bool iterate( const float3 q, float *resPot, float4 *resColor ); 23 | bool ifractal( __local Ray *ray); 24 | 25 | inline bool isphere( __local Ray *ray ) { 26 | const float3 oc = ray->origin - ray->sph.origin; 27 | const float b = dot(oc,ray->dir); 28 | const float c = dot(oc,oc) - ray->sph.r*ray->sph.r; 29 | 30 | const float h = b*b - c; 31 | if( h<0 ) 32 | return false; 33 | 34 | const float g = native_sqrt( h ); 35 | ray->sph.dis = (float2) ( - b - g, - b + g); 36 | 37 | return true; 38 | } 39 | 40 | __constant const int NumIte=8; 41 | __constant const float Bailout=100.f; 42 | __constant const float EPS=0.001f; 43 | __constant const float MAXT=1.e20f; 44 | __constant const float3 light1 = (float3)( 0.577f, 0.577f, 0.577f ); 45 | __constant const float3 light2 = (float3)( -0.707f, 0, 0.707f ); 46 | __constant const float3 material1=(float3)(0.8f,0.6f,0.2f); 47 | __constant const float3 material2=(float3)(0.8f,0.3f,0.3f); 48 | __constant const float3 material3=(float3)(0.7f,0.4f,0.3f); 49 | 50 | inline bool iterate( const float3 q, float *resPot, float4 *resColor ) { 51 | float4 trap = (float4)(100.f); 52 | float3 zz = q; 53 | float m = dot(zz,zz); 54 | 55 | if( m > Bailout ) { 56 | *resPot = 0.5f*native_log(m); 57 | *resColor = (float4)(1.f); 58 | return false; 59 | } 60 | 61 | *resPot = 0; 62 | 63 | float x, x2, x4; 64 | float y, y2, y4; 65 | float z, z2, z4 ; 66 | float k1,k2,k3,k4; 67 | 68 | //#pragma unroll 2 69 | for( int i=0; i Bailout ) { 88 | *resPot = 0.5f*native_log(m)/native_powr(8.0f,i); 89 | break; 90 | } 91 | } 92 | 93 | *resColor = trap; 94 | return (m<=Bailout); 95 | } 96 | 97 | inline bool ifractal(__local Ray *ray) { 98 | __local Sphere *sph=&ray->sph; 99 | sph->origin = (float3)(0.f); 100 | sph->r = 1.25f; 101 | 102 | // bounding sphere 103 | if( !isphere(ray) ) return false; 104 | 105 | // early skip 106 | if( sph->dis.ydis.xdis.x = EPS; 110 | 111 | if( sph->dis.y>MAXT) sph->dis.y = MAXT; 112 | 113 | float dt; 114 | float3 gra; 115 | float4 color, col2; 116 | float pot1, pot2, pot3, pot4; 117 | 118 | // raymarch! 119 | float t=sph->dis.x, Surface, eps; 120 | float3 p = ray->origin + ray->dir * t; 121 | 122 | while(t < sph->dis.y) { 123 | if( iterate(p,&pot1,&color) ) { 124 | ray->t = t; 125 | ray->nor = fast_normalize(gra); 126 | ray->col = color; 127 | return true; 128 | } 129 | 130 | Surface = clamp( EPS*t*ray->fovfactor, 0.000001f, 0.005f ); 131 | eps = Surface*0.1f; 132 | 133 | iterate(p+(float3)(eps,0.0f,0.0f),&pot2,&col2); 134 | iterate(p+(float3)(0.0f,eps,0.0f),&pot3,&col2); 135 | iterate(p+(float3)(0.0f,0.0f,eps),&pot4,&col2); 136 | 137 | gra = (float3)( pot2-pot1, pot3-pot1, pot4-pot1 ); 138 | dt = 0.5f*pot1*eps/fast_length(gra); 139 | 140 | if( dtcol = color; 142 | ray->nor = fast_normalize( gra ); 143 | ray->t = t; 144 | return true; 145 | } 146 | 147 | t += dt; 148 | p += ray->dir * dt; 149 | } 150 | 151 | return false; 152 | } 153 | 154 | // Note: autovectorize assuming float4 as the basic computation width 155 | __kernel /*__attribute__((vec_type_hint(float4)))*/ 156 | void compute(__write_only image2d_t pix, const float time) { 157 | const int x = get_global_id(0); 158 | const int y = get_global_id(1); 159 | const int xl = get_local_id(0); 160 | const int yl = get_local_id(1); 161 | const int tid = xl+yl*get_local_size(0); 162 | const int width = get_global_size(0); 163 | const int height = get_global_size(1); 164 | 165 | const float2 resolution = (float2)(width,height); 166 | const float2 gl_FragCoord = (float2)(x,y); 167 | 168 | const float2 p = (float2)(-1.f + 2.f * gl_FragCoord / resolution); 169 | const float2 s = p*(float2)(1.33f,1.0f); 170 | 171 | const float fov = 0.5f, fovfactor = rsqrt(1.0f+fov*fov); 172 | 173 | const float ct=native_cos(2.f*M_PI_F*time/20.f), st=native_sin(2.f*M_PI_F*time/20.f); 174 | const float r = 1.4f+0.2f*ct; 175 | const float3 campos = (float3)( r*st, 0.3f-0.4f*st, r*ct ); // camera origin 176 | const float3 camtar = (float3)(0.f,0.1f,0.f); // camera target 177 | 178 | //camera matrix 179 | const float3 cw = fast_normalize(camtar-campos); 180 | const float3 cp = (float3)(0.f,1.f,0.f); 181 | const float3 cu = fast_normalize(cross(cw,cp)); 182 | const float3 cv = fast_normalize(cross(cu,cw)); 183 | 184 | // ray 185 | __local Ray rays[MAX_WORKGROUP_SIZE+1], *ray=rays+tid; 186 | ray->origin=campos; // camera is at ray origin 187 | ray->dir = fast_normalize( s.x*cu + s.y*cv + 1.5f*cw ); 188 | ray->fovfactor = fovfactor; 189 | ray->rgb = (float3)(1.f); 190 | 191 | //barrier(CLK_LOCAL_MEM_FENCE); 192 | const bool res=ifractal(ray); 193 | 194 | if( !res ) { 195 | // background color 196 | ray->rgb = 1.3f*(float3)(1.f,0.98f,0.9f)*(0.7f+0.3f*ray->dir.y); 197 | } 198 | else { 199 | // intersection point 200 | const float3 xyz = ray->origin + ray->t * ray->dir; 201 | 202 | // sun light 203 | float dif1 = clamp( 0.2f + 0.8f*dot( light1, ray->nor ), 0.f, 1.f ); 204 | dif1=dif1*dif1; 205 | 206 | // back light 207 | const float dif2 = clamp( 0.3f + 0.7f*dot( light2, ray->nor ), 0.f, 1.f ); 208 | 209 | // ambient occlusion 210 | const float aot = clamp(1.25f*ray->col.w-.4f, 0.f, 1.f); 211 | const float ao=0.5f*aot*(aot+1); 212 | 213 | // shadow: cast a lightray from intersection point 214 | if( dif1 > EPS ) { 215 | __local Ray *lray=rays+MAX_WORKGROUP_SIZE; 216 | lray->origin=xyz; 217 | lray->dir=light1; 218 | lray->fovfactor = fovfactor; 219 | if( ifractal(lray) ) 220 | dif1 = 0.1f; 221 | } 222 | 223 | // material color 224 | ray->rgb = mix( ray->rgb, material1, (float3)(native_sqrt(ray->col.x)*1.25f) ); 225 | ray->rgb = mix( ray->rgb, material2, (float3)(native_sqrt(ray->col.y)*1.25f) ); 226 | ray->rgb = mix( ray->rgb, material3, (float3)(native_sqrt(ray->col.z)*1.25f) ); 227 | 228 | // lighting 229 | ray->rgb *= (0.5f+0.5f * ray->nor.y)* 230 | (float3)(.14f,.15f,.16f)*0.8f + 231 | dif1*(float3)(1.0f,.85f,.4f) + 232 | 0.5f*dif2*(float3)(.08f,.10f,.14f); 233 | ray->rgb *= (float3)( native_powr(ao,0.8f), native_powr(ao,1.0f), native_powr(ao,1.1f) ); 234 | 235 | // gamma 236 | ray->rgb = 1.5f*(ray->rgb*0.15f + 0.85f*native_sqrt(ray->rgb)); 237 | } 238 | 239 | const float2 uv = 0.5f*(p+1.f); 240 | ray->rgb *= 0.7f + 0.3f*16.f*uv.x*uv.y*(1.f-uv.x)*(1.f-uv.y); 241 | ray->rgb = clamp( ray->rgb, (float3)(0.f), (float3)(1.f) ); 242 | 243 | //barrier(CLK_LOCAL_MEM_FENCE); 244 | write_imagef(pix,(int2)(x,y),(float4)(ray->rgb,1.0f)); 245 | } 246 | -------------------------------------------------------------------------------- /examples/sine.cl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. 3 | * 4 | * Please refer to the NVIDIA end user license agreement (EULA) associated 5 | * with this source code for terms and conditions that govern your use of 6 | * this software. Any use, reproduction, disclosure, or distribution of 7 | * this software and related documentation outside the terms of the EULA 8 | * is strictly prohibited. 9 | * 10 | */ 11 | 12 | /* This example demonstrates how to use the OpenCL/OpenGL bindings */ 13 | 14 | /////////////////////////////////////////////////////////////////////////////// 15 | //! Simple kernel to modify vertex positions in sine wave pattern 16 | //! @param data data in global memory 17 | /////////////////////////////////////////////////////////////////////////////// 18 | __kernel void sine_wave(__global float4* pos, unsigned int width, unsigned int height, float time) 19 | { 20 | unsigned int x = get_global_id(0); 21 | unsigned int y = get_global_id(1); 22 | 23 | // calculate uv coordinates 24 | float u = x / (float) width; 25 | float v = y / (float) height; 26 | u = u*2.0f - 1.0f; 27 | v = v*2.0f - 1.0f; 28 | 29 | // calculate simple sine wave pattern 30 | float freq = 4.0f; 31 | float w = sin(u*freq + time) * cos(v*freq + time) * 0.5f; 32 | 33 | // write output vertex 34 | pos[y*width+x] = (float4)(u, w, v, 1.0f); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /examples/swapRB.cl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | __kernel void swapRB(__global const uchar* src, 28 | __global uchar* dst, 29 | uint2 size) 30 | { 31 | int x = get_global_id(0); 32 | int i = x*4; 33 | if(i>=size.x*size.y*4) return; 34 | 35 | dst[i]=src[i+2]; 36 | dst[i+1]=src[i+1]; 37 | dst[i+2]=src[i]; 38 | dst[i+3]=src[i+3]; 39 | } 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-webcl", 3 | "version": "0.9.1", 4 | "description": "A WebCL implementation for desktops with NodeJS", 5 | "main": "webcl.js", 6 | "author": "Mikael Bourges-Sevenier ", 7 | "keywords": [ 8 | "webcl", 9 | "opencl" 10 | ], 11 | "maintainers": [ 12 | { 13 | "name": "Mikael Bourges-Sevenier", 14 | "email": "mikeseven@gmail.com" 15 | } 16 | ], 17 | "licenses": [ 18 | { 19 | "type": "BSD", 20 | "url": "https://github.com/mikeseven/node-webcl/blob/master/LICENSES" 21 | } 22 | ], 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/mikeseven/node-webcl" 26 | }, 27 | "directories": { 28 | "src": "src", 29 | "lib": "lib", 30 | "docs": "docs", 31 | "examples": "examples", 32 | "test": "test" 33 | }, 34 | "scripts": { 35 | "install": "node-gyp rebuild --msvs_version=2013" 36 | }, 37 | "dependencies": { 38 | "node-webgl": ">=0.4.2", 39 | "node-image": ">=0.7.1", 40 | "nan": "~1.2.0" 41 | }, 42 | "devDependencies": { 43 | "chai": "*", 44 | "mocha": "*" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /runner.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | Mocha = require("mocha"), 3 | path = require('path'); 4 | 5 | // Our Mocha runner 6 | var mocha = new Mocha({ 7 | ui:"bdd", 8 | reporter:"spec", 9 | timeout:5000, 10 | slow:1000 11 | }); 12 | 13 | // Files which need to be ignored 14 | var avoided = [ 15 | "node_modules" 16 | ]; 17 | 18 | // Add the tests to the Mocha instance 19 | (addFiles = function(dir){ 20 | fs.readdirSync(dir).filter(function(file){ 21 | if(!~avoided.indexOf(file)){ 22 | if(fs.statSync(dir + '/' + file).isDirectory()){ 23 | addFiles(dir + '/' + file); 24 | } 25 | return file.substr(-3) === '.js'; 26 | } 27 | }).forEach(function(file){ 28 | mocha.addFile(dir + '/' + file); 29 | }); 30 | })(path.join(process.cwd(), process.argv[2] || ".")); 31 | 32 | // Run the files in Mocha 33 | mocha.run(function(failures){ 34 | process.exit(failures); 35 | }); -------------------------------------------------------------------------------- /src/cl_checks.cc: -------------------------------------------------------------------------------- 1 | #include "cl_checks.h" 2 | 3 | namespace webcl { 4 | 5 | /* 6 | * Various checking methods to validate inputs before they hit CL drivers 7 | * and potentially crash machines badly due to poor drivers out there. 8 | */ 9 | 10 | /* number of bytes in the specified rectangle buffer. 11 | * @return -1 if error 12 | */ 13 | int bufferRectSize(const size_t offset[3], const size_t region[3], size_t row_pitch, size_t slice_pitch, size_t buffer_len) 14 | { 15 | size_t x= offset[0], y=offset[1], z=offset[2]; 16 | size_t w=region[0], h=region[1], d=region[2]; 17 | if(w==0 || h==0 || d==0) 18 | return -1; 19 | 20 | if(row_pitch==0) 21 | row_pitch=w; 22 | else if (row_pitch=buffer_len) 23 | return -1; 24 | 25 | if(slice_pitch==0) 26 | slice_pitch=row_pitch*h; 27 | else if (slice_pitch<(row_pitch * h) || slice_pitch>=buffer_len) 28 | return -1; 29 | 30 | if((slice_pitch % row_pitch) !=0) 31 | return -1; 32 | 33 | return (int)(z * slice_pitch + y * row_pitch + x + (w * h * d)); 34 | } 35 | 36 | /* 37 | * @return number of bytes in an image region 38 | * @return -1 if error 39 | */ 40 | int imageRectSize(const size_t origin[3], const size_t region[3], size_t row_pitch, size_t slice_pitch, cl_mem img, int buffer_len) 41 | { 42 | size_t w = region[0], h=region[1], d=region[2]; 43 | 44 | if ( w==0 || h==0 || d==0 ) 45 | return -1; 46 | 47 | size_t imgW, imgH, bpp; 48 | cl_int ret = clGetImageInfo(img,CL_IMAGE_WIDTH,sizeof(size_t),&imgW,NULL); 49 | ret |= clGetImageInfo(img,CL_IMAGE_HEIGHT,sizeof(size_t),&imgH,NULL); 50 | ret |= clGetImageInfo(img,CL_IMAGE_ELEMENT_SIZE,sizeof(size_t),&bpp,NULL); 51 | // printf("[imageRectSize] image %lu x %lu x %lu\n",imgW, imgH, bpp); 52 | 53 | if(ret!=CL_SUCCESS) 54 | return -1; 55 | 56 | // printf("[imageRectSize] buffer_len %d, origin %lu %lu %lu, region %lu %lu %lu, pitch %lu %lu\n", 57 | // buffer_len, 58 | // origin[0],origin[1],origin[2], 59 | // w,h,d, 60 | // row_pitch,slice_pitch); 61 | if(buffer_len>=0 && buffer_len < (int)(region[0]*region[1]*region[2]*bpp)) 62 | return -1; 63 | 64 | if(origin[0]+region[0]>imgW || origin[1]+region[1]>imgH) 65 | return -1; 66 | 67 | if ( row_pitch == 0 ) 68 | row_pitch = w; 69 | else if ( row_pitch < w || row_pitch<(imgW*bpp) || (row_pitch % (imgW*bpp)) !=0) 70 | return -1; 71 | 72 | if ( slice_pitch == 0 ) 73 | slice_pitch = row_pitch * h; 74 | else if ( slice_pitch < (row_pitch * h)) 75 | return -1; 76 | 77 | if(origin[0]+region[0]>imgW || origin[1]+region[1]>imgH) 78 | return -1; 79 | 80 | return (int)(slice_pitch * d); 81 | } 82 | 83 | /* 84 | * @return number of bytes per elements in a TypedArray 85 | * @return -1 if wrong type 86 | */ 87 | int getTypedArrayBytes(ExternalArrayType type) 88 | { 89 | switch(type) { 90 | case kExternalByteArray: 91 | case kExternalUnsignedByteArray: 92 | case kExternalPixelArray: 93 | return 1; 94 | case kExternalShortArray: 95 | case kExternalUnsignedShortArray: 96 | return 2; 97 | case kExternalIntArray: 98 | case kExternalUnsignedIntArray: 99 | case kExternalFloatArray: 100 | return 4; 101 | case kExternalDoubleArray: 102 | return 8; 103 | } 104 | return -1; 105 | } 106 | 107 | void getPtrAndLen(const Local value, void* &ptr, int &len) 108 | { 109 | ptr=NULL; 110 | len=0; 111 | if(!value->IsUndefined() && !value->IsNull()) { 112 | if(value->IsArray()) { 113 | Local arr=Local::Cast(value); 114 | ptr = arr->GetIndexedPropertiesExternalArrayData(); 115 | len = arr->GetIndexedPropertiesExternalArrayDataLength() * getTypedArrayBytes(arr->GetIndexedPropertiesExternalArrayDataType()); 116 | } 117 | else if(value->IsObject()) { 118 | Local obj=value->ToObject(); 119 | String::AsciiValue name(obj->GetConstructorName()); 120 | if(!strcmp("Buffer",*name)) { 121 | ptr=node::Buffer::Data(obj); 122 | len=(int) node::Buffer::Length(obj); 123 | } 124 | else { 125 | ptr = obj->GetIndexedPropertiesExternalArrayData(); 126 | len = obj->GetIndexedPropertiesExternalArrayDataLength() * getTypedArrayBytes(obj->GetIndexedPropertiesExternalArrayDataType()); 127 | // printf("TypedArray %d elements, %d bytes/element\n", 128 | // obj->GetIndexedPropertiesExternalArrayDataLength(), 129 | // getTypedArrayBytes(obj->GetIndexedPropertiesExternalArrayDataType())); 130 | } 131 | } 132 | } 133 | } 134 | 135 | /** 136 | * @return number of channels in the specified cl_channel_order 137 | * @return -1 if error 138 | */ 139 | int getChannelCount(const int channelOrder) 140 | { 141 | switch ( channelOrder ) { 142 | case CL_R: 143 | case CL_A: 144 | case CL_INTENSITY: 145 | case CL_LUMINANCE: 146 | case CL_Rx: 147 | case CL_DEPTH: 148 | case CL_DEPTH_STENCIL: 149 | return 1; 150 | case CL_RG: 151 | case CL_RA: 152 | case CL_RGx: 153 | return 2; 154 | case CL_RGB: 155 | case CL_RGBx: 156 | return 3; 157 | case CL_RGBA: 158 | case CL_BGRA: 159 | case CL_ARGB: 160 | return 4; 161 | } 162 | return -1; 163 | } 164 | 165 | /** 166 | * @return the number of bytes in the specified cl_channel_type. 167 | * @return -1 if unknown 168 | */ 169 | int getChannelSize(int channelType) { 170 | switch (channelType) { 171 | case CL_SNORM_INT8: 172 | case CL_UNORM_INT8: 173 | case CL_SIGNED_INT8: 174 | case CL_UNSIGNED_INT8: 175 | return 1; 176 | case CL_SNORM_INT16: 177 | case CL_UNORM_INT16: 178 | case CL_UNORM_SHORT_565: 179 | case CL_UNORM_SHORT_555: 180 | case CL_SIGNED_INT16: 181 | case CL_UNSIGNED_INT16: 182 | case CL_HALF_FLOAT: 183 | return 2; 184 | case CL_UNORM_INT_101010: 185 | case CL_SIGNED_INT32: 186 | case CL_UNSIGNED_INT32: 187 | case CL_FLOAT: 188 | return 4; 189 | } 190 | return -1; 191 | } 192 | 193 | } // namespace webcl 194 | -------------------------------------------------------------------------------- /src/cl_checks.h: -------------------------------------------------------------------------------- 1 | #ifndef CL_CHECKS_ 2 | #define CL_CHECKS_ 3 | 4 | #include "common.h" 5 | #include 6 | #include 7 | 8 | using namespace v8; 9 | 10 | namespace webcl { 11 | 12 | int bufferRectSize(const size_t offset[3], const size_t region[3], size_t row_pitch, size_t slice_pitch, size_t buffer_len); 13 | int imageRectSize(const size_t origin[3], const size_t region[3], size_t row_pitch, size_t slice_pitch, cl_mem img, int buffer_len=-1); 14 | void getPtrAndLen(const Local value, void* &ptr, int &len); 15 | int getChannelCount(const int channelOrder); 16 | int getChannelSize(int channelType); 17 | int getTypedArrayBytes(ExternalArrayType type); 18 | inline bool validateMemFlags(int value) { 19 | return (value>=CL_MEM_READ_WRITE && value<=CL_MEM_HOST_NO_ACCESS && value!=(1<<6)); 20 | } 21 | 22 | } // namespace webcl 23 | 24 | #endif // CL_CHECKS_ -------------------------------------------------------------------------------- /src/commandqueue.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef COMMANDQUEUE_H_ 28 | #define COMMANDQUEUE_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class CommandQueue : public WebCLObject 35 | { 36 | 37 | public: 38 | void Destructor(); 39 | 40 | static void Init(v8::Handle exports); 41 | 42 | static CommandQueue *New(cl_command_queue cw, WebCLObject *parent); 43 | static NAN_METHOD(New); 44 | 45 | // Copying: Buffer <-> Buffer, Image <-> Image, Buffer <-> Image 46 | static NAN_METHOD(enqueueCopyBuffer); 47 | static NAN_METHOD(enqueueCopyBufferRect); 48 | static NAN_METHOD(enqueueCopyImage); 49 | static NAN_METHOD(enqueueCopyImageToBuffer); 50 | static NAN_METHOD(enqueueCopyBufferToImage); 51 | 52 | // Reading: Buffer -> Host, Image -> Host 53 | static NAN_METHOD(enqueueReadBuffer); 54 | static NAN_METHOD(enqueueReadBufferRect); 55 | static NAN_METHOD(enqueueReadImage); 56 | 57 | // Writing: Host -> Buffer, Host -> Image 58 | static NAN_METHOD(enqueueWriteBuffer); 59 | static NAN_METHOD(enqueueWriteBufferRect); 60 | static NAN_METHOD(enqueueWriteImage); 61 | 62 | // Executing kernels 63 | static NAN_METHOD(enqueueNDRangeKernel); 64 | static NAN_METHOD(enqueueTask); 65 | 66 | // Synchronization 67 | static NAN_METHOD(enqueueMarker); 68 | static NAN_METHOD(enqueueBarrier); 69 | static NAN_METHOD(enqueueWaitForEvents); 70 | static NAN_METHOD(flush); 71 | static NAN_METHOD(finish); 72 | 73 | // Querying command queue information 74 | static NAN_METHOD(getInfo); 75 | static NAN_METHOD(release); 76 | 77 | // Buffer mapping 78 | static NAN_METHOD(enqueueMapBuffer); 79 | static NAN_METHOD(enqueueMapImage); 80 | static NAN_METHOD(enqueueUnmapMemObject); 81 | 82 | // CL-GL 83 | static NAN_METHOD(enqueueAcquireGLObjects); 84 | static NAN_METHOD(enqueueReleaseGLObjects); 85 | 86 | cl_command_queue getCommandQueue() const { return command_queue; }; 87 | virtual bool operator==(void *clObj) { return ((cl_command_queue)clObj)==command_queue; } 88 | 89 | private: 90 | CommandQueue(v8::Handle wrapper); 91 | ~CommandQueue(); 92 | 93 | static v8::Persistent constructor; 94 | 95 | cl_command_queue command_queue; 96 | 97 | private: 98 | DISABLE_COPY(CommandQueue) 99 | }; 100 | 101 | } // namespace 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef WEBCL_COMMON_H_ 28 | #define WEBCL_COMMON_H_ 29 | 30 | // Node includes 31 | #include 32 | #include "nan.h" 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #ifdef LOGGING 39 | #include 40 | #endif 41 | 42 | using namespace std; 43 | 44 | // OpenCL includes 45 | #define CL_USE_DEPRECATED_OPENCL_1_1_APIS 46 | 47 | #if defined (__APPLE__) || defined(MACOSX) 48 | #ifdef __ECLIPSE__ 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #else 57 | #include 58 | #include 59 | #include 60 | #include 61 | #define CL_GL_CONTEXT_KHR 0x2008 62 | #define CL_EGL_DISPLAY_KHR 0x2009 63 | #define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR CL_INVALID_GL_CONTEXT_APPLE 64 | #endif 65 | #define HAS_clGetContextInfo 66 | #elif defined(_WIN32) 67 | #include 68 | #include 69 | #define strcasecmp _stricmp 70 | #define strncasecmp _strnicmp 71 | char *strcasestr(const char *s, char *find); 72 | #else 73 | #include 74 | #include 75 | #include 76 | #endif 77 | 78 | #ifndef CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 79 | #define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006 80 | #endif 81 | #ifndef CL_DEVICES_FOR_GL_CONTEXT_KHR 82 | #define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007 83 | #endif 84 | 85 | // TODO value not defined in spec 86 | #define WEBCL_EXTENSION_NOT_ENABLED 0x8000 87 | 88 | namespace { 89 | #define JS_STR(...) NanNew(__VA_ARGS__) 90 | #define JS_INT(val) NanNew(val) 91 | #define JS_NUM(val) NanNew(val) 92 | #define JS_BOOL(val) NanNew(val) 93 | #define JS_RETHROW(tc) NanNew >(tc.Exception()); 94 | 95 | #define REQ_ARGS(N) \ 96 | if (args.Length() < (N)) \ 97 | NanThrowTypeError("Expected " #N " arguments"); 98 | 99 | #define REQ_STR_ARG(I, VAR) \ 100 | if (args.Length() <= (I) || !args[I]->IsString()) \ 101 | NanThrowTypeError("Argument " #I " must be a string"); \ 102 | String::Utf8Value VAR(args[I]->ToString()); 103 | 104 | #define REQ_EXT_ARG(I, VAR) \ 105 | if (args.Length() <= (I) || !args[I]->IsExternal()) \ 106 | NanThrowTypeError("Argument " #I " invalid"); \ 107 | Local VAR = Local::Cast(args[I]); 108 | 109 | #define REQ_FUN_ARG(I, VAR) \ 110 | if (args.Length() <= (I) || !args[I]->IsFunction()) \ 111 | NanThrowTypeError("Argument " #I " must be a function"); \ 112 | Local VAR = Local::Cast(args[I]); 113 | 114 | #define REQ_ERROR_THROW_NONE(error) if (ret == CL_##error) ThrowException(NanObjectWrapHandle(WebCLException::New(#error, ErrorDesc(CL_##error), CL_##error))); return; 115 | 116 | #define REQ_ERROR_THROW(error) if (ret == CL_##error) return ThrowException(NanObjectWrapHandle(WebCLException::New(#error, ErrorDesc(CL_##error), CL_##error))); 117 | 118 | #define DESTROY_WEBCL_OBJECT(obj) \ 119 | obj->Destructor(); 120 | 121 | #define DISABLE_COPY(ClassName) \ 122 | ClassName( const ClassName& other ); /* non construction-copyable */ \ 123 | ClassName& operator=( const ClassName& ); /* non copyable */ 124 | 125 | } // namespace 126 | 127 | namespace webcl { 128 | 129 | const char* ErrorDesc(cl_int err); 130 | 131 | // generic baton for async callbacks 132 | struct Baton { 133 | NanCallback *callback; 134 | int error; 135 | char *error_msg; 136 | uint8_t *priv_info; 137 | 138 | // Custom user data 139 | v8::Persistent data; 140 | 141 | // parent of this callback (WebCLEvent object) 142 | v8::Persistent parent; 143 | 144 | Baton() : callback(NULL), error(CL_SUCCESS), error_msg(NULL), priv_info(NULL) {} 145 | ~Baton() { 146 | if(error_msg) delete error_msg; 147 | if(priv_info) delete priv_info; 148 | } 149 | }; 150 | 151 | namespace CLObjType { 152 | enum CLObjType { 153 | None=0, 154 | Platform, 155 | Device, 156 | Context, 157 | CommandQueue, 158 | Kernel, 159 | Program, 160 | Sampler, 161 | Event, 162 | MemoryObject, 163 | Exception, 164 | MAX_WEBCL_TYPES 165 | }; 166 | static const char* CLObjName[] = { 167 | "UNKNOWN", 168 | "Platform", 169 | "Device", 170 | "Context", 171 | "CommandQueue", 172 | "Kernel", 173 | "Program", 174 | "Sampler", 175 | "Event", 176 | "MemoryObject", 177 | "Exception", 178 | }; 179 | } 180 | 181 | class WebCLObject; 182 | void registerCLObj(void *clid, WebCLObject* obj); 183 | void unregisterCLObj(WebCLObject* obj); 184 | WebCLObject* findCLObj(void* clid, CLObjType::CLObjType type); 185 | void onExit(); 186 | 187 | class WebCLObject : public node::ObjectWrap { 188 | public: 189 | inline CLObjType::CLObjType getType() const { return _type; } 190 | 191 | inline const char* getCLObjName() const { 192 | return _type BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef WEBCL_CONTEXT_H_ 28 | #define WEBCL_CONTEXT_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class Context : public WebCLObject 35 | { 36 | 37 | public: 38 | void Destructor(); 39 | 40 | static void Init(v8::Handle exports); 41 | 42 | static Context *New(cl_context cw); 43 | static Context *New(cl_context cw, v8::Handle webgl_context); 44 | static NAN_METHOD(New); 45 | 46 | static NAN_METHOD(getInfo); 47 | static NAN_METHOD(createProgram); 48 | static NAN_METHOD(createCommandQueue); 49 | static NAN_METHOD(createBuffer); 50 | static NAN_METHOD(createImage); 51 | static NAN_METHOD(createSampler); 52 | static NAN_METHOD(createUserEvent); 53 | static NAN_METHOD(getSupportedImageFormats); 54 | static NAN_METHOD(createFromGLBuffer); 55 | static NAN_METHOD(createFromGLTexture); 56 | static NAN_METHOD(createFromGLRenderbuffer); 57 | static NAN_METHOD(release); 58 | static NAN_METHOD(retain); 59 | static NAN_METHOD(releaseAll); 60 | 61 | #ifdef HAS_clGetContextInfo 62 | static NAN_METHOD(getGLContextInfo); 63 | #endif 64 | static NAN_METHOD(getGLContext); 65 | 66 | cl_context getContext() const { return context; }; 67 | virtual bool operator==(void *clObj) { return ((cl_context)clObj)==context; } 68 | 69 | private: 70 | Context(v8::Handle wrapper); 71 | ~Context(); 72 | 73 | static v8::Persistent constructor; 74 | 75 | cl_context context; 76 | v8::Persistent webgl_context_; 77 | 78 | private: 79 | DISABLE_COPY(Context) 80 | }; 81 | 82 | } // namespace 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/device.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef DEVICE_H_ 28 | #define DEVICE_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class Device : public WebCLObject 35 | { 36 | 37 | public: 38 | static void Init(v8::Handle exports); 39 | 40 | static Device *New(cl_device_id did); 41 | static NAN_METHOD(New); 42 | static NAN_METHOD(getInfo); 43 | static NAN_METHOD(getSupportedExtensions); 44 | 45 | static NAN_METHOD(enableExtension); 46 | bool hasGLSharingEnabled() const { return (enableExtensions & GL_SHARING); } 47 | bool hasFP16Enabled() const { return (enableExtensions & FP16)==FP16; } 48 | bool hasFP64Enabled() const { return (enableExtensions & FP64)==FP64; } 49 | 50 | cl_device_id getDevice() const { return device_id; }; 51 | virtual bool operator==(void *clObj) { return ((cl_device_id)clObj)==device_id; } 52 | 53 | private: 54 | Device(v8::Handle wrapper); 55 | 56 | static v8::Persistent constructor; 57 | 58 | cl_device_id device_id; 59 | 60 | cl_uint enableExtensions; 61 | cl_uint availableExtensions; 62 | 63 | enum WEBCL_EXTENSIONS { 64 | NONE = 0x00, 65 | GL_SHARING = 0x01, 66 | FP16 = 0x02, 67 | FP64 = 0x04 68 | }; 69 | 70 | private: 71 | DISABLE_COPY(Device) 72 | }; 73 | 74 | } // namespace 75 | 76 | 77 | #endif /* DEVICE_H_ */ 78 | -------------------------------------------------------------------------------- /src/event.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef EVENT_H_ 28 | #define EVENT_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class Event : public WebCLObject 35 | { 36 | 37 | public: 38 | void Destructor(); 39 | 40 | static void Init(v8::Handle exports); 41 | 42 | static Event *New(cl_event ew, WebCLObject *parent); 43 | 44 | static NAN_METHOD(New); 45 | 46 | static NAN_METHOD(getInfo); 47 | static NAN_METHOD(getProfilingInfo); 48 | static NAN_METHOD(setCallback); 49 | static NAN_METHOD(release); 50 | 51 | cl_event getEvent() const { return event; }; 52 | void setEvent(cl_event e); 53 | 54 | static NAN_GETTER(GetStatus); 55 | void setStatus(int s) { status = s; } 56 | cl_int getStatus() { return status; } 57 | virtual bool operator==(void *clObj) { return ((cl_event)clObj)==event; } 58 | 59 | protected: 60 | Event(v8::Handle wrapper); 61 | ~Event(); 62 | 63 | // called by clSetEventCallback 64 | static void CL_CALLBACK callback (cl_event event, cl_int event_command_exec_status, void *user_data); 65 | // static void After_cb(uv_async_t* handle, int status); 66 | // NanCallback *callback; 67 | 68 | static v8::Persistent constructor; 69 | 70 | cl_event event; 71 | cl_int status; 72 | 73 | private: 74 | DISABLE_COPY(Event) 75 | }; 76 | 77 | class UserEvent : public Event 78 | { 79 | 80 | public: 81 | static void Init(v8::Handle exports); 82 | 83 | static UserEvent *New(cl_event ew, WebCLObject *parent); 84 | 85 | static NAN_METHOD(New); 86 | 87 | static NAN_METHOD(getInfo); 88 | static NAN_METHOD(getProfilingInfo); 89 | static NAN_METHOD(setStatus); 90 | static NAN_METHOD(setCallback); 91 | static NAN_METHOD(release); 92 | 93 | static NAN_GETTER(GetStatus); 94 | 95 | private: 96 | UserEvent(v8::Handle wrapper); 97 | ~UserEvent(); 98 | 99 | static v8::Persistent constructor; 100 | 101 | private: 102 | DISABLE_COPY(UserEvent) 103 | }; 104 | 105 | } // namespace 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /src/exceptions.cc: -------------------------------------------------------------------------------- 1 | #include "exceptions.h" 2 | 3 | using namespace v8; 4 | 5 | namespace webcl { 6 | 7 | const char* ErrorDesc(cl_int err) 8 | { 9 | switch (err) { 10 | case CL_SUCCESS: return "Success!"; 11 | case CL_DEVICE_NOT_FOUND: return "Device not found."; 12 | case CL_DEVICE_NOT_AVAILABLE: return "Device not available"; 13 | case CL_COMPILER_NOT_AVAILABLE: return "Compiler not available"; 14 | case CL_MEM_OBJECT_ALLOCATION_FAILURE: return "Memory object allocation failure"; 15 | case CL_OUT_OF_RESOURCES: return "Out of resources"; 16 | case CL_OUT_OF_HOST_MEMORY: return "Out of host memory"; 17 | case CL_PROFILING_INFO_NOT_AVAILABLE: return "Profiling information not available"; 18 | case CL_MEM_COPY_OVERLAP: return "Memory copy overlap"; 19 | case CL_IMAGE_FORMAT_MISMATCH: return "Image format mismatch"; 20 | case CL_IMAGE_FORMAT_NOT_SUPPORTED: return "Image format not supported"; 21 | case CL_BUILD_PROGRAM_FAILURE: return "Program build failure"; 22 | case CL_MAP_FAILURE: return "Map failure"; 23 | case CL_MISALIGNED_SUB_BUFFER_OFFSET: return "Misaligned sub-buffer offset"; 24 | case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: return "Execution status error for events in wait list"; 25 | case CL_COMPILE_PROGRAM_FAILURE: return "Compile program failure"; 26 | case CL_LINKER_NOT_AVAILABLE: return "Linker not available"; 27 | case CL_LINK_PROGRAM_FAILURE: return "Link program failure"; 28 | case CL_DEVICE_PARTITION_FAILED: return "Device partition failed"; 29 | case CL_KERNEL_ARG_INFO_NOT_AVAILABLE: return "Kernel argument info not available"; 30 | 31 | case CL_INVALID_VALUE: return "Invalid value"; 32 | case CL_INVALID_DEVICE_TYPE: return "Invalid device type"; 33 | case CL_INVALID_PLATFORM: return "Invalid platform"; 34 | case CL_INVALID_DEVICE: return "Invalid device"; 35 | case CL_INVALID_CONTEXT: return "Invalid context"; 36 | case CL_INVALID_QUEUE_PROPERTIES: return "Invalid queue properties"; 37 | case CL_INVALID_COMMAND_QUEUE: return "Invalid command queue"; 38 | case CL_INVALID_HOST_PTR: return "Invalid host pointer"; 39 | case CL_INVALID_MEM_OBJECT: return "Invalid memory object"; 40 | case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: return "Invalid image format descriptor"; 41 | case CL_INVALID_IMAGE_SIZE: return "Invalid image size"; 42 | case CL_INVALID_SAMPLER: return "Invalid sampler"; 43 | case CL_INVALID_BINARY: return "Invalid binary"; 44 | case CL_INVALID_BUILD_OPTIONS: return "Invalid build options"; 45 | case CL_INVALID_PROGRAM: return "Invalid program"; 46 | case CL_INVALID_PROGRAM_EXECUTABLE: return "Invalid program executable"; 47 | case CL_INVALID_KERNEL_NAME: return "Invalid kernel name"; 48 | case CL_INVALID_KERNEL_DEFINITION: return "Invalid kernel definition"; 49 | case CL_INVALID_KERNEL: return "Invalid kernel"; 50 | case CL_INVALID_ARG_INDEX: return "Invalid argument index"; 51 | case CL_INVALID_ARG_VALUE: return "Invalid argument value"; 52 | case CL_INVALID_ARG_SIZE: return "Invalid argument size"; 53 | case CL_INVALID_KERNEL_ARGS: return "Invalid kernel arguments"; 54 | case CL_INVALID_WORK_DIMENSION: return "Invalid work dimension"; 55 | case CL_INVALID_WORK_GROUP_SIZE: return "Invalid work group size"; 56 | case CL_INVALID_WORK_ITEM_SIZE: return "Invalid work item size"; 57 | case CL_INVALID_GLOBAL_OFFSET: return "Invalid global offset"; 58 | case CL_INVALID_EVENT_WAIT_LIST: return "Invalid event wait list"; 59 | case CL_INVALID_EVENT: return "Invalid event"; 60 | case CL_INVALID_OPERATION: return "Invalid operation"; 61 | case CL_INVALID_GL_OBJECT: return "Invalid OpenGL object"; 62 | case CL_INVALID_BUFFER_SIZE: return "Invalid buffer size"; 63 | case CL_INVALID_MIP_LEVEL: return "Invalid mip-map level"; 64 | case CL_INVALID_GLOBAL_WORK_SIZE: return "Invalid global work size"; 65 | case CL_INVALID_PROPERTY: return "Invalid property"; 66 | case CL_INVALID_IMAGE_DESCRIPTOR: return "Invalid image descriptor"; 67 | case CL_INVALID_COMPILER_OPTIONS: return "Invalid compiler options"; 68 | case CL_INVALID_LINKER_OPTIONS: return "Invalid linker options"; 69 | case CL_INVALID_DEVICE_PARTITION_COUNT: return "Invalid device partition count"; 70 | case WEBCL_EXTENSION_NOT_ENABLED: return "KHR_gl_sharing extension not enabled"; 71 | } 72 | return "Unknown"; 73 | } 74 | 75 | Persistent WebCLException::constructor; 76 | 77 | void WebCLException::Init(Handle exports) 78 | { 79 | NanScope(); 80 | 81 | // constructor 82 | Local ctor = FunctionTemplate::New(WebCLException::New); 83 | ctor->InstanceTemplate()->SetInternalFieldCount(1); 84 | ctor->SetClassName(NanNew("WebCLException")); 85 | 86 | // prototype 87 | Local proto = ctor->PrototypeTemplate(); 88 | proto->SetAccessor(JS_STR("name"), GetName, NULL); 89 | proto->SetAccessor(JS_STR("description"), GetDescription, NULL); 90 | proto->SetAccessor(JS_STR("code"), GetCode, NULL); 91 | 92 | NanAssignPersistent(constructor, ctor->GetFunction()); 93 | exports->Set(NanNew("WebCLException"), ctor->GetFunction()); 94 | } 95 | 96 | WebCLException::WebCLException(Handle wrapper) : name_(NULL), desc_(NULL),code_(0) 97 | { 98 | _type=CLObjType::Exception; 99 | } 100 | 101 | NAN_GETTER(WebCLException::GetName) { 102 | NanScope(); 103 | WebCLException *ex = ObjectWrap::Unwrap(args.This()); 104 | if(ex->name_) 105 | NanReturnValue(JS_STR(ex->name_)); 106 | NanReturnNull(); 107 | } 108 | 109 | NAN_GETTER(WebCLException::GetDescription) { 110 | NanScope(); 111 | WebCLException *ex = ObjectWrap::Unwrap(args.This()); 112 | if(ex->desc_) 113 | NanReturnValue(JS_STR(ex->desc_)); 114 | NanReturnNull(); 115 | } 116 | 117 | NAN_GETTER(WebCLException::GetCode) { 118 | NanScope(); 119 | WebCLException *ex = ObjectWrap::Unwrap(args.This()); 120 | NanReturnValue(JS_INT(ex->code_)); 121 | } 122 | 123 | NAN_METHOD(WebCLException::New) 124 | { 125 | if (!args.IsConstructCall()) 126 | return NanThrowTypeError("Constructor cannot be called as a function."); 127 | 128 | NanScope(); 129 | WebCLException *ex = new WebCLException(args.This()); 130 | ex->Wrap(args.This()); 131 | 132 | NanReturnValue(args.This()); 133 | } 134 | 135 | WebCLException *WebCLException::New(const char *name, const char *desc, const int code) 136 | { 137 | 138 | NanScope(); 139 | 140 | Local cons = NanNew(constructor); 141 | Local obj = cons->NewInstance(); 142 | 143 | WebCLException *ex = ObjectWrap::Unwrap(obj); 144 | ex->name_=name; 145 | ex->desc_=desc; 146 | ex->code_=code; 147 | 148 | return ex; 149 | } 150 | 151 | } // namespace webcl 152 | -------------------------------------------------------------------------------- /src/exceptions.h: -------------------------------------------------------------------------------- 1 | #ifndef EXCEPTIONS_H_ 2 | #define EXCEPTIONS_H_ 3 | 4 | #include "common.h" 5 | 6 | namespace webcl { 7 | 8 | class WebCLException : public WebCLObject 9 | { 10 | 11 | public: 12 | static void Init(v8::Handle exports); 13 | 14 | static WebCLException *New(const char *name, const char *desc, const int code); 15 | 16 | static NAN_METHOD(New); 17 | static NAN_GETTER(GetName); 18 | static NAN_GETTER(GetDescription); 19 | static NAN_GETTER(GetCode); 20 | 21 | protected: 22 | WebCLException(v8::Handle wrapper); 23 | 24 | static v8::Persistent constructor; 25 | 26 | const char *name_; 27 | const char *desc_; 28 | int code_; 29 | 30 | private: 31 | DISABLE_COPY(WebCLException) 32 | }; 33 | 34 | } // namespace 35 | 36 | #endif // EXCEPTIONS_H_ 37 | -------------------------------------------------------------------------------- /src/kernel.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef KERNEL_H_ 28 | #define KERNEL_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class Kernel : public WebCLObject 35 | { 36 | 37 | public: 38 | void Destructor(); 39 | 40 | static void Init(v8::Handle exports); 41 | 42 | static Kernel *New(cl_kernel kw, WebCLObject *parent); 43 | static NAN_METHOD(New); 44 | static NAN_METHOD(getInfo); 45 | static NAN_METHOD(getWorkGroupInfo); 46 | static NAN_METHOD(getArgInfo); 47 | static NAN_METHOD(setArg); 48 | static NAN_METHOD(release); 49 | 50 | cl_kernel getKernel() const { return kernel; }; 51 | 52 | virtual bool operator==(void *clObj) { return ((cl_kernel)clObj)==kernel; } 53 | 54 | private: 55 | Kernel(v8::Handle wrapper); 56 | ~Kernel(); 57 | 58 | static v8::Persistent constructor; 59 | 60 | cl_kernel kernel; 61 | 62 | private: 63 | DISABLE_COPY(Kernel) 64 | }; 65 | 66 | } // namespace 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/manager.cc: -------------------------------------------------------------------------------- 1 | #include "manager.h" 2 | 3 | using namespace node; 4 | using namespace v8; 5 | 6 | namespace webcl { 7 | 8 | void Manager::add(Persistent* p, cl_type id) { 9 | if(objects.count(p)<1) { 10 | #ifdef LOGGING 11 | WebCLObject *obj=ObjectWrap::Unwrap(*p); 12 | printf("Adding %s cl %p, handle %p\n",obj->getCLObjName(),id,p); 13 | #endif 14 | objects[p]=id; 15 | references[p]=0; 16 | } 17 | references[p]++; 18 | } 19 | 20 | void Manager::remove(Persistent* p) { 21 | if(references.count(p)<1) 22 | return; 23 | if(--references[p]<=0) { 24 | #ifdef LOGGING 25 | printf("Erasing %p\n",p); 26 | #endif 27 | objects.erase(p); 28 | references.erase(p); 29 | } 30 | } 31 | 32 | Persistent* Manager::find(cl_type id) { 33 | #ifdef LOGGING 34 | printf("find %p\n",id); 35 | #endif 36 | for(auto it=objects.begin();it!=objects.end();++it) { 37 | if(it->second == id) { 38 | return it->first; 39 | } 40 | } 41 | return nullptr; 42 | } 43 | 44 | void Manager::clear() { 45 | for(auto it=objects.begin();it!=objects.end();++it) { 46 | auto p= *(it->first); 47 | if(!p.IsEmpty() && !p.IsNearDeath()) { 48 | WebCLObject *obj=ObjectWrap::Unwrap(p); 49 | obj->Destructor(); 50 | } 51 | } 52 | references.clear(); 53 | objects.clear(); 54 | } 55 | 56 | void Manager::stats() { 57 | printf("WebCL Manager stats:\n"); 58 | printf(" #objects: %ld\n",objects.size()); 59 | for(auto it=references.begin(); it!=references.end(); ++it) { 60 | auto p= *(it->first); 61 | if(!p.IsEmpty() && !p.IsNearDeath()) { 62 | WebCLObject *obj=ObjectWrap::Unwrap(p); 63 | int count=it->second; 64 | printf(" %s: %d\n",obj->getCLObjName(),count); 65 | } 66 | } 67 | } 68 | 69 | } // namespace webcl -------------------------------------------------------------------------------- /src/manager.h: -------------------------------------------------------------------------------- 1 | #ifndef __WEBCLMANAGER_H__ 2 | #define __WEBCLMANAGER_H__ 3 | 4 | #include "platform.h" 5 | #include "device.h" 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace v8; 11 | 12 | namespace webcl { 13 | 14 | typedef void* cl_type; 15 | 16 | class Manager { 17 | public: 18 | static Manager* instance() { 19 | static Manager mgr; 20 | return &mgr; 21 | } 22 | 23 | void add(Persistent* p, cl_type id); 24 | void remove(Persistent* p); 25 | Persistent* find(cl_type id); 26 | void clear(); 27 | void stats(); 28 | 29 | private: 30 | explicit Manager() {} 31 | ~Manager() { 32 | #ifdef LOGGING 33 | cout<<"~Manager"<*, cl_type> objects; 40 | map*, int> references; 41 | }; 42 | 43 | } // namespace webcl 44 | 45 | #endif // __WEBCLMANAGER_H__ 46 | -------------------------------------------------------------------------------- /src/memoryobject.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef MEMORYOBJECT_H_ 28 | #define MEMORYOBJECT_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class MemoryObject : public WebCLObject 35 | { 36 | 37 | public: 38 | virtual void Destructor(); 39 | 40 | static void Init(v8::Handle exports); 41 | 42 | static MemoryObject *New(cl_mem mw); 43 | static NAN_METHOD(New); 44 | static NAN_METHOD(getInfo); 45 | static NAN_METHOD(getGLObjectInfo); 46 | static NAN_METHOD(release); 47 | 48 | cl_mem getMemory() const { return memory; }; 49 | virtual bool operator==(void *clObj) { return ((cl_mem)clObj)==memory; } 50 | 51 | private: 52 | static v8::Persistent constructor; 53 | 54 | protected: 55 | MemoryObject(v8::Handle wrapper); 56 | ~MemoryObject(); 57 | 58 | cl_mem memory; 59 | 60 | private: 61 | DISABLE_COPY(MemoryObject) 62 | }; 63 | 64 | class WebCLBuffer : public MemoryObject { 65 | public: 66 | static void Init(v8::Handle exports); 67 | 68 | static WebCLBuffer *New(cl_mem mw, WebCLObject *parent); 69 | static NAN_METHOD(New); 70 | static NAN_METHOD(getInfo); 71 | static NAN_METHOD(getGLObjectInfo); 72 | static NAN_METHOD(release); 73 | static NAN_METHOD(createSubBuffer); 74 | 75 | bool isSubBuffer() const { return isSubBuffer_; } 76 | 77 | private: 78 | WebCLBuffer(v8::Handle wrapper); 79 | 80 | static v8::Persistent constructor; 81 | 82 | bool isSubBuffer_; 83 | 84 | private: 85 | DISABLE_COPY(WebCLBuffer) 86 | }; 87 | 88 | class WebCLImage : public MemoryObject { 89 | public: 90 | static void Init(v8::Handle exports); 91 | 92 | static WebCLImage *New(cl_mem mw, WebCLObject *parent); 93 | static NAN_METHOD(New); 94 | static NAN_METHOD(release); 95 | static NAN_METHOD(getInfo); 96 | static NAN_METHOD(getGLObjectInfo); 97 | static NAN_METHOD(getGLTextureInfo); 98 | 99 | private: 100 | WebCLImage(v8::Handle wrapper); 101 | 102 | static v8::Persistent constructor; 103 | 104 | private: 105 | DISABLE_COPY(WebCLImage) 106 | }; 107 | 108 | class WebCLImageDescriptor : public WebCLObject 109 | { 110 | public: 111 | static void Init(v8::Handle exports); 112 | 113 | static WebCLImageDescriptor* New(int order=0, int type=0, int w=0, int h=0, int d=0, int rp=0, int sp=0); 114 | static NAN_METHOD(New); 115 | static NAN_GETTER(getChannelOrder); 116 | static NAN_GETTER(getChannelType); 117 | static NAN_GETTER(getWidth); 118 | static NAN_GETTER(getHeight); 119 | static NAN_GETTER(getDepth); 120 | static NAN_GETTER(getRowPitch); 121 | static NAN_GETTER(getSlicePitch); 122 | 123 | private: 124 | WebCLImageDescriptor(v8::Handle wrapper); 125 | 126 | static v8::Persistent constructor; 127 | 128 | int channelOrder, channelType; 129 | int width, height, depth; 130 | int rowPitch, slicePitch; 131 | 132 | private: 133 | DISABLE_COPY(WebCLImageDescriptor) 134 | }; 135 | 136 | } // namespace 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /src/platform.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef PLATFORM_H_ 28 | #define PLATFORM_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class Platform : public WebCLObject 35 | { 36 | 37 | public: 38 | static void Init(v8::Handle exports); 39 | 40 | static Platform *New(cl_platform_id pid); 41 | static NAN_METHOD(New); 42 | static NAN_METHOD(getInfo); 43 | static NAN_METHOD(getDevices); 44 | static NAN_METHOD(getSupportedExtensions); 45 | 46 | cl_platform_id getPlatformId() const { return platform_id; }; 47 | virtual bool operator==(void *clObj) { return ((cl_platform_id)clObj)==platform_id; } 48 | 49 | static NAN_METHOD(enableExtension); 50 | bool hasGLSharingEnabled() const { return (enableExtensions & GL_SHARING); } 51 | bool hasFP16Enabled() const { return (enableExtensions & FP16)==FP16; } 52 | bool hasFP64Enabled() const { return (enableExtensions & FP64)==FP64; } 53 | 54 | private: 55 | Platform(v8::Handle wrapper); 56 | 57 | static v8::Persistent constructor; 58 | 59 | cl_platform_id platform_id; 60 | 61 | cl_uint enableExtensions; 62 | cl_uint availableExtensions; 63 | 64 | enum WEBCL_EXTENSIONS { 65 | NONE = 0x00, 66 | GL_SHARING = 0x01, 67 | FP16 = 0x02, 68 | FP64 = 0x04 69 | }; 70 | 71 | private: 72 | DISABLE_COPY(Platform) 73 | }; 74 | 75 | } 76 | 77 | #endif /* PLATFORM_H_ */ 78 | -------------------------------------------------------------------------------- /src/program.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef PROGRAM_H_ 28 | #define PROGRAM_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class Program : public WebCLObject 35 | { 36 | 37 | public: 38 | void Destructor(); 39 | 40 | static void Init(v8::Handle exports); 41 | 42 | static Program *New(cl_program pw, WebCLObject *parent); 43 | static NAN_METHOD(New); 44 | 45 | static NAN_METHOD(getInfo); 46 | static NAN_METHOD(getBuildInfo); 47 | static NAN_METHOD(build); 48 | static NAN_METHOD(createKernel); 49 | static NAN_METHOD(createKernelsInProgram); 50 | static NAN_METHOD(release); 51 | static NAN_METHOD(retain); 52 | 53 | cl_program getProgram() const { return program; }; 54 | virtual bool operator==(void *clObj) { return ((cl_program)clObj)==program; } 55 | 56 | private: 57 | Program(v8::Handle wrapper); 58 | ~Program(); 59 | 60 | static void callback (cl_program program, void *user_data); 61 | 62 | static v8::Persistent constructor; 63 | 64 | cl_program program; 65 | 66 | private: 67 | DISABLE_COPY(Program) 68 | }; 69 | 70 | } // namespace 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/sampler.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #include "sampler.h" 28 | #include "platform.h" 29 | #include "context.h" 30 | 31 | using namespace v8; 32 | using namespace node; 33 | 34 | namespace webcl { 35 | 36 | Persistent Sampler::constructor; 37 | 38 | void Sampler::Init(Handle exports) 39 | { 40 | NanScope(); 41 | 42 | // constructor 43 | Local ctor = FunctionTemplate::New(Sampler::New); 44 | ctor->InstanceTemplate()->SetInternalFieldCount(1); 45 | ctor->SetClassName(NanNew("WebCLSampler")); 46 | 47 | // prototype 48 | NODE_SET_PROTOTYPE_METHOD(ctor, "_getInfo", getInfo); 49 | NODE_SET_PROTOTYPE_METHOD(ctor, "_release", release); 50 | 51 | NanAssignPersistent(constructor, ctor->GetFunction()); 52 | exports->Set(NanNew("WebCLSampler"), ctor->GetFunction()); 53 | } 54 | 55 | Sampler::Sampler(Handle wrapper) : sampler(0) 56 | { 57 | _type=CLObjType::Sampler; 58 | } 59 | 60 | Sampler::~Sampler() { 61 | #ifdef LOGGING 62 | printf("In ~Sampler\n"); 63 | #endif 64 | // Destructor(); 65 | } 66 | 67 | void Sampler::Destructor() { 68 | if(sampler) { 69 | cl_uint count; 70 | ::clGetSamplerInfo(sampler,CL_SAMPLER_REFERENCE_COUNT,sizeof(cl_uint),&count,NULL); 71 | #ifdef LOGGING 72 | cout<<" Destroying Sampler, CLrefCount is: "<(args.This()); 86 | 87 | sampler->Destructor(); 88 | 89 | NanReturnUndefined(); 90 | } 91 | 92 | NAN_METHOD(Sampler::getInfo) 93 | { 94 | NanScope(); 95 | Sampler *sampler = ObjectWrap::Unwrap(args.This()); 96 | cl_sampler_info param_name = args[0]->Uint32Value(); 97 | 98 | switch (param_name) { 99 | case CL_SAMPLER_ADDRESSING_MODE: 100 | case CL_SAMPLER_FILTER_MODE: 101 | case CL_SAMPLER_REFERENCE_COUNT: { 102 | cl_uint param_value=0; 103 | cl_int ret=::clGetSamplerInfo(sampler->getSampler(), param_name,sizeof(cl_uint), ¶m_value, NULL); 104 | if (ret != CL_SUCCESS) { 105 | REQ_ERROR_THROW(INVALID_VALUE); 106 | REQ_ERROR_THROW(INVALID_SAMPLER); 107 | REQ_ERROR_THROW(OUT_OF_RESOURCES); 108 | REQ_ERROR_THROW(OUT_OF_HOST_MEMORY); 109 | return NanThrowError("UNKNOWN ERROR"); 110 | } 111 | NanReturnValue(Integer::NewFromUnsigned(param_value)); 112 | } 113 | case CL_SAMPLER_NORMALIZED_COORDS: { 114 | cl_uint param_value=0; 115 | cl_int ret=::clGetSamplerInfo(sampler->getSampler(), param_name,sizeof(cl_uint), ¶m_value, NULL); 116 | if (ret != CL_SUCCESS) { 117 | REQ_ERROR_THROW(INVALID_VALUE); 118 | REQ_ERROR_THROW(INVALID_SAMPLER); 119 | REQ_ERROR_THROW(OUT_OF_RESOURCES); 120 | REQ_ERROR_THROW(OUT_OF_HOST_MEMORY); 121 | return NanThrowError("UNKNOWN ERROR"); 122 | } 123 | NanReturnValue(JS_BOOL((int)param_value)); 124 | } 125 | case CL_SAMPLER_CONTEXT:{ 126 | cl_context param_value=0; 127 | cl_int ret=::clGetSamplerInfo(sampler->getSampler(), param_name,sizeof(cl_context), ¶m_value, NULL); 128 | if (ret != CL_SUCCESS) { 129 | REQ_ERROR_THROW(INVALID_VALUE); 130 | REQ_ERROR_THROW(INVALID_SAMPLER); 131 | REQ_ERROR_THROW(OUT_OF_RESOURCES); 132 | REQ_ERROR_THROW(OUT_OF_HOST_MEMORY); 133 | return NanThrowError("UNKNOWN ERROR"); 134 | } 135 | if(param_value) { 136 | WebCLObject *obj=findCLObj((void*)param_value, CLObjType::Context); 137 | if(obj) 138 | NanReturnValue(NanObjectWrapHandle(obj)); 139 | else 140 | NanReturnValue(NanObjectWrapHandle(Context::New(param_value))); 141 | } 142 | NanReturnUndefined(); 143 | } 144 | default: { 145 | cl_int ret=CL_INVALID_VALUE; 146 | REQ_ERROR_THROW(INVALID_VALUE); 147 | NanReturnUndefined(); 148 | } 149 | } 150 | 151 | } 152 | 153 | NAN_METHOD(Sampler::New) 154 | { 155 | if (!args.IsConstructCall()) 156 | return NanThrowTypeError("Constructor cannot be called as a function."); 157 | 158 | NanScope(); 159 | Sampler *s = new Sampler(args.This()); 160 | s->Wrap(args.This()); 161 | NanReturnValue(args.This()); 162 | } 163 | 164 | Sampler *Sampler::New(cl_sampler sw, WebCLObject *parent) 165 | { 166 | 167 | NanScope(); 168 | 169 | Local cons = NanNew(constructor); 170 | Local obj = cons->NewInstance(); 171 | 172 | Sampler *sampler = ObjectWrap::Unwrap(obj); 173 | sampler->sampler = sw; 174 | registerCLObj(sw, sampler); 175 | 176 | return sampler; 177 | } 178 | 179 | } 180 | -------------------------------------------------------------------------------- /src/sampler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef SAMPLER_H_ 28 | #define SAMPLER_H_ 29 | 30 | #include "common.h" 31 | 32 | namespace webcl { 33 | 34 | class Sampler : public WebCLObject 35 | { 36 | 37 | public: 38 | void Destructor(); 39 | 40 | static void Init(v8::Handle exports); 41 | 42 | static Sampler *New(cl_sampler sw, WebCLObject *parent); 43 | static NAN_METHOD(New); 44 | static NAN_METHOD(getInfo); 45 | static NAN_METHOD(release); 46 | 47 | cl_sampler getSampler() const { return sampler; }; 48 | virtual bool operator==(void *clObj) { return ((cl_sampler)clObj)==sampler; } 49 | 50 | private: 51 | Sampler(v8::Handle wrapper); 52 | ~Sampler(); 53 | 54 | static v8::Persistent constructor; 55 | 56 | cl_sampler sampler; 57 | 58 | private: 59 | DISABLE_COPY(Sampler) 60 | }; 61 | 62 | } // namespace 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/webcl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef WEBCL_H_ 28 | #define WEBCL_H_ 29 | 30 | #include "common.h" 31 | 32 | using namespace v8; 33 | 34 | namespace webcl { 35 | 36 | NAN_METHOD(getPlatforms); 37 | NAN_METHOD(createContext); 38 | // NAN_METHOD(getSupportedExtensions); 39 | // NAN_METHOD(enableExtension); 40 | NAN_METHOD(waitForEvents); 41 | NAN_METHOD(releaseAll); 42 | 43 | } 44 | 45 | #endif /* WEBCL_H_ */ 46 | -------------------------------------------------------------------------------- /test/callback.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | require('../webcl'); 30 | log = console.log; 31 | exit = process.exit; 32 | } 33 | else 34 | webcl = window.webcl; 35 | 36 | // kernel callback 37 | function kernel_complete(event, data) { 38 | var status=event.status; 39 | log('[JS CB] kernel_complete, status: '+status); 40 | if(status<0) 41 | log('Error: '+status); 42 | log(data); 43 | } 44 | 45 | // read buffer callback 46 | function read_complete(event, data) { 47 | var status=event.status; 48 | log('[JS CB] read_complete, status: '+status); 49 | if(status<0) 50 | log('Error: '+status); 51 | 52 | log('data: '+data+' size: '+data.length) 53 | var check = true; 54 | //var str=""; 55 | for(i=0; i<4096; i++) { 56 | //str+=data[i]+' '; 57 | if(data[i] != 5.0) { 58 | check = false; 59 | break; 60 | } 61 | } 62 | //log(str); 63 | if(check) 64 | log("The data has been initialized successfully."); 65 | else 66 | log("The data has not been initialized successfully."); 67 | } 68 | 69 | (function main() { 70 | /* CL objects */ 71 | var /* WebCLPlatform */ platform; 72 | var /* WebCLDevice */ device; 73 | var /* WebCLContext */ context; 74 | var /* WebCLProgram */ program; 75 | var /* WebCLKernel */ kernel; 76 | var /* WebCLCommandQueue */ queue; 77 | var /* WebCLEvent */ kernel_event, read_event; 78 | var /* WebCLBuffer */ data_buffer; 79 | 80 | /* Create a device and context */ 81 | log('creating context'); 82 | 83 | //Pick platform 84 | var platformList=webcl.getPlatforms(); 85 | platform=platformList[0]; 86 | log('using platform: '+platform.getInfo(webcl.PLATFORM_NAME)); 87 | 88 | //Query the set of devices on this platform 89 | var devices = platform.getDevices(webcl.DEVICE_TYPE_GPU); 90 | device=devices[0]; 91 | log('using device: '+device.getInfo(webcl.DEVICE_NAME)); 92 | 93 | // create GPU context for this platform 94 | var context=webcl.createContext(device ,'Error occured in context', function(err,data){ 95 | log(data+" : "+err); 96 | exit(1); 97 | }); 98 | 99 | /* Build the program and create a kernel */ 100 | var source = [ 101 | "__kernel void callback(__global float *buffer) {", 102 | " for(int i=0;i<4096;i++)", 103 | " buffer[i]=5;", 104 | "}" 105 | ].join("\n"); 106 | 107 | // Create and program from source 108 | log('create program'); 109 | try { 110 | program=context.createProgram(source); 111 | } catch(ex) { 112 | log("Couldn't create the program. "+ex); 113 | exit(1); 114 | } 115 | 116 | /* Build program */ 117 | log('build program'); 118 | try { 119 | program.build(device); 120 | } catch(ex) { 121 | /* Find size of log and print to std output */ 122 | log('build program error'); 123 | var info=program.getBuildInfo(device, webcl.PROGRAM_BUILD_LOG); 124 | log(info); 125 | exit(1); 126 | } 127 | 128 | log('create kernel'); 129 | try { 130 | kernel = program.createKernel("callback"); 131 | } catch(ex) { 132 | log("Couldn't create a kernel. "+ex); 133 | exit(1); 134 | } 135 | 136 | /* Create a write-only buffer to hold the output data */ 137 | log('create output buffer'); 138 | try { 139 | data_buffer = context.createBuffer(webcl.MEM_WRITE_ONLY, 4096*4); 140 | } catch(ex) { 141 | log("Couldn't create a buffer. "+ex); 142 | exit(1); 143 | } 144 | 145 | /* Create kernel argument */ 146 | log('kernel set arg'); 147 | try { 148 | kernel.setArg(0, data_buffer); 149 | } catch(ex) { 150 | log("Couldn't set a kernel argument. "+ex); 151 | exit(1); 152 | }; 153 | 154 | /* Create a command queue */ 155 | log('create q'); 156 | try { 157 | queue = context.createCommandQueue(device,0); 158 | } catch(ex) { 159 | log("Couldn't create a command queue. "+ex); 160 | exit(1); 161 | }; 162 | 163 | /* Enqueue kernel */ 164 | log('enqueue task'); 165 | try { 166 | kernel_event=new webcl.WebCLEvent(); 167 | queue.enqueueTask(kernel , null, kernel_event); 168 | } catch(ex) { 169 | log("Couldn't enqueue the kernel. "+ex); 170 | exit(1); 171 | } 172 | 173 | /* Read the buffer */ 174 | var data=new Float32Array(4096); 175 | try { 176 | read_event=new webcl.WebCLEvent(); 177 | queue.enqueueReadBuffer(data_buffer, false, 0, 4096*4, data, null, read_event); 178 | } catch(ex) { 179 | log("Couldn't read the buffer. "+ex); 180 | exit(1); 181 | } 182 | 183 | /* Set event handling routines */ 184 | log('set event callbacks'); 185 | kernel_event.setCallback(webcl.COMPLETE, kernel_complete, "The kernel finished successfully."); 186 | read_event.setCallback(webcl.COMPLETE, read_complete, data); 187 | 188 | // test 1: queue should finish with event completed 189 | // log('q finish'); 190 | // queue.finish(); // wait for everything to finish 191 | 192 | // test 2: wait for all events to complete 193 | log('Wait for events to complete'); 194 | webcl.waitForEvents([kernel_event, read_event]); 195 | 196 | // test 3: spin on all event completions 197 | // log(' spinning on event completion'); 198 | // var event_list=[kernel_event, read_event]; 199 | // for(var i=0;i BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../webcl'); 30 | log = console.log; 31 | exit = process.exit; 32 | } 33 | else 34 | webcl = window.webcl; 35 | 36 | /* CL objects */ 37 | var /* WebCLPlatform */ platform; 38 | var /* WebCLDevice */ device; 39 | var /* WebCLContext */ context; 40 | var /* WebCLProgram */ program; 41 | var /* WebCLKernel */ kernel; 42 | var /* WebCLCommandQueue */ queue; 43 | var /* WebCLEvent */ kernel_event, read_event; 44 | var /* WebCLBuffer */ data_buffer; 45 | var done=false; 46 | 47 | // kernel callback 48 | function kernel_complete(event, data) { 49 | var status=event.status; 50 | log('[JS CB] kernel_complete, status: '+status); 51 | if(status<0) 52 | log('Error: '+status); 53 | log(data); 54 | } 55 | 56 | // read buffer callback 57 | function read_complete(event, data) { 58 | var status=event.status; 59 | log('[JS CB] read_complete, status: '+status); 60 | if(status<0) 61 | log('Error: '+status); 62 | 63 | var check = webcl.TRUE; 64 | //var str=""; 65 | for(i=0; i<4096; i++) { 66 | //str+=data[i]+' '; 67 | if(data[i] != 5.0) { 68 | check = webcl.FALSE; 69 | break; 70 | } 71 | } 72 | //log(str); 73 | if(check) 74 | log("The data has been initialized successfully."); 75 | else 76 | log("The data has not been initialized successfully."); 77 | } 78 | 79 | function program_built(err, data) { 80 | log('[JS CB] program built'); 81 | try { 82 | kernel = program.createKernel("callback"); 83 | } catch(ex) { 84 | log("Couldn't create a kernel. "+ex); 85 | exit(1); 86 | } 87 | 88 | /* Create a write-only buffer to hold the output data */ 89 | try { 90 | data_buffer = context.createBuffer(webcl.MEM_WRITE_ONLY, 4096*4); 91 | } catch(ex) { 92 | log("Couldn't create a buffer. "+ex); 93 | exit(1); 94 | } 95 | 96 | /* Create kernel argument */ 97 | try { 98 | kernel.setArg(0, data_buffer); 99 | } catch(ex) { 100 | log("Couldn't set a kernel argument. "+ex); 101 | exit(1); 102 | }; 103 | 104 | /* Create a command queue */ 105 | try { 106 | queue = context.createCommandQueue(device, 0); 107 | } catch(ex) { 108 | log("Couldn't create a command queue. "+ex); 109 | exit(1); 110 | }; 111 | 112 | /* Enqueue kernel */ 113 | try { 114 | kernel_event=new webcl.WebCLEvent(); 115 | queue.enqueueTask(kernel , null, kernel_event); 116 | } catch(ex) { 117 | log("Couldn't enqueue the kernel. "+ex); 118 | exit(1); 119 | } 120 | 121 | /* Read the buffer */ 122 | var data=new Float32Array(4096); 123 | try { 124 | read_event=new webcl.WebCLEvent(); 125 | queue.enqueueReadBuffer(data_buffer, false, 0, 4096*4, data, null, read_event); 126 | } catch(ex) { 127 | log("Couldn't read the buffer. "+ex); 128 | exit(1); 129 | } 130 | 131 | /* Set event handling routines */ 132 | try { 133 | kernel_event.setCallback(webcl.COMPLETE, kernel_complete, "The kernel finished successfully."); 134 | } catch(ex) { 135 | log("Couldn't set callback for event. "+ex); 136 | exit(1); 137 | } 138 | read_event.setCallback(webcl.COMPLETE, read_complete, data); 139 | 140 | queue.finish(); // wait for everything to finish 141 | done=true; 142 | } 143 | function main() { 144 | 145 | /* Create a device and context */ 146 | log('creating context'); 147 | 148 | //Pick platform 149 | var platformList=webcl.getPlatforms(); 150 | platform=platformList[0]; 151 | log('using platform: '+platform.getInfo(webcl.PLATFORM_NAME)); 152 | 153 | //Query the set of devices on this platform 154 | var devices = platform.getDevices(webcl.DEVICE_TYPE_GPU); 155 | 156 | // make sure we use a discrete GPU (Intel embedded GPU don't support event correctly) 157 | device=null; 158 | for(var i=0;i=0) { 161 | device=devices[i]; 162 | break; 163 | } 164 | } 165 | if(!device || i==devices.length) { 166 | log("[ERROR] No suitable device found"); 167 | exit(-1); 168 | } 169 | 170 | log('using device: '+device.getInfo(webcl.DEVICE_VENDOR).trim()+ 171 | ' '+device.getInfo(webcl.DEVICE_NAME).trim()); 172 | 173 | // create GPU context for this platform 174 | context=webcl.createContext(device); 175 | 176 | /* Build the program and create a kernel */ 177 | var source = [ 178 | "__kernel void callback(__global float *buffer) {", 179 | " for(int i=0; i<4096; i++) ", 180 | " buffer[i]=5;", 181 | "}" 182 | ].join("\n"); 183 | 184 | // Create and program from source 185 | try { 186 | program=context.createProgram(source); 187 | } catch(ex) { 188 | log("Couldn't create the program. "+ex); 189 | exit(1); 190 | } 191 | 192 | /* Build program */ 193 | try { 194 | program.build(device, null, program_built); 195 | } catch(ex) { 196 | /* Find size of log and print to std output */ 197 | var info=program.getBuildInfo(device, webcl.PROGRAM_BUILD_LOG); 198 | log(info); 199 | exit(1); 200 | } 201 | 202 | log("main app thread END"); 203 | 204 | // sleeping the main thread to let events propagate 205 | // function sleep() { 206 | // if(!done) { 207 | // log('sleeping 0.5s'); 208 | // setTimeout(sleep, 500); 209 | // } 210 | // } 211 | // sleep(); 212 | } 213 | 214 | main(); 215 | -------------------------------------------------------------------------------- /test/callback_empty_eventList.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../webcl'); 30 | log = console.log; 31 | exit = process.exit; 32 | } 33 | else 34 | webcl = window.webcl; 35 | 36 | // kernel callback 37 | function kernel_complete(event, data) { 38 | var status=event.status; 39 | log('[JS CB] kernel_complete, status: '+status); 40 | if(status<0) 41 | log('Error: '+status); 42 | log(data); 43 | } 44 | 45 | // read buffer callback 46 | function read_complete(event, data) { 47 | var status=event.status; 48 | log('[JS CB] read_complete, status: '+status); 49 | if(status<0) 50 | log('Error: '+status); 51 | 52 | var check = webcl.TRUE; 53 | //var str=""; 54 | for(i=0; i<4096; i++) { 55 | //str+=data[i]+' '; 56 | if(data[i] != 5.0) { 57 | check = webcl.FALSE; 58 | break; 59 | } 60 | } 61 | //log(str); 62 | if(check) 63 | log("The data has been initialized successfully."); 64 | else 65 | log("The data has not been initialized successfully."); 66 | } 67 | 68 | (function main() { 69 | /* CL objects */ 70 | var /* WebCLPlatform */ platform; 71 | var /* WebCLDevice */ device; 72 | var /* WebCLContext */ context; 73 | var /* WebCLProgram */ program; 74 | var /* WebCLKernel */ kernel; 75 | var /* WebCLCommandQueue */ queue; 76 | var /* WebCLEvent */ kernel_event, read_event; 77 | var /* WebCLBuffer */ data_buffer; 78 | 79 | /* Create a device and context */ 80 | log('creating context'); 81 | 82 | //Pick platform 83 | var platformList=webcl.getPlatforms(); 84 | platform=platformList[0]; 85 | log('using platform: '+platform.getInfo(webcl.PLATFORM_NAME)); 86 | 87 | //Query the set of devices on this platform 88 | var devices = platform.getDevices(webcl.DEVICE_TYPE_GPU); 89 | device=devices[0]; 90 | log('using device: '+device.getInfo(webcl.DEVICE_NAME)); 91 | 92 | // create GPU context for this platform 93 | var context=webcl.createContext(device ,'Error occured in context', function(err,data){ 94 | log(data+" : "+err); 95 | exit(1); 96 | }); 97 | 98 | /* Build the program and create a kernel */ 99 | var source = [ 100 | "__kernel void callback(__global float *buffer) {", 101 | " for(int i=0;i<4096;i++)", 102 | " buffer[i]=5;", 103 | "}" 104 | ].join("\n"); 105 | 106 | // Create and program from source 107 | log('create program'); 108 | try { 109 | program=context.createProgram(source); 110 | } catch(ex) { 111 | log("Couldn't create the program. "+ex); 112 | exit(1); 113 | } 114 | 115 | /* Build program */ 116 | log('build program'); 117 | try { 118 | program.build(device); 119 | } catch(ex) { 120 | /* Find size of log and print to std output */ 121 | log('build program error'); 122 | var info=program.getBuildInfo(device, webcl.PROGRAM_BUILD_LOG); 123 | log(info); 124 | exit(1); 125 | } 126 | 127 | log('create kernel'); 128 | try { 129 | kernel = program.createKernel("callback"); 130 | } catch(ex) { 131 | log("Couldn't create a kernel. "+ex); 132 | exit(1); 133 | } 134 | 135 | /* Create a write-only buffer to hold the output data */ 136 | log('create output buffer'); 137 | try { 138 | data_buffer = context.createBuffer(webcl.MEM_WRITE_ONLY, 4096*4); 139 | } catch(ex) { 140 | log("Couldn't create a buffer. "+ex); 141 | exit(1); 142 | } 143 | 144 | /* Create kernel argument */ 145 | log('kernel set arg'); 146 | try { 147 | kernel.setArg(0, data_buffer); 148 | } catch(ex) { 149 | log("Couldn't set a kernel argument. "+ex); 150 | exit(1); 151 | }; 152 | 153 | /* Create a command queue */ 154 | log('create q'); 155 | try { 156 | queue = context.createCommandQueue(device,0); 157 | } catch(ex) { 158 | log("Couldn't create a command queue. "+ex); 159 | exit(1); 160 | }; 161 | 162 | /* Enqueue kernel */ 163 | log('enqueue task'); 164 | try { 165 | kernel_event=new webcl.WebCLEvent(); 166 | queue.enqueueTask(kernel , null, kernel_event); 167 | } catch(ex) { 168 | log("Couldn't enqueue the kernel. "+ex); 169 | exit(1); 170 | } 171 | 172 | /* Read the buffer */ 173 | var data=new Float32Array(4096); 174 | try { 175 | read_event=new webcl.WebCLEvent(); 176 | queue.enqueueReadBuffer(data_buffer, false, 0, 4096*4, data, [], read_event); 177 | } catch(ex) { 178 | log("Couldn't read the buffer. "+ex); 179 | exit(1); 180 | } 181 | 182 | /* Set event handling routines */ 183 | log('set event callbacks'); 184 | kernel_event.setCallback(webcl.COMPLETE, kernel_complete, "The kernel finished successfully."); 185 | read_event.setCallback(webcl.COMPLETE, read_complete, data); 186 | 187 | // test 1: queue should finish with event completed 188 | // log('q finish'); 189 | // queue.finish(); // wait for everything to finish 190 | 191 | // test 2: wait for all events to complete 192 | log('Wait for events to complete'); 193 | var event_list=[kernel_event, read_event]; 194 | webcl.waitForEvents(event_list); 195 | 196 | // test 3: spin on all event completions 197 | // log(' spinning on event completion'); 198 | // var event_list=[kernel_event, read_event]; 199 | // for(var i=0;i BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var util=require('util'); 28 | var log=console.log; 29 | try { 30 | ArrayBuffer; 31 | Int8Array; 32 | } catch (e) { 33 | var typed_arrays = process.binding('typed_array'); 34 | ArrayBuffer=typed_arrays.ArrayBuffer; 35 | Int8Array=typed_arrays.Int8Array; 36 | Int16Array=typed_arrays.Int16Array; 37 | Int32Array=typed_arrays.Int32Array; 38 | Int64Array=typed_arrays.Int64Array; 39 | Float32Array=typed_arrays.Float32Array; 40 | Float64Array=typed_arrays.Float64Array; 41 | } 42 | 43 | // note: ctype field is useless 44 | var ctypes= { 45 | char : { 46 | ctype : 'char', 47 | num : 1, 48 | fill : function(buffer, offset, values) { 49 | var fbuf=new Int8Array(buffer, offset); 50 | if(typeof values == 'string') { 51 | values=values.charCodeAt(0) & 0xFF; 52 | } 53 | fbuf[0]=values; 54 | return offset + 1; 55 | } 56 | }, 57 | short : { 58 | ctype : 'short', 59 | num : 2, 60 | fill : function(buffer, offset, values) { 61 | var fbuf=new Int16Array(buffer, offset); 62 | if(typeof values == 'string') { 63 | values=values.charCodeAt(0); 64 | } 65 | fbuf[0]=values; 66 | return offset + 2; 67 | } 68 | }, 69 | int : { 70 | ctype : 'int', 71 | num : 4, 72 | fill : function(buffer, offset, values) { 73 | var fbuf=new Int32Array(buffer, offset); 74 | if(typeof values == 'string') { 75 | values=values.charCodeAt(0); 76 | } 77 | fbuf[0]=values; 78 | return offset + 4; 79 | } 80 | }, 81 | long : { 82 | ctype : 'int', 83 | num : 8, 84 | fill : function(buffer, offset, values) { 85 | var fbuf=new Int64Array(buffer, offset); 86 | if(typeof values == 'string') { 87 | values=values.charCodeAt(0); 88 | } 89 | fbuf[0]=values; 90 | return offset + 8; 91 | } 92 | }, 93 | float : { 94 | ctype : 'float', 95 | num : 4, 96 | fill : function(buffer, offset, values) { 97 | var fbuf=new Float32Array(buffer, offset); 98 | fbuf[0]=values; 99 | return offset + 4; 100 | } 101 | }, 102 | double : { 103 | ctype : 'float', 104 | num : 8, 105 | fill : function(buffer, offset, values) { 106 | var fbuf=new Float64Array(buffer, offset); 107 | fbuf[0]=values; 108 | return offset + 8; 109 | } 110 | }, 111 | Array : function(type, num) { 112 | return { 113 | ctype : 'Array', 114 | type : type, 115 | num : num * type.num, 116 | fill : function(buffer, offset, values) { 117 | for(var v=0,l=values.length;v=0) 33 | isAMD=true; 34 | break; 35 | } 36 | } 37 | } 38 | if(i==devices.length) { 39 | log("Error: can't find a device that supports 64-bit floats"); 40 | return null; 41 | } 42 | log('Found fp64 device: '+device.getInfo(webcl.DEVICE_VENDOR)+device.getInfo(webcl.DEVICE_NAME)); 43 | return [device, isAMD]; 44 | } 45 | 46 | function VectorAdd() { 47 | dumpResults=(BUFFER_SIZE<=128); 48 | 49 | var A=new Float64Array(BUFFER_SIZE); 50 | var B=new Float64Array(BUFFER_SIZE); 51 | 52 | for (var i = 0; i < BUFFER_SIZE; i++) { 53 | A[i] = i; 54 | B[i] = i * 2; 55 | } 56 | 57 | var platformList=webcl.getPlatforms(); 58 | platform=platformList[0]; 59 | log('Using platform: '+platform.getInfo(webcl.PLATFORM_NAME)); 60 | 61 | //Query the set of devices on this platform 62 | var devices = platform.getDevices(webcl.DEVICE_TYPE_ALL); 63 | 64 | // find a device that supports fp64 65 | // Note: Intel integrated GPU HD 4000 doesn't support fp64 66 | var dev=select_FP64_device(devices, useGPU); 67 | if(!dev) 68 | process.exit(-1); 69 | 70 | device=dev[0]; 71 | isAMD=dev[1]; 72 | 73 | // create GPU context for this platform 74 | var context=webcl.createContext(device); 75 | 76 | // Create command queue 77 | queue=context.createCommandQueue(); 78 | 79 | kernelSourceCode = [ 80 | "__kernel void vadd(__global double *a, __global double *b, __global double *c, uint iNumElements) ", 81 | "{ ", 82 | " size_t i = get_global_id(0); ", 83 | " if(i >= iNumElements) return; ", 84 | " c[i] = a[i] + b[i]; ", 85 | "} " 86 | ].join("\n"); 87 | 88 | if(isAMD) 89 | kernelSourceCode = "#pragma OPENCL EXTENSION cl_amd_fp64 : enable\n" + kernelSourceCode; 90 | else 91 | kernelSourceCode = "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n" + kernelSourceCode; 92 | 93 | //Create and program from source 94 | program=context.createProgram(kernelSourceCode); 95 | 96 | //Build program 97 | try { 98 | program.build(device); 99 | } 100 | catch(ex) { 101 | log(ex); 102 | log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG)); 103 | } 104 | 105 | size=BUFFER_SIZE*Float64Array.BYTES_PER_ELEMENT; // size in bytes 106 | 107 | // Create buffer for A and B and copy host contents 108 | aBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 109 | bBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 110 | 111 | // Create buffer for C to read results 112 | cBuffer = context.createBuffer(webcl.MEM_WRITE_ONLY, size); 113 | 114 | // Create kernel object 115 | try { 116 | kernel= program.createKernel("vadd"); 117 | } 118 | catch(err) { 119 | console.log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG)); 120 | } 121 | 122 | // Set kernel args 123 | kernel.setArg(0, aBuffer); 124 | kernel.setArg(1, bBuffer); 125 | kernel.setArg(2, cBuffer); 126 | kernel.setArg(3, new Uint32Array([BUFFER_SIZE])); 127 | 128 | // Execute the OpenCL kernel on the list 129 | var localWS = [8]; // process one list at a time 130 | var globalWS = [clu.roundUp(localWS, BUFFER_SIZE)]; // process entire list 131 | 132 | log("Global work item size: " + globalWS); 133 | log("Local work item size: " + localWS); 134 | 135 | // Do the work 136 | queue.enqueueWriteBuffer (aBuffer, false, 0, A.length*Float64Array.BYTES_PER_ELEMENT, A); 137 | queue.enqueueWriteBuffer (bBuffer, false, 0, B.length*Float64Array.BYTES_PER_ELEMENT, B); 138 | 139 | // Execute (enqueue) kernel 140 | log("execute kernel"); 141 | queue.enqueueNDRangeKernel(kernel, 1, 142 | null, 143 | globalWS, 144 | localWS); 145 | 146 | // get results and block while getting them 147 | var C=new Float64Array(BUFFER_SIZE); 148 | queue.enqueueReadBuffer (cBuffer, true, 0, C.length*Float64Array.BYTES_PER_ELEMENT, C); 149 | 150 | // print results 151 | printResults(A,B,C); 152 | } 153 | 154 | function printResults(A,B,C) { 155 | // Print input vectors and result vector 156 | var i, ok=true; 157 | if(dumpResults) { 158 | var output = "\nA = "; 159 | for (i = 0; i < BUFFER_SIZE; i++) { 160 | output += A[i] + ", "; 161 | } 162 | output += "\nB = "; 163 | for (i = 0; i < BUFFER_SIZE; i++) { 164 | output += B[i] + ", "; 165 | } 166 | output += "\nC = "; 167 | for (i = 0; i < BUFFER_SIZE; i++) { 168 | output += C[i] + ", "; 169 | if(C[i] != A[i]+B[i]) { 170 | ok=false; 171 | break; 172 | } 173 | } 174 | log(output); 175 | } 176 | else { 177 | for (i = 0; i < BUFFER_SIZE; i++) { 178 | if(C[i] != A[i]+B[i]) { 179 | ok=false; 180 | break; 181 | } 182 | } 183 | } 184 | log(ok ? "PASS" : "FAIL: incorrect vector addition"); 185 | } 186 | -------------------------------------------------------------------------------- /test/gradient.cl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012, Motorola Mobility, Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // * Neither the name of the Motorola Mobility, Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived from this 14 | // software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | // ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | __kernel void compute(__write_only image2d_t bmp) 28 | { 29 | int x = get_global_id(0); 30 | int y = get_global_id(1); 31 | int w = get_global_size(0)-1; 32 | int h = get_global_size(1)-1; 33 | 34 | int2 coords = (int2)(x,y); 35 | 36 | float red = (float)x/(float)w; 37 | float blue = (float)y/(float)h; 38 | 39 | write_imagef(bmp, coords, (float4)(blue, 0.0f, red, 1.0f)); 40 | 41 | // on Mac, writing integers doesn't work!!! 42 | //write_imagei(bmp, coords, (int4)(blue*255, 0, red*255, 255)); 43 | } 44 | -------------------------------------------------------------------------------- /test/lenaRGB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikeseven/node-webcl/100ce70280e020028b72e8b80a116bcef513a355/test/lenaRGB.jpg -------------------------------------------------------------------------------- /test/node_buffer.js: -------------------------------------------------------------------------------- 1 | var nodejs = (typeof window === 'undefined'); 2 | if(nodejs) { 3 | webcl = require('../webcl'); 4 | clu = require('../lib/clUtils'); 5 | log=console.log; 6 | } 7 | else 8 | webcl = window.webcl; 9 | 10 | //First check if the webcl extension is installed at all 11 | if (webcl == undefined) { 12 | alert("Unfortunately your system does not support webcl. " + 13 | "Make sure that you have the webcl extension installed."); 14 | process.exit(-1); 15 | } 16 | 17 | VectorAdd(); 18 | 19 | function VectorAdd() { 20 | BUFFER_SIZE=10; 21 | var A=new Buffer(BUFFER_SIZE); 22 | var B=new Buffer(BUFFER_SIZE); 23 | var USE_CREATE_BUFFER=true; 24 | 25 | for (var i = 0; i < BUFFER_SIZE; i++) { 26 | A[i] = i; 27 | B[i] = i * 2; 28 | } 29 | 30 | // create GPU context for this platform 31 | context=webcl.createContext(webcl.DEVICE_TYPE_DEFAULT); 32 | 33 | // Create command queue 34 | try { 35 | queue=context.createCommandQueue(); 36 | } 37 | catch(ex) { 38 | log(ex); 39 | exit(-1); 40 | } 41 | 42 | device = queue.getInfo(webcl.QUEUE_DEVICE); 43 | log('using device: '+device.getInfo(webcl.DEVICE_NAME)); 44 | 45 | kernelSourceCode = [ 46 | "__kernel void vadd(__global int *a, __global int *b, __global int *c, uint iNumElements) ", 47 | "{ ", 48 | " size_t i = get_global_id(0); ", 49 | " if(i >= iNumElements) return; ", 50 | " c[i] = a[i] + b[i]; ", 51 | "} " 52 | ].join("\n"); 53 | 54 | //Create and program from source 55 | program=context.createProgram(kernelSourceCode); 56 | 57 | //Build program 58 | program.build(device); 59 | 60 | size=BUFFER_SIZE*Uint32Array.BYTES_PER_ELEMENT; // size in bytes 61 | 62 | // Create buffer for A and B and copy host contents 63 | if(USE_CREATE_BUFFER) { 64 | aBuffer = context.createBuffer(webcl.MEM_READ_ONLY | webcl.MEM_USE_HOST_PTR, size, A); 65 | bBuffer = context.createBuffer(webcl.MEM_READ_ONLY | webcl.MEM_USE_HOST_PTR, size, B); 66 | } 67 | else { 68 | aBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 69 | bBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 70 | } 71 | // Create buffer for C to read results 72 | cBuffer = context.createBuffer(webcl.MEM_WRITE_ONLY, size); 73 | 74 | // Create kernel object 75 | try { 76 | kernel= program.createKernel("vadd"); 77 | } 78 | catch(err) { 79 | console.log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG)); 80 | } 81 | 82 | // Set kernel args 83 | kernel.setArg(0, aBuffer); 84 | kernel.setArg(1, bBuffer); 85 | kernel.setArg(2, cBuffer); 86 | kernel.setArg(3, new Uint32Array([BUFFER_SIZE])); 87 | 88 | // Execute the OpenCL kernel on the list 89 | var localWS = [5]; // process one list at a time 90 | var globalWS = [clu.roundUp(localWS, BUFFER_SIZE)]; // process entire list 91 | 92 | log("Global work item size: " + globalWS); 93 | log("Local work item size: " + localWS); 94 | 95 | // Do the work 96 | if(!USE_CREATE_BUFFER) { 97 | queue.enqueueWriteBuffer (aBuffer, false, 0, A.length*Uint32Array.BYTES_PER_ELEMENT, A); 98 | queue.enqueueWriteBuffer (bBuffer, false, 0, B.length*Uint32Array.BYTES_PER_ELEMENT, B); 99 | } 100 | 101 | // Execute (enqueue) kernel 102 | log("using enqueueNDRangeKernel"); 103 | queue.enqueueNDRangeKernel(kernel, 1, 104 | null, 105 | globalWS, 106 | localWS); 107 | 108 | // get results and block while getting them 109 | var C=new Buffer(BUFFER_SIZE); 110 | queue.enqueueReadBuffer (cBuffer, true, 0, C.length*Uint32Array.BYTES_PER_ELEMENT, C); 111 | 112 | // print results 113 | printResults(A,B,C); 114 | 115 | // cleanup 116 | // test release each CL object 117 | // queue.release(); 118 | // kernel.release(); 119 | // program.release(); 120 | // aBuffer.release(); 121 | // bBuffer.release(); 122 | // cBuffer.release(); 123 | // context.release(); 124 | 125 | // test release all CL objects 126 | // webcl.releaseAll(); 127 | 128 | // if no manual cleanup specified, webcl.releaseAll() is called at exit of program 129 | } 130 | 131 | function printResults(A,B,C) { 132 | // Print input vectors and result vector 133 | var output = "\nA = "; 134 | for (var i = 0; i < BUFFER_SIZE; i++) { 135 | output += A[i] + ", "; 136 | } 137 | output += "\nB = "; 138 | for (var i = 0; i < BUFFER_SIZE; i++) { 139 | output += B[i] + ", "; 140 | } 141 | output += "\nC = "; 142 | for (var i = 0; i < BUFFER_SIZE; i++) { 143 | output += C[i] + ", "; 144 | } 145 | 146 | log(output); 147 | } 148 | -------------------------------------------------------------------------------- /test/perf.chai.js: -------------------------------------------------------------------------------- 1 | var chai=require('chai'),expect=chai.expect, assert=chai.assert, 2 | should=require('should'), 3 | cl=require("../webcl"), 4 | Benchmark=require('benchmark'), 5 | log=console.log; 6 | var suite=new Benchmark.Suite("Performance of getting JS class name"); 7 | 8 | var platforms=cl.getPlatforms(); 9 | var platform=platforms[0]; 10 | 11 | log('typeof [] '+(typeof ([]))) 12 | log('typeof platform '+(typeof platform)) 13 | log('instanceof cl.WebCLPlatform '+(platform instanceof cl.WebCLPlatform)) 14 | log('proto '+(Object.prototype.toString.call(platform))) 15 | log('expect '+(expect(platform).instanceof(cl.WebCLPlatform))) 16 | log('assert '+(assert.instanceOf(platform, cl.WebCLPlatform))) 17 | log('should '+(platform.should.be.instanceOf(cl.WebCLPlatform))) 18 | 19 | suite.add('typeof',function() { 20 | typeof platform === 'object'; 21 | }) 22 | .add('instanceof', function() { 23 | platform instanceof cl.WebCLPlatform; 24 | }) 25 | .add('proto', function() { 26 | Object.prototype.toString.call(platform) ==='[object WebCLPlatform]'; 27 | }) 28 | .add('expect', function() { 29 | expect(platform).to.be.an.instanceof(cl.WebCLPlatform); 30 | }) 31 | .add('assert', function() { 32 | assert.instanceOf(platform, cl.WebCLPlatform); 33 | }) 34 | .add('should', function() { 35 | platform.should.be.instanceOf(cl.WebCLPlatform); 36 | }) 37 | // add listeners 38 | .on('start', function(event) { 39 | log('Benchmark started...'); 40 | }) 41 | .on('cycle', function(event) { 42 | log(' '+String(event.target)); 43 | }) 44 | .on('complete', function() { 45 | log(' --> Fastest is ' + this.filter('fastest').pluck('name')); 46 | log('Benchmark completed.') 47 | }) 48 | // run async 49 | .run({ 'async': false }); 50 | 51 | // log('typeof '+(typeof platform)) 52 | // log('instanceof '+(platform instanceof cl.WebCLPlatform)) 53 | // expect(platform).to.be.an.instanceof(cl.WebCLPlatform) 54 | 55 | // var devices=platform.getDevices(cl.DEVICE_TYPE_ALL); 56 | // for(var i=0;i BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../webcl'); 30 | log = console.log; 31 | exit = process.exit; 32 | } 33 | else 34 | webcl = window.webcl; 35 | 36 | function read_complete(status, data) { 37 | log('in read_complete, status: '+status); 38 | log("New data: "+data[0]+', '+data[1]+', '+data[2]+', '+data[3]); 39 | } 40 | 41 | function main() { 42 | /* CL objects */ 43 | var /* WebCLPlatform */ platform; 44 | var /* WebCLDevice */ device; 45 | var /* WebCLContext */ context; 46 | var /* WebCLProgram */ program; 47 | var /* WebCLKernel */ kernel; 48 | var /* WebCLCommandQueue */ queue; 49 | var /* WebCLEvent */ prof_event; 50 | var /* WebCLBuffer */ data_buffer; 51 | var /* ArrayBuffer */ mapped_memory; 52 | 53 | var NUM_INTS = 4096; 54 | var NUM_ITEMS = 512; 55 | var NUM_ITERATIONS = 2000; 56 | 57 | /* Initialize data */ 58 | var data=new Uint32Array(NUM_INTS); 59 | for(i=0; i BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../webcl'); 30 | log = console.log; 31 | exit = process.exit; 32 | } 33 | else 34 | webcl = window.webcl; 35 | 36 | function read_complete(status, data) { 37 | log('in read_complete, status: '+status); 38 | log("New data: "+data[0]+', '+data[1]+', '+data[2]+', '+data[3]); 39 | } 40 | 41 | function main() { 42 | /* CL objects */ 43 | var /* WebCLPlatform */ platform; 44 | var /* WebCLDevice */ device; 45 | var /* WebCLContext */ context; 46 | var /* WebCLProgram */ program; 47 | var /* WebCLKernel */ kernel; 48 | var /* WebCLCommandQueue */ queue; 49 | var /* WebCLEvent */ prof_event; 50 | var /* WebCLBuffer */ data_buffer; 51 | var /* ArrayBuffer */ mapped_memory; 52 | 53 | var NUM_BYTES = 128*1024; // 128 KB 54 | var NUM_ITERATIONS = 2000; 55 | var PROFILE_READ = true; // profile read vs. map buffer 56 | 57 | /* Initialize data */ 58 | var data=new Uint8Array(NUM_BYTES); 59 | 60 | /* Create a device and context */ 61 | log('creating context'); 62 | 63 | var context=null; 64 | try { 65 | context=webcl.createContext(webcl.DEVICE_TYPE_GPU); 66 | } 67 | catch(ex) { 68 | throw new Error("Can't create CL context. "+ex); 69 | } 70 | 71 | var devices=context.getInfo(webcl.CONTEXT_DEVICES); 72 | log("Found "+devices.length+" devices"); 73 | var device=devices[0]; 74 | 75 | /* Build the program and create a kernel */ 76 | var source = [ 77 | "__kernel void profile_read(__global char16 *c, int num) {", 78 | " for(int i=0; i= iNumElements) return; ", 49 | " c[i] = a[i] + b[i]; ", 50 | "} " 51 | ].join("\n"); 52 | 53 | //Create and program from source 54 | program=context.createProgram(kernelSourceCode); 55 | 56 | //Build program 57 | program.build(device); 58 | 59 | size=BUFFER_SIZE*Uint32Array.BYTES_PER_ELEMENT; // size in bytes 60 | 61 | // Create buffer for A and B and copy host contents 62 | aBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 63 | bBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 64 | 65 | // Create buffer for C to read results 66 | cBuffer = context.createBuffer(webcl.MEM_WRITE_ONLY, size); 67 | 68 | // Create kernel object 69 | try { 70 | kernel= program.createKernel("vadd"); 71 | } 72 | catch(err) { 73 | console.log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG)); 74 | } 75 | 76 | // Set kernel args 77 | kernel.setArg(0, aBuffer); 78 | kernel.setArg(1, bBuffer); 79 | kernel.setArg(2, cBuffer); 80 | kernel.setArg(3, new Uint32Array([BUFFER_SIZE])); 81 | 82 | // Execute the OpenCL kernel on the list 83 | var localWS = [5]; // process one list at a time 84 | var globalWS = [clu.roundUp(localWS, BUFFER_SIZE)]; // process entire list 85 | 86 | log("Global work item size: " + globalWS); 87 | log("Local work item size: " + localWS); 88 | 89 | // Do the work 90 | queue.enqueueWriteBuffer (aBuffer, false, 0, A.length*Uint32Array.BYTES_PER_ELEMENT, A); 91 | queue.enqueueWriteBuffer (bBuffer, false, 0, B.length*Uint32Array.BYTES_PER_ELEMENT, B); 92 | 93 | // Execute (enqueue) kernel 94 | log("using enqueueNDRangeKernel"); 95 | queue.enqueueNDRangeKernel(kernel, 1, 96 | null, 97 | globalWS, 98 | localWS); 99 | 100 | // get results and block while getting them 101 | var C=new Uint32Array(BUFFER_SIZE); 102 | queue.enqueueReadBuffer (cBuffer, true, 0, C.length*Uint32Array.BYTES_PER_ELEMENT, C); 103 | 104 | // print results 105 | printResults(A,B,C); 106 | 107 | // cleanup 108 | // test release each CL object 109 | // queue.release(); 110 | // kernel.release(); 111 | // program.release(); 112 | // aBuffer.release(); 113 | // bBuffer.release(); 114 | // cBuffer.release(); 115 | // context.release(); 116 | 117 | // test release all CL objects 118 | // webcl.releaseAll(); 119 | 120 | // if no manual cleanup specified, webcl.releaseAll() is called at exit of program 121 | } 122 | 123 | function printResults(A,B,C) { 124 | // Print input vectors and result vector 125 | var output = "\nA = "; 126 | for (var i = 0; i < BUFFER_SIZE; i++) { 127 | output += A[i] + ", "; 128 | } 129 | output += "\nB = "; 130 | for (var i = 0; i < BUFFER_SIZE; i++) { 131 | output += B[i] + ", "; 132 | } 133 | output += "\nC = "; 134 | for (var i = 0; i < BUFFER_SIZE; i++) { 135 | output += C[i] + ", "; 136 | } 137 | 138 | log(output); 139 | } 140 | -------------------------------------------------------------------------------- /test/test.createQ_no_locals.js: -------------------------------------------------------------------------------- 1 | var nodejs = (typeof window === 'undefined'); 2 | if(nodejs) { 3 | webcl = require('../webcl'); 4 | clu = require('../lib/clUtils'); 5 | log=console.log; 6 | } 7 | else 8 | webcl = window.webcl; 9 | 10 | //First check if the webcl extension is installed at all 11 | if (webcl == undefined) { 12 | alert("Unfortunately your system does not support webcl. " + 13 | "Make sure that you have the webcl extension installed."); 14 | process.exit(-1); 15 | } 16 | 17 | VectorAdd(); 18 | 19 | function VectorAdd() { 20 | BUFFER_SIZE=10; 21 | var A=new Uint32Array(BUFFER_SIZE); 22 | var B=new Uint32Array(BUFFER_SIZE); 23 | 24 | for (var i = 0; i < BUFFER_SIZE; i++) { 25 | A[i] = i; 26 | B[i] = i * 2; 27 | } 28 | 29 | // create GPU context for this platform 30 | context=webcl.createContext(webcl.DEVICE_TYPE_DEFAULT); 31 | 32 | // Create command queue 33 | queue=context.createCommandQueue(); 34 | 35 | device = queue.getInfo(webcl.QUEUE_DEVICE); 36 | log('using device: '+device.getInfo(webcl.DEVICE_NAME)); 37 | 38 | kernelSourceCode = [ 39 | "__kernel void vadd(__global int *a, __global int *b, __global int *c, uint iNumElements) ", 40 | "{ ", 41 | " size_t i = get_global_id(0); ", 42 | " if(i >= iNumElements) return; ", 43 | " c[i] = a[i] + b[i]; ", 44 | "} " 45 | ].join("\n"); 46 | 47 | //Create and program from source 48 | program=context.createProgram(kernelSourceCode); 49 | 50 | //Build program 51 | program.build(device); 52 | 53 | size=BUFFER_SIZE*Uint32Array.BYTES_PER_ELEMENT; // size in bytes 54 | 55 | // Create buffer for A and B and copy host contents 56 | aBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 57 | bBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 58 | 59 | // Create buffer for C to read results 60 | cBuffer = context.createBuffer(webcl.MEM_WRITE_ONLY, size); 61 | 62 | // Create kernel object 63 | try { 64 | kernel= program.createKernel("vadd"); 65 | } 66 | catch(err) { 67 | console.log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG)); 68 | } 69 | 70 | // Set kernel args 71 | kernel.setArg(0, aBuffer); 72 | kernel.setArg(1, bBuffer); 73 | kernel.setArg(2, cBuffer); 74 | kernel.setArg(3, new Uint32Array([BUFFER_SIZE])); 75 | 76 | // Do the work 77 | queue.enqueueWriteBuffer (aBuffer, false, 0, A.length*Uint32Array.BYTES_PER_ELEMENT, A); 78 | queue.enqueueWriteBuffer (bBuffer, false, 0, B.length*Uint32Array.BYTES_PER_ELEMENT, B); 79 | 80 | // Execute (enqueue) kernel 81 | log("using enqueueNDRangeKernel"); 82 | queue.enqueueNDRangeKernel(kernel, 1, 83 | null, 84 | [BUFFER_SIZE]); 85 | 86 | // get results and block while getting them 87 | var C=new Uint32Array(BUFFER_SIZE); 88 | queue.enqueueReadBuffer (cBuffer, true, 0, C.length*Uint32Array.BYTES_PER_ELEMENT, C); 89 | 90 | // print results 91 | printResults(A,B,C); 92 | 93 | // cleanup 94 | // test release each CL object 95 | // queue.release(); 96 | // kernel.release(); 97 | // program.release(); 98 | // aBuffer.release(); 99 | // bBuffer.release(); 100 | // cBuffer.release(); 101 | // context.release(); 102 | 103 | // test release all CL objects 104 | // webcl.releaseAll(); 105 | 106 | // if no manual cleanup specified, webcl.releaseAll() is called at exit of program 107 | } 108 | 109 | function printResults(A,B,C) { 110 | // Print input vectors and result vector 111 | var output = "\nA = "; 112 | for (var i = 0; i < BUFFER_SIZE; i++) { 113 | output += A[i] + ", "; 114 | } 115 | output += "\nB = "; 116 | for (var i = 0; i < BUFFER_SIZE; i++) { 117 | output += B[i] + ", "; 118 | } 119 | output += "\nC = "; 120 | for (var i = 0; i < BUFFER_SIZE; i++) { 121 | output += C[i] + ", "; 122 | } 123 | 124 | log(output); 125 | } 126 | -------------------------------------------------------------------------------- /test/test.exceptions.js: -------------------------------------------------------------------------------- 1 | var cl=require('../webcl'); 2 | var log=console.log; 3 | 4 | console.error(new Error('something broke')) 5 | 6 | var err=new Error('something broke') 7 | console.error(err.stack.trim()) 8 | 9 | 10 | function WebCLException(name, code, msg) { 11 | this.name = name; 12 | this.code=code; 13 | this.message = msg; 14 | } 15 | require('util').inherits(WebCLException, Error); 16 | 17 | console.error(new WebCLException('CL_INVALID_ARG', 12345, "webcl Exception")) 18 | 19 | var platforms=cl.getPlatforms(); 20 | var platform = platforms[0]; 21 | try { 22 | var value=platform.getInfo(12345); 23 | } 24 | catch(err) { 25 | log("Error: ") 26 | log(" name: "+err.name) 27 | log(" message: "+err.message) 28 | log(" code: "+err.code) 29 | log(" stack: "+err.stack) 30 | } -------------------------------------------------------------------------------- /test/test.memory.js: -------------------------------------------------------------------------------- 1 | var nodejs = (typeof window === 'undefined'); 2 | var assert=require('assert'); 3 | 4 | if(nodejs) { 5 | webcl = require('../webcl'); 6 | clu = require('../lib/clUtils'); 7 | log=console.log; 8 | } 9 | else 10 | webcl = window.webcl; 11 | 12 | //First check if the webcl extension is installed at all 13 | if (webcl == undefined) { 14 | alert("Unfortunately your system does not support webcl. " + 15 | "Make sure that you have the webcl extension installed."); 16 | process.exit(-1); 17 | } 18 | 19 | VectorAdd(); 20 | 21 | // kernel callback 22 | function kernel_complete(event, data) { 23 | var status=event.status; 24 | log('[JS CB] kernel_complete, status: '+status); 25 | if(status<0) 26 | log('Error: '+status); 27 | log(data); 28 | } 29 | 30 | // read buffer callback 31 | function read_complete(event, data) { 32 | var status=event.status; 33 | log('[JS CB] read_complete, status: '+status); 34 | if(status<0) 35 | log('Error: '+status); 36 | 37 | var check = webcl.TRUE; 38 | //var str=""; 39 | for(i=0; i= iNumElements) return; ", 83 | " c[i] = a[i] + b[i]; ", 84 | "} " 85 | ].join("\n"); 86 | 87 | //Create and program from source 88 | program=context.createProgram(kernelSourceCode); 89 | 90 | //Build program 91 | program.build(device); 92 | 93 | size=BUFFER_SIZE*Uint32Array.BYTES_PER_ELEMENT; // size in bytes 94 | 95 | // Create buffer for A and B and copy host contents 96 | aBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 97 | bBuffer = context.createBuffer(webcl.MEM_READ_ONLY, size); 98 | 99 | // Create buffer for C to read results 100 | cBuffer = context.createBuffer(webcl.MEM_WRITE_ONLY, size); 101 | 102 | // Create kernel object 103 | try { 104 | kernel= program.createKernel("vadd"); 105 | } 106 | catch(err) { 107 | console.log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG)); 108 | } 109 | 110 | // get a bunch of references 111 | var ctx = kernel.getInfo(webcl.KERNEL_CONTEXT); 112 | assert(ctx === context); 113 | 114 | var prog=kernel.getInfo(webcl.KERNEL_PROGRAM); 115 | assert(prog === program); 116 | 117 | // Set kernel args 118 | kernel.setArg(0, aBuffer); 119 | kernel.setArg(1, bBuffer); 120 | kernel.setArg(2, cBuffer); 121 | kernel.setArg(3, new Uint32Array([BUFFER_SIZE])); 122 | 123 | // Execute the OpenCL kernel on the list 124 | var localWS = [5]; // process one list at a time 125 | var globalWS = [clu.roundUp(localWS, BUFFER_SIZE)]; // process entire list 126 | 127 | log("Global work item size: " + globalWS); 128 | log("Local work item size: " + localWS); 129 | 130 | // Do the work 131 | queue.enqueueWriteBuffer (aBuffer, false, 0, A.length*Uint32Array.BYTES_PER_ELEMENT, A); 132 | queue.enqueueWriteBuffer (bBuffer, false, 0, B.length*Uint32Array.BYTES_PER_ELEMENT, B); 133 | 134 | // get more references 135 | var qctx = queue.getInfo(webcl.QUEUE_CONTEXT); 136 | assert(qctx === context); 137 | var qdev=queue.getInfo(webcl.QUEUE_DEVICE); 138 | assert(qdev === device); 139 | 140 | // Execute (enqueue) kernel 141 | log("using enqueueNDRangeKernel"); 142 | kernel_event=new webcl.WebCLEvent(); 143 | queue.enqueueNDRangeKernel(kernel, 1, 144 | null, 145 | globalWS, 146 | localWS, 147 | null, 148 | kernel_event); 149 | 150 | kernel_event.setCallback(webcl.COMPLETE, kernel_complete, "The kernel finished successfully."); 151 | 152 | // get results and block while getting them 153 | var C=new Uint32Array(BUFFER_SIZE); 154 | read_event=new webcl.WebCLEvent(); 155 | queue.enqueueReadBuffer (cBuffer, true, 0, C.length*Uint32Array.BYTES_PER_ELEMENT, C, null, read_event); 156 | read_event.setCallback(webcl.COMPLETE, read_complete, C); 157 | 158 | // more references 159 | var ectx=read_event.getInfo(webcl.EVENT_CONTEXT); 160 | assert(ectx === context); 161 | var eq=read_event.getInfo(webcl.EVENT_COMMAND_QUEUE); 162 | assert(eq === queue); 163 | 164 | // print results 165 | printResults(A,B,C); 166 | 167 | // cleanup 168 | read_event.release(); 169 | kernel_event.release(); 170 | 171 | // test release each CL object 172 | // queue.release(); 173 | kernel.release(); 174 | program.release(); 175 | // aBuffer.release(); 176 | // bBuffer.release(); 177 | // cBuffer.release(); 178 | // context.release(); 179 | 180 | // test release all CL objects 181 | webcl.releaseAll(); 182 | 183 | // if no manual cleanup specified, webcl.releaseAll() is called at exit of program 184 | } 185 | 186 | function printResults(A,B,C) { 187 | // Print input vectors and result vector 188 | var output = "\nA = "; 189 | for (var i = 0; i < BUFFER_SIZE; i++) { 190 | output += A[i] + ", "; 191 | } 192 | output += "\nB = "; 193 | for (var i = 0; i < BUFFER_SIZE; i++) { 194 | output += B[i] + ", "; 195 | } 196 | output += "\nC = "; 197 | for (var i = 0; i < BUFFER_SIZE; i++) { 198 | output += C[i] + ", "; 199 | } 200 | 201 | log(output); 202 | } 203 | -------------------------------------------------------------------------------- /test/test.platform.js: -------------------------------------------------------------------------------- 1 | var webcl=require('../webcl'); 2 | var log=console.log; 3 | 4 | var platforms=webcl.getPlatforms(); 5 | log(platforms) 6 | -------------------------------------------------------------------------------- /test/test.typedarrays.js: -------------------------------------------------------------------------------- 1 | 2 | var chai = require('chai') 3 | , expect = chai.expect 4 | , should = chai.should(); 5 | var log=console.log; 6 | 7 | function dumpArray(msg, array) { 8 | log(msg+':'); 9 | for(var i=0;i BE LIABLE FOR ANY 20 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | var nodejs = (typeof window === 'undefined'); 28 | if(nodejs) { 29 | webcl = require('../webcl'); 30 | log = console.log; 31 | exit = process.exit; 32 | } 33 | else 34 | webcl = window.webcl; 35 | 36 | function read_complete(event, data) { 37 | log('in read_complete, status: '+event.status); 38 | log("New data: "+data[0]+', '+data[1]+', '+data[2]+', '+data[3]); 39 | } 40 | 41 | function main() { 42 | /* CL objects */ 43 | var /* WebCLPlatform */ platform; 44 | var /* WebCLDevice */ device; 45 | var /* WebCLContext */ context; 46 | var /* WebCLProgram */ program; 47 | var /* WebCLKernel */ kernel; 48 | var /* WebCLCommandQueue */ queue; 49 | var /* WebCLEvent */ user_event; 50 | var /* WebCLBuffer */ data_buffer; 51 | 52 | /* Initialize data */ 53 | var data=new Float32Array(4); 54 | for(i=0; i<4; i++) 55 | data[i] = i * 2.0; 56 | 57 | /* Create a device and context */ 58 | log('creating context'); 59 | 60 | // //Pick platform 61 | // var platformList=webcl.getPlatforms(); 62 | // platform=platformList[0]; 63 | // log('using platform: '+platform.getInfo(webcl.PLATFORM_NAME)); 64 | 65 | 66 | // //Query the set of devices on this platform 67 | // var devices = platform.getDevices(webcl.DEVICE_TYPE_GPU); 68 | // device=devices[0]; 69 | // log('using device: '+device.getInfo(webcl.DEVICE_NAME)); 70 | 71 | // // create GPU context for this platform 72 | // var context=webcl.createContext({ 73 | // devices: device, 74 | // platform: platform 75 | // }); 76 | 77 | var context=null; 78 | try { 79 | context=webcl.createContext(webcl.DEVICE_TYPE_ALL); 80 | } 81 | catch(ex) { 82 | throw new Exception("Can't create CL context"); 83 | } 84 | 85 | var devices=context.getInfo(webcl.CONTEXT_DEVICES); 86 | log("Found "+devices.length+" devices"); 87 | var device=devices[0]; 88 | 89 | /* Build the program and create a kernel */ 90 | var source = [ 91 | "__kernel void user_event(__global float4 *v) {", 92 | " *v *= -1.0f;", 93 | "}" 94 | ].join("\n"); 95 | 96 | // Create and program from source 97 | try { 98 | program=context.createProgram(source); 99 | } catch(ex) { 100 | log("Couldn't create the program. "+ex); 101 | exit(1); 102 | } 103 | 104 | /* Build program */ 105 | try { 106 | program.build(devices); 107 | } catch(ex) { 108 | /* Find size of log and print to std output */ 109 | var info=program.getBuildInfo(devices[0], webcl.PROGRAM_BUILD_LOG); 110 | log(info); 111 | exit(1); 112 | } 113 | 114 | try { 115 | kernel = program.createKernel("user_event"); 116 | } catch(ex) { 117 | log("Couldn't create a kernel. "+ex); 118 | exit(1); 119 | } 120 | 121 | /* Create a write-only buffer to hold the output data */ 122 | try { 123 | data_buffer = context.createBuffer(webcl.MEM_READ_WRITE | webcl.MEM_COPY_HOST_PTR, 4*Float32Array.BYTES_PER_ELEMENT,data); 124 | } catch(ex) { 125 | log("Couldn't create a buffer. "+ex); 126 | exit(1); 127 | } 128 | 129 | /* Create kernel argument */ 130 | try { 131 | kernel.setArg(0, data_buffer); 132 | } catch(ex) { 133 | log("Couldn't set a kernel argument. "+ex); 134 | exit(1); 135 | }; 136 | 137 | /* Create a command queue */ 138 | try { 139 | queue = context.createCommandQueue(device, webcl.QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); 140 | } catch(ex) { 141 | log("Couldn't create an out of order command queue, using in-order queue. "+ex); 142 | queue = context.createCommandQueue(device); 143 | }; 144 | 145 | /* Configure events */ 146 | try { 147 | user_event = context.createUserEvent(); 148 | } catch(ex) { 149 | log("Couldn't create UserEvent. "+ex); 150 | exit(1); 151 | } 152 | 153 | /* Enqueue kernel */ 154 | try { 155 | kernel_event=new webcl.WebCLEvent(); 156 | queue.enqueueTask(kernel , [user_event], kernel_event); 157 | } catch(ex) { 158 | log("Couldn't enqueue the kernel. "+ex); 159 | exit(1); 160 | } 161 | 162 | /* Read the buffer */ 163 | try { 164 | read_event=new webcl.WebCLEvent(); 165 | queue.enqueueReadBuffer(data_buffer, false, 0, data.byteLength, data, [ kernel_event ], read_event); 166 | } catch(ex) { 167 | log("Couldn't read the buffer. "+ex); 168 | exit(1); 169 | } 170 | 171 | /* Set event handling routines */ 172 | try { 173 | read_event.setCallback(webcl.COMPLETE, read_complete, data); 174 | } catch(ex) { 175 | log("Couldn't set callback for read event. "+ex); 176 | exit(1); 177 | } 178 | 179 | log("Old data: "+data[0]+', '+data[1]+', '+data[2]+', '+data[3]); 180 | 181 | /* Set user event to success */ 182 | user_event.setStatus(webcl.SUCCESS); 183 | 184 | queue.finish(); 185 | log('queue finished'); 186 | } 187 | 188 | main(); 189 | --------------------------------------------------------------------------------