使用OpenMP在循环中调用函数时出现线程分段错误

时间:2018-03-31 05:22:13

标签: fortran openmp

我试图在Fortran 90中使用OpenMP来将do循环与函数调用并行化。首先列出的代码运行正常。接下来列出的代码没有。我收到了分段错误。

第一个程序:$ gfortran -O3 -o output -fopenmp OMP10.f90

program OMP10  

        !$ use omp_lib  
        IMPLICIT NONE  
        integer, parameter :: n = 100000  
        integer :: i  
        real(kind = 8) :: sum,h,x(0:n),f(0:n),ZBQLU01  
        !$ call OMP_set_num_threads(4)  
        h = 2.d0/dble(n)  
        !$OMP PARALLEL DO PRIVATE(i)  
        do i = 0,n  
                x(i) = -1.d0+dble(i)*h  
                f(i) = 2.d0*x(i)  
        end do  
        !$OMP END PARALLEL DO  
        sum = 0.d0  
        !$OMP PARALLEL DO PRIVATE(i) REDUCTION(+:SUM)  
        do i = 0,n-1  
                sum = sum + h*f(i)  
        end do  
        !$OMP END PARALLEL DO  
        write(*,*) "The integral is  ", sum  
end program OMP10  

第二个计划:$ gfortran -O3 -o output -fopenmp randgen.f OMP10.f90

program OMP10  

    !$ use omp_lib  
    IMPLICIT NONE  
    integer, parameter :: n = 100000  
    integer :: i  
    real(kind = 8) :: sum,h,x(0:n),f(0:n),ZBQLU01  
    !$ call OMP_set_num_threads(4)  
    h = 2.d0/dble(n)  
    !$OMP PARALLEL DO PRIVATE(i)  
    do i = 0,n  
            x(i) = ZBQLU01(0.d0)  
    end do  
    !$OMP END PARALLEL DO  
    sum = 0.d0  
    !$OMP PARALLEL DO PRIVATE(i) REDUCTION(+:SUM)  
    do i = 0,n-1  
            sum = sum + h*f(i)  
    end do  
    !$OMP END PARALLEL DO  
    write(*,*) "The integral is  ", sum  
end program OMP10  

在上面的命令中,randgen.f是一个包含函数ZBQLU01的库。

1 个答案:

答案 0 :(得分:0)

您不能只从并行区域调用任何函数。该函数必须是线程安全的。请参阅What is meant by "thread-safe" code?https://en.wikipedia.org/wiki/Thread_safety

您的功能与线程安全完全相反,这对于随机数生成器来说非常典型。只需注意源代码中的许多局部变量和公共块的SAVE语句。

解决方案是使用一个好的并行随机数生成器。该网站不是用于软件推荐,而是作为指针只搜索网络中的“并行prng”或“并行随机数生成器”。我亲自使用我已在https://stackoverflow.com/a/38263032/721644中指出的库。简单的网络搜索在https://jblevins.org/log/openmp中揭示了另一种简单的可能性。然后有许多更大,更复杂的库。