Cl_device_platform?


#1

How to get CL_DEVICE_PLATFORM using clGetDeviceInfo?

I can get ints using this code

private int getDeviceInfoInt(int param) {
        byte[] buf = new byte[4];
        long[] result = new long[1];

        clGetDeviceInfo(deviceId, param, buf.length, Pointer.to(buf), result);
        int resultValue = -1;
        try {
            resultValue = new DataInputStream(new ByteArrayInputStream(buf)).readInt();
        } catch (IOException ex) {
            Logger.getLogger(Device.class.getName()).log(Level.SEVERE, null, ex);
        }
        return resultValue;
    }

But getting platform is problematic. cl_platform_id is a class, I don’t know how to deal with this. It has no constructors with parameters, has no factory to create it. All constructors in the superclass are package visible.

Do I have to hack it using subclassing?

Thanks.


#2

((( The class is final


#3

Hello

It should be possible to obtain the platform with

cl_platform_id platform = new cl_platform_id();
clGetDeviceInfo(deviceId, CL_DEVICE_PLATFORM, Sizeof.cl_platform_id, Pointer.to(platform), null);

If it does not work, I’ll have to check this again this evening.

Creating an instance of a cl_platform_id from an arbitrary ‘int’ value is not supported, and I’m not sure if it should be…

Note that with the latest NVIDIA implementation, some of these queries do not work properly. For example, it is not possible to query the command queue from an event … Hopefully this will all be fixed in their OpenCL 1.1 release…

bye
Marco


#4

Oh, by the way: This DataInputStream/ByteArrayInputStream thing should also not be necessary: You can simply do a

int buf[] = new int[1];
clGetDeviceInfo(deviceId, param, Sizeof.cl_int, Pointer.to(buf), result);
return buf[1];

EDIT: And it is possible to pass ‘null’ as the last argument (‘param_value_size_ret’, or ‘result’ in your code), for the case that you do not want to check the result explicitly, e.g. if you have enabled exceptions.


#5

Thank you for your reply. Everything works and your suggestions made my code much cleaner.

I have one more question, tell me if I have to open a new topic.

Another developer in our project works on the same code as I do, but on .NET. He writes the code on the top low-level binding for OpenCL for .NET. He had to overcome some issues with passing pointers to the native code. Before doing that he had to “pin” the object, so it is not moved my garbage collector to another location in memory. It seems like in Java it is not an issue. Is this correct?


#6

I’m not familiar with C# or the OpenCL .NET bindings. But I assume that this “pinning” refers to C#-Objects which are passed to OpenCL for copying them into a buffer. For example, roughly like


int someArray[] = new int[100];
[b]pin(someArray);[/b]
clEnqueueWriteBuffer (queue, mem, true, 0,n, [b]someArray[/b], 0,null,null);
[b]unpin(someArray);[/b]

to avoid the ‘someArray’ being moved or GC’ed while OpenCL is copying it?

For blocking read- or write-operations, this is not necessary in JOCL. The array will be pinned internally on native side, if this is possible. In most other Java bindings for native libraries, the data may only be passed to the native side using direct buffers (see ByteBuffer#allocateDirect), but in JOCL, it is also possible to simply use the arrays. Again, this only refers to blocking operations.

For non-blocking operations, some difficulties may arise, because the data may be GC’ed before it can be pinned. At the moment, the respective functions will throw an Exception when there is an attempt to use something else than a direct buffer for a non-blocking operation. In most cases, this should not be a problem. However, I’m already working to also support non-blocking operations on non-direct data - I think the new functions that have been introduced with OpenCL 1.1 should make this possible, although I have not yet done specific tests.