/* * Copyright (c) 2002-2010 LWJGL Project * 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 'LWJGL' 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 THE COPYRIGHT OWNER OR * CONTRIBUTORS 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. */ package org.lwjgl.test.opencl; import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLException; import org.lwjgl.LWJGLUtil; import org.lwjgl.PointerBuffer; import org.lwjgl.opencl.*; import org.lwjgl.opencl.api.CLBufferRegion; import java.nio.ByteBuffer; import java.util.List; import static org.lwjgl.opencl.CL10.*; import static org.lwjgl.opencl.CL11.*; /** Basic OpenCL test. */ public class HelloOpenCL { public HelloOpenCL() { } protected static void execute() { try { CL.create(); final List<CLPlatform> platforms = CLPlatform.getPlatforms(); if ( platforms == null ) throw new RuntimeException("No OpenCL platforms found."); for ( CLPlatform platform : platforms ) { System.out.println("\n-------------------------"); System.out.println("NEW PLATFORM: " + platform.getPointer()); System.out.println(CLCapabilities.getPlatformCapabilities(platform)); System.out.println("-------------------------"); printPlatformInfo(platform, "CL_PLATFORM_PROFILE", CL_PLATFORM_PROFILE); printPlatformInfo(platform, "CL_PLATFORM_VERSION", CL_PLATFORM_VERSION); printPlatformInfo(platform, "CL_PLATFORM_NAME", CL_PLATFORM_NAME); printPlatformInfo(platform, "CL_PLATFORM_VENDOR", CL_PLATFORM_VENDOR); printPlatformInfo(platform, "CL_PLATFORM_EXTENSIONS", CL_PLATFORM_EXTENSIONS); System.out.println(""); final PointerBuffer ctxProps = BufferUtils.createPointerBuffer(3); ctxProps.put(CL_CONTEXT_PLATFORM).put(platform.getPointer()).put(0).flip(); final List<CLDevice> devices = platform.getDevices(CL_DEVICE_TYPE_ALL); for ( CLDevice device : devices ) { final CLDeviceCapabilities caps = CLCapabilities.getDeviceCapabilities(device); System.out.println("\n\tNEW DEVICE: " + device.getPointer()); System.out.println(caps); System.out.println("\t-------------------------"); System.out.println("\tCL_DEVICE_TYPE = " + device.getInfoLong(CL_DEVICE_TYPE)); System.out.println("\tCL_DEVICE_VENDOR_ID = " + device.getInfoInt(CL_DEVICE_VENDOR_ID)); System.out.println("\tCL_DEVICE_MAX_COMPUTE_UNITS = " + device.getInfoInt(CL_DEVICE_MAX_COMPUTE_UNITS)); System.out.println("\tCL_DEVICE_MAX_WORK_ITEM_DIMENSIONS = " + device.getInfoInt(CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS)); //CL10.clGetDeviceInfo(device, CL10.CL_DEVICE_MAX_WORK_ITEM_SIZES, info, size_ret); //System.out.println("\tCL_DEVICE_MAX_WORK_ITEM_SIZES = " + info.getInt(0)); System.out.println("\tCL_DEVICE_MAX_WORK_GROUP_SIZE = " + device.getInfoSize(CL_DEVICE_MAX_WORK_GROUP_SIZE)); System.out.println("\tCL_DEVICE_MAX_CLOCK_FREQUENCY = " + device.getInfoInt(CL_DEVICE_MAX_CLOCK_FREQUENCY)); System.out.println("\tCL_DEVICE_ADDRESS_BITS = " + device.getInfoInt(CL_DEVICE_ADDRESS_BITS)); System.out.println("\tCL_DEVICE_AVAILABLE = " + device.getInfoBoolean(CL_DEVICE_AVAILABLE)); System.out.println("\tCL_DEVICE_COMPILER_AVAILABLE = " + device.getInfoBoolean(CL_DEVICE_COMPILER_AVAILABLE)); printDeviceInfo(device, "CL_DEVICE_NAME", CL_DEVICE_NAME); printDeviceInfo(device, "CL_DEVICE_VENDOR", CL_DEVICE_VENDOR); printDeviceInfo(device, "CL_DRIVER_VERSION", CL_DRIVER_VERSION); printDeviceInfo(device, "CL_DEVICE_PROFILE", CL_DEVICE_PROFILE); printDeviceInfo(device, "CL_DEVICE_VERSION", CL_DEVICE_VERSION); printDeviceInfo(device, "CL_DEVICE_EXTENSIONS", CL_DEVICE_EXTENSIONS); if ( caps.OpenCL11 ) printDeviceInfo(device, "CL_DEVICE_OPENCL_C_VERSION", CL_DEVICE_OPENCL_C_VERSION); CLContext context = clCreateContext(ctxProps, device, new CLContextCallback() { protected void handleMessage(final String errinfo, final ByteBuffer private_info) { System.out.println("IN CLContextCallback :: " + errinfo); } }, null); CLMem buffer = clCreateBuffer(context, CL_MEM_READ_ONLY, 128, null); if ( caps.OpenCL11 ) { clSetMemObjectDestructorCallback(buffer, new CLMemObjectDestructorCallback() { protected void handleMessage(final long memobj) { System.out.println("FIRST Buffer destructed: " + memobj); } }); clSetMemObjectDestructorCallback(buffer, new CLMemObjectDestructorCallback() { protected void handleMessage(final long memobj) { System.out.println("SECOND Buffer destructed: " + memobj); } }); } if ( caps.OpenCL11 ) { CLMem subbuffer = buffer.createSubBuffer(CL_MEM_READ_ONLY, CL_BUFFER_CREATE_TYPE_REGION, new CLBufferRegion(0, 64), null); clSetMemObjectDestructorCallback(subbuffer, new CLMemObjectDestructorCallback() { protected void handleMessage(final long memobj) { System.out.println("Sub Buffer destructed: " + memobj); } }); } clRetainMemObject(buffer); if ( LWJGLUtil.getPlatform() != LWJGLUtil.PLATFORM_MACOSX ) { // TODO: Native kernels crash on MacOSX, disable this until we can debug properly. final long exec_caps = device.getInfoLong(CL_DEVICE_EXECUTION_CAPABILITIES); if ( (exec_caps & CL_EXEC_NATIVE_KERNEL) == CL_EXEC_NATIVE_KERNEL ) { System.out.println("-TRYING TO EXEC NATIVE KERNEL-"); final CLCommandQueue queue = clCreateCommandQueue(context, device, 0, null); final PointerBuffer ev = BufferUtils.createPointerBuffer(1); clEnqueueNativeKernel(queue, new CLNativeKernel() { protected void execute(final ByteBuffer[] memobjs) { System.out.println("\tmemobjs.length = " + memobjs.length); for ( int k = 0; k < memobjs.length; k++ ) { System.out.println("\tmemobjs[" + k + "].remaining() = " + memobjs[k].remaining()); for ( int l = memobjs[k].position(); l < memobjs[k].limit(); l++ ) { memobjs[k].put(l, (byte)l); } } System.out.println("\tNative kernel done."); } }, new CLMem[] { buffer }, new long[] { 128 }, null, ev); final CLEvent e = queue.getCLEvent(ev.get(0)); clSetEventCallback(e, CL_COMPLETE, new CLEventCallback() { protected void handleMessage(final CLEvent event, final int event_command_exec_status) { System.out.println("\t\tEvent callback status: " + getEventStatusName(event_command_exec_status)); } }); int status = e.getInfoInt(CL_EVENT_COMMAND_EXECUTION_STATUS); System.out.println("NATIVE KERNEL STATUS: " + getEventStatusName(status)); clFlush(queue); do { int newStatus = e.getInfoInt(CL_EVENT_COMMAND_EXECUTION_STATUS); if ( newStatus != status ) { status = newStatus; System.out.println("NATIVE KERNEL STATUS: " + getEventStatusName(status)); } } while ( status != CL_SUCCESS ); // Busy-spin until we're done clReleaseEvent(e); } } clReleaseMemObject(buffer); clReleaseContext(context); } } } catch (LWJGLException le) { die("Init", le.getMessage()); } CL.destroy(); } private static void printPlatformInfo(final CLPlatform platform, final String param_name, final int param) { System.out.println("\t" + param_name + " = " + platform.getInfoString(param)); } private static void printDeviceInfo(final CLDevice device, final String param_name, final int param) { System.out.println("\t" + param_name + " = " + device.getInfoString(param)); } private static String getEventStatusName(final int status) { switch ( status ) { case CL_QUEUED: return "CL_QUEUED"; case CL_SUBMITTED: return "CL_SUBMITTED"; case CL_RUNNING: return "CL_RUNNING"; default: return "CL_COMPLETE"; } } private static void die(String kind, String description) { System.out.println(kind + " error " + description + " occured"); } /** * main entry point * * @param args String array containing arguments */ public static void main(String[] args) { new HelloOpenCL().execute(); } }