openmp遗留代码的分段错误

时间:2013-12-15 05:37:18

标签: parallel-processing fortran openmp

我正在尝试将openmp应用于遗留的fortran代码,我尝试按照以下方式执行操作,但在运行代码时遇到运行时错误。

Line 89 of expect.f is the line: rv_avg(m) = rv_avg(m) + psi(k,m)*psi(k,m)*rosc(k)

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
main               0000000000411CE9  expect_                    89  expect.f
libiomp5.so        00002B13E9690FE3  Unknown               Unknown  Unknown
Command exited with non-zero status 174

我使用ulimit制作足够大的堆栈并导出KMP_STACKSIZE。我想知道出了什么问题以及有关如何优化遗留代码的任何建议。非常感谢!

login1$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 514847
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) unlimited
cpu time               (seconds, -t) unlimited
max user processes              (-u) 150
virtual memory          (kbytes, -v) 8388608
file locks                      (-x) unlimited
!$OMP PARALLEL shared(ng,nstates,natoms,psi,rosc,grt,frt)
!$OMP DO private(k,m)&
!$OMP& reduction(+:rv_avg,b_avg)
      do k = 1, ng
         do m = 0, nstates - 1
            rv_avg(m) = rv_avg(m) + psi(k,m)*psi(k,m)*rosc(k)
            b_avg(m) = b_avg(m) + psi(k,m)*psi(k,m)/(mu*rosc(k)**2)
         enddo
      enddo
!$OMP ENDDO 

!$OMP DO private(k,m,j)&
!$OMP& reduction(+:grt_avg)     
      do k = 1,ng
         do m = 0, nstates -1
            do j = 1, 3
               grt_avg(m,j) = grt_avg(m,j) + psi(k,m)*psi(k,m)*grt(k,j)
            enddo
         enddo
      enddo    
!$OMP ENDDO

!$OMP DO private(k,m,j,l)&
!$OMP reduction(+:frt_avg)
      do k = 1,ng  
         do m = 0, nstates -1
            do j = 1,3
               do l = 1, natoms
                  frt_avg(m,l,j) = frt_avg(m,l,j)   &
                       + psi(k,m)*psi(k,m)*frt(k,l,j)
                enddo
             enddo
         enddo
      enddo
!$OMP DO private(k,m,j,l,mp)&
!$OMP reduction(+:d_coup)      
      do k = 1,ng
         do m =0 , nstates - 1
            do j = 1,natoms
               do l = 1, natoms
                  do mp = 0, nstates - 1
                     d_coup(m,mp,l,j) = d_coup(m,mp,l,j)   &
                          + psi(k,m)*psi(k,mp)*frt(k,l,j)
                  enddo
               enddo
            enddo
         enddo
      enddo
!$OMP END DO
!$OMP END PARALLEL

1 个答案:

答案 0 :(得分:0)

我立刻怀疑这些行

     do m = 0, nstates - 1
        rv_avg(m) = rv_avg(m) + psi(k,m)*psi(k,m)*rosc(k)

因为他们建议代码读取和写入数组0的元素rv_avg。由于默认情况下Fortran数组索引是基于1的,因此这种访问可能会引起分段错误。

rv_avg的声明可能会设置0或更低的索引下限,可能是rv_avg(0:99)