2012-04-27 61 views
3

我正在使用parallel.gpu.CUDAKernel在Matlab 2011a中啓動CUDA內核。我已經設計了我的代碼,以便在循環內部隨後的內核啓動時填充相同的gpuArray,但每次啓動都會將自己限制爲gpuArray的唯一段。在Matlab中啓動CUDA內核之間維護gpuArray數據

執行結束時,整個數組應該已滿。但是,當我使用gather()將內存傳回主機時,只有最後一次內核啓動時寫入的內存是正確的;一切都是空白的。如果我在中間的某處跳出循環,也是如此。

我已經證實,通過傳遞標誌來表示內核迭代的確是這種情況。如果它是第一次迭代之外的任何事情,那麼內核什麼都不做。但是,第一個內核寫入的數據位置仍然是空的,即使後續的內核不起作用!如果我在啓動第一個內核之後直接跳出循環,則情況並非如此。

因此,在我看來,Matlab重新啓動內核之間的gpuArray。有沒有辦法阻止它這樣做?

+0

並行計算工具箱中的gpuArray功能不是很強大。你最好用夾克。雖然因爲我在Jacket工作而感到有點偏見,但當我說你不應該在gpuArray上浪費時間時,我並不是在開玩笑。如果你不打算使用Jacket,你最好堅持使用CPU或者編寫你自己的CUDA代碼。 – arrayfire 2012-04-28 00:44:17

+0

這似乎是一個偉大的產品。不幸的是,作爲一名學生,我僅限於我大學提供的免費軟件和軟件。現在我要嘗試寫一個mex接口。 – Richard 2012-04-28 20:27:07

+0

聽起來不錯。如果您向IT部門發送便條,要求他們購買夾克,他們可能會這樣做。事實上,他們可能已經擁有夾克的許可證(目前大多數大學都有一些夾克許可證)。 – arrayfire 2012-04-29 02:07:40

回答

2

這應該工作,提供您捕獲feval調用的輸出。考慮一個簡單的內核是這樣的:

__global__ void setOneEl(double * array, double val, int element) { 
    array[element] = val; 
} 

然後,運行在MATLAB下面的代碼工作,因爲我相信你是後:

>> k = parallel.gpu.CUDAKernel('kern.ptx'); 
>> g = parallel.gpu.GPUArray.zeros(1,10); 
>> for ii = 1:2:10, g = k.feval(g, rand, ii); end 
>> gather(g) 
ans = 
     0 0.0975   0 0.2785   0 0.5469   0 0.9575   0 0.9649 

爲了與普通MATLAB語義一致,gpuArray對象值因此,當你想修改一個gpuArray實例時,你必須將輸出值捕獲回到同一個數組中,就像使用其他任何MATLAB數據類型一樣。但是,請注意,當您將結果捕獲到相同變量時,CUDAKernel.feval調用會理解,並且可以使用就地優化來避免進行復制。