【问题标题】:OpenCL and std::vector<bool> incompatibilityOpenCL 和 std::vector<bool> 不兼容
【发布时间】:2015-03-18 06:50:30
【问题描述】:

我有一个形成为 std::vector 的 C++ 输入,我想将它传递给我的 OpenCL 内核(Nvidia 平台)。

但执行以下操作时,我不断收到分段错误:

queue.enqueueReadBuffer(dev_input, CL_TRUE, 0, sizeof(bool) * input.size(), &input);

因此,我尝试将我的 std::vector&lt;bool&gt; 复制到 bool[] 并且一切正常。但是,将向量转换为 C 数组的常用方法(&amp;input[0], input.data()) 根本不起作用。

您对 ReadBuffer 或快速分配给 C 数组有什么建议吗?

谢谢!

【问题讨论】:

  • vector&lt;bool&gt; 是“特殊的”。参见例如stackoverflow.com/questions/670308/…
  • 您的 OpenCL 内核如何知道您输入的内存布局?您正确使用了sizeof(bool),因此您的 OpenCL 内核知道有多少字节的输入,但它不知道您传递了多少元素。
  • sizeof(bool) 是 1,所以它实际上是不需要的,但另外我乘以 sizeof(bool) * input.size()。感谢您的帮助!

标签: c++ c++11 vector boolean opencl


【解决方案1】:

两个问题。

  1. 实现可以(可选地)优化std::vector&lt;bool&gt; 以提高空间效率,可能通过将值打包到内存的各个位中。这与 bool 数组的布局不匹配。

  2. 你不能像传递数组一样传递向量的地址。

    std::vector<bool> input;
    queue.enqueueReadBuffer(
        dev_input, CL_TRUE, 0,
        sizeof(bool) * input.size(), &input);
    //                               ^^^^^^ wrong
    

    如果您想将向量作为指针传递,您必须使用input.data()&amp;input[0] 之类的东西。这些不起作用的原因是因为std::vector&lt;bool&gt; 旨在防止它,因为可能会优化实现(参见第 1 点)。

这基本上是 C++ 库中的一个“疣”,随着时间的推移而形成。

解决这个问题很痛苦。

// One way to do things...
struct Bool { bool value; }
std::vector<Bool> input;

// Another way to do things...
// (You have to choose the right type here, it depends
// on your platform)
std::vector<int> input;

// Yet another way...
bool *input = new bool[N];

这就是为什么这是一个这么大的臭疣。

【讨论】:

  • 感谢您的回复!当我使用input.data()&amp;input[0] 中的任何一个时,我会收到“无效使用无效表达式”错误。那么,有没有办法直接使用呢?
  • 对。除了std::vector&lt;bool&gt;,您将不得不使用其他一些数据结构。我已经扩展了答案。
【解决方案2】:

一种可能是使用Boost.Compute提供的copy()算法。

基本上,你可以这样做:

// vector of bools on the host
std::vector<bool> host_vec = { ... };

// vector of bools on the device (each represented with a uchar)
boost::compute::vector<uchar_> gpu_vec(host_vec.size(), ctx);

// copy bool values on host to the device
boost::compute::copy(host_vec.begin(), host_vec.end(), gpu_vec.begin(), queue);

Boost.Compute 会负责将数据正确复制到计算设备。

【讨论】:

    【解决方案3】:

    还要补充一点:

    OpenCL 内核中的类型bool 不能保证匹配任何主机端类型。一般来说,在主机-设备互连中应避免使用布尔类型。

    【讨论】:

      猜你喜欢
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 2016-11-12
      相关资源
      最近更新 更多