Я новичок в oneAPI и подобных фреймворках, поэтому у меня проблемы с управлением данными с использованием буферов данных SYCL.
Моя задача - найти подстроки в заданной строке с помощью алгоритма Ахо-Корасика.
Моя идея заключалась в том, чтобы построить tr ie и после этого отправить ядро, которое параллельно будет находить подстроки в tr ie. Поэтому для этого я создал очередь SYCL, создал буферы для строки (для поиска подстрок), для вектора (для хранения результатов поиска) и для моего объекта Aho-Corasick, который содержит root ранее построено тр ie. Однако насчет последнего я не уверен, поскольку я создаю буфер для объекта в памяти хоста, который содержит указатели на другие объекты (например, узлы, которые содержат указатели на другие узлы).
Структура объекта Node:
class Node {
typedef Node *node_ptr;
private:
std::set<std::pair<int, std::string>> retVals;
std::unordered_map<char, node_ptr> children;
node_ptr fail;
char value;
Это метод поиска:
void
matchWords(char *text, int startIdx, int endIdx, cl::sycl::cl_int *matched) {
node_ptr child = start;
int item = startIdx;
for (int i = startIdx; i < endIdx; ++i) {
child = child->nextNode(text[i]);
if (child == nullptr) {
child = start;
continue;
}
for (const auto &returns: child->getRetVals()) {
matched[item++] = returns.first;
if (item == endIdx) item = startIdx;
}
}
}
Буферы:
cl::sycl::buffer<char, 1> fasta_buf(tempFasta.data(), cl::sycl::range<1>(len));
cl::sycl::buffer<cl::sycl::cl_int, 1> vec_buf(vec.data(), cl::sycl::range<1>(len));
cl::sycl::buffer<aho_corasick::AhoCorasick, 1> aho_buf(a, cl::sycl::range<1>(1));
и добавление очереди :
q.submit([&](cl::sycl::handler &cgh) {
auto string_acc = fasta_buf.get_access<cl::sycl::access::mode::read>(cgh);
auto vec_acc = vec_buf.get_access<cl::sycl::access::mode::read_write>(cgh);
auto aho_acc = aho_buf.get_access<cl::sycl::access::mode::read>(cgh);
cgh.parallel_for<class dummy>(
cl::sycl::range<1>(10), [=](cl::sycl::item<1> i) {
// 10 is the number of workers I want
int startInx = (int) (i.get_linear_id() * (len / 10));
int endInx = (int) ((i.get_linear_id() + 1) * (len / 10));
aho_acc.get_pointer()->matchWords(string_acc.get_pointer(), startInx, endInx, vec_acc.get_pointer());
});
});
q.wait_and_throw();
Я понял, что программа не работает после попытки доступа к элементам дочерней карты. Таким образом, я думаю, что проблема в том, что указатели, хранящиеся в карте, являются указателями на память хоста, к которой устройство не имеет доступа.