2013-12-06 2 views
0

Я пытаюсь изучить OpenCL с помощью привязок C++. Единственное, что я до сих пор не понял, - это следующий синтаксис. Попытка создать контекст, основанный на типе устройства:Синтаксис свойств контекста OpenCL C++

cl::Context context(CL_DEVICE_TYPE_CPU, properties); 

Я использую ICD NVidia, которая, как я понимаю, не позволит вам создать контекст без определения платформы, поэтому мне нужен второй аргумент. Из стандарта cl_context_properties должен быть список имен свойств, за которыми следуют соответствующие значения, заканчивающиеся на 0. В стандарте есть только один cl_context_properties (таблица 4.4), который является свойством CL_CONTEXT_PLATFORM и имеет значение свойства cl_platform_id. Основываясь на том, что я думал, что таким образом, что это должно быть в порядке:

cl_context_properties properties[] = 
    { CL_CONTEXT_PLATFORM, platforms[0], 0}; 

где platforms мой вектор платформ. Но это не будет компилироваться, если вместо platforms[0] я ставлю:

(cl_context_properties)(platforms[0])() 

Это из примера кода в файле cl.hpp заголовка.

1) Похоже, что platforms ливается до типа cl_context_properties. Почему это необходимо?

2) Почему в конце имеется дополнительный набор кронштейнов ()?

Предположим, что я не эксперт на C++ (определенно верно). Я знаю, что это всего лишь небольшая вещь, но мне не нравится писать код, который я не понимаю полностью.

ответ

3

У меня нет опыта, связанного с OpenCL. Итак, в основном, мой ответ касается использования C++.

  1. Зачем нужен бросок? Приведение необходимо, потому что вы объявляете массив C properties[], где каждый элемент должен иметь тип cl_context_properties. Поскольку cl_platform_id имеет другой тип, он должен быть отлит соответствующим типом, точно - cl_context_properties. Вы используете C-стиль, который выглядит так: (type_to_cast_to) (expression_to_be_cast). Если expression_to_be_cast это просто переменная, как и в случае, если вы вы можете опустить скобки вокруг expression_to_be_cast:

    cl_context_properties свойства [] = { CL_CONTEXT_PLATFORM (cl_context_properties) платформы [0], 0};

  2. Почему в конце есть дополнительный набор кронштейнов()? Вы должны использовать скобки, так как переменная platform[0] имеет тип cl::Platform, который не является простым (например, int, char, double) и cl::Platform класс является оберткой. Вы должны вызвать operator() этого класса, чтобы получить базовые данные типа cl_platform_id, которые вам нужны. Так следующий код должен быть проще: cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, static_cast<cl_context_properties>(platforms[0]()), 0};

Здесь вы делаете залиты стилем C++ отливать static_cast который является предпочтительным отлитым в C++ (you can read about it here) объекта, возвращаемого вызовом operator() на объекте platforms[0]. operator() определяется в классе cl::detail::Wrapper<T> (class reference), который является родительским классом для класса cl::Platform

+0

1) Хорошо, я думаю, я понимаю необходимость бросить сейчас - я думаю, вы не можете иметь массив, содержащий различные типы, после все. 2) Если я скомпилирую без дополнительных скобок, вы получите: 'error: invalid cast from type 'cl :: Platform' для ввода 'cl_context_properties {aka long int}'' – badger5000

+2

Скобка на C++-оболочке должна получить собственный Объект OpenCL. Оператор() определен для этого. Я бы подумал, что это может быть «(cl_context_properties) (platform [0]())» хотя (возьмите первую cl :: Platform из вектора, получите дескриптор OpenCL, отбросите его в cl_context_properties, чтобы поместить его в массив). – Dithermaster

+0

@ Dithermaster, спасибо! Оба '(platform [0]())' и '(platform [0])()' работают, хотя – badger5000

Смежные вопросы