我正在使用cuda fortran,並且我一直在一個簡單的內核中解決此問題,並且找不到解決方案。 是不是可以使用存儲在數組中的整數值作爲另一個數組的索引?當使用存儲在另一個陣列中的數組索引時,Cuda非法內存訪問錯誤
下面是一個簡單的例子(編輯還包括主程序):
program test
use cudafor
integer:: ncell, i
integer, allocatable:: values(:)
integer, allocatable, device :: values_d(:)
ncell = 10
allocate(values(ncell), values_d(ncell))
do i=1,ncell
values(i) = i
enddo
values_d = values
call multipleindices_kernel<<< ncell/1024+1,1024 >>> (values_d,
+ ncell)
values = values_d
write (*,*) values
end program test
!////////////////////////////////////////////////////
attributes(global) subroutine multipleindices_kernel(valu, ncell)
use cudafor
implicit none
integer, value:: ncell ! ncell = 10
integer :: valu(ncell)
integer :: tempind(10)
integer:: i
tempind(1)=10
tempind(2)=3
tempind(3)=5
tempind(4)=7
tempind(5)=9
tempind(6)=2
tempind(7)=4
tempind(8)=6
tempind(9)=8
tempind(10)=1
i = (blockidx%x - 1) * blockdim%x + threadidx%x
if (i .LE. ncell) then
valu(tempind(i))= 1
endif
end subroutine
我明白,如果有所述tempind陣列中重複的值不同的線程可以訪問相同的存儲器位置讀取或書面方式, 但事實並非如此。 儘管如此,這給出錯誤「0:拷貝Memcpy(主機= 0x303610,dev = 0x3e20000,大小= 40)失敗:77(遇到非法內存訪問)
有誰知道是否有可能使用來自cuda中的另一個數組的這些索引?
經過一些額外的測試後,我發現問題不在運行內核本身時發生,而是在將數據傳輸回CPU(如果刪除「值= values_d「,那麼不會顯示錯誤)另外,如果我通過valu(i)替換內核值(tempind(i)),它可以正常工作,但我希望索引來自數組,因爲這樣做的目的測試的目的是對索引存儲的CFD代碼進行並行化處理。
這是可能的,所以錯誤可能與價值有關。自從我做了CUDA Fortran以來,已經有一段時間了,但是它不應該具有設備屬性?無論如何,我建議你發佈一個完整的再現範例,否則任何人都很難幫助你。 – Jez 2014-10-01 23:12:05
內核子程序定義中的變量聲明(即使是參數)也不需要'device'屬性。然而,在主程序代碼中這是必需的(對於由內核子程序使用的變量)。這看起來很奇怪:'integer :: valu(ncell)'我會期望:'integer :: valu(:)'但它可能是好的。我同意需要一個完整的複製示例。 – 2014-10-01 23:35:45
嗨,謝謝你的答案。我編輯過也發佈了調用內核的簡單程序測試,並添加了其他註釋以幫助我們解決此問題的原因。 – renatogsousa 2014-10-02 09:45:33