2013-01-24 124 views
5

我已經在.cl文件中編寫了OpenCL內核。它試圖#include幾個標題。包含頭文件到OpenCL .cl文件

其編譯失敗,因爲包含的頭文件是「未找到」。 我知道clBuildProgram可以採取-I dir選項,它將目錄dir添加到要搜索的頭文件的目錄列表。

在khronus網站論壇中,這篇文章http://www.khronos.org/message_boards/viewtopic.php?f=37&t=2535談到了這個問題。

他們建議使用clCreateProgramWithSource它指定所有源(包括.h文件)。

我有一個關於這個問題一個問題:

  1. 哪種選擇更好? (clBuildProgramclCreateProgramWithSource,如上所述)
  2. 如果我使用clCreateProgramWithSource編譯器如何知道要包含什麼?我的意思是,哪個來源代表哪個包含文件名?
  3. 如果我使用clBuildProgram並且有幾個包含文件的目錄,我該如何指定它們?

回答

5

的OpenCL需要使用clCreateProgramWithSource()其次clBuildProgram()

ClCreateProgramWithSource()創建並返回一個cl_program對象。

cl_program對象輸入clBuildProgram()

clBuildProgram()允許您指定編譯器選項,其中包括包含文件 目錄。在你的情況下,頭文件還包括,它會是這樣的字符串:

-I myincludedir1 -I myincludedir2 ... 

使用的編譯器是內部OpenCL編譯OpenCL的SDK您使用。所以,如果你 使用AMD的SDK,則AMD OpenCL編譯那是他們的OpenCL的SDK的一部分將被使用。同樣適用於NvidiaIntel

其重要的是檢查所有OpenCL狀態碼OpenCL函數調用。 這是強制要求clCreateProgramWithSource()clBuildProrgam()得到 任何編譯器錯誤或消息。還有一個完整的其他位代碼來編寫 以獲取消息的大小,然後自己檢索消息。

2

Nvidia OpenCL設備驅動程序在使用-I時包含一定數量的包含和代碼長度時會出現錯誤。 AMD和英特爾沒有這個問題。我的解決方案是在運行時將所有.cl文件連接成一個大文件。這樣做的缺點是,在調試代碼時,錯誤的行號對應於concatenated .cl文件,而不是單個的.cl文件。

我懷疑Nvidia會永遠解決這個問題。他們不再關心OpenCL了。

+0

AMD APP與-I問題也從我的經驗(它根本不工作),但英特爾處理它完美。 – Thomas

+0

這很有趣。我雖然我在CPU上測試過它。我沒有AMD GPU,所以我無法在GPU上進行測試。也許這是一個GPU與CPU的問題? – 2013-03-10 07:18:53

+0

不,我在Windows下的兩個設備下試過,編譯器似乎並不處理相對包含路徑。基本上,我的編譯器命令行中有「-I cl /」,我的內核整齊排列在cl /目錄下,雖然在Intel/Linux下工作正常,但AMD不會有任何問題,無論如何我嘗試的是,我發現的唯一解決方案是在#include指令中對每個.cl文件的*絕對路徑*進行硬編碼,或將我的cl /文件夾添加到系統$ PATH。這可能是我的安裝,但是我的Linux系統並沒有像我的Linux系統那樣維護。 – Thomas

0

還有一個骯髒的竅門:你應該模仿包括你自己(即類似手動合併)。編碼並不十分清楚,但如果您的OpenCL編譯器不支持(或不正確地支持)-I指令,則它可以工作。這種方法並不完美(例如,您會失去語法突出顯示),但可以爲舊的或有問題的OpenCL編譯器提供幫助。這種可能性

小簡單的例子:

std::string load_file(const std::string &file_name, int max_size = 0x100000) 
{ 
    FILE *fp = fopen(file_name.c_str(), "rb"); 
    if (!fp) 
    { 
     // print some error or throw exception here 
     return std::string(); 
    } 
    char *source = new char[max_size]; 
    size_t source_size = fread(source, 1, max_size, fp); 
    fclose(fp); 
    if (!source_size) 
    { 
     delete[] source; 
     // print some error or throw exception here 
     return std::string(); 
    } 
    std::string result(source); 
    delete[] source; 
    return result; 
} 

// errors checks are omitted for simplification 
std::string full_source = load_file("header.h"); 
full_source += load_file("source.cl"); 

const char *source_ptr = full_source.c_str(); 
size_t source_size = full_source.size(); 
cl_int_status = CL_SUCCESS; 
cl_program program = clCreateProgramWithSource(context, 1, 
     (const char **)&source_ptr, (const size_t *)&source_size, &ret); 
// check status for CL_SUCCESS here 
// now you have your program (include + source)