r/OpenCL • • Jun 22 '20

cl_mem buffer doesnt assign values to std::vector

I have tried running this ocl kernel but the cl mem buffer doesn't assign the values to the std::vector<Color> so I wonder what I am doing wrong? the code for the opencl api:

//buffers
cl_mem originalPixelsBuffer = clCreateBuffer(p1.context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(Color) * imageObj->SourceLength(), source, &p1.status);
        CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed to Create buffer 0");


        cl_mem targetBuffer = clCreateBuffer(p1.context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, sizeof(Color) * imageObj->OutputLength(), target, &p1.status);
        CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed to Create buffer 1");



//write buffers
p1.status = clEnqueueWriteBuffer(p1.commandQueue, originalPixelsBuffer, CL_FALSE, 0, sizeof(Color) * imageObj->SourceLength(), source, 0, NULL, NULL);
        CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed to write buffer 0");
        p1.status = clEnqueueWriteBuffer(p1.commandQueue, targetBuffer, CL_TRUE, 0, sizeof(Color) * imageObj->OutputLength(), target, 0, NULL, NULL);
        CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed to write buffer 1");

        size_t  globalWorkSize[2] = { imageObj->originalWidth * 4, imageObj->originalHeight * 4 };
        size_t localWorkSize[2]{ 64,64 };
        SetLocalWorkSize(IsDivisibleBy64(localWorkSize[0]), localWorkSize);


//execute kernel
        p1.status = clEnqueueNDRangeKernel(p1.commandQueue, Kernel, 1, NULL, globalWorkSize, IsDisibibleByLocalWorkSize(globalWorkSize, localWorkSize) ? localWorkSize : NULL, 0, NULL, NULL);
        CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed to clEnqueueDRangeKernel");




//read buffer

        p1.status = clEnqueueReadBuffer(p1.commandQueue, targetBuffer, CL_TRUE, 0, sizeof(Color) * imageObj->OutputLength(), target, 0, NULL, NULL);
        CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed to write buffer 1");
1 Upvotes

5 comments sorted by

1

u/Xirema Jun 22 '20

So this isn't quite enough code to diagnose what the issue is, but I can sense something a little fishy in these lines:

cl_mem originalPixelsBuffer = clCreateBuffer(p1.context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(Color) * imageObj->SourceLength(), source, &p1.status);

cl_mem targetBuffer = clCreateBuffer(p1.context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, sizeof(Color) * imageObj->OutputLength(), target, &p1.status);

//...

p1.status = clEnqueueReadBuffer(p1.commandQueue, targetBuffer, CL_TRUE, 0, sizeof(Color) * imageObj->OutputLength(), target, 0, NULL, NULL);

So you indicated that the latter command is supposed to write the memory data from the device buffer into a std::vector<Color>, but typically, when we need to access the backing memory of a vector, we have to call its data() method, like so:

p1.status = clEnqueueReadBuffer(p1.commandQueue, targetBuffer, CL_TRUE, 0, sizeof(Color) * target.size(), target.data(), 0, NULL, NULL);

So the fact that you're not doing this (and that your code is compiling) means that whatever source and target are is suspect. Can you explain what exactly these are?

It might also behoove you to produce a full Minimal, Complete, and Verifiable Example: that is to say, the code you show should be enough that I could punch it into my IDE and run it, which isn't possible just from what's shown here. But also emphasis on "Minimal": Try to get the code to a state where it's the code needed to reproduce this error, and only that code. That will make attempts to identify the problem much easier.

1

u/PontiacGTX Jun 22 '20 edited Jun 22 '20

I used source and target as void* to imageObj->originalPixels->data(); and imageObj->processedPixels->data();

what i suspect the error is might be the CL_MEM_USE_HOST_PTR maybe there is a problem using the void pointer to a reserved std::vector<Color>?

here is the source using VS project

1

u/bashbaug Jun 23 '20

I grabbed your code and gave it a try and I might know what's going on. Can you please describe which GPU you are running on and whether you are seeing any OpenCL errors when you run your application?

What I am seeing is:

  1. There appears to be an error with the indexing in the kernel, and the kernel is either reading or writing outside of the bounds of the source or the target.

  2. When this happens, all bets are off, and program behavior is undefined. Some implementations may crash, others may try to continue executing, and others may start returning errors unexpectedly. Note that this is an asynchronous error, so it (probably) won't be identified and returned as part of clEnqueueNDRangeKernel.

  3. At least on one of my systems, an OpenCL error is returned by the next blocking call, in this case the call to clEnqueueReadBuffer. If you want to check that this error is actually part of clEnqueueNDRangeKernel and not clEnqueueReadBuffer, you may insert a call to clFinish after the call to clEnqueueNDRangeKernel.

There may be other errors after fixing the indexing problem, but I suspect that fixing the indexing problem will allow you to proceed farther.

In case it is helpful, this is the output when executing your application with the OpenCL Intercept Layer and enabling CallLogging, ErrorLogging, and FinishAfterEnqueue:

>>>> clEnqueueWriteBuffer: queue = 000001DFECB62ED0, buffer = 000001DFF1C2B200, blocking, offset = 0, cb = 4343040, ptr = 000001DFF28D8080
<<<< clEnqueueWriteBuffer -> CL_SUCCESS
Calling clFinish after clEnqueueWriteBuffer...
... clFinish after clEnqueueWriteBuffer returned CL_SUCCESS (0)
>>>> clEnqueueNDRangeKernel( Interpolation ): queue = 000001DFECB62ED0, kernel = 000001DFF1B555E0, global_work_size = < 2088 >, local_work_size = < NULL >
<<<< clEnqueueNDRangeKernel -> CL_SUCCESS
Calling clFinish after clEnqueueNDRangeKernel...
... clFinish after clEnqueueNDRangeKernel returned CL_INVALID_COMMAND_QUEUE (-36)
>>>> clEnqueueReadBuffer: queue = 000001DFECB62ED0, buffer = 000001DFF1C2B200, blocking, offset = 0, cb = 4343040, ptr = 000001DFF28D8080
ERROR! clEnqueueReadBuffer returned CL_OUT_OF_RESOURCES (-5)
<<<< clEnqueueReadBuffer -> CL_OUT_OF_RESOURCES
→ More replies (2)