如何使用CUDA Fortran在结构中分配数组数组?

时间:2017-06-21 15:19:29

标签: arrays cuda fortran pgi

使用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}}属性,因为我会在内核中使用它。

谢谢!

2 个答案:

答案 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代码中的非常标准设计模式,这里的原理是相同的。