2015-04-05 2 views
0

Я пытаюсь скомпилировать код найти здесь: http://developer.amd.com/tools-and-sdks/opencl-zone/opencl-resources/introductory-tutorial-to-opencl/«__kernel» не называет тип

Я компиляции с помощью команды:

g++ -Wall -O2 -lm -lOpenCL -g -Wno-unknown-pragmas foo.cpp -o foo 

Часть кода вызывает проблемы это :

#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable 
__constant char hw[] = "Hello World\n"; 

__kernel void hello(__global char * out) { 
     size_t tid = get_global_id(0); 
     out[tid] = hw[tid]; 
} 

я получаю следующие ошибки:

foo.cpp:105:2: error: ‘__constant’ does not name a type 
    __constant char hw[] = "Hello World\n"; 

foo.cpp:107:2: error: ‘__kernel’ does not name a type 
    __kernel void hello(__global char * out) { 

Может кто-нибудь объяснить, почему это происходит? Заголовки точно такие же, как на ссылке.

Благодаря

+2

Похоже, вы пытаетесь скомпилировать OpenCL-код как собственный код (для запуска на вашем CPU). Насколько я могу судить, gcc не распознает opencl как язык. Для компиляции кода необходим компилятор opencl. Clang действительно понимает opencl, но вы по-прежнему не можете скомпилировать его как родное приложение без дополнительной поддержки в виде библиотеки времени выполнения. Обычный способ использования OpenCL - использовать clCreateProgramFromSource(), clBuildProgram(), clCreateKernel() и clEnqueueNDRange() [с некоторым шаблоном до/после] –

+0

@MatsPetersson правильный (и должен представить это как ответ) – Dithermaster

+0

Я не пытаясь скомпилировать с GCC в качестве ссылки. Я использую g ++ с -lOpenCl, и он должен работать, поэтому я запутался ... Другие вызовы функции opencl - это все, что только объявление метода ядра является проблемой – theNoobProgrammer

ответ

1

Вы не можете скомпилировать OpenCL подобный код (без справедливого чуть более вспомогательной инфраструктуры, такие как OpenCL-способной компилятор и библиотеки для функциональности OpenCL - Clang способна компиляции OpenCL для x86, но затем жалуется на то, что у него нет библиотек supprting, когда он пытается связать вещи).

Типичное применение OpenCL будет выглядеть примерно так:

// Get platform, device and context - this is about 10-20 lines of "boilerplate" code. 
const char* source = "... your code goes here ..."; 
// But you could of course read it from a file, for example! 
cl_int err; 
clProgram prog = clCreateProgramWithSource(context, 1, &source, NULL, &err); 
err = clBuildProgram(prog, 1, &device, NULL, NULL, NULL); 
cl_kernel kern = clCreateKernel(prog, "hello", &err); 
cl_mem out = clCreateBuffer(context, CL_MEM_READ_WRITE, 100, NULL, err); 
err = clSetKernelArg(kernel, 0, sizeof(out), out); 
size_t range = 1; 
cl_command_queue queue = cl_create_command_queue(...); 
cl_event event; 
err = clEnqueueNDRange(queue, kern, 1, NULL, &size, NULL, 0, NULL, &event); 
clFlush(queue); 
clWaitForEvent(event); 
// Lots of lines of code to release everything. 

[Я только от руки написаны эти строки - у меня нет среды CL дома, поэтому я не могу проверить его - он показывает общий принцип, и я пропустил совсем немного кода установки/разрыва - и, конечно, проверка ошибок должна выполняться для каждого вызова библиотеки OpenCL, так как часто бывает легко получить это немного неправильно и получить ошибку назад, что затем приводит к следующему шагу, сбой/неправильный ход]

Существуют объектно-ориентированные варианты, которые позволяют избежать некоторой очистки (деструктор делает это за вас), но так как я только написал такой код несколько раз [vs. много раз с базовой версией C, показанной выше], мне пришлось бы пройти через документы или посмотреть «карту привязки OpenCL C++», которую я имею на работе.

0

Я столкнулся с той же проблемой в том же учебнике. Вот моя попытка преодолеть это.

Запутанной часть этого учебника, где это дает вам код OpenCL без явно говорит вам, чтобы поместить этот код в файл с именем «lesson1_kernel.cl»

Я понял это, потому что раньше в учебнике, родной код считывает этот файл:

std::ifstream file("lesson1_kernels.cl"); 
checkErr(file.is_open() ? CL_SUCCESS:-1, "lesson1_kernel.cl"); 
std::string prog(
    std::istreambuf_iterator<char>(file), 
    (std::istreambuf_iterator<char>())); 
cl::Program::Sources source(
    1, 
    std::make_pair(prog.c_str(), prog.length()+1)); 

Все предыдущий «родной код» в этом руководстве принадлежит в файле, который вы собираете. В соответствии с инструкциями данного пособия, нативный код принадлежит в файл с именем «lesson1.cpp»

gcc –o hello_world –Ipath-OpenCL-include –Lpath-OpenCL-libdir lesson1.cpp –lOpenCL 

Я не хочу, чтобы создать новый файл lesson1_kernels.cl для простого разового сценария, как это, так что я вместо того, чтобы поместить весь код OpenCL в строку и создал ХЛ :: Программа :: Источники объекта с этой строки с использованием соответствующих экранирующих символов:

const std::string openCLCode("#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable\n__constant char hw[] = \"Hello World\\n\";\n__kernel void hello(__global char * out) \n\n{\n size_t tid = get_global_id(0);\n out[tid] = hw[tid];\n}\n"); 

и:

cl::Program::Sources source(
    1, 
    std::make_pair(openCLCode.c_str(), openCLCode.length()+1)); 
cl::Program program(context, source); 

После того, как я сделал, что я был чтобы компилировать и запускать программу без каких-либо дополнительных проблем.Благодарим вас за анонимность для публикации моей проблемы, и спасибо Маттс Петерсону за помощь в решении этой проблемы без существенного изменения кода учебника.