如何在 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
以及向量 XP
和 YP
定义为双精度数:
integer, parameter :: DP = selected_real_kind(15)
因此,为此,您需要使用 dgemv
或将精度定义为单精度。
调用dgemv
和dgemv_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)
我想使用 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
以及向量 XP
和 YP
定义为双精度数:
integer, parameter :: DP = selected_real_kind(15)
因此,为此,您需要使用 dgemv
或将精度定义为单精度。
调用dgemv
和dgemv_f95
也有区别。 dgemv_f95
是英特尔 MKL 的一部分,并不是一个常见的命名方式。出于可移植性原因,我不会使用该表示法,而是坚持使用经典的 dgemv
,它也是英特尔 MKL 的一部分。
DGEMV
performs one of the matrix-vector operationsy := alpha*A*x + beta*y, or y := alpha*A**T*x + beta*y,
where
alpha
andbeta
are scalars,x
andy
are vectors andA
is anm
byn
matrix.
如果你想知道如何调用这个函数,我建议看一下here,但最终应该是这样的:
call DGEMV('N',3,3,ALPHA,A,3,XP,1,BETA,YP,1)