如何在 Fortran 中正确调用 SGEMV?

How to properly call the SGEMV in Fortran?

我想使用 BLAS 的 SGEMV 子例程在 fortran 中执行矩阵向量乘积。 我有一个与此类似的代码:

program test
integer, parameter :: DP = selected_real_kind(15)
real(kind=DP), dimension (3,3) :: A
real(kind=DP), dimension (3) :: XP,YP
call sgemv(A,XP,YP)

A 是 3x3 矩阵,XP 和 YP 是向量。 在包含的模块中可以看到以下代码:

PURE SUBROUTINE SGEMV_F95(A,X,Y,ALPHA,BETA,TRANS)
    ! Fortran77 call:
    ! SGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
    USE F95_PRECISION, ONLY: WP => SP
    REAL(WP), INTENT(IN), OPTIONAL :: ALPHA
    REAL(WP), INTENT(IN), OPTIONAL :: BETA
    CHARACTER(LEN=1), INTENT(IN), OPTIONAL :: TRANS
    REAL(WP), INTENT(IN) :: A(:,:)
    REAL(WP), INTENT(IN) :: X(:)
    REAL(WP), INTENT(INOUT) :: Y(:)
END SUBROUTINE SGEMV_F95

我知道有些参数是可选的,那么我在方法调用中哪里错了?

也许 trans 参数是必需的?

trans: Must be 'N', 'C', or 'T'.

(根据 Developer Reference for Intel® Math Kernel Library - Fortran 底部的注释。)

精度不兼容。您调用的 sgemv 接受单精度参数,但您传递的是双精度数组和向量。

当您查看 BLAS 或 LAPACK 例程时,您应该始终查看第一个字母:

  • S: 单精度
  • D: 双精度
  • C: 单精度复数
  • Z: 双精度复数

您使用以下语句将矩阵 A 以及向量 XPYP 定义为双精度数:

integer, parameter :: DP = selected_real_kind(15)

因此,为此,您需要使用 dgemv 或将精度定义为单精度。

调用dgemvdgemv_f95也有区别。 dgemv_f95 是英特尔 MKL 的一部分,并不是一个常见的命名方式。出于可移植性原因,我不会使用该表示法,而是坚持使用经典的 dgemv,它也是英特尔 MKL 的一部分。

DGEMV performs one of the matrix-vector operations

y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,

where alpha and beta are scalars, x and y are vectors and A is an m by n matrix.

如果你想知道如何调用这个函数,我建议看一下here,但最终应该是这样的:

call DGEMV('N',3,3,ALPHA,A,3,XP,1,BETA,YP,1)