1

使用 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,但它非常“重”。大多数情况下,如果我使用很多像 mytype 这样的结构。

编辑:代码已修改为使用 Vladimir F 的解决方案。如果我device从声明中删除属性T_Device(3),那么分配似乎没问题并且也给出了值(分配下方的注释行)。但我需要该device属性T_Device(3),因为我将在内核中使用它。

谢谢 !

4

2 回答 2

1

这里的问题是您如何声明T_Device. 要使用主机端分配,您首先填充设备结构的主机内存副本,然后将其复制到设备内存。这个:

type(mytypeDevice) :: T_Device(3)

do i=1,3
  allocate(T_Device(i)%a(10))
 end do

将正常工作。这是基于 C++ 的 CUDA 代码中非常标准的设计模式,这里的原理是相同的。

于 2017-06-22T10:57:38.087 回答
1

我认为你需要一个设备指针

type mytype_device
 ...
 real,dimension(:),pointer, device :: a
end type

在我的生活中从未使用过 CUDA Fortran,但它似乎足以下注。

于 2017-06-21T15:36:58.177 回答