2011-10-12 71 views
8

私はOpenCLカーネルから関数を呼び出すことができます。しかし、私の状況では、複雑な関数を並列化する必要があります(使用可能なすべてのスレッドで実行する必要があります)ので、その関数をカーネルにする必要がありますか?またはこの状況のた​​めの可能な解決策は何ですか?別のOpenCLカーネルからOpenCLカーネルを呼び出す

答えて

8

カーネルからヘルパー関数を呼び出すことができます。ヘルパー関数はカーネルと同じ方法で並列化され、カーネルコード内にインライン展開されていると想定します。したがって、各作業項目は、処理する作業セットのヘルパー関数を呼び出します。

float4 helper_function(float4 input) 
{ 
    return input.x + input.y + input.z + input.w; 
} 
__kernel kernel_function(const float4* arr, float4* out) 
{ 
    id = get_global_id(0); 
    out[id] = helper_function(arr[id]); 
} 
+0

は、ダイナミック並列処理と呼ばれています。このためには、OpenCL 2.0をサポートするデバイスが必要です。 http://stackoverflow.com/questions/12913640/opencl-dynamic-parallelism-gpu-spawned-threadsを参照できます – Meluha

3

私があなたの質問を正しく理解していれば、カーネル内部からバッファを別々にフルパスしたいと思っています。私はそれがカーネル内では可能ではないと思うので、別のカーネルとして "内部"パスのコードを作成し、ホストコードとは別にカーネルを呼び出さなければなりません。そのカーネルからの出力は、ホストメモリに読み戻す必要はありませんが、カーネル呼び出しの間にデバイスメモリに残ることがあります。

2

OpenCL 2.0 specは動的パラレル化の新機能を追加しました。デバイス上のmy_func_B enqueus my_func_A以下の例で

6.13.17 Enqueuing Kernels 
OpenCL 2.0 allows a kernel to independently enqueue to the same device, without host 
interaction. ... 

:カーネル自体から別のカーネルを呼び出すsramij回答に追加

kernel void 
my_func_A(global int *a, global int *b, global int *c) 
{ 
... 
} 

kernel void 
my_func_B(global int *a, global int *b, global int *c) 
{ 
ndrange_t ndrange; 
// build ndrange information 
... 
// example – enqueue a kernel as a block 
enqueue_kernel(get_default_queue(), ndrange, ^{my_func_A(a, b, c);}); 
... 
} 
関連する問題