2011-10-12 16 views
8

He visto en una publicación aquí que podemos llamar a una función desde un kernel OpenCL. Pero en mi situación, necesito esa función compleja para ser paralelizada (ejecutada por todos los hilos disponibles) también, así que ¿tengo que hacer que esa función también sea un kernel y llamarlo directamente como la función del kernel principal? o cuál es la solución posible para esta situación? Gracias de antemanoLlamar al kernel OpenCL desde otro kernel OpenCL

Respuesta

8

Puede llamar a las funciones auxiliares de su kernel y se paralelizarán de la misma manera que el núcleo, imagínelas como están dentro del código del kernel. Por lo tanto, cada elemento de trabajo invocará la función auxiliar para el conjunto de trabajo que maneja.

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

adición a la respuesta sramij, llamando a otro núcleo desde el kernel es llamado como dinámico paralelismo. para esto necesitas el dispositivo que admite OpenCL 2.0. puede referirse a http://stackoverflow.com/questions/12913640/opencl-dynamic-parallelism-gpu-spawned-threads – Meluha

3

Si entiendo su pregunta correctamente, quiere hacer un pase completo separado sobre un búfer desde el interior del kernel. No creo que eso sea posible desde el kernel, por lo que tendrías que crear el código para el pase "interno" como un núcleo separado y también llamar ese kernel por separado desde tu código de host. La salida de ese kernel no tiene que volverse a leer en la memoria del host, pero puede permanecer en la memoria del dispositivo entre las llamadas al kernel.

2

OpenCL 2.0 spec agregó una nueva función para el paralelismo dinámico.

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

En el siguiente ejemplo my_func_B enqueus my_func_A en el dispositivo:

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