OpenCL 和 std::vector<bool> 不兼容
OpenCL and std::vector<bool> incompatibility
我有一个形成为 std::vector 的 C++ 输入,我想将它传递给我的 OpenCL 内核(Nvidia 平台)。
但是当执行以下命令时,我总是遇到分段错误:
queue.enqueueReadBuffer(dev_input, CL_TRUE, 0, sizeof(bool) * input.size(), &input);
因此,我尝试将我的 std::vector<bool>
复制到 bool[]
并且一切正常。但是,将向量转换为C数组的常用方法(&input[0], input.data())
根本不起作用。
您对 ReadBuffer 或对 C 数组的快速赋值有什么建议吗?
谢谢!
两个问题。
实现可以(可选)优化 std::vector<bool>
以提高 space 效率,可能是通过将值打包到内存的各个位中。这将不匹配 bool
.
数组的布局
不能像传递数组一样传递向量的地址。
std::vector<bool> input;
queue.enqueueReadBuffer(
dev_input, CL_TRUE, 0,
sizeof(bool) * input.size(), &input);
// ^^^^^^ wrong
如果你想将向量作为指针传递,你必须使用 input.data()
或类似 &input[0]
的东西。这些不起作用的原因是因为 std::vector<bool>
旨在防止它,因为实现可能会被优化(参见第 #1 点)。
这基本上是 C++ 库中的一个 "wart",随着时间的推移已经融入其中。
解决这个问题很痛苦。
// 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];
这就是为什么这是一个这么大的臭疣。
一种可能是使用 copy()
algorithm provided by Boost.Compute。
基本上,您可以这样做:
// 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 将负责将数据正确复制到计算设备。
再补充一点:
不保证 OpenCL 内核中的 Type bool
与任何主机端类型匹配。 Host-Device 互联一般应避免使用 boolean 类型。
我有一个形成为 std::vector 的 C++ 输入,我想将它传递给我的 OpenCL 内核(Nvidia 平台)。
但是当执行以下命令时,我总是遇到分段错误:
queue.enqueueReadBuffer(dev_input, CL_TRUE, 0, sizeof(bool) * input.size(), &input);
因此,我尝试将我的 std::vector<bool>
复制到 bool[]
并且一切正常。但是,将向量转换为C数组的常用方法(&input[0], input.data())
根本不起作用。
您对 ReadBuffer 或对 C 数组的快速赋值有什么建议吗?
谢谢!
两个问题。
实现可以(可选)优化
std::vector<bool>
以提高 space 效率,可能是通过将值打包到内存的各个位中。这将不匹配bool
. 数组的布局
不能像传递数组一样传递向量的地址。
std::vector<bool> input; queue.enqueueReadBuffer( dev_input, CL_TRUE, 0, sizeof(bool) * input.size(), &input); // ^^^^^^ wrong
如果你想将向量作为指针传递,你必须使用
input.data()
或类似&input[0]
的东西。这些不起作用的原因是因为std::vector<bool>
旨在防止它,因为实现可能会被优化(参见第 #1 点)。
这基本上是 C++ 库中的一个 "wart",随着时间的推移已经融入其中。
解决这个问题很痛苦。
// 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];
这就是为什么这是一个这么大的臭疣。
一种可能是使用 copy()
algorithm provided by Boost.Compute。
基本上,您可以这样做:
// 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 将负责将数据正确复制到计算设备。
再补充一点:
不保证 OpenCL 内核中的Type bool
与任何主机端类型匹配。 Host-Device 互联一般应避免使用 boolean 类型。