1

我有一个 fortran 代码,其中有一个并行部分。它已gfortran成功编译,但运行它时出现分段错误。串行编译的运行文件没有显示任何故障。我还检查了具有非常小的输入矩阵(rho1 和 rho2)的并行程序,并逐步测试了参数。没有错。如果我理解正确,当我将变量确定为 时PRIVATE,无需使用 $OMP ATOMIC. 这里矩阵 rho1 和 rho2 的维数约为 15,000,000。这是代码的并行部分:

!$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
4

3 回答 3

2

它看起来好像您的数组rho1并被rho2声明为私有。这样做的一个结果是每个线程在进入并行区域时将拥有这些数组的私有实例。如果数组很大,您的程序可能只是试图分配比可用内存更多的内存。

在不共享的大型数组上编写 OpenMP 程序是比较少见的。在大型共享数组的不同部分上运行的多个线程可能是 OpenMP 的规范应用程序。

于 2013-11-03T16:08:27.537 回答
1

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

于 2013-11-06T06:18:01.510 回答
1

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

于 2014-06-06T17:11:07.820 回答