#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 требуется компилятор устройства, но обеспечивает (ИМХО) хорошие абстракции и обработку исключений. Предварительная спецификация уже доступна, и уже существует (незавершенная) реализация с открытым исходным кодом.