繁体   English   中英

在 C++ 中调用 lapack 和 blas

[英]call lapack and blas in c++

我需要在我的 C++ 代码中使用 lapack 和 blas,我想在 linux 系统中链接 MKL、ACML 或默认的 lapack 和 blas。 不幸的是,它们在 c 中有不同的约定。 例如,MKL ( mkl_blas.h ) 中的 zdotc 是

zdotc(&result, &n, x, &incx, y, &incy);

并从默认 lapack 和 blas(fortran 版本)调用 zdotc 是:

result = zdotc_(&n, x, &incx, y, &incy);

如果我希望我的代码使用 MKL、ACML 或默认 lapack 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
}

虽然有这么多函数,但为每个函数编写包装需要时间。 我希望他们有一个独特的约定。 如果你在你的代码中使用了 lapack 和 blas,你是如何解决这个问题的? 你有所有功能的包装吗? 如果有包装的话,如果你能和我分享,那就太好了。


更新:

我找到了解决这个问题的一种方法:

#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编译。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM