如何创建一个 cl::sycl::buffers 数组?
How to create an array of cl::sycl::buffers?
我正在使用Xilinx的triSYCL github实现,https://github.com/triSYCL/triSYCL。
我正在尝试创建一个具有 100 个生产者/消费者的设计,以从 100 个管道中读取/写入。 我不确定的是,如何创建一个cl::sycl::buffer
数组并使用std::iota
初始化它。
这是我的代码:
constexpr size_t T=6;
constexpr size_t n_threads=100;
cl::sycl::buffer<float, n_threads> a { T };
for (int i=0; i<n_threads; i++)
{
auto ba = a[i].get_access<cl::sycl::access::mode::write>();
// Initialize buffer a with increasing integer numbers starting at 0
std::iota(ba.begin(), ba.end(), i*T);
}
我收到以下错误:error: no matching function for call to ‘cl::sycl::buffer<float, 2>::buffer(<brace-enclosed initializer list>)’
cl::sycl::buffer<float, n_threads> a { T };
我是C++编程新手。所以我无法弄清楚做到这一点的确切方法。
我认为有两点会导致您目前遇到的问题:
缓冲区- 对象定义中的第二个模板参数应该是缓冲区的维度(维度计数,应为 1、2 或 3),而不是维度本身。 缓冲区
- 的构造函数应包含缓冲区的实际维度,或者希望缓冲区具有的数据和维度。要传递维度,您需要将 cl::sycl::range 对象传递给构造函数
据我了解,您正在尝试初始化维度为 1 且维度为 { 100, 1, 1 } 的缓冲区。为此,应将 a 的定义更改为:
cl::sycl::缓冲区<浮点数,1> a(cl::sycl::范围<1>(n_threads));
此外,由于维度可以从范围模板参数中推导出来,因此您可以使用以下方法实现相同的效果:
cl::sycl::buffer
a (cl::sycl::range<1>(n_threads));
至于使用 std::iota 初始化缓冲区,您有 3 个选项:
- 使用数组使用 iota 用法初始化数据并将它们传递给 sycl 缓冲区(情况 A),
- 使用访问器直接写入主机的缓冲区 - 仅 CPU(情况 B),或
- 使用带有parallel_for的访问器在主机或 OpenCL 设备上执行(情况 C)。
访问器不应用作迭代器(使用 .begin()、.end())
案例 A:
std::vector<float> data(n_threads); // or std::array<float, n_threads> data;
std::iota(data.begin(), data.end(), 0); // this will create the data { 0, 1, 2, 3, ... }
cl::sycl::buffer<float> a(data.data(), cl::sycl::range<1>(n_threads));
// The data in a are already initialized, you can create an accessor to use them directly
案例B:
cl::sycl::buffer<float> a(cl::sycl::range<1>(n_threads));
{
auto ba = a.get_access<cl::sycl::access::mode::write>();
for(size_t i=0; i< n_threads; i++) {
ba[i] = i;
}
}
案例C:
cl::sycl::buffer<float> a(cl::sycl::range<1>(n_threads));
cl::sycl::queue q{cl::sycl::default_selector()}; // create a command queue for host or device execution
q.Submit([&](cl::sycl::handler& cgh) {
auto ba = a.get_access<cl::sycl::access::mode::write>();
cgh.parallel_for<class kernel_name>([=](cl::sycl::id<1> i){
ba[i] = i.get(0);
});
});
q.wait_and_throw(); // wait until kernel execution completes
另请查看 SYCL 1.2.1 规范 https://www.khronos.org/registry/SYCL/specs/sycl-1.2.1.pdf 的第 4.8 章,因为它有一个 iota 的示例
免责声明:triSYCL目前是一个研究项目。请使用ComputeCpp处理任何严重的事情。:-)
如果你真的需要buffer
数组,我想你可以使用类似于 有没有办法创建一个 cl::sycl::p ipe 数组?
作为变体,您可以使用std::vector<cl::sycl::buffer<float>>
或std::array<cl::sycl::buffer<float>, n_threads>
并使用cl::sycl::buffer<float> { T }
的循环进行初始化。
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '