2013-08-01 58 views
7

我想在我的OpenCL內核中創建一個本地數組,它的大小取決於內核的參數。看起來這是不被允許的 - 至少在AMD應用程序中。OpenCL中不允許使用變長數組聲明 - 爲什麼?

您的體驗與衆不同嗎?也許它只是APP?或者在這裏有一些理由嗎?

編輯:我現在建議可變長度數組也應該允許在CPU端代碼中,這是C標準委員會的一個不幸的調用;但問題的立場。

回答

4

您可以動態分配本地塊的大小。您需要將其作爲內核的參數,並在調用clSetKernelArg時定義其大小。

定義的例子:

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

主機代碼:

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

確保您知道本地內存的限制是你的設備上你這樣做之前。調用clGetDeviceInfo,並輪詢「CL_DEVICE_LOCAL_MEM_SIZE」值。

+1

這是我正在使用的解決方法,但是 - 因爲這是可能的,爲什麼我不應該只能聲明一個變長數組或者調用一些OpenCL malloc-like函數來分配一個本地數組? – einpoklum

+0

我認爲它與現在的許多設備需要事先了解這些信息有關,因此他們可以安全地進行驗證和分配。我還不知道AMD的GCN架構將支持gpu-side malloc調用。 – mfa

+0

如果這是允許的,那麼你應該能夠動態地分配內核內的設備內存,返回alloc錯誤等等,而這在GPU中是不可能的。在內核級別,一切都需要是靜態的。正如他們所說,唯一的方法是從主機代碼中設置它。 – DarkZeros

3

不知道爲什麼人們說你不能這樣做,因爲它是許多人用OpenCL做的事情(是的,我知道它不完全相同,但它在很多情況下運行得很好)。

由於OpenCL內核是在運行時編譯的,就像文本一樣,您可以簡單地將大小設置爲任意大小,然後重新編譯內核。當你在大小上有很大的變化時,這顯然不會是完美的,但通常我會在啓動時編譯幾個不同的大小,然後根據需要調用正確的大小(基於內核參數)。如果我得到一個新的大小,我沒有一個內核,我將編譯它,然後緩存內核,以防它再次出現。

+0

嗯,是的,這確實開啓了一些有趣的可能性,但我必須說我不明白爲什麼OpenCL內核是在運行時編譯的,如果我可以編譯我的主機代碼儘管它可能是硬件專用的(x86_64比x86等),但我不明白爲什麼我的GPU代碼不應該這樣。無論如何,你會得到你的upvote .. – einpoklum

+0

我相信當硬件或驅動程序無法做到這些類型的東西時,就有靈活性。如果您只是在適度的努力下尋求主要的性能提升,並且在可能的情況下達到理論最大值,那麼OpenCL非常適合。 (駕駛員有點頭疼,但這總是與這些事情有關的問題,你找出他們的怪癖)。 –

相關問題