# #opencl #sycl #dpc
Вопрос:
В своей программе я определил массив функций
#include <CL/sycl.hpp>
#include <iostream>
#include <tbb/tbb.h>
#include <tbb/parallel_for.h>
#include <vector>
#include <string>
#include <queue>
#include<tbb/blocked_range.h>
#include <tbb/global_control.h>
#include <chrono>
using namespace tbb;
template<class Tin, class Tout, class Function>
class Map {
private:
Function fun;
public:
Map() {}
Map(Function f):fun(f) {}
std::vector<Tout> operator()(bool use_tbb, std::vector<Tin>amp; v) {
std::vector<Tout> r(v.size());
if(use_tbb){
// Start measuring time
auto begin = std::chrono::high_resolution_clock::now();
tbb::parallel_for(tbb::blocked_range<Tin>(0, v.size()),
[amp;](tbb::blocked_range<Tin> t) {
for (int index = t.begin(); index < t.end(); index){
r[index] = fun(v[index]);
}
});
// Stop measuring time and calculate the elapsed time
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
printf("Time measured: %.3f seconds.n", elapsed.count() * 1e-9);
return r;
} else {
sycl::queue gpuQueue{sycl::gpu_selector()};
sycl::range<1> n_item{v.size()};
sycl::buffer<Tin, 1> in_buffer(amp;v[0], n_item);
sycl::buffer<Tout, 1> out_buffer(amp;r[0], n_item);
gpuQueue.submit([amp;](sycl::handleramp; h){
//local copy of fun
auto f = fun;
sycl::accessor in_accessor(in_buffer, h, sycl::read_only);
sycl::accessor out_accessor(out_buffer, h, sycl::write_only);
h.parallel_for(n_item, [=](sycl::id<1> index) {
out_accessor[index] = f(in_accessor[index]);
});
}).wait();
}
return r;
}
};
template<class Tin, class Tout, class Function>
Map<Tin, Tout, Function> make_map(Function f) { return Map<Tin, Tout, Function>(f);}
typedef int(*func)(int x);
//define different functions
auto function = [](int x){ return x; };
auto functionTimesTwo = [](int x){ return (x*2); };
auto functionDivideByTwo = [](int x){ return (x/2); };
auto lambdaFunction = [](int x){return ( x);};
int main(int argc, char *argv[]) {
std::vector<int> v = {1,2,3,4,5,6,7,8,9};
//auto f = [](int x){return ( x);};
//Array of functions
func functions[] =
{
function,
functionTimesTwo,
functionDivideByTwo,
lambdaFunction
};
for(int i = 0; i< sizeof(functions); i ){
auto m1 = make_map<int, int>(functions[i]);
//auto m1 = make_map<int, int>(f);
std::vector<int> r = m1(true, v);
//print the result
for(auto amp;e:r) {
std::cout << e << " ";
}
}
return 0;
}
вместо того, чтобы каждый раз определять функцию, я заинтересован в определении массива функций, а затем в их выполнении в своей программе. Но в части SYCL для выполнения на GPU у меня есть ошибка, и я не знаю, как ее исправить.
ОШИБКА: ядро SYCL не может вызвать через указатель функции
Комментарии:
1. По описываемому вами инструменту не так много документации, но я бы рекомендовал ознакомиться с документацией. Я думаю, что если у вас возникнут проблемы с использованием инструмента, вам следует поднять их в репозитории проекта.
2. проблема в том, что я понятия не имею, как их использовать, и не могу найти никаких примеров. я запутался и застрял в этой части
Ответ №1:
В частности, код устройства SYCL, определенный этой спецификацией, не поддерживает вызовы виртуальных функций, указатели функций в целом, исключения, информацию о типе среды выполнения или полный набор библиотек C , которые могут зависеть от этих функций или функций конкретного хост-компилятора. Тем не менее, эти основные ограничения могут быть устранены некоторыми конкретными расширениями Хроноса или поставщиков.
В соответствии со спецификацией sycl 2020, в ядре SYCL не разрешается вызывать указатели функций или любые функции, вызываемые ядром. Пожалуйста, обратитесь https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#introduction