【问题标题】:Passing size as argument VS assuming shape in Fortran procedures将大小作为参数传递 VS 在 Fortran 过程中假设形状
【发布时间】:2018-06-03 11:20:08
【问题描述】:

我正在尝试决定这两个选项中的哪一个是最好的:

subroutine sqtrace( Msize, Matrix, Value )
  integer, intent(in)  :: Msize
  real*8,  intent(in)  :: Matrix(Msize, Msize)
  real*8,  intent(out) :: Value

  [instructions...]

end subroutine sqtrace

VS

subroutine sqtrace( Matrix, Value )
  real*8,  intent(in)  :: Matrix(:,:)
  real*8,  intent(out) :: Value

  if ( size(Matrix,1) /= size(Matrix,2) ) then
    [error case instructions]
  end if

  [instructions...]

end subroutine sqtrace

我了解当您编译时出现警告,第一种情况应在编译时自动检查对 sqtrace 的调用是否符合指示的大小。但是,我不知道编译器是否可以在给定参数可分配时执行这些检查,例如(如果这种分配取决于在运行时确定的其他事情,则更是如此)。第二个需要显式接口并且有更多代码(检查),但似乎会捕获更多错误。

使用每种方法的优点/缺点是什么?在哪些情况下应该使用一种而不是另一种?

【问题讨论】:

  • 可能以前处理过,可能从不同的角度来看。 It.可能会带来速度与假设形状的差异,在适当的情况下建议使用contiguous
  • 要求“首选方式”可能会导致人们选择基于意见关闭。也许你可以改写清楚地询问具体方面? (请注意,显式形状和假定形状不仅仅是一点点不同。)
  • “我知道当你编译时出现警告,第一种情况应该在编译时自动检查对 sqtrace 的调用是否符合指示的大小。” 也许,如果你使用使用正确的编译器可能会发生这种情况。通常不会进行检查。无论如何,调用站点的大小在编译时可能是未知的。显式大小参数来自过去,大多数时间都没有对参数进行检查。
  • @francescalus 不,这确实是一个广泛的问题。问题是我发现自己不断地在没有明确信念的情况下将我的编程从一种方式切换到另一种方式。而且我觉得我缺乏某种知识来帮助我制定如何使用它的标准,但不清楚这些知识到底是什么。
  • 我认为需要一个真正令人信服的理由来强制调用例程传递一个多余的大小参数。我什么都看不到。

标签: fortran allocation subroutine error-checking


【解决方案1】:

首先,一些术语。考虑声明为的虚拟参数

real :: a(n)                ! An explicit shape array
real :: b(:)                ! An assumed shape array
real, allocatable :: c(:)   ! A deferred shape array
real :: d(*)                ! An assumed size array

(延迟形状数组也可以是指针而不是可分配的)。

我不会回答在给定情况下哪个更好,但会简单地详细说明一些重要的特征,将选择权留给程序员。粗略地说,许多人将显式形状数组视为“Fortran 77”,并将形状数组视为“Fortran 90+”。


形状:

  • 显式形状数组的形状遵循其声明;
  • 假定形状数组虚拟参数的形状是实际参数的形状;
  • 延迟形状虚拟参数的形状可能未定义,在过程中或实际参数中已定义。

连续性:

  • 显式形状数组只是连续的;
  • 假定的形状数组虚拟参数的连续性与关联的实际参数的连续性相关;
  • 延迟形状虚拟参数可能是实际参数的参数,或者取决于过程的执行。

对实参的限制:

  • 与显式形状数组关联的实际参数必须至少具有与虚拟参数一样多的元素;
  • 与假定形状数组关联的实际参数本身不得假定为大小;
  • 与假定或延迟形状数组关联的实际参数必须与虚拟参数具有相同的等级。

调用范围内的接口:

  • 如果虚拟参数具有假定或延迟形式,则引用范围必须具有可访问过程的显式接口。

考虑real a(6)。这可能是假人的实际论据

real b(3)
real c(2,3)
real d(:)   ! With an explicit interface available

a(1::2) 可能与b 相关联,但由于b 是连续的,因此将涉及复制输入/复制输出。与d关联时不需要涉及复制输入/复制输出,但可以。

还有很多其他方面,但希望这是一个初步的高级介绍。

【讨论】:

  • 感谢您的概述!似乎这些是由您编译的,但是您是否碰巧知道是否有任何源材料明确详细介绍了不同类型的数组之间的差异以及使用其中一种或另一种的情况?我阅读的所有关于 fortran 的书籍通常只是单独介绍它们,并且没有明确列出这些差异。如果我想比介绍更进一步,我应该在哪里寻找它?
  • 一旦您对这些概念有了合理的理解,Fortran 标准文档实际上是非常可读的。在某些地方几乎没有交叉引用,但很快就会变得熟悉。或者,如果人们继续在这里提出好问题,我建议关注他们。
  • @Eular,可能存在性能差异,但可以预期这与过程引用的一般开销相当。主要的实际性能差异在于连续性方面:显式形状虚拟参数始终是连续的(可能涉及制作临时副本)。
猜你喜欢
  • 2011-07-03
  • 2015-12-09
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多