I have been having trouble understanding when to use the OpenCL API data types like cl_float, cl_uchar, etc., which can be found here:
http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/scalarDataTypes.html
The examples I have seen that involve copying a buffer to the device look like this:
float data[DATA_SIZE]; // original data set given to device
//Create the input and output arrays in device memory for our calculation
input = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float) * count, NULL,
// Write our data set into the input array in device memory
err = clEnqueueWriteBuffer(commands, input, CL_TRUE, 0, sizeof(float) * count, data, 0, NULL, NULL);
if (err != CL_SUCCESS)
{
printf("Error: Failed to write to source array!\n");
exit(1);
}
This code was taken directly from an Apple code sample available here: https://developer.apple.com/library/mac/samplecode/OpenCL_Hello_World_Example/Listings/ReadMe_txt.html
You will notice in the above code that an array of floats is copied to the device. Why does this not need to be an array of cl_floats? The memory is directly copied, right? What happens if your host float and the device float are not the same size?
Could you explain why it is not necessary to use cl_float? If it is not necessary in this case, then when should the opencl types be used?
The whole point of these
cl_
-prefixed types are they are defined as the same size on the host and device by the OpenCL runtime. In practice, for simple types such as afloat
you can often get away without usingcl_float
(as afloat
andcl_float
are often the same size) but it is always recommended to use thecl_
-prefixed types for maximum portability. As pointed out in the comments (thanks @DarkZeros), a good example of a type that may cause problems is anint
, as this can vary in size depending on the host platform. Usingcl_int
means that this is not a problem.As pointed out in the documentation that you have linked to, OpenCL C is based on C99 with specific extensions and restrictions (I've heard it described as a "supersubset" :-). As well as ensuring that the sizes of your types match up, you are also limiting yourself to using types that are defined in OpenCL C (
size_t
doesn't have a matchingcl_size_t
, for example).In terms of your example, the buffers are the same size as the reads and writes that are being carried out but the potential problem is that the device may have a differently sized
float
type, so your kernels may potentially be working with garbage values. I would change all instances offloat
tocl_float
to guard against this possibility.