xxxxx_()、LAPACK_xxxxx() 和 LAPACKE_xxxxx() 函数之间的区别
Difference between xxxxx_(), LAPACK_xxxxx() and LAPACKE_xxxxx() functions
假设我想使用 LAPACK 求解 C (GCC) 中的线性方程组。
我设置问题如下:
/* Want to solve Ax=b */
int n = ...; // size
double *A = ...; // nxn matrix
double *b = ...; // length-n vector
int m = 1; // number of columns in b (needs to be in a variable)
double *pivot; // records pivoting
int info; // return value
现在看来我可以使用三个函数中的一个来解决这个问题。
第一个是这样的:
dgesv_( &n, &m, A, &n, pivot, b, &n, &info );
我很惊讶地发现这不需要任何 #include
s,这看起来......很奇怪。
第二个函数具有几乎相同的签名,除了前缀 LAPACK_
,我认为它会导致歧义较少并且可能更不容易出错:
#include <lapack/lapacke.h>
LAPACK_dgesv( &n, &m, A, &n, pivot, b, &n, &info );
请注意,这需要我包含 lapacke.h
。
第三个函数通过返回 info
而不是将所有参数都作为指针来稍微更改签名:
#include <lapack/lapacke.h>
info = LAPACKE_dgesv( LAPACK_COL_MAJOR, n, m, A, n, pivot, b, n);
同样,此函数需要 lapacke.h
。它还需要使用 -llapacke
链接到一个额外的库。
这三个函数都需要 -llapack
.
我正在尝试找出这些函数之间的区别。
我四处窥探了一下,在 lapacke.h
和相关的头文件中发现了以下宏:
#define LAPACK_GLOBAL(name,NAME) name##_
#define LAPACK_dgesv LAPACK_GLOBAL(dgesv,DGESV)
所以 LAPACK_dgesv()
和 dgesv_()
似乎是完全相同功能的不同名称。
但是,LAPACKE_dgesv()
似乎是另外一种可能具有不同实现方式的东西,特别是考虑到它需要一个额外的库这一事实。
所以我的问题是:这两个函数有什么区别?
文档说LAPACKE是LAPACK的C接口,但是函数dgesv_()
呢?
很明显,我可以正常使用它而不需要 LAPACKE,也不需要在 Fortran 中编译任何东西,那有什么不同呢?
谢谢。
更新
奇怪的是,函数 dgemm_()
(矩阵乘法)没有任何等价的 LAPACK_dgemm()
。
怎么回事?
注意 LAPACKE_dgesv()
有一个额外的标志,它可以是 LAPACK_COL_MAJOR
(通常的 fortran 顺序)或 LAPACK_ROW_MAJOR
(通常的 c 顺序)。在 LAPACK_COL_MAJOR
的情况下,它只是直接调用 LAPACK_dgesv()
。在 LAPACK_ROW_MAJOR
的情况下,LAPACKE_dgesv()
将在调用 LAPACK_dgesv()
之前转置矩阵。它不是 dgesv_()
的新实现。看看 lapack-3.5.0/lapacke/src/dgesv_work.c 在这个文件中,有一些关于错误处理的小的额外变化。
LAPACK_dgesv()
在 header lapacke.h 中定义为 LAPACK_GLOBAL(dgesv,DGESV)
。宏 LAPACK_GLOBAL
在 lapacke_mangling.h 中定义:它只是包装 dgesv_
并在使用其他约定时关心命名约定。
所以,基本上,函数LAPACK_dgesv()
只需要lapacke的headers。与dgesv_
相比,可以避免一些与库中的命名约定相关的问题。但是 LAPACK_dgesv()
和 dgesv_()
完全一样。函数 LAPACKE_dgesv()
扩大了 LAPACK_dgesv()
的范围来处理通常的 c matrix.But 它最后仍然调用 dgesv_
.
函数dgemm()
is part of the BLAS library. A wrapped c version cblas_dgemm()
can be found in CBLAS。同样,需要一个附加标志 CBLAS_ORDER
,可能的值为 CblasRowMajor
和 CblasColMajor
.
假设我想使用 LAPACK 求解 C (GCC) 中的线性方程组。 我设置问题如下:
/* Want to solve Ax=b */
int n = ...; // size
double *A = ...; // nxn matrix
double *b = ...; // length-n vector
int m = 1; // number of columns in b (needs to be in a variable)
double *pivot; // records pivoting
int info; // return value
现在看来我可以使用三个函数中的一个来解决这个问题。 第一个是这样的:
dgesv_( &n, &m, A, &n, pivot, b, &n, &info );
我很惊讶地发现这不需要任何 #include
s,这看起来......很奇怪。
第二个函数具有几乎相同的签名,除了前缀 LAPACK_
,我认为它会导致歧义较少并且可能更不容易出错:
#include <lapack/lapacke.h>
LAPACK_dgesv( &n, &m, A, &n, pivot, b, &n, &info );
请注意,这需要我包含 lapacke.h
。
第三个函数通过返回 info
而不是将所有参数都作为指针来稍微更改签名:
#include <lapack/lapacke.h>
info = LAPACKE_dgesv( LAPACK_COL_MAJOR, n, m, A, n, pivot, b, n);
同样,此函数需要 lapacke.h
。它还需要使用 -llapacke
链接到一个额外的库。
这三个函数都需要 -llapack
.
我正在尝试找出这些函数之间的区别。
我四处窥探了一下,在 lapacke.h
和相关的头文件中发现了以下宏:
#define LAPACK_GLOBAL(name,NAME) name##_
#define LAPACK_dgesv LAPACK_GLOBAL(dgesv,DGESV)
所以 LAPACK_dgesv()
和 dgesv_()
似乎是完全相同功能的不同名称。
但是,LAPACKE_dgesv()
似乎是另外一种可能具有不同实现方式的东西,特别是考虑到它需要一个额外的库这一事实。
所以我的问题是:这两个函数有什么区别?
文档说LAPACKE是LAPACK的C接口,但是函数dgesv_()
呢?
很明显,我可以正常使用它而不需要 LAPACKE,也不需要在 Fortran 中编译任何东西,那有什么不同呢?
谢谢。
更新
奇怪的是,函数 dgemm_()
(矩阵乘法)没有任何等价的 LAPACK_dgemm()
。
怎么回事?
注意
LAPACKE_dgesv()
有一个额外的标志,它可以是LAPACK_COL_MAJOR
(通常的 fortran 顺序)或LAPACK_ROW_MAJOR
(通常的 c 顺序)。在LAPACK_COL_MAJOR
的情况下,它只是直接调用LAPACK_dgesv()
。在LAPACK_ROW_MAJOR
的情况下,LAPACKE_dgesv()
将在调用LAPACK_dgesv()
之前转置矩阵。它不是dgesv_()
的新实现。看看 lapack-3.5.0/lapacke/src/dgesv_work.c 在这个文件中,有一些关于错误处理的小的额外变化。LAPACK_dgesv()
在 header lapacke.h 中定义为LAPACK_GLOBAL(dgesv,DGESV)
。宏LAPACK_GLOBAL
在 lapacke_mangling.h 中定义:它只是包装dgesv_
并在使用其他约定时关心命名约定。
所以,基本上,函数LAPACK_dgesv()
只需要lapacke的headers。与dgesv_
相比,可以避免一些与库中的命名约定相关的问题。但是 LAPACK_dgesv()
和 dgesv_()
完全一样。函数 LAPACKE_dgesv()
扩大了 LAPACK_dgesv()
的范围来处理通常的 c matrix.But 它最后仍然调用 dgesv_
.
函数dgemm()
is part of the BLAS library. A wrapped c version cblas_dgemm()
can be found in CBLAS。同样,需要一个附加标志 CBLAS_ORDER
,可能的值为 CblasRowMajor
和 CblasColMajor
.