Intel Software: Intel FPGA SDK for OpenCL, Quartus Prime Pro, Quartus Prime Standard

Type: Answers, KDB Area

Area: Embedded, OpenCL



Why do I get the error “CL_INVALID_ARG_SIZE” when using type long long as an OpenCL™ kernel argument in the host code?

Description

If a signed or unsigned long long type is used in the OpenCL™ host code function clSetKernelArg() as shown below

  unsigned long long data = 1;

  clSetKernelArg(kernel, 0, sizeof(unsigned long long), (void*)&data);

then an error like the following may occur when the host code is compiled using the Intel® SDK for OpenCL™.

  Context callback: Argument size is the wrong size

  ERROR: CL_INVALID_ARG_SIZE 

  Location: host/src/main.cpp:91

  Failed to set kernel arg 0

This error did not appear for this case in versions earlier than 18.1 of the Intel® SDK for OpenCL™. The error now appears because the size of an unsigned long long type was changed from 8 to 16 in the underlying kernel compiler, but the host call sizeof(unsigned long long) still returns 8.

Types signed / unsigned long long do not have a defined size in C99 or OpenCL™ version 1.X so it's allowed for the host and device to use different sizes for the type.  As such, one should never use it as the type of an argument to the kernel.  It's not guaranteed to be portable between compilers, devices, or even compiler versions.  In the OpenCL™ 2.0 specification, a long long type is defined as 128 bits, but the C99 ambiguity remains. The OpenCL™ specification does not add a cl_* compatibility type, so it is not possible to use a long long type as a scalar argument safely.  

Workaround/Fix

The recommended workaround for this problem is to use an OpenCL™ defined type such as cl_ulong/unsigned long in your host/device code.  

 

Alternately, do not use the sizeof() call and force the size of the long long argument to be 16 bytes as shown below.

    clSetKernelArg(kernel, 0, 16, (void*)&data);