何时使用 OpenCL API 标量数据类型?

Posted

技术标签:

【中文标题】何时使用 OpenCL API 标量数据类型?【英文标题】:When to use the OpenCL API scalar data types? 【发布时间】:2014-08-20 06:53:39 【问题描述】:

我一直无法理解何时使用 cl_float、cl_uchar 等 OpenCL API 数据类型,可在此处找到:

http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/scalarDataTypes.html

我见过的涉及将缓冲区复制到设备的示例如下所示:

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

此代码直接取自此处提供的 Apple 代码示例: https://developer.apple.com/library/mac/samplecode/OpenCL_Hello_World_Example/Listings/ReadMe_txt.html

您会注意到在上面的代码中,一个浮点数组被复制到了设备中。为什么这不需要是一个 cl_floats 数组?内存是直接复制的吧?如果您的主机浮动和设备浮动大小不同会怎样?

您能解释一下为什么不需要使用 cl_float 吗?如果在这种情况下不需要,那么什么时候应该使用 opencl 类型?

【问题讨论】:

【参考方案1】:

这些以cl_ 为前缀的类型的全部意义在于它们在 OpenCL 运行时在主机和设备上定义为相同的大小。实际上,对于诸如float 之类的简单类型,您通常可以不使用cl_float(因为floatcl_float 通常大小相同),但始终建议使用cl_-前缀类型以获得最大的可移植性。正如the comments 中所指出的(感谢@DarkZeros),int 是可能导致问题的类型的一个很好的例子,因为它的大小可能因主机平台而异。使用cl_int 表示这不是问题。

正如您链接到的文档中所指出的,OpenCL C 基于 C99,具有特定的扩展和限制(我听说它被描述为“超级子集”:-)。除了确保类型的大小匹配之外,您还限制自己使用 OpenCL C 中定义的类型(例如,size_t 没有匹配的 cl_size_t)。

就您的示例而言,缓冲区与正在执行的读取和写入的大小相同,但潜在的问题是设备可能具有不同大小的 float 类型,因此您的内核可能正在工作带有垃圾值。我会将float 的所有实例更改为cl_float 以防止这种可能性。

【讨论】:

所以为了安全起见,每次我们想从程序中的其他地方发送一个 host_type 数组到设备时,我们需要将它复制并转换为一个新的 cl_type 数组?而对我们读回的数据做相反的事情? 如果没有充分的理由在您的主机代码中使用本机 C 类型,而不是强制转换,我建议直接使用 cl_ 类型。顺便说一句,我在我的答案中添加了一个额外的段落。 我明白了。在我的情况和我想象的大多数其他情况下,opencl 计算的输入和结果必须由主机程序的其余部分提供/使用。您可能还希望将 opencl 依赖项排除在其余代码之外。这相当于不幸的副本和样板转换数量。但我想这是没有办法的! 一个很好的例子是cl_int。在 OpenCL 中总是 32 位。虽然每个 C 平台可能有不同的 int 大小。

以上是关于何时使用 OpenCL API 标量数据类型?的主要内容,如果未能解决你的问题,请参考以下文章

OpenCL:如何避免重复的标量/向量函数?

OpenCL C

为啥 OpenCL 没有矩阵数据类型?

NVIDIA 硬件的 OpenCL 1.2 何时可用?

OpenCL 中主机和设备的 64 位数据类型

OpenCL API 中的类型转换 (void *)&c_mem_obj