node-webcl
Version:
A WebCL implementation for desktops with NodeJS
153 lines (124 loc) • 5.07 kB
JavaScript
// Copyright (c) 2011-2012, Motorola Mobility, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Motorola Mobility, Inc. nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var nodejs = (typeof window === 'undefined');
if(nodejs) {
webcl = require('../webcl');
clu = require('../lib/clUtils');
util = require("util"),
fs = require("fs");
Image = require("node-image").Image;
log = console.log;
}
else
webcl = window.webcl;
//First check if the webcl extension is installed at all
if (webcl == undefined) {
alert("Unfortunately your system does not support webcl. " +
"Make sure that you have the webcl extension installed.");
process.exit(-1);
}
var file = __dirname+'/mike_scooter.jpg';
log('Loading image '+file);
var img=Image.load(file);
var image=img.convertTo32Bits();
log('Image '+file+': \n'+util.inspect(image));
image.size = image.height*image.pitch;
var outBuf=ImageFilter(image);
// PNG uses 32-bit images, JPG can only work on 24-bit images
if(!Image.save('out.png',outBuf, image.width, image.height, image.pitch, image.bpp, 0xFF0000, 0x00FF00, 0xFF))
log("Error saving image");
image.unload();
function ImageFilter(image) {
var out=new Uint8Array(image.size);
// create GPU context for this platform
var context=webcl.createContext(webcl.DEVICE_TYPE_GPU);
// find the device for this context
var devices = context.getInfo(webcl.CONTEXT_DEVICES);
device=devices[0];
// Report the device vendor and device name
//
var vendor_name = device.getInfo(webcl.DEVICE_VENDOR);
var device_name = device.getInfo(webcl.DEVICE_NAME);
log("Connecting to: "+vendor_name+" "+device_name);
kernelSourceCode = fs.readFileSync(__dirname+'/swapRB.cl','ascii');
//Create and program from source
program=context.createProgram(kernelSourceCode);
//Build program
try {
program.build(device);
} catch (err) {
log('Error building program: ' + err);
log(program.getBuildInfo(device, webcl.PROGRAM_BUILD_LOG));
process.exit(-1);
}
// create device buffers
try {
cmPinnedBufIn = context.createBuffer(webcl.MEM_READ_ONLY | webcl.MEM_ALLOC_HOST_PTR, image.size);
cmPinnedBufOut = context.createBuffer(webcl.MEM_WRITE_ONLY | webcl.MEM_ALLOC_HOST_PTR, image.size);
}
catch(err) {
console.log('error creating buffers');
process.exit(-1);
}
//Create kernel object
try {
kernel= program.createKernel("swapRB");
}
catch(err) {
console.log(program.getBuildInfo(device,webcl.PROGRAM_BUILD_LOG));
}
// Set the arguments to our compute kernel
var aints=new Int32Array(3);
aints.set([image.width, image.height, 0]);
try {
kernel.setArg(0, cmPinnedBufIn);
kernel.setArg(1, cmPinnedBufOut);
kernel.setArg(2, aints);
// kernel.setArg(3, aints.subarray(1));
}
catch(ex) {
log(ex);
process.exit(-1);
}
//Create command queue
queue=context.createCommandQueue(device, 0);
// Init ND-range
// Get the maximum work group size for executing the kernel on the device
var localWS=[ kernel.getWorkGroupInfo(device, webcl.KERNEL_WORK_GROUP_SIZE) ];
var globalWS = [ localWS[0] * clu.DivUp(image.size, localWS[0]) ];
log("Global work item size: " + globalWS);
log("Local work item size: " + localWS);
// Write our data set into the input array in device memory asynchronously
queue.enqueueWriteBuffer(cmPinnedBufIn, false, 0, image.size, image.buffer);
// Execute (enqueue) kernel
queue.enqueueNDRangeKernel(kernel, 1,
null,
globalWS,
localWS);
queue.enqueueReadBuffer(cmPinnedBufOut, false, 0, out.length, out);
queue.finish(); //Finish all the operations
return out;
}