CUDA-Fortran 设备数据结构中的可分配数组
Allocatable arrays in CUDA-Fortran device data structures
我正在尝试在驻留在 GPU 内存中的 "device" 数据结构中使用可分配数组。代码(粘贴在下面)可以编译,但会出现段错误。我做错了什么吗?
模块文件名为'gpu_modules.F90',如下:
!=============
! This module contains definitions for data structures and the data
! stored on the device
!=============
module GPU_variables
use cudafor
type :: data_str_def
!=============
! single number quantities
!=============
integer :: i, j
real(kind=8) :: a
!=============
! Arrays
!=============
real(kind=8), allocatable :: b(:)
real(kind=8), allocatable :: c(:,:)
real(kind=8), allocatable :: d(:,:,:)
real(kind=8), allocatable :: e(:,:,:,:)
end type data_str_def
!=============
! Actual data is here
!=============
type(data_str_def), device, allocatable :: data_str(:)
contains
!=============
! subroutine to allocate memory
!=============
subroutine allocate_mem(n1)
implicit none
integer, intent(in) :: n1
call deallocate_mem()
write(*,*) 'works here'
allocate(data_str(n1))
write(*,*) 'what about allocating memory?'
allocate(data_str(n1) % b(10))
write(*,*) 'success!'
return
end subroutine allocate_mem
!=============
! subroutine to deallocate memory
!=============
subroutine deallocate_mem()
implicit none
if(allocated(data_str)) deallocate(data_str)
return
end subroutine deallocate_mem
end module GPU_variables
主程序为'gpu_test.F90',如下:
!=============
! main program
!=============
program gpu_test
use gpu_variables
implicit none
!=============
! local variables
!=============
integer :: i, j, n
!=============
! allocate data
!=============
n = 2 ! number of data structures
call allocate_mem(n)
!=============
! dallocate device data structures and exit
!=============
call deallocate_mem()
end program
编译命令(来自当前文件夹)是:
pgfortran -Mcuda=cc5x *.F90
终端输出:
$ ./a.out
works here
what about allocating memory?
Segmentation fault (core dumped)
任何 help/insight 和解决方案将不胜感激..不,使用指针不是一个可行的选择。
编辑:另一个可能相关的细节:我使用的是 pgfortran 版本 16.10
分段错误的原因是您必须访问主机上 data_str 的内存才能分配 data_str(n1)%b。由于 data_str 在设备内存中,而不是主机内存中,因此您会遇到分段错误。理论上,编译器可以创建一个主机临时文件,分配它,然后将它复制到 data_str(n1)%b 的描述符,但这不是今天 CUDA Fortran 的一部分。
您可以通过自己创建临时文件来解决这个问题:
subroutine allocate_mem(n1)
implicit none
integer, intent(in) :: n1
type(data_str_def) :: data_str_h
call deallocate_mem()
write(*,*) 'works here'
allocate(data_str(n1))
write(*,*) 'what about allocating memory?'
allocate(data_str_h% b(10))
data_str(n1) = data_str_h
write(*,*) 'success!'
return
end subroutine allocate_mem
顺便说一句,您打算将组件 b、c、d 和 e 分配在主机内存还是设备内存中?我没有看到它们的设备属性,所以在上面,它们会转到主机内存。
所以我在 PGI 论坛上发布了这个问题,PGI 的一个人确认不支持该功能,因为我正在尝试使用它。
http://www.pgroup.com/userforum/viewtopic.php?t=5661
他的建议是使用 "managed" 属性或在数据结构中使用固定大小的数组。
我正在尝试在驻留在 GPU 内存中的 "device" 数据结构中使用可分配数组。代码(粘贴在下面)可以编译,但会出现段错误。我做错了什么吗?
模块文件名为'gpu_modules.F90',如下:
!=============
! This module contains definitions for data structures and the data
! stored on the device
!=============
module GPU_variables
use cudafor
type :: data_str_def
!=============
! single number quantities
!=============
integer :: i, j
real(kind=8) :: a
!=============
! Arrays
!=============
real(kind=8), allocatable :: b(:)
real(kind=8), allocatable :: c(:,:)
real(kind=8), allocatable :: d(:,:,:)
real(kind=8), allocatable :: e(:,:,:,:)
end type data_str_def
!=============
! Actual data is here
!=============
type(data_str_def), device, allocatable :: data_str(:)
contains
!=============
! subroutine to allocate memory
!=============
subroutine allocate_mem(n1)
implicit none
integer, intent(in) :: n1
call deallocate_mem()
write(*,*) 'works here'
allocate(data_str(n1))
write(*,*) 'what about allocating memory?'
allocate(data_str(n1) % b(10))
write(*,*) 'success!'
return
end subroutine allocate_mem
!=============
! subroutine to deallocate memory
!=============
subroutine deallocate_mem()
implicit none
if(allocated(data_str)) deallocate(data_str)
return
end subroutine deallocate_mem
end module GPU_variables
主程序为'gpu_test.F90',如下:
!=============
! main program
!=============
program gpu_test
use gpu_variables
implicit none
!=============
! local variables
!=============
integer :: i, j, n
!=============
! allocate data
!=============
n = 2 ! number of data structures
call allocate_mem(n)
!=============
! dallocate device data structures and exit
!=============
call deallocate_mem()
end program
编译命令(来自当前文件夹)是:
pgfortran -Mcuda=cc5x *.F90
终端输出:
$ ./a.out
works here
what about allocating memory?
Segmentation fault (core dumped)
任何 help/insight 和解决方案将不胜感激..不,使用指针不是一个可行的选择。
编辑:另一个可能相关的细节:我使用的是 pgfortran 版本 16.10
分段错误的原因是您必须访问主机上 data_str 的内存才能分配 data_str(n1)%b。由于 data_str 在设备内存中,而不是主机内存中,因此您会遇到分段错误。理论上,编译器可以创建一个主机临时文件,分配它,然后将它复制到 data_str(n1)%b 的描述符,但这不是今天 CUDA Fortran 的一部分。
您可以通过自己创建临时文件来解决这个问题:
subroutine allocate_mem(n1)
implicit none
integer, intent(in) :: n1
type(data_str_def) :: data_str_h
call deallocate_mem()
write(*,*) 'works here'
allocate(data_str(n1))
write(*,*) 'what about allocating memory?'
allocate(data_str_h% b(10))
data_str(n1) = data_str_h
write(*,*) 'success!'
return
end subroutine allocate_mem
顺便说一句,您打算将组件 b、c、d 和 e 分配在主机内存还是设备内存中?我没有看到它们的设备属性,所以在上面,它们会转到主机内存。
所以我在 PGI 论坛上发布了这个问题,PGI 的一个人确认不支持该功能,因为我正在尝试使用它。
http://www.pgroup.com/userforum/viewtopic.php?t=5661
他的建议是使用 "managed" 属性或在数据结构中使用固定大小的数组。