2011-10-12 14 views
8

Ho visto in un post qui che possiamo chiamare una funzione da un kernel OpenCL. Ma nella mia situazione, ho bisogno di quella funzione complessa per essere parallelizzata (gestita da tutti i thread disponibili), quindi devo fare di quella funzione anche un kernel e chiamarlo subito come funzione dal kernel principale? o qual è la soluzione possibile per questa situazione? Grazie in anticipoChiamare il kernel OpenCL da un altro kernel OpenCL

risposta

8

Puoi chiamare le funzioni di aiuto dal tuo kernel e saranno parallelizzate nello stesso modo del kernel, immaginandole come inline all'interno del codice del tuo kernel. Quindi, ogni elemento di lavoro invocherà la funzione di supporto per il set di lavoro che gestisce.

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

aggiunta a risposta sramij, chiamare un altro kernel kernel è chiamato Dynamic parallelismo. per questo è necessario il dispositivo che supporta OpenCL 2.0. può fare riferimento a http://stackoverflow.com/questions/12913640/opencl-dynamic-parallelism-gpu-spawned-threads – Meluha

3

Se ho compreso correttamente la tua domanda, vuoi eseguire un passaggio completo separato su un buffer all'interno del kernel. Non penso che sia possibile all'interno del kernel, quindi dovresti creare il codice per il passaggio "interno" come un kernel separato e anche chiamare quel kernel separatamente dal tuo codice host. L'output da quel kernel non deve essere riletto alla memoria dell'host, ma può rimanere nella memoria del dispositivo tra le chiamate del kernel.

2

OpenCL 2.0 spec ha aggiunto una nuova funzionalità per il paralelismo dinamico.

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

Nell'esempio sotto my_func_B enqueus my_func_A sul 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);}); 
... 
} 
Problemi correlati