我有一个(对我来说)非常奇怪的分割错误。起初,我认为由于openmp,我的4个内核之间存在干扰,但是从等式中删除openmp是不我想要的。事实证明,当我这样做时,段错误仍然会发生。
奇怪的是,如果我在内部的任何地方添加 print 或 write ,它就可以工作。
subroutine histogrambins(rMatrix, N, L, dr, maxBins, bins)
implicit none;
double precision, dimension(N,3), intent(in):: rMatrix;
integer, intent(in) :: maxBins, N;
double precision, intent(in) :: L, dr;
integer, dimension(maxBins, 1), intent(out) :: bins;
integer :: i, j, b;
double precision, dimension(N,3) :: cacheParticle, cacheOther;
double precision :: r;
do b= 1, maxBins
bins(b,1) = 0;
end do
!$omp parallel do &
!$omp default(none) &
!$omp firstprivate(N, L, dr, rMatrix, maxBins) &
!$omp private(cacheParticle, cacheOther, r, b) &
!$omp shared(bins)
do i = 1,N
do j = 1,N
!Check the pair distance between this one (i) and its (j) closest image
if (i /= j) then
!should be faster, because it doesn't have to look for matrix indices
cacheParticle(1, :) = rMatrix(i,:);
cacheOther(1, :) = rMatrix(j, :);
call inbox(cacheParticle, L);
call inbox(cacheOther, L);
call closestImage(cacheParticle, cacheOther, L);
r = sum( (cacheParticle - cacheOther) * (cacheParticle - cacheOther) ) ** .5;
if (r /= r) then
! r is NaN
bins(maxBins,1) = bins(maxBins,1) + 1;
else
b = floor(r/dr);
if (b > maxBins) then
b = maxBins;
end if
bins(b,1) = bins(b,1) + 1;
end if
end if
end do
end do
!$omp end parallel do
end subroutine histogramBins
我在f2py命令中启用了 -debug-capi :
f2py --fcompiler=gfortran --f90flags="-fopenmp -fcheck=all" -lgomp --debug-capi --debug -m -c modulename module.f90;
这给了我这个:
debug-capi:Fortran subroutine histogrambins(rmatrix,&n,&l,&dr,&maxbins,bins)'
At line 320 of file mol-dy.f90
Fortran runtime error: Aborted
它还会加载其他检查,列出给定的参数和其他子程序,等等。
无论如何,调用的两个子程序都是非并行子程序。我在其他几个子程序中使用它们,我认为最好不要使用另一个子程序的并行代码调用并行子程序。因此,在处理此功能时,不应激活其他功能。
这里发生了什么?如何添加“print *,;”会导致段错误消失?
感谢您的时间。
答案 0 :(得分:2)
打印语句影响并不常见 - 并创建或删除段错误。原因是它们改变了内存布局的方式,以便为正在打印的字符串腾出空间,或者如果你正在进行一些格式化,你将为临时字符串腾出空间。这种变化足以导致错误第一次出现崩溃或消失。
我看到你是用Python调用的。如果您正在使用Linux - 您可以尝试关注a guide to using a debugger with Fortran called from Python并找到导致崩溃的行和数据值。此方法也适用于OpenMP。您也可以尝试使用GDB作为调试器。
如果没有您的问题的源代码,我认为您不可能得到问题的“答案” - 但希望上述想法可以帮助您自己解决这个问题。
使用调试器(根据我的经验)现在使用调试器的可能性要小得多,而不是使用print语句(如果只使用一个线程,几乎肯定是这样)。 / p>