Я использую реализацию github triSYCL Xilinx,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 ++. Так что я не могу понять точный способ сделать это.
Есть 2 пункта, которые, я думаю, являются причиной проблемы, с которой вы столкнулись:
Как я понимаю, вы пытаетесь инициализировать буфер размерности 1 и с размерами {100, 1, 1}. Для этого определение a должно измениться на:
кл :: sycl :: буфер < float, 1> a (cl :: sycl :: range< 1> (n_threads));
Кроме того, поскольку размерность может быть выведена из параметра шаблона диапазона, таким образом, вы можете добиться того же эффекта с помощью:
кл :: sycl :: буфер< float> a (cl :: sycl :: range< 1> (n_threads));
Что касается инициализации буфера с помощью std :: iota, у вас есть 3 варианта:
Средства доступа не должны использоваться в качестве итераторов (с .begin (), .end ())
Дело А:
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
Дело Б:
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;
}
}
Дело С:
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
Также проверьте главу 4.8 спецификации SYCL 1.2.1 https://www.khronos.org/registry/SYCL/specs/sycl-1.2.1.pdf как это имеет пример для йоты
Отказ от ответственности: triSYCL является исследовательским проектом на данный момент. Пожалуйста, используйте ComputeCpp для чего-либо серьезного. 🙂
Если вам действительно нужны массивы buffer
Я думаю, вы можете использовать что-то похожее на Есть ли способ, которым я могу создать массив cl :: sycl :: pipe?
Как вариант, вы можете использовать std::vector<cl::sycl::buffer<float>>
или же std::array<cl::sycl::buffer<float>, n_threads>
и инициализировать с помощью цикла из cl::sycl::buffer<float> { T }
,