"总线错误 "和 "munmap_chunk(): Fortran 95中的 "无效指针

问题描述 投票:0回答:1

我正在做一个python项目,为了提高效率,通过f2py调用fortran子程序。

当我执行这段代码时,它在看似随机(非一致)的点上失败,并出现Segmentation Fault错误。使用 faulthandler Python库,我把搜索范围缩小到了一个 Bus Errormunmap_chunk(): Invalid Pointer 错误,虽然错误仍然不一致。

鉴于错误的看似随机性,恐怕我无法提供一个MWE。我的Fortran代码是(节选的--完整版的 此处):

module event_rates
      contains
      subroutine event_rate_f95(events, edges, events_edges, lifetimes, lt_size, NBins)
            implicit none
            ! define input parameters
            ! define internal variables

            dtd = delay_time_distribution(lifetimes, edges, NBins)
            print *, "DTD generated"
            do i = 1, NBins+1
                  t1 = events_edges(i-1)
                  t2 = events_edges(i)
                  print *, "Ts done"

                  z1 = estimate_redshift(t1)
                  z2 = estimate_redshift(t2)

                  print *, 'computing sfr'

                  SFR = compute_SFR(z1, z2) / (1E-3) ** 3

                  print *, "about to enter inner loop"

                  do j = 0, i-1
                        ! do a computation
                  enddo

                  print *, "exited inner loop"
                  print *, i
            enddo
      end subroutine
end module event_rates

哪儿 delay_time_distribution, estimate_redshift, compute_SFR 是我前面定义的函数。供参考。NBins 大约是50,每当我调用这个。在最近的3次执行中,它失败了。

1) i=20 里面 estimate_redshift(),

(2) 在 delay_time_distribution() 职能。

3)Fortran代码终止并将控制权返回给Python后。

从阅读这些错误的背景资料来看,似乎是内存管理的问题,因为Segmentation Faults访问的是我不能访问的内存,Bus Errors访问的是不存在的内存,而 munmap_chunk() 传递了错误的指针到一个FREE指令。但我依靠Fortran 95的内置内存管理来处理这个问题。监视 htop 当代码执行时,显示我的一个核心的CPU使用量激增,但内存使用量保持不变。

我的问题有两点:是什么原因导致这些错误,以及如何进一步调试这个一般情况?

python f2py fortran95
1个回答
0
投票

调试问题

有一个简单的方法来调试。使用调试标志.

你可能知道,如果你用gfortran编译FORTRAN,你可以通过 -fcheck=boundsgfortran 命令。同样,你也可以通过 --opt='-fcheck=bounds'f2py3 命令来调试这个问题。

这个具体问题

我试图访问一个数组是错误的。请考虑粘贴栏的第122行。

bin_low = floor(NBins * (x1 - NBins) / (NBins))

如果 x1 = 0那么 bin_low = -NBins. 其中,由于 NBins (你所拥有的仓数)是正数,就变成负数。在FORTRAN中,你不能用负的索引进入一个数组--那是访问无效的内存,也就是seg fault。

这里的解决方案是约束索引。

bin_low = max(1, floor(NBins * (x1 - NBins) / (NBins)))

这样一来,如果公式给了你一个负数,你就可以访问第一个数组。(记住,FORTRAN是1-索引的)

© www.soinside.com 2019 - 2024. All rights reserved.