使用CUDA,我试图在一个结构中分配数组,但我有一个问题,我不知道为什么。所以这里有一个简短的代码(存储在一个名为struct.cuf
的文件中)来描述我的问题。我正在使用PGI 16.10 version
进行编译,我使用以下选项:-O3 -Mcuda=cc60 -tp=x64 struct.cuf -o struct_out
module structure
contains
type mytype
integer :: alpha,beta,gamma
real,dimension(:),pointer :: a
end type mytype
type mytypeDevice
integer :: alpha,beta,gamma
real,dimension(:),pointer,device :: a
end type mytypeDevice
end module structure
program main
use cudafor
use structure
type(mytype) :: T(3)
type(mytypeDevice),device :: T_Device(3)
! For the host
do i=1,3
allocate(T(i)%a(10))
end do
T(1)%a=1; T(2)%a=2; T(3)%a=3
! For the device
print *, 'Everything from now is ok'
do i=1,3
allocate(T_Device(i)%a(10))
end do
!do i=1,3
! T_Device(i)%a=T(i)%a
!end do
end program main
输出错误:
Everything from now is ok
Segmentation fault
我在这里做错了什么?
我找到(并且正在工作)的唯一解决方案是将值存储在不同的数组中并将它们传输到GPU,但它非常重#34;大多数情况下,如果我使用很多像mytype这样的结构。
编辑:代码已被修改为使用Vladimir F的解决方案。如果我从device
声明中删除T_Device(3)
属性,那么分配似乎没问题并且也给出了值(在分配下面的注释行)。但我需要device
的{{1}}属性,因为我会在内核中使用它。
谢谢!
答案 0 :(得分:1)
我认为你需要一个设备指针
type mytype_device
...
real,dimension(:),pointer, device :: a
end type
在我的生活中从未使用过CUDA Fortran,但下注似乎已经足够明显了。
答案 1 :(得分:1)
这里的问题是您如何声明T_Device
。要使用主机端分配,首先要填充设备结构的主机内存副本,然后将其复制到设备内存。这样:
type(mytypeDevice) :: T_Device(3)
do i=1,3
allocate(T_Device(i)%a(10))
end do
将正常工作。这是基于C ++的CUDA代码中的非常标准设计模式,这里的原理是相同的。