2013-11-03 74 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語句,以便私有變量在並行化區域之前具有該變量的值。