2015-04-05 112 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()[在一些樣板之前/之後] – 2015-04-05 07:53:05

+0

@MatsPetersson是正確的(並且應該將其作爲答案提交) – Dithermaster 2015-04-05 15:16:42

+0

我不是嘗試使用GCC編譯鏈接建議。我正在使用g ++和-lOpenCl,它應該工作,這就是爲什麼我很困惑......其他opencl函數調用都發現它只是內核方法的聲明是一個問題 – theNoobProgrammer 2015-04-05 15:40:33

回答

1

你不能編譯的OpenCL代碼那樣(不公平一點更多的支持基礎設施,如在OpenCL功能的編譯器和庫OpenCL的功能 - 鏘能夠編譯OpenCL的針對x86的,但後來抱怨沒有支持圖書館,當它試圖鏈接的東西)。

典型的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成一個字符串,並創建了CL ::項目::源與字符串中使用適當的轉義字符對象:

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); 

一旦我做到了我曾經是一個無需進一步的問題就可以編譯和運行程序。感謝NooProgrammer發佈我的問題,並感謝Matts Petersson幫助我解決問題,而無需修改教程代碼。