2017-01-17 13 views
1

私はOpenCLカーネルを持っています。このカーネルは、デバイス内から特定の機能を呼び出し、出力を出します。私は最初に垂直パスが実行され、次に水平パスが行われるような画像を処理しています。現時点では、ホスト側からカーネルを2回呼び出していますが、各呼び出しで引数の値を変更します。OpenCLカーネルで関数を順番に実行する方法は?

kernel void image_filter(a, b, c, d) 
{ 
    func1(a, b, c, d); 
    if(<condition>) 
     func2(a, b, c, d); 
} 

カーネルを一度だけ呼び出すことができるように、水平パスと垂直パスの両方が実行されるようにします。

kernel void image_filter(a, b, c, d) 
{ 
    // Vertical pass 
    func1(a, b, c, d); 
    if(<condition>) 
     func2(a, b, c, d); 

    // When execution of the above functions is complete 
    // Horizontal pass 
    // Some computation 
    func1(a, b, c, d); 
    if(<condition>) 
     func2(a, b, c, d); 
} 

垂直パスと水​​平パスの間にデータ依存関係があることに注意してください。

答えて

8

これは、2つのカーネル・エンキューを使用する必要があり、単一のカーネル・エンキューでは不可能です。

なぜですか? は、他の作業項目が開始される前にすべての作業項目が開始されるわけではないため、が終了します。あなたはそれを制御することはできません(ランタイムまでです)。また、垂直パスと水​​平パスの間にデータ依存関係があることを示したので、2番目のセットを開始する前に、完了するための最初の作業項目セットがすべて必要です。したがって、2つのカーネルがエンキューします。

TL; DRは:カーネル(のみワークグループ同期)内のグローバルな同期はありません。 2つのエンキューを使用します。

+0

ここで '' barrier() ''を使うことができますか? –

+3

いいえ、あなたは 'barrier'を使うことはできません。これはワークグループ同期のためのものです。グローバル同期が必要です。これを実行する唯一の方法は、複数のカーネルをエンキューすることです。 – Dithermaster

+0

n個の作業項目を持つ作業グループが1つだけの場合はどうなりますか? –

関連する問題