Article ID: 000086479 Content Type: Troubleshooting Last Reviewed: 12/13/2018

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

Environment

  • Intel® Quartus® Prime Standard Edition
  • Intel® Quartus® Prime Pro Edition
  • Intel® FPGA SDK for OpenCL™ Pro Edition
  • BUILT IN - ARTICLE INTRO SECOND COMPONENT
    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.  

    Resolution

    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);

    Related Products

    This article applies to 1 products

    Intel® Programmable Devices