Arrays 在Fortran中进行整个数组操作之前,我们是否应该检查数组的形状?

Arrays 在Fortran中进行整个数组操作之前,我们是否应该检查数组的形状?,arrays,matrix,fortran,Arrays,Matrix,Fortran,我想问一个关于Fortran中矩阵乘法错误处理的一般性问题 假设下面的代码 MODULE MatMulTest IMPLICIT NONE CONTAINS SUBROUTINE C_EQ_AB( A, B, C ) REAL, DIMENSION( :, : ), INTENT( IN ) :: A, B REAL, DIMENSION( :, : ), INTENT( OUT ) :: C C = MATMUL

我想问一个关于Fortran中矩阵乘法错误处理的一般性问题

假设下面的代码

MODULE MatMulTest
  IMPLICIT NONE
  CONTAINS
      SUBROUTINE C_EQ_AB( A, B, C )
          REAL, DIMENSION( :, : ), INTENT( IN ) :: A, B
          REAL, DIMENSION( :, : ), INTENT( OUT ) :: C

          C = MATMUL( A, B )

      END SUBROUTINE C_EQ_AB
END MODULE MatMulTest

PROGRAM MAIN
  USE MatMulTest
  IMPLICIT NONE
  REAL, DIMENSION( 3, 2 ) :: B, C
  REAL, DIMENSION( 2, 2 ) :: A

  CALL C_EQ_AB( A, B, C )

END PROGRAM MAIN
现在主程序在概念上是错误的,因为我们将(2,2)数组与(3,2)数组相乘。程序产生的错误是

Fortran runtime error: dimension of array B incorrect in MATMUL intrinsic

Error termination. Backtrace:
#0  0x10b5696a9
#1  0x10b56a365
#2  0x10b56a63a
#3  0x10b5f2bab
#4  0x10b563d27
#5  0x10b563e7d
#6  0x10b563eb6

从这个错误消息中,我们无法找到(或者我们可以?)错误发生的位置(假设有许多执行矩阵乘法的子例程)。那么,我们是否应该始终检查数组的边界或形状?如果是,那么如果有许多执行矩阵乘法的子程序,那么对计算速度有什么影响?有什么有效的方法来处理矩阵乘法错误吗?

您获得的信息取决于您的编译器,不同的编译器将为您提供不同的诊断

在gfortran中,您将获得关于哪个尺寸不符合要求以及左右两侧的形状的信息

为了找出它发生在哪里,你得到了回溯。然而,你只有一些地址,你不知道它们指向哪里。您必须使用编译器选项编译代码,如
-g
。请参阅编译器手册。然后,您将获得文件名和行号,而不是内存中的地址



您是否应该始终检查阵列形状?通常不会。通常,您设置代码,以便通过在程序早期的某个地方进行检查和正确的程序设计,不会发生这种不一致性。如果它确实是由于一个bug而发生的,那么您可以去查找并修复这个bug。您可以临时进行这些检查以查找bug。

对于生产代码,可能不

但是!我经常使用D行,并使用编译器开关-修复了开发代码,可以在没有D行的情况下重新编译


有时进行检查是值得的,因此我建议您尝试一下,看看您是否喜欢它。

这真的与
MATMUL
有关,还是与任何需要一致参数的函数几乎相同的问题?如果您的算法可能导致错误,您需要进行检查并接受性能影响。您使用什么调试标志来编译程序?看起来您使用的是gfortran。如果要获取行信息,请使用标志
-g-fbacktrace
编译。实际上我现在正在尝试此操作,但也没有获得行(使用
-g-fbacktarce
)。我可以使用
-fcheck=all
获得有关矩阵维度的更多信息,看起来它与版本有关。我在
4.4.7
中得到了很好的跟踪,但在
4.8.4
中没有。