如何使用clGetPlatformInfo(和朋友)查询字符串长度?

时间:2011-09-20 04:07:32

标签: c malloc opencl

简短版:是否有正式/正确的方式来查询CL_PLATFORM_VENDOR等字符串的大小?

长版: 查看像clGetPlatformInfo这样的OpenCL函数我想知道为结果分配多少空间。该函数具有以下签名:

cl_int clGetPlatformInfo(cl_platform_id platform,
    cl_platform_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret)

文档说:

param_value_size

Specifies the size in bytes of memory pointed to by
param_value. This size in bytes must be greater
than or equal to size of return type specified in the
table below.

所有返回类型都列为char[]。我想知道要保留多少空间,所以我这样调用它,我为0传递param_value_sizeNULL传递param_value,希望获得正确的大小返回在param_value_size_ret

  size_t size = 0;
  l_success = clGetPlatformInfo(platform_id,
                                CL_PLATFORM_VENDOR, 0, NULL, &size);

  if( l_success != CL_SUCCESS)
  {
    printf("Failed getting vendor name size.\n");
    return -1;
  }
  printf("l_success = %d, size = %d\n", l_success, size);
  char* vendor = NULL;
  vendor = malloc(size);
  if( vendor )
  {
    l_success = clGetPlatformInfo(platform_id,
                                  CL_PLATFORM_VENDOR, size, vendor, &size);
    if( l_success != CL_SUCCESS )
    {
      printf("Failed getting vendor name.\n");
      return -1;
    }
    printf("Vendor name is '%s', length is %d\n", vendor, strlen(vendor));
  } else {
    printf("malloc failed.\n");
    return -1;
  }

它的行为与我希望的一样,它返回字符串大小为19,“NVIDIA公司”(大小包括空终止符)和strlen返回18.这是查询参数的“正确”方式我或者我的供应商实施幸运吗?有人看到这个成语在一些供应商上失败了吗?

编辑:绊倒我的是这个,“这个大小以字节为单位必须大于或等于返回类型的大小”,这似乎就在我通过{{1}时}和0调用失败,因为它不大于或等于返回的的大小。我不确定他们为什么说“返回类型”。

2 个答案:

答案 0 :(得分:4)

是的,正确的方式。

same doc you've mentioned

  

如果param_value为NULL,则忽略它。

以下:

  

如果函数执行成功,则返回CL_SUCCESS。否则,它返回以下内容:

     

...

     

CL_INVALID_VALUE如果param_name不是受支持的值之一,或param_value_size指定的字节数小于返回类型的大小且param_value不是NULL值。

因此,即使未明确说明,如果param_value为NULL,也不应生成错误,因此代码应该正常工作。

以下是来自Khronos OpenCL C++ bindingsspecs)的一段代码。他们也这样做,我认为它算作“官方”:

// Specialized GetInfoHelper for STRING_CLASS params
template <typename Func>
struct GetInfoHelper<Func, STRING_CLASS>
{
    static cl_int get(Func f, cl_uint name, STRING_CLASS* param)
    {
        ::size_t required;
        cl_int err = f(name, 0, NULL, &required);
        if (err != CL_SUCCESS) {
            return err;
        }

        char* value = (char*) alloca(required);
        err = f(name, required, value, NULL);
        if (err != CL_SUCCESS) {
            return err;
        }

        *param = value;
        return CL_SUCCESS;
    }
};

答案 1 :(得分:1)

在示例中请注意,在请求值时,第四个参数必须为NULL。否则,某些平台会回复CL_INVALID_VALUE作为返回。

由于前期查询和malloc在某种程度上超过顶部,我使用一个大的char缓冲区作为解决方法。

char vendor[10240];
l_success = clGetPlatformInfo( platform_id,
                     CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL);