Как создать массив cl :: sycl :: buffers?

Я использую реализацию 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 ++. Так что я не могу понять точный способ сделать это.

0

Решение

Есть 2 пункта, которые, я думаю, являются причиной проблемы, с которой вы столкнулись:

  1. Вторым аргументом шаблона в определении объекта буфера должна быть размерность буфера (количество измерений должно быть 1, 2 или 3), а не сами измерения.
  2. Конструктор для буфера должен содержать либо фактические размеры буфера, либо данные, которые вы хотите иметь в буфере, и размеры. Чтобы передать размеры, вам нужно передать объект cl :: sycl :: range в конструктор

Как я понимаю, вы пытаетесь инициализировать буфер размерности 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 варианта:

  1. Используйте массив для инициализации данных с использованием йоты и передачи их в буфер sycl (случай A),
  2. Используйте средство доступа для записи в буфер напрямую только для хоста — ЦП (случай B), или
  3. Используйте средство доступа с параметром parallel_for для выполнения на хосте или устройстве OpenCL (случай C).

Средства доступа не должны использоваться в качестве итераторов (с .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 как это имеет пример для йоты

3

Другие решения

Отказ от ответственности: 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 },

1

По вопросам рекламы [email protected]