在c++中调用lapack和blas
call lapack and blas in c++
我需要在我的c++代码中使用lapack和blas,我想链接MKL, ACML或linux系统中的默认lapack和blas。不幸的是,它们在c中有不同的约定。例如,MKL (mkl_blas.h)中的zdot是
zdotc(&result, &n, x, &incx, y, &incy);
和调用zdotc从默认的包和blas (fortran版本)是:
result = zdotc_(&n, x, &incx, y, &incy);
如果我想让我的代码使用MKL、ACML或默认的包blas。我需要写一个换行:
#ifdef FORTRAN_NO_UNDERSCORE
#define F77NAME(x) x
#else
#define F77NAME(x) x##_
#endif
complex<double> zdotc_wrap(int n, const complex<double>*x, int incx, const complex<double>*y, int incy)
{
#if defined(USE_MKL)
complex<double> result;
zdotc(&result, &n, x, &incx, y, &incy)
return result;
#elif defined(USE_LAPACK_BLAS)
return F77NAME(zdotc)(&n, x, &incx, y, &incy);
#elif defined(USE_ACML)
...
#endif
}
虽然有这么多函数,但为每个函数编写换行需要花费时间。我希望他们有一个独特的惯例。如果您在代码中使用了包和包,如何解决这个问题?你有所有功能的包装吗?如果有结局,如果你能和我分享就太好了。
更新:
我找到了一个解决这个问题的方法:
#ifndef FORTRAN_COMPLEX_FUNCTIONS_RETURN_VOID
extern complex<double> zdotc(
#else
extern void zdotc(complex<double>* retval,
#endif
const int *n,
const complex<double> *zx,
const int *incx,
const complex<double> *zy,
const int *incy
);
然后我可以调用这个函数:
complex<double> result;
#ifndef FORTRAN_COMPLEX_FUNCTIONS_RETURN_VOID
result = zdotc(
#else
zdotc(&result,
#endif
&n, x, &incx, y, &incy);
有什么建议吗?更好的解决方案吗?谢谢你的帮助。
供应商提供的BLAS和LAPACK实现通常包括末尾带有下划线的符号,因为这是Fortran 77编译器最初的工作方式。现代的gfortran行为也是为了兼容性而添加末尾下划线,但是有一个-fno-underscoring
选项可以关闭它。
对于使用gfortran自己编译的代码,例如引用BLAS和LAPACK,您可以选择是直接返回复杂值还是使用间接的result
指针参数返回复杂值。为了得到间接行为,用-ff2c
编译。默认的gfortran行为是直接返回复杂的值。
避免在代码中使用宏和包装的最简单方法是在名称中假定尾随下划线,并在添加的第一个参数中假定复杂结果的间接返回值。这将与供应商库兼容。然后用-ff2c
编译BLAS和LAPACK使其在那里工作。
为了获得最大的灵活性,你可以使用换行函数。在包装器中,您只需要担心是否直接返回复杂的参数,不需要对每个不同的库进行特殊处理。
complex<double> zdotc_wrap(int n, const complex<double>*x, int incx, const complex<double>*y, int incy)
{
#if defined(FORTRAN_COMPLEX_FUNCTIONS_RETURN_VOID)
complex<double> result;
zdotc_(&result, &n, x, &incx, y, &incy);
return result;
#else
return zdotc_(&n, x, &incx, y, &incy);
#endif
}
在BLAS中,只有少数函数需要包装:CDOTU CDOTC ZDOTU ZDOTC
。在LAPACK中只有CLADIV ZLADIV
(我想)。
我在我的c++代码中使用lapack,我还没有遇到这个问题。您可以查看cosmo++库。查看source/matrix_impl.cpp文件。我有一个extern "C"
块,其中包含我需要的函数,以_
结束。我已经编译了这个代码对lapack/blas以及MKL没有问题。我用过gcc和intel编译器。它也可以在我的mac上编译framework Accelerate
。
- 直接在RcppArmadillo中调用LAPACK例程
- Armadillo正在为共享的lapack库获取未定义的参考
- LAPACK函数在第一次迭代后变慢
- BLAS 2 级波段矩阵向量积多个向量
- 有没有一种算法可以将 LAPACK 排列更改为真正的排列?
- Lapack函数DGTSV通过C /Visual Studio提供未解决的外部符号
- MATLAB faster than LAPACK?
- SuperLu和LaPack的比较在与犰狳进行基准测试时失败
- 检查并行化 BLAS 例程的结果
- Blas 和 Lapack 库是否有本机 C++(不是 C)接口?
- 推广到多个BLAS/LAPACK库
- 矩阵乘法的快速LAPACK/BLAS
- 在Windows 7的Qt Creator项目中链接MLPACK, Armadillo和LAPACK/BLAS
- 与LAPACK和BLAS的链接会导致c++异常无法处理
- BLAS/LAPACK未安装:如何安装
- 在c++中调用lapack和blas
- 可变大小阵列与LAPACK/BLAS
- 将英特尔的MKL(BLAS&LAPACK)连接到GCC
- Armadillo C++和BLAS和ATLAS在mingw32下找不到lapack BLAS
- C++中的矩阵操作(使用 Blas/Lapack 或其他替代方案)