Существуют ли привязки OpenCL, которые не написаны в стиле C / C ?

#c #binding #opencl

#c #привязка #opencl

Вопрос:

Текущие привязки OpenCL C CL/cl.hpp представляют собой очень тонкую оболочку поверх C OpenCL API. Я понимаю причины, по которым это было сделано именно так, хотя на самом деле я этого не понимаю.

Существуют ли какие-либо существующие альтернативные оболочки, которые полагаются на исключения в качестве обработки ошибок, позволяя просто писать такой код:

 auto platform_list = cl::Platform::get();
 

потому что, ну, RVO и удобочитаемость и тому подобное, вместо текущего

 std::vector<cl::Platform> platform_list;
auto error = cl::Platform::get(amp;platformList);
if(error != CL_SUCCESS)
 

Или, если кто-то выбирает обработку исключений (путем определения __CL_ENABLE_EXCEPTIONS ):

 std::vector<cl::Platform> platform_list;
cl::Platform::get(amp;platformList);
 

Обратите внимание, что фактический код обработки ошибок не показан, хотя в случае отсутствия исключений это может стать довольно запутанным.

Я уверен, что написать такие привязки было бы не так уж сложно, но крайние случаи остаются крайними случаями, и я бы предпочел надежную предварительно написанную оболочку. Назовите меня избалованным, но если привязки C не предлагают реального интерфейса C , я действительно не вижу в них смысла.

Ответ №1:

Проверьте Boost.Вычислительная библиотека. Он доступен только для заголовков и предоставляет высокоуровневый C API для GPGPU / параллельных вычислений на основе OpenCL.

Получение списка платформ выглядит следующим образом:

 for(auto platform : boost::compute::system::platforms()){
    std::cout << platform.vendor() << std::endl;
}
 

И он использует исключения для обработки ошибок (что значительно уменьшает количество требуемых явных проверок и выдает гораздо более приятные сообщения об ошибках при сбое):

 try {
    // attempt to compile to program
    program.build();
}
catch(boost::compute::opencl_error amp;e){
    // program failed to compile, print out the build log
    std::cout << program.build_log() << std::endl;
}
 

Помимо всего прочего, он также предлагает интерфейс, подобный STL, с контейнерами типа vector<T> and array<T, N> , а также алгоритмами типа sort() and transform() (наряду с другими функциями, такими как генерация случайных чисел и поддержка лямбда-выражений).

Например, чтобы отсортировать вектор float s на устройстве, вы просто:

 // vector of floats on the device
boost::compute::vector<float> vec = ...;

// sort the vector
boost::compute::sort(vec.begin(), vec.end(), queue);

// copy the sorted vector back to the host
boost::compute::copy(vec.begin(), vec.end(), host_vec.begin(), queue);
 

В документации есть больше руководств и примеров.

Ответ №2:

Оболочки C предназначены для того, чтобы быть просто тонким слоем поверх OpenCL, поэтому их можно включать просто как заголовочный файл. Существуют некоторые библиотеки C / OpenCL, которые предлагают различные виды поддержки C , такие как AMD Bolt.

Есть предложение для слоя / библиотеки для C , SYCL. Это немного сложнее, чем оболочка, поскольку для создания ядер OpenCL требуется компилятор устройства, но обеспечивает (ИМХО) хорошие абстракции и обработку исключений. Предварительная спецификация уже доступна, и уже существует (незавершенная) реализация с открытым исходным кодом.