【问题标题】:Fortran: Whole array operations in Fixed Form SourceFortran:固定形式源中的整个数组操作
【发布时间】:2012-12-19 16:31:01
【问题描述】:

在使用我的子例程(我已将它们全部放在 MODULE 中)和以固定格式源代码编写的代码时(在 fortran77 天内),我一遍又一遍地收到“分段错误”错误。

原来的make文件(Linux平台)是一团糟,它只编译“.f”源,所以我不得不将我的文件扩展名从“.f90”改为“.f”,并留下了前7个我的模块中的列空白。 我的模块广泛使用整个数组操作和数组部分的操作,并且我以 F90 样式声明变量,其中许多是假定大小的数组。

我的问题:-虽然编译器编译这些模块(具有整个数组/数组部分操作)没有任何警告/错误,但是由于使用了模块,这是否是“分段错误”在遗留代码中使用整个数组/数组部分操作(保存在 .f 文件中)?

例如,我在“algebra.f”模块中编写了以下代码:

    function dyad_vv(v1,v2)     !dyadic product of two vectors
    real*8, dimension(:)::v1,v2
    real*8, dimension(size(v1,1),size(v2,1))::dyad_vv
    integer i,j
    do i=1,size(v1,1)
    do j=1,size(v2,1)
    dyad_vv(i,j)=v1(i)*v2(j)
    end do 
    end do
    end function
    !==================================        
    function dot_mv(m,v)   !dot product of a matrix and a vector
    real*8, dimension(:,:)::m
    real*8, dimension(:)::v
    real*8, dimension(size(m,1))::dot_mv
    integer i,j
    do i=1,size(m,1)
    dot_mv(i)=0.0000D0
    do j=1,size(v,1)
    dot_mv(i)=dot_mv(i)+m(i,j)*v(j)
    end do 
    end do        
    end function
    !==================================        
    function dot_vm(v,m)  !dot product of a vector and a matrix
    real*8, dimension(:)::v
    real*8, dimension(:,:)::m
    real*8, dimension(size(m,2))::dot_vm
    integer i,j
    do i=1,size(m,2)
    dot_vm(i)=0.0000D0
    do j=1,size(v,1)
    dot_vm(i)=dot_vm(i)+v(j)*m(j,i)
    end do 
    end do                
    end function

【问题讨论】:

  • 你在想什么?为什么要将代码从 Fortran 90 降级到 FORTRAN77 ?我们大多数人,当需要协调新旧代码时,抓住机会从 77 升级到 90。此外,您的 dot_product 例程似乎是多余的,可以被固有的 matmul 替换。至于您的问题,Fortran 程序中的分段错误通常来自(a)尝试访问数组边界之外的数组元素,或(b)过程实际参数和虚拟参数不匹配。这些中的任何一个似乎都很可能与您的代码混乱有关。
  • 您的参数是 assumed-shape 数组,而不是假定大小的数组。这些需要调用例程中的显式接口。你是通过“模块”理解Fortran 90 MODULEs 那你然后USE 在调用例程还是简单的“编译模块/单元”,也称为“源文件”?
  • @HristoIliev:感谢您纠正我有关数组名称的问题。我正在使用 fortran 模块,文件以 -- module module_name --- 开头,下面的语句是我的子例程:use module_name

标签: module segmentation-fault fortran


【解决方案1】:

稍微扩展一下我已经过长的评论:

Fortran 程序中的分段错误通常源于 (a) 尝试访问数组边界之外的数组元素,或 (b) 过程实际参数和伪参数不匹配。

幸运的是,巧妙地使用编译器可以帮助您发现这两种情况。对于 (a) 您需要打开运行时数组边界检查,对于 (b) 您需要打开编译时子例程接口检查。您的编译器手册会告诉您需要设置哪些标志。

现代 Fortran 的优点之一,特别是 modules 的优点是,您可以免费获得过程接口检查,编译器会在编译时检查该虚拟和实际参数匹配。

所以我不认为您的问题直接源于以固定源代码形式编写现代 Fortran。但我确实认为以固定源代码形式编写现代 Fortran 以避免重写您的 makefile 并避免升级某些 FORTRAN77 是一种非常不正当的活动,您会发现它在短期内很痛苦,从长远来看会后悔你继续开发退化的代码。

面对现实,立即重构。

【讨论】:

  • +1 我要做的第一件事是打开运行时边界检查。
  • @High-Performance-Mark :感谢您对问题的详细回复。
猜你喜欢
  • 2021-01-20
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多