【问题标题】:What is the proper way to handle OpenCL buffers of structs?处理结构的 OpenCL 缓冲区的正确方法是什么?
【发布时间】:2014-08-27 23:46:49
【问题描述】:

我有以下 OpenCL 内核:

//OPENCL KERNEL
struct MyStruct
{
  float A;
  float B;
  float C;
  float D;
  float E;
};

__kernel void kernelMain(struct MyStruct* outputBuffer)
{
   size_t idx = get_global_id(0);

   //Do some stuff here with the outputBuffer
   outputBuffer[idx].A = 42.0;
}

如您所见,它定义了一个自定义类型,称为 MyStruct。

在主机端,我有相同的结构定义(复制粘贴):

//HOST SIDE
struct MyStruct
{
  float A;
  float B;
  float C;
  float D;
  float E;
};

我正在尝试为内核数据的写入创建一个缓冲区,同样是主机端代码:

//HOST SIDE
cl::Buffer outputBuffer(clContext, CL_MEM_READ_WRITE, (size_t)numElements * sizeof(MyStruct));

clKernel.setArg(0, outputBuffer);

当我调用 clKernel.setArg 时出现问题。它失败并显示错误代码 -51,根据 OpenCL 文档,这是内核无效参数大小错误。

我尝试使用 openCL 数据类型,将结构的主机定义重写为:

struct MyStruct
{
  cl_float A;
  cl_float B;
  cl_float C;
  cl_float D;
  cl_float E;
};

但这也会报错。

我的问题是: 为使用自定义结构创建 OpenCL 缓冲区的正确方法是什么?

【问题讨论】:

  • 尝试 __kernel void kernelMain(__global struct MyStruct* outputBuffer) 或只是 __kernel void kernelMain(__global MyStruct* outputBuffer)
  • 使用typedef struct {...} MyStruct;和内核参数__kernel void kernelMain(__global MyStruct* outputBuffer)

标签: c++ opencl


【解决方案1】:

如果您能够使用 C++,则可以使用 BOOST_COMPUTE_ADAPT_STRUCT() 宏,该宏负责包装结构并使其可用于 OpenCL 内核。

包装后,您可以使用 boost::compute::vector<T> 容器类为您的结构集合创建一个 OpenCL 内存缓冲区:

// adapt "MyStruct" for OpenCL
BOOST_COMPUTE_ADAPT_STRUCT(MyStruct, MyStruct, (A, B, C, D, E));

// create a OpenCL buffer with 100 "MyStruct" objects
boost::compute::vector<MyStruct> my_structs(100);

// use "my_structs" with an opencl kernel
my_kernel.set_arg(0, my_structs);

【讨论】:

    【解决方案2】:

    如果添加__global 关键字没有帮助,听起来您可能有different struct padding between host and device。这会使结构的大小或结构中的数据位置不同。结构填充是platform and compiler dependent

    这是您在使用 OpenCL 在主机和设备上使用相同结构时应该考虑的问题。尤其是当您将软件定位到多个平台时。

    一种解决方法是使用浮点数组在主机和设备之间移动数据。

    【讨论】:

      猜你喜欢
      • 2014-03-05
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 2013-08-08
      相关资源
      最近更新 更多