Fortran OpenACC 使用函数指针调用设备上的函数

标签 fortran function-pointers openacc

如何通过函数指针访问设备上的函数?

在下面的代码中,我尝试使用函数指针init访问init0init1。如果编译期间未启用 OpenACC,则代码确实可以按预期工作。但是,使用 OpenACC 编译时会失败。以下代码保存为 stackOverflow2.f95:

module modTest2

  use openacc
  implicit none

  
  type :: Container
    sequence
    integer :: n
    integer, allocatable :: arr(:)
  end type Container


  interface Container
    procedure :: new_Container
  end interface 


  abstract interface
    integer function function_template (i)
      integer, intent (in) :: i
    end function function_template
  end interface


  contains
  
    type(Container) function new_Container(n)
      integer, intent(in) :: n

      allocate(new_Container%arr(n))
    end function new_Container    
end module modTest2

program test2

  use modTest2
  implicit none


  integer :: n, x, i
  type(Container) :: c
  procedure(function_template), pointer :: init


  print *, "Enter array size: "
  read *, n
  print *, "Allocating..."
  c = Container(n)
  print *, "Allocation complete!"
  
  
  print *, "Enter initialization type (x): "
  read *, x
  print *, "Initializing..."
  select case (x)
    case (0)
      init => init0
    case default
      init => init1
  end select
  !$acc data copyin(c) copyout(c%arr)
  !$acc parallel loop present(c)
  do i = 1, n
    c%arr(i) = init(i)
  end do
  !$acc end data
  print *, "Initialization complete..."


  do i = 1, n
    print *, i, c%arr(i)
  end do
  
  
  contains
  
    integer function init0(i)
      !$acc routine
      integer, intent(in) :: i
      init0 = 10*i
    end function init0

    
    integer function init1(i)
      !$acc routine
      integer, intent(in) :: i
      init1 = 20*i
    end function init1
end program test2

在没有 OpenACC 的情况下可以看到正确的输出:

$ gfortran -c stackOverflow2.f95
$ gfortran stackOverflow2.o -o a.out
$ ./a.out
 Enter array size: 
3
 Allocating...
 Allocation complete!
 Enter initialization type (x): 
0
 Initializing...
 Initialization complete...
           1          10
           2          20
           3          30

下面使用 OpenACC 可以看到不正确的输出(请注意,此处使用了 NVIDIA 编译器):

$ /opt/nvidia/hpc_sdk/Linux_x86_64/22.1/compilers/bin/nvfortran stackOverflow2.f95 -acc; ./a.out
 Enter array size: 
3
 Allocating...
 Allocation complete!
 Enter initialization type (x): 
0
 Initializing...
 Initialization complete...
            1            0
            2            0
            3            0

最佳答案

抱歉,该设备尚不支持函数指针(以及 C++ 虚拟函数)。添加编译器反馈标志 (-Minfo=accel),您将看到以下消息:

% nvfortran -acc -Minfo=accel test.f90
test2:
     62, Generating copyout(c%arr(:)) [if not already present]
         Generating copyin(c) [if not already present]
     65, Accelerator restriction: Indirect function/procedure calls are not supported

问题是间接函数需要设备跳转表和运行时动态链接,但目前不可用。虽然我没有时间表,但我们正在探索 future 如何提供这种支持的选项。

关于Fortran OpenACC 使用函数指针调用设备上的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70818524/

相关文章:

c# - 带有函数参数的重载函数的奇怪模糊调用

c++ - 回调函数 C++

java - java代码可以使用open account在GPU上并行化吗

c++ - 如何在OpenAcc计算区域中直接(不使用指针作为函数参数)访问GPU上的数组?

fortran - 如何左对齐 Fortran 中的数字输出?

vim - vim 上的不同配色方案

不同模块上的 Fortran 扩展类型

module - Fortran 中 INCLUDE 和模块之间的区别

C++ std::function 语法问题

windows - OpenACC 与 OpenMP