LWJGL 3 - OpenCL Argument Problems

Started by jammin123, January 21, 2015, 16:52:53

Previous topic - Next topic

jammin123

So I am trying to make a basic OpenCL script and I am getting stuck with using memory I have allocated with clCreateBuffer.
I have two arguments for the OpenCL script, number one is a float array which is the input, the second is a float array for the output.

It is currently erroring when setting the arguments to the inputMem and outputMem pointer.

FloatBuffer dataBuf = BufferUtils.createFloatBuffer(length);
		float[] dataArray = new float[length];
		for (int i = 0;i < length;i++) {
			dataArray[i] = i; // Initialise our memory with some values.
		}
		dataBuf.put(dataArray);
		dataBuf.rewind();
		
		long inputMem = clCreateBuffer(clContext, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, dataBuf, errorBuf); // input memory with the initialised floatbuffer
		checkCLError(errorBuf);
		
		long outputMem = clCreateBuffer(clContext, CL_MEM_READ_ONLY, size, errorBuf); // create the output memory of the same array size.
		checkCLError(errorBuf);

		// Set the kernel arguments.
		
		// This is the current problem, wont work error code -52
		clSetKernelArg(kernel, 0, inputMem);
		clSetKernelArg(kernel, 1, outputMem);


Is there any way to fix this problem?

Regards,
    Jammin123.

spasi

The buffer usage flags are wrong. The input buffer should have CL_MEM_READ_ONLY and the output buffer CL_MEM_WRITE_ONLY.

jammin123

So I have changed that and thank you, but I am still having issues with the clSetKernelArgs. It crashes the JVM as I think it is trying to allocate a stupid size of memory because the arguments for the function are kernel_id, arg_index, arg_size. I need it to accept the memory I create with clCreateBuffer but the API doesn't seem to support it.

spasi

Oh, ouch, indeed. You want to use clSetKernelArg1p(kernel, i, memobj).

I think this deserves some explanation. The native function has the signature:

cl_int clSetKernelArg (cl_kernel kernel, cl_uint arg_index, size_t arg_size, const void *arg_value)

which as you can see is not really convenient to use in Java. In LWJGL, it maps to:

clSetKernelArg(long kernel, int arg_index, long arg_size, ByteBuffer arg_value)

and overloaded versions for each NIO buffer type. There are also several other overloads for primitive values, from 1 value up to 4. For example, there are clSetKernelArg1i (1 int), clSetKernelArg4f (4 floats) and so on. The clSetKernalArg1p overloads means "1 pointer value" (which can be either 32bits or 64bits, but mapped to long in Java).

The version you were using is a special case for initializing the size of __local arguments.

jammin123

Ahh that makes more sense. I didn't really understand what all the overrides meant like 4f or 2i and how they worked, but the use of the pointer makes sense. Thank you very much, I will have to try it later on.

proton2

Hello!
I want to call
clSetKernelArg(ckScanExclusiveLocal1, 2, 2 * WORKGROUP_SIZE * sizeof(uint), NULL);
in cl method it was local argument: __local uint *l_Data,

full code:
ciErrNum  = clSetKernelArg(ckScanExclusiveLocal1, 0, sizeof(cl_mem), (void *)&d_Dst);
ciErrNum |= clSetKernelArg(ckScanExclusiveLocal1, 1, sizeof(cl_mem), (void *)&d_Src);
ciErrNum |= clSetKernelArg(ckScanExclusiveLocal1, 2, 2 * WORKGROUP_SIZE * sizeof(uint), NULL);
ciErrNum |= clSetKernelArg(ckScanExclusiveLocal1, 3, sizeof(uint), (void *)&size);

void scanExclusiveLocal1(
    __global uint4 *d_Dst,
    __global uint4 *d_Src,
    __local uint *l_Data,
    uint size
){

how I can do it in LWJGL?

When I call it
CL10.clSetKernelArg2i(ckScanExclusiveLocal1, 2, 2 * WORKGROUP_SIZE * 4, 0);
I get -52 error (CL_INVALID_KERNEL_ARGS error)

please, said me analog of clSetKernelArg(ckScanExclusiveLocal1, 2, 2 * WORKGROUP_SIZE * sizeof(uint), NULL);
local variable call in lwjgl

spasi

Hey proton2, use the clSetKernelArg(long kernel, int arg_index, long arg_size) method.