首页 文章

在c中调用lapack和blas

提问于
浏览
1

我需要在我的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);

有什么建议?好的解决方案谢谢您的帮助 .

2 回答

  • 1

    供应商提供的BLAS和LAPACK实现通常包括带有尾随下划线的符号,因为这是Fortran 77编译器最初的工作方式 . 现代gfortran行为也是为兼容性添加尾随下划线,但是有 -fno-underscoring option将其关闭 .

    对于使用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 (我认为) .

  • 0

    我在我的c代码中使用lapack而我没有遇到过这个问题 . 您可以查看cosmo++库 . 查看source / matrix_impl.cpp文件 . 我有一个 extern "C" 块,其中包含我需要的函数,以 _ 结尾 . 我已经针对lapack / blas以及MKL编译了这段代码而没有任何问题 . 我使用过gcc和intel编译器 . 它还用 framework Accelerate 在我的mac上编译 .

相关问题