簡體   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