The code that you wrote there should work, indeed.
I have inserted it into an MCVE here:
package org.jocl.test;
import static org.jocl.CL.CL_CONTEXT_PLATFORM;
import static org.jocl.CL.CL_DEVICE_NAME;
import static org.jocl.CL.CL_DEVICE_TYPE_ALL;
import static org.jocl.CL.CL_DEVICE_VERSION;
import static org.jocl.CL.CL_MAP_WRITE;
import static org.jocl.CL.CL_MEM_READ_WRITE;
import static org.jocl.CL.clCreateCommandQueueWithProperties;
import static org.jocl.CL.clCreateContext;
import static org.jocl.CL.clEnqueueSVMMap;
import static org.jocl.CL.clFinish;
import static org.jocl.CL.clGetDeviceIDs;
import static org.jocl.CL.clGetDeviceInfo;
import static org.jocl.CL.clGetPlatformIDs;
import static org.jocl.CL.clSVMAlloc;
import java.nio.ByteBuffer;
import org.jocl.CL;
import org.jocl.Pointer;
import org.jocl.cl_command_queue;
import org.jocl.cl_context;
import org.jocl.cl_context_properties;
import org.jocl.cl_device_id;
import org.jocl.cl_platform_id;
import org.jocl.cl_queue_properties;
public class JOCLSVMAllocTest
{
private static cl_context context;
private static cl_device_id device;
private static cl_command_queue commandQueue;
public static void main(String[] args)
{
initCL();
long size = 1024;
Pointer svm = clSVMAlloc(context, CL_MEM_READ_WRITE, size, 0);
clEnqueueSVMMap(
commandQueue, true, CL_MAP_WRITE, svm, size, 0, null, null);
ByteBuffer bb = svm.getByteBuffer(0, size);
byte[] bytes = new byte[(int)size];
bb.put(bytes);
clFinish(commandQueue);
System.out.println("Done");
}
/**
* Default OpenCL initialization of the devices, context,
* command queue, program and kernel.
*/
private static void initCL()
{
// The platform and device type that will be used
final int platformIndex = 0;
final long deviceType = CL_DEVICE_TYPE_ALL;
// Enable exceptions and subsequently omit error checks in this sample
CL.setExceptionsEnabled(true);
// Obtain the number of platforms
int numPlatformsArray[] = new int[1];
clGetPlatformIDs(0, null, numPlatformsArray);
int numPlatforms = numPlatformsArray[0];
// Obtain a platform ID
cl_platform_id platforms[] = new cl_platform_id[numPlatforms];
clGetPlatformIDs(platforms.length, platforms, null);
cl_platform_id platform = platforms[platformIndex];
// Initialize the context properties
cl_context_properties contextProperties = new cl_context_properties();
contextProperties.addProperty(CL_CONTEXT_PLATFORM, platform);
// Obtain the number of devices for the platform
int numDevicesArray[] = new int[1];
clGetDeviceIDs(platform, deviceType, 0, null, numDevicesArray);
int numDevices = numDevicesArray[0];
// Obtain the all device IDs
cl_device_id allDevices[] = new cl_device_id[numDevices];
clGetDeviceIDs(platform, deviceType, numDevices, allDevices, null);
// Find the first device that supports OpenCL 2.0
for (cl_device_id currentDevice : allDevices)
{
String deviceName = getString(currentDevice, CL_DEVICE_NAME);
float version = getOpenCLVersion(currentDevice);
if (version >= 2.0)
{
System.out.println("Using device "+
deviceName+", version "+version);
device = currentDevice;
break;
}
else
{
System.out.println("Skipping device "+
deviceName+", version "+version);
}
}
if (device == null)
{
System.out.println("No OpenCL 2.0 capable device found");
System.exit(1);
}
// Create a context
context = clCreateContext(
contextProperties, 1, new cl_device_id[]{ device },
null, null, null);
// Create the command queue
cl_queue_properties properties = new cl_queue_properties();
commandQueue = clCreateCommandQueueWithProperties(
context, device, properties, null);
}
/**
* Returns the OpenCL version of the given device, as a float
* value
*
* @param device The device
* @return The OpenCL version
*/
private static float getOpenCLVersion(cl_device_id device)
{
String deviceVersion = getString(device, CL_DEVICE_VERSION);
String versionString = deviceVersion.substring(7, 10);
float version = Float.parseFloat(versionString);
return version;
}
/**
* Returns the value of the device info parameter with the given name
*
* @param device The device
* @param paramName The parameter name
* @return The value
*/
private static String getString(cl_device_id device, int paramName)
{
// Obtain the length of the string that will be queried
long size[] = new long[1];
clGetDeviceInfo(device, paramName, 0, null, size);
// Create a buffer of the appropriate size and fill it with the info
byte buffer[] = new byte[(int)size[0]];
clGetDeviceInfo(device, paramName, buffer.length, Pointer.to(buffer), null);
// Create a string from the buffer (excluding the trailing \0 byte)
return new String(buffer, 0, buffer.length-1);
}
}
(The initCL
method is basically taken from the JOCLSample_2_0_SVM.java
file at http://www.jocl.org/samples/samples.html - I still have to move the samples from this site into a dedicated repo, so that people can more quickly and easily get started here…)
Does this work for you?
Maybe you are accidentally re-assigning the bb
with a new byte buffer in the lines that you didn’t show. But even then, I cannot imagine what should cause an UnsupportedOperationException
here. Can you provide the stack trace of that?