Arrays 在Fortran中进行整个数组操作之前,我们是否应该检查数组的形状?
我想问一个关于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
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
中没有。