2013-08-01 9 views
7

Voglio creare un array locale all'interno del mio kernel OpenCL, la cui dimensione dipende da un parametro del kernel. Sembra che non sia permesso - almeno con APP AMD.dichiarazione di array di lunghezza variabile non consentita in OpenCL - perché?

La tua esperienza è diversa? Forse è solo l'APP? O c'è qualche razionale qui?

Modifica: Vorrei ora suggerire che gli array di lunghezza variabile dovrebbero essere consentiti anche nel codice lato CPU, ed è stata una richiesta sfortunata da parte del comitato standard C; ma la domanda è valida.

risposta

4

È possibile allocare dinamicamente la dimensione di un blocco locale. Devi prenderlo come parametro per il tuo kernel e definirne le dimensioni quando chiami clSetKernelArg.

esempio di definizione:

__kernel void kernelName(__local float* myLocalFloats, ...) 

di codice host:

clSetKernelArg(kernel, 0, myLocalFloatCount * sizeof(float), NULL); // <-- set the size to the correct number of bytes to allocate, but use NULL for the data. 

Assicurarsi di sapere qual è il limite per la memoria locale è sul dispositivo prima di fare questo. Chiama clGetDeviceInfo e esegui il poll per il valore 'CL_DEVICE_LOCAL_MEM_SIZE'.

+1

Questa è la soluzione che sto utilizzando, ma - poiché ciò è possibile, perché non dovrei essere in grado di allocare un array locale, dichiarando una matrice a lunghezza variabile o chiamando una funzione simile a malloc di OpenCL? – einpoklum

+0

Penso che abbia a che fare con molti dispositivi odierni che hanno bisogno di conoscere queste informazioni in anticipo, in modo che possano validare e allocare in modo sicuro. Non conosco ancora l'architettura GCN di AMD che supporterà le chiamate malloc di gpu-side. – mfa

+0

Se fosse permesso, dovresti essere in grado di allocare dinamicamente la memoria del dispositivo all'interno del kernel, restituire errori di allocazione, ecc ... E ciò non è possibile nella GPU. A livello di kernel tutto deve essere statico. Come hanno già detto, l'unico modo è impostarlo dal codice host. – DarkZeros

3

Non sono sicuro del motivo per cui le persone dicono che non è possibile farlo poiché è qualcosa che molte persone fanno con OpenCL (Sì, ho capito che non è esattamente la stessa cosa ma funziona abbastanza bene per molti casi).

Dal kernel OpenCL sono compilati in fase di esecuzione e, proprio come il testo, si può semplicemente impostare la dimensione di qualsiasi dimensione che si desidera e poi ricompilare il kernel. Questo ovviamente non sarà perfetto nei casi in cui si ha un'enorme variabilità nelle dimensioni, ma di solito compilo diverse dimensioni all'avvio e poi basta chiamare quello corretto secondo necessità (nel tuo caso basato sull'argomento del kernel). Se ottengo una nuova dimensione, non ho un kernel perché lo compilerò proprio in quel momento e conserverò la cache del kernel nel caso in cui ritorni di nuovo.

+0

Hmm. Sì, questo apre alcune possibilità interessanti, anche se devo dire che non capisco perché i kernel OpenCL siano compilati in fase di esecuzione Se posso compilare il mio codice host in anticipo e supponiamo che funzioni, anche se potrebbe essere specifico dell'hardware (x86_64 vs x86 ecc.), non vedo perché lo stesso non dovrebbe essere il caso per il mio codice GPU. Comunque, ottieni il tuo upvote .. – einpoklum

+0

Credo che sia quello di avere la flessibilità per fare questo tipo di cose quando l'hardware o il driver non possono.OpenCL è molto bello da usare se si cercano miglioramenti di prestazioni importanti con uno sforzo moderato, oltre a raggiungere il massimo teorico quando possibile. (i driver sono un po 'mal di testa, ma questo è sempre un problema con questo genere di cose e capisci le loro stranezze). –

Problemi correlati