简短版:是否有正式/正确的方式来查询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_size
而NULL
传递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
调用失败,因为它不大于或等于返回的值的大小。我不确定他们为什么说“返回类型”。
答案 0 :(得分:4)
是的,是正确的方式。
如果
param_value
为NULL,则忽略它。
以下:
如果函数执行成功,则返回
CL_SUCCESS
。否则,它返回以下内容:...
CL_INVALID_VALUE
如果param_name
不是受支持的值之一,或param_value_size
指定的字节数小于返回类型的大小且param_value
不是NULL值。
因此,即使未明确说明,如果param_value
为NULL,也不应生成错误,因此代码应该正常工作。
以下是来自Khronos OpenCL C++ bindings(specs)的一段代码。他们也这样做,我认为它算作“官方”:
// 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);