我正在尝试将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
答案 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)
。