2013-11-03 26 views
1

我有一个Fortran代码,其中有一个并行部分。它由gfortran成功编译,但运行它会导致分段错误。串行编译的运行文件不显示任何故障。我也用非常小的输入矩阵(rho1 & rho2)检查了并行程序并测试了逐步参数。没有错。如果我理解正确,当我确定变量为PRIVATE时,不需要使用 $OMP ATOMIC。这里矩阵rho1和rho2的尺寸约为15,000,000。这里是代码的并行部分:Fortran并行程序使用openmp的segmantation故障

!$OMP PARALLEL DO ORDERED DEFAULT(PRIVATE) 
    do ix = 1 , nx 
    do iy = 1 , ny 
     do iz = 1 , nz 
     k = iz + (iy-1) * nz + (ix-1) * ny * nz 
     if (rho1(k) .GT. 0.d0) then 
      x1 = x0 + ((ix-1) * dx) 
      y1 = y0 + ((iy-1) * dy) 
      z1 = z0 + ((iz-1) * dz) 
      rr = (x1-xa)**2 + (y1-ya)**2 + (z1-za)**2 
      r1a = dsqrt (rr) 
      rr = (x1-xb)**2 + (y1-yb)**2 + (z1-zb)**2 
      r1b = dsqrt (rr) 
      if (r1a == 0.d0) Vnuc = (rho1(k) * Znb)/r1b 
      if (r1b == 0.d0) Vnuc = (rho1(K) * Zna)/r1a 
      if (r1a .GT. 0.d0 .AND. r1b .GT. 0.d0) then 
      Vnuc = (rho1(k) * Zna)/r1a + (rho1(K) * Znb)/r1b 
      endif 
      Ve = 0 
      !$OMP ORDERED 
      j = 1 
      do jx = 1 , nx 
      do jy = 1 , ny 
      do jz = 1 , nz 
       if (rho2(j) .GT. 0.d0) then 
       x2 = x0 + ((jx-1) * dx) 
       y2 = y0 + ((jy-1) * dy) 
       z2 = z0 + ((jz-1) * dz) 
       rr= (x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2 
       r12 = dsqrt (rr) 
       if (r12 .GT. 0.d0) then 
       Ve = Ve + (rho1(k)*rho2(j))/r12 
       endif 
       endif 
       j = j + 1 
      enddo 
      enddo 
      enddo 
      !$OMP END ORDERED 
      V1 = (Ve * dx * dy * dz * 0.529177d0) - Vnuc 
      rr = (x1-xmid)**2 + (y1-ymid)**2 + (z1-zmid)**2 
      r = dsqrt (rr) 
      zef1(k) = V1 * r    
      endif 
     enddo 
    enddo 
    enddo 
    !$OMP END PARALLEL DO 
+0

作为一个开始,你是否尝试用例如'gfortran -fbounds-check -O0 -g -ggdb'或其他东西然后运行? – steabert

+0

第二条评论:不应该'ny'和'nz'是'firstprivate'? – steabert

+0

更多的变量应该可能共享。 –

回答

2

看起来好像你的阵列rho1rho2被声明为私有。这样做的一个结果是每个线程在进入并行区域时都会有这些数组的私有实例。如果数组很大,你的程序可能会试图分配更多的内存。

在不共享的大型数组上编写OpenMP程序相对不常见;在大型共享阵列的不同部分上运行的多个线程可能是OpenMP的规范应用程序。

+0

我试着让rho1和rho2变量共享,但是错误是一样的。我也尝试过让所有的变量共享,并且错误信息是一样的,尽管我用一个简单的输入来跟踪程序并且过程正确。 –

1

我在网站上发现了一些其他帖子的解决方案,“为什么分段错误发生在这个openmp代码中”。 问题是由于堆栈大小的限制。 它通过以下命令解决: ulimit -s unlimited

1

一个问题可能是当变量被声明为private时,每个线程都会创建该对象的单位化专用副本。您可能需要包含copyin openmp语句,以便私有变量在并行化区域之前具有该变量的值。