Ifort 在访问共享变量时会在 OpenMP 并行化代码中出现段错误,但 gfortran 不会出现

问题描述 投票:0回答:1

我制作了一个更复杂的 Fortran 代码的最小示例,其中使用英特尔 Fortran 编译器 ifort 而不是使用 GNU 编译器 gfortran 编译和运行时出现分段错误。

如果我用

gfortran <source file> -fopenmp
编译它就可以了。

如果我使用

ifort <source file> -qopenmp
进行编译,运行后会出现分段错误。

在下面的最小示例中,分段错误似乎来自 y_index 在第 31 行“g = x + y(y_index)”处没有其初始化值。这是为什么?

program segfault
    implicit none
    integer  :: i, y_index
    real(16) :: x(20), y(20)

    x = 1
    y = 1
    y_index = 5
    !$omp parallel do shared(x,y,y_index) num_threads(1)
    do i=1, size(x)
      print*, 'g(x) = ', f(g, x(i))
    end do
    !$omp end parallel do

contains
    
    real(16) function f(g, x)
        real(16), intent(in) :: x
        
        interface
          real(16) function g(x)
            real(16), intent(in) :: x
          end function
        end interface
        
        f = g(x)
    end function
    
    real(16) function g(x)
        real(16), intent(in) :: x
        g = x + y(y_index)
    end function
    
end program

我尝试使用 OpenMP do 构造的 private、firstprivate 和共享子句。我还使用了 kind 参数,它似乎适用于 real(4) 和 real(8)。但我需要真实的(16)。我还将线程数设置为 1,以检查问题是否与多个线程的并行化有关。无论如何,分段错误都会出现。

segmentation-fault fortran openmp gfortran intel-fortran
1个回答
0
投票

ifort 使用 OpenMP 5.0 版本 TR4 https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2023-0/openmp-support.html。 OpenMP 5.0 版本 TR4 规范支持 Fortran 2003,其中不允许内部过程作为虚拟参数。请参阅 https://www.openmp.org/wp-content/uploads/openmp-tr4.pdf 中的第 24 和 34 页。

两种可能的解决方案:

  1. 将 g 放入模块中

  2. 创建一个过程指针 g_ptr => g 并将 g_ptr 传递给 f。

© www.soinside.com 2019 - 2024. All rights reserved.