2011-10-12 12 views
8

Widziałem w jednym poście, że możemy wywołać funkcję z jądra OpenCL. Ale w mojej sytuacji potrzebuję, aby ta złożona funkcja była równoległa (obsługiwana przez wszystkie dostępne wątki), więc czy muszę również nadać tej funkcji jądro i wywołać ją od razu jak funkcję z głównego jądra? lub jakie jest możliwe rozwiązanie tej sytuacji? Z góry dziękujęWywołanie kernela OpenCL z innego kernela OpenCL

Odpowiedz

8

Możesz wywoływać funkcje pomocnicze z jądra i będą one zrównoleglone w taki sam sposób, jak jądro, wyobraź sobie je tak, jak podano w kodzie twojego jądra. Tak więc każdy element pracy wywoła funkcję pomocnika dla zestawu roboczego, który obsługuje.

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

Dodawanie do sramij odpowiedzi, nazywając inny kernel od samego jądra nazywa się dynamicznego Równoległość. do tego potrzebujesz urządzenia obsługującego OpenCL 2.0. może odnosić się do http://stackoverflow.com/questions/12913640/opencl-dynamic-parallelism-gpu-spawned-threads – Meluha

3

Jeśli dobrze rozumiem twoje pytanie, chcesz wykonać osobne pełne przejście przez bufor z wnętrza jądra. Nie sądzę, że jest to możliwe z poziomu jądra, więc musisz utworzyć kod dla "wewnętrznego" przebiegu jako oddzielnego jądra, a także wywołać to jądro oddzielnie od kodu hosta. Dane wyjściowe tego jądra nie muszą być odczytywane z powrotem do pamięci hosta, ale mogą pozostać w pamięci urządzenia między wywołaniami jądra.

2

OpenCL 2.0 spec dodano nową funkcję dynamicznego paralelizmu.

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

W poniższym przykładzie my_func_B enqueus my_func_A na urządzeniu:

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