Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parallel processing OpenMP并行DO中的子例程-程序崩溃_Parallel Processing_Fortran_Openmp_Subroutine - Fatal编程技术网

Parallel processing OpenMP并行DO中的子例程-程序崩溃

Parallel processing OpenMP并行DO中的子例程-程序崩溃,parallel-processing,fortran,openmp,subroutine,Parallel Processing,Fortran,Openmp,Subroutine,我读过和。我的理解是: 参数列表中的变量从调用例程继承其数据范围属性 Fortran中的公共块或模块变量是共享的,除非声明为THREADPRIVATE Fortran中的保存变量是共享的 所有其他局部变量都是私有的 以下是我的代码的简化版本: !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(j,dummy1,dummy2,dummy3,dummy4) DO j=1,ntotal dummy1 = 0.0d0 dummy2 = foo(j) CA

我读过和。我的理解是:

  • 参数列表中的变量从调用例程继承其数据范围属性
  • Fortran中的公共块或模块变量是共享的,除非声明为THREADPRIVATE
  • Fortran中的保存变量是共享的
  • 所有其他局部变量都是私有的
以下是我的代码的简化版本:

!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(j,dummy1,dummy2,dummy3,dummy4)
DO j=1,ntotal
  dummy1 = 0.0d0
  dummy2 = foo(j)
  CALL kernel(dummy1,dummy1,dummy2,dummy3,dummy4)  
  Variable(j) = dummy3 + dummy4
END DO 
!$OMP END PARALLEL DO 
然后,子例程内核接收dummy1和dummy2,并输出dummy3和dummy4。我编译时使用:

 -fopenmp -fno-automatic -fcheck=all
我得到:

Fortran runtime error: Recursive call to nonrecursive procedure 'kernel'
据我所知,这是意料之中的。当我在没有-fcheck的情况下编译时,有时代码会毫无意外地通过子例程调用,但大多数情况下它会崩溃而不会出错。我猜这是因为我的子程序不是线程安全的。传递给子例程的所有参数对于每个线程都应该是私有的和独立的。修剪后的子例程如下所示:

SUBROUTINE kernel(r,dx,hsml,w,dwdx)   

  USE Initial_Parameters
  IMPLICIT NONE 

  ! DATA DICTIONARY: DECLARE CALLING PARAMETER TYPES AND DEFINITIONS
  REAL(KIND=dp), INTENT(IN)                 ::  r           
  REAL(KIND=dp), DIMENSION(dim), INTENT(IN) ::  dx          
  REAL(KIND=dp), INTENT(IN)                 ::  hsml        
  REAL(KIND=dp), INTENT(OUT)                ::  w           
  REAL(KIND=dp), DIMENSION(dim), INTENT(OUT)::  dwdx        
  ! DATA DICTIONARY: DECLARE LOCAL VARIABLE TYPES AND DEFINITIONS
  INTEGER                                   ::  i, d  
  REAL(KIND=dp)                             ::  q, dw
  REAL(KIND=dp)                             ::  factor      


  ! Kernel functions are funcitons of q, the distance between particles
  ! divided by the smoothing length  
  q = r/hsml 
  ! Preset the kernel to zero
  w = 0.e0
  ! Preset the derivative of the kernel to zero
  DO d=1,dim         
    dwdx(d) = 0.e0
  END DO   

  IF (skf == 1) THEN     

    ! If the problem is one dimensional then,
    IF (dim == 1) THEN
      ! The coefficient, alpha = factor is given by:
      factor = 1.e0/hsml
    ! If the problem is two dimensional then,
    ELSE IF (dim == 2) THEN
      ! The coefficient, alpha = factor is given by:
      factor = 15.e0/(7.e0*pi*hsml*hsml)
    ! If the problem is two dimensional then,
    ELSE IF (dim == 3) THEN
      ! The coefficient, alpha = factor is given by:
      factor = 3.e0/(2.e0*pi*hsml*hsml*hsml)
    ! If the dimension value is not 1, 2 or 3 then there is a problem.
    ELSE
       WRITE(*,*)' >>> Error <<< : Wrong dimension: Dim =',dim
       STOP
    END IF

    ! Smoothing function for 1st range of q.                                         
    IF (q >= 0 .AND. q <= 1.e0) THEN
      ! The smoothing function is given by:
      w = factor * (2./3. - q*q + q*q*q / 2.)
      ! For each dimension work out the gradient of the smoothing function
      DO d = 1, dim
        dwdx(d) = factor * (-2.+3./2.*q)/hsml**2 * dx(d)       
      END DO   

    ! Smoothing function for 2nd range of q.  
    ELSE IF (q > 1.e0 .AND. q <= 2) THEN  
      ! Smoothing function is equal to:        
      w = factor * 1.e0/6.e0 * (2.-q)**3 
      ! Gadient of the smoothing function in each dimension.
      DO d = 1, dim
        dwdx(d) =-factor * 1.e0/6.e0 * 3.*(2.-q)**2/hsml * (dx(d)/r)        
      END DO   

    ! Smoothing function and gradient for all other values of q is zero.
    ELSE
      ! Smoothing function is equal to: 
      w=0.
      ! Gadient of the smoothing function in each dimension.
      DO d= 1, dim
        dwdx(d) = 0.
      END DO             
    END IF     

END SUBROUTINE kernel
子程序内核(r、dx、hsml、w、dwdx)
使用初始参数
隐式无
! 数据字典:声明调用参数类型和定义
真实(种类=dp),意图(IN)::r
真实(种类=dp)、尺寸(尺寸)、意图(英寸)::dx
真实(种类=dp),意图(IN)::hsml
真实(种类=dp),意图(输出)::w
实际(种类=dp)、尺寸(尺寸)、意图(外部)::dwdx
! 数据字典:声明局部变量类型和定义
整数::i,d
实际(种类=dp)::q,dw
实际(种类=dp)::系数
! 核函数是q的函数,q是粒子之间的距离
! 除以平滑长度
q=r/hsml
! 将内核预设为零
w=0.e0
! 将内核的导数预设为零
DO d=1,变暗
dwdx(d)=0.e0
结束
如果(skf==1),则
! 如果问题是一维的话,
如果(dim==1),则
! 系数α=系数由下式给出:
系数=1.e0/hsml
! 如果问题是二维的,那么,
否则,如果(dim==2),则
! 系数α=系数由下式给出:
系数=15.e0/(7.e0*pi*hsml*hsml)
! 如果问题是二维的,那么,
否则,如果(dim==3),则
! 系数α=系数由下式给出:
系数=3.e0/(2.e0*pi*hsml*hsml*hsml)
! 如果尺寸值不是1、2或3,则存在问题。
其他的

使用
-fno automatic
写入(*,*)'>>>>错误,
内核中的局部变量将隐式地
保存
d。描述说明

在从并行区域调用的过程中声明了SAVE属性的局部变量被隐式共享

因此,
内核
确实不是线程安全的(据我所知)


请注意,在您的示例中,您将
dummy1
作为第一个和第二个参数传递给
kernel
,但此例程的定义指定了标量中的第一个参数(
r
),而第二个(
dx
)是长度数组
dim
。我不确定这是否只是您的最小示例或真实代码的产物,但这可能会导致问题。您是否在模块内声明
内核
,然后使用该模块?这将生成有助于捕获此类内容的接口。

这是一个最小示例的产品。对于这个例子,代码是1D(dim=1),所以希望不会有什么不同。内核不在模块中,它是一个独立的子例程。@1QuickQuestion如果我试图编译类似这样的东西,我会得到
警告:参数“b”在(1)(秩-1和标量)
中的秩不匹配,但如果我将
子例程
放在
包含的
部分中(即存在接口)这将变成
错误:参数“b”在(1)(秩-1和标量)中的秩不匹配
,因此我会小心使用这种方法。如果没有
-fno automatic
,代码将编译,但根本不会运行@d_1999我将进一步研究这个问题。所有子程序现在都在一个模块中。修复了秩不匹配但传递秩1数组的问题。如果没有-fno automatic,即使我将其设置为只有1个线程,可执行文件也会立即崩溃。有什么办法可以解决这个问题吗?@1QuickQuestion如果在编译时没有
-fopenmp
,它还会崩溃吗?这次事故的性质是什么?如果你能用一个(新的)最小+完整的例子来更新你的问题,那么其他人将更容易重现错误并确定问题的来源。一个选项是删除
-fno automatic
并添加
-fmax stack var size=X
,其中
X
是一些小变量。我想知道你是不是刚用完了堆栈空间。您能否尝试运行
ulimit-s
并报告堆栈大小?请尝试运行
ulimit-s unlimited
,然后运行在没有
-fno automatic
的情况下编译的代码。