2016-09-13 3 views
0

Я читал здесь много, но это мой первый пост.OpenCL C++: CL_INVALID_KERNEL и make_kernel не являются членами cl

Я пытаюсь запустить код C++ OpenCL для FPGA Altera, совместимый с OpenCL 1.0 только сейчас. Пока подготовка среды, запрос платформы и использование других функций OpenCL работает нормально. Но когда я пытаюсь создать ядро ​​и добавлять аргументы, я сталкиваюсь с проблемами. Я попробовал два подхода, и оба пришли со своими ошибками:

Approach один:

auto simple_add = cl::make_kernel<cl::Buffer&, cl::Buffer&, cl::Buffer&> (opencl_Program, ocl_func_name.c_str()); 
    cl::EnqueueArgs eargs(queue, cl::NullRange, cl::NDRange(n), cl::NullRange); 
    simple_add(eargs, buffer_A, buffer_B, buffer_C).wait(); 

Thsi дает следующую ошибку компиляции:

об ошибке: 'make_kernel' не является членом of 'cl'

auto simple_add = cl :: make_kernel (opencl_Program, ocl_func_name.c_str());

подход два:

cl::Kernel simple_add = cl::Kernel(opencl_Program, ocl_func_name.c_str(), p_err); 
if (p_err != NULL) 
    display_OpenCL_ErrorCode(*p_err); 

err = simple_add.setArg(0, sizeof(cl::Buffer), (void*)&buffer_A); 
display_OpenCL_ErrorCode(err); 

err = simple_add.setArg(1, sizeof(cl::Buffer), (void*)&buffer_B); 
display_OpenCL_ErrorCode(err); 

err = simple_add.setArg(2, sizeof(cl::Buffer), (void*)&buffer_C); 
display_OpenCL_ErrorCode(err); 

Это дает следующее время выполнения выходного кода в каждой строке "setArg" (о создании ядра не дает ошибку):

-48 (т.е. CL_INVALID_KERNEL) ,

Мои рассуждения:

  • Я не смог найти где-либо документации OpenCL 1.0 C++. Кажется, что он доступен только начиная с версии 1.2, поэтому, возможно, мне не удастся написать какой-либо код для FPGA на C++, но я сначала хотел убедиться (хотя кажется мне маловероятным).
  • Код от подхода один из исходного файла, который я создал при использовании OpenCL 2.0 и C++ 11, и это отлично работало. Это уже задокументировано в OpenCL 1.2, поэтому, вероятно, оно должно работать, тем не менее?
  • Несмотря на то, что создание второго ядра кажется безупречным во втором подходе, я подозреваю, что он не работал должным образом, поскольку он не позволит установить какие-либо аргументы связанной функции. Но мне трудно отлаживать это, поскольку ошибок нет ...

Любая помощь и поддержка оценены!

(Не хочу перегружать первое сообщение, но при необходимости я могу разместить больше кода).

EDIT1: Я посмотрел на файл cl.hpp и нашел следующую строку: * \ краток C++ привязок для OpenCL 1.0 (ред 48) и OpenCL 1.1 (ред 33) Таким образом, это подтверждает тот факт, что там является оболочкой OpenCL 1.0 C++. То, что я также узнал, было внутри, не было функции make_kernel. Я присмотрюсь к файлу и опубликую исправленный код, если найду решение.

+0

Вы можете использовать opencl C api с C++, если вы хотите проверить, вызывает ли C++ api ваши проблемы. – Jovasa

+0

Я понимаю, что вы не видите ничего плохого в реализации C++, которую я описал выше? –

+0

Обычно я использую подход Two, и это отлично работает с Altera. Никаких особых требований не требуется. Я предлагаю сделать это сначала для OpenCL CPU или GPU, а затем перейти на Altera. Вы также можете попробовать установить '-DCL_HPP_TARGET_OPENCL_VERSION = 100 -DCL_HPP_MINIMUM_OPENCL_VERSION = 100' для обеспечения совместимости с OpenCL 1.0, однако мне никогда не нужно было это устанавливать. – doqtor

ответ

0

Я также натолкнулся на ошибку несколько дней назад, и я просто ее разработал. Я здесь разделяю решение.Это код:

inline void CreateOCLKernels() 
{ 
    filterDepth_ocl_kernel = clCreateKernel(program, "filterDepthKernel", &clError); 
    checkErr(clError, "clCreateKernel"); 
    convertDisparityToDepth_ocl_kernel = clCreateKernel(program, "convertDisparityToDepthKernel", &clError); 
    checkErr(clError, "clCreateKernel"); 
    ComputeNormalAndWeight_ocl_kernel = clCreateKernel(program, "ComputeNormalAndWeightKernel", &clError); 
    checkErr(clError, "clCreateKernel"); 
    convertDepthAffineToFloat_ocl_kernel = clCreateKernel(program, "convertDepthAffineToFloatKernel", &clError); 
    checkErr(clError, "clCreateKernel"); 
} 
ITMViewBuilder_OpenCL::ITMViewBuilder_OpenCL(const ITMRGBDCalib *calib):ITMViewBuilder(calib) { CreateOCLKernels(); } 

Как вы можете видеть, это встроенная функция, вызываемая конструктором. И я продолжаю получать «недопустимое имя ядра» из функции «CreateOCLKernels()», пока не добавлю «статическую» к этой функции.

static inline void CreateOCLKernels() 
{ ... } 

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

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

  • Нет связанных вопросов^_^