ОК, так что, похоже, вы хотите передать массив/вектор строк в ядро и иметь каждый рабочий элемент в процессе ядра другую строку. Вы не можете сделать это с помощью векторных и строковых классов STL, так как они не работают внутри ядер OpenCL, поэтому проще всего использовать сплющенный массив массивов C (со всеми строками в одном массиве).
Я изменил вашу программу ниже, чтобы сделать это. В основном, мы устанавливаем максимальное количество символов, которое потребуется любой строке (если вы знаете, что это такое) в переменной charsPerString
. Затем мы выделяем массив с символами elements*charsPerString
и инициализируем строки одним символом, как вы делали. I-я строка начинается с индекса i*charsPerString
. Затем мы можем передать это ядру в виде одного буфера.
В ядре затем каждый рабочий элемент распечатывает первый символ в каждой из двух строк, который передается с использованием printf
, вычисляя начало его строки так же, как указано выше.
Я также добавил типичный подход проверки ошибок C++ с исключениями, в котором будут отображаться любые ошибки OpenCL, которые могут возникнуть. Я тестировал это на своем собственном ноутбуке, и он работает, распечатывая:
0 has characters a and b
1 has characters a and b
2 has characters a and b
3 has characters a and b
4 has characters a and b
(что и следовало ожидать).
Надеюсь, вы сможете расширить его до своих собственных случаев использования.
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <iostream>
using namespace cl;
using namespace std;
int main(void) {
try {
Context(CL_DEVICE_TYPE_GPU);
static const unsigned elements = 1000;
static const unsigned charsPerString = 16;
char *dataA = new char[elements*charsPerString];
for (int i = 0; i < elements; i++) {
dataA[i*charsPerString] = 'a';
}
char *dataB = new char[elements*charsPerString];
for (int i = 0; i < elements; i++) {
dataB[i*charsPerString] = 'b';
}
Buffer a(dataA, dataA+elements*charsPerString, true, false);
Buffer b(dataB, dataB+elements*charsPerString, true, false);
Program addProg(R"d(
constant unsigned charsPerString = 16;
kernel
void add(global char *a, global char *b) {
unsigned idx = get_global_id(0);
printf("%d has characters %c and %c\n",
idx, a[idx*charsPerString], b[idx*charsPerString]);
}
)d");
try {
addProg.build();
}
catch (Error err) {
if (err.err() == CL_BUILD_PROGRAM_FAILURE) {
cout << "OpenCL build failure:" << endl;
cout << addProg.getBuildInfo<CL_PROGRAM_BUILD_LOG>(Device::getDefault());
}
throw err;
}
addProg.build();
auto add = make_kernel<Buffer, Buffer>(addProg, "add");
add(EnqueueArgs(elements), a, b);
CommandQueue::getDefault().finish();
delete[] dataA;
delete[] dataB;
}
catch (Error err) {
cerr << "ERROR: " << err.what() << " (" << err.err() << ")" << endl;
}
system("pause");
}
С какой платформой вы используете OpenCL? Можете ли вы показать код ядра? Вы пытались поймать любые исключения, брошенные из привязок OpenCL C++, чтобы получить полезное сообщение об ошибке? – jprice
Согласен с jprice. Кроме того, на ваш вопрос: единственный возможный способ печати данных в строку из CL - использование расширений (например: cl_amd_printf) – DarkZeros
Я использую версию OpenCL в комплекте с AMD SDK. Ядро находится в коде, я связал строку, начинающуюся с Program addPr ... Я не могу получить никакого исключения, кажется, что они не выбрасываются или что-то в этом роде, я просто получаю это окно http: //i.imgur .com/Vhj9uUD.png – Rogue