11

.clファイルに OpenCL カーネルを記述しました。#includeいくつかのヘッダーを試みます。

インクルードされたヘッダー ファイルが「見つからない」ため、コンパイルは失敗します。ヘッダーファイルを検索するディレクトリのリストにディレクトリを追加するオプションをclBuildProgram使用できることは承知しています。-I dirdir

khronus サイト フォーラムでは、この投稿http://www.khronos.org/message_boards/viewtopic.php?f=37&t=2535でこの問題について説明しています。

clCreateProgramWithSource彼らは、すべてのソース (.h ファイルを含む) を指定するものを使用することを提案しています。

この問題に関して質問があります。

  1. どちらのオプションが優れていますか? (clBuildProgramclCreateProgramWithSource、上記のように)
  2. 使用する場合 clCreateProgramWithSource、コンパイラーは何を含めるかをどのように認識しますか? つまり、どのソースがどのインクルード ファイル名を表しているのでしょうか?
  3. 使用clBuildProgramしていて、インクルード ファイルを含む複数のディレクトリがある場合、それらを指定するにはどうすればよいですか?
4

3 に答える 3

10

OpenCLclCreateProgramWithSource()では、 の後にを使用する必要がありますclBuildProgram()

ClCreateProgramWithSource()オブジェクトを作成して返し cl_programます。

そのcl_programオブジェクトは に入力されclBuildProgram()ます。

clBuildProgram()インクルード ファイル ディレクトリを含むコンパイラ オプションを指定できます。あなたの場合、ヘッダーファイルが含まれている場合、それは次のような文字列になります。

-I myincludedir1 -I myincludedir2  ...

使用されるコンパイラは、使用している OpenCL SDK の内部OpenCLコンパイラです。したがって、 AMD の SDKを使用している場合は、AMD のOpenCL SDKの一部であるAMD OpenCL コンパイラが使用されます。NvidiaまたはIntelの場合も同様です。

すべてのOpenCL関数呼び出しの OpenCL ステータス コードを確認することが重要です。これは、コンパイラ エラーまたはメッセージを取得するためclCreateProgramWithSource()に必須です。clBuildProrgam()メッセージのサイズを取得してから、メッセージ自体を取得するために、別のビット コードを記述する必要があります。

于 2013-01-24T21:28:54.373 に答える
4

特定のインクルード数とコード長で -I を使用すると、Nvidia OpenCL デバイス ドライバーにバグが発生します。AMD と Intel にはこの問題はありません。私の解決策は、実行時にすべての .cl ファイルを 1 つの大きなファイルに連結することです。これの欠点は、コードのデバッグでは、エラーの行番号が個々の .cl ファイルではなく、連結された .cl ファイルに対応することです。

Nvidiaがこれを修正することはないと思います。彼らはもう OpenCL をあまり気にしません。

于 2013-03-09T20:58:04.527 に答える
1

もう 1 つ汚いトリックがあります。インクルードを自分でエミュレートする必要があります (つまり、手動の融合のようなものです)。コーディングについてはあまり明確ではありませんが、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)
于 2015-11-19T09:45:13.360 に答える