2

假设我想使用 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 );

我很惊讶地发现这不需要任何#includes,这看起来……很奇怪。

第二个函数具有几乎相同的签名,除了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()等价物。这是怎么回事?

4

1 回答 1

2
  • 请注意,它LAPACKE_dgesv()具有一个附加标志,可以是LAPACK_COL_MAJOR(通常的 fortran 顺序)或LAPACK_ROW_MAJOR(通常的 c 顺序)。在 的情况下LAPACK_COL_MAJOR,它只是LAPACK_dgesv()直接调用。在 的情况下LAPACK_ROW_MAJORLAPACKE_dgesv()将在调用之前转置矩阵LAPACK_dgesv()。它不是dgesv_(). 看看lapack-3.5.0/lapacke/src/dgesv_work.c在这个文件中,关于错误处理有一些额外的小改动。

  • LAPACK_dgesv()在头文件lapacke.h中定义为LAPACK_GLOBAL(dgesv,DGESV). 该宏LAPACK_GLOBAL在 lapacke_mangling.h 中定义:dgesv_如果使用其他约定,它只是包装并关心命名约定。

所以,基本上,这个函数LAPACK_dgesv()只需要 lapacke 的头文件。与 相比dgesv_,可以避免一些与库中命名约定相关的问题。但LAPACK_dgesv()与 完全一样dgesv_()。该函数LAPACKE_dgesv()扩大了LAPACK_dgesv()处理通常c矩阵的范围。但它dgesv_最终仍然调用。

该函数dgemm()是 BLAS 库的一部分。cblas_dgemm()可以在CBLAS中找到打包的 c 版本。同样,需要一个附加标志CBLAS_ORDER,带有可能的值CblasRowMajorCblasColMajor

于 2015-07-02T19:23:40.383 回答