c-xxxxx_()、LAPACK_xxxx()和LAPACKE_xxxxx()函数之间的差异



假设我想使用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,这似乎。。。奇怪的

第二个函数具有几乎相同的签名,除了前缀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在这个文件中,有一些关于错误处理的小的附加更改。

  • CCD_ 24在报头lapacke.h中被定义为CCD_。宏LAPACK_GLOBAL是在lapack_mangling.h中定义的:它只是包装dgesv_,如果使用其他约定,则关心命名约定。

所以,基本上,函数LAPACK_dgesv()只需要lapacke的头。与dgesv_相比,可以避免库中与命名约定有关的一些问题。但CCD_ 30与CCD_。函数CCD_ 32扩大了CCD_。但最终还是调用了dgesv_

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

相关内容

  • 没有找到相关文章

最新更新