Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用c+调用lapack和blas+; 我需要在我的C++代码中使用LAPACK和BLAS,我想链接Linux系统中的MKL、ACML或默认LAPACK和BLAS。不幸的是,它们在c中有不同的约定。例如,MKL(MKL_blas.h)中的zdotc是_C++_Lapack_Blas - Fatal编程技术网

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

用c+调用lapack和blas+; 我需要在我的C++代码中使用LAPACK和BLAS,我想链接Linux系统中的MKL、ACML或默认LAPACK和BLAS。不幸的是,它们在c中有不同的约定。例如,MKL(MKL_blas.h)中的zdotc是,c++,lapack,blas,C++,Lapack,Blas,从默认lapack和blas(fortran版本)调用zdotc为: 如果我希望我的代码使用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, i

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

如果我希望我的代码使用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
}
\ifdef FORTRAN\u无下划线
#定义F77名称(x)x
#否则
#定义F77名称(x)x##_
#恩迪夫
复数zdotc_包裹(整数n,常数复数*x,整数incx,常数复数*y,整数incy)
{
#如果已定义(使用_MKL)
复杂结果;
zdotc(结果和n、x和incx、y和incy)
返回结果;
#定义的elif(使用LAPACK)
返回F77NAME(zdotc)(&n,x,&incx,y,&incy);
#定义的elif(使用ACML)
...
#恩迪夫
}
虽然函数太多,但为每个函数编写包装都需要花费时间。我希望他们有一个独特的惯例。如果在代码中使用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
);
\ifndef FORTRAN\u复杂函数\u返回\u无效
外部复合体(
#否则
外部无效zdotc(复杂*retval,
#恩迪夫
常数int*n,
常数复合体*zx,
常数int*incx,
const complex*zy,
常量整数*incy
);
然后我可以通过以下方式调用此函数:

complex<double> result;
#ifndef FORTRAN_COMPLEX_FUNCTIONS_RETURN_VOID
result = zdotc(
#else
zdotc(&result,
#endif
&n, x, &incx, y, &incy);
复杂结果;
#ifndef FORTRAN\u复数函数\u返回\u无效
结果=zdotc(
#否则
zdoc&result,
#恩迪夫
&n、 (x,incx,y,incy),;

有什么建议?更好的解决方案?谢谢你的帮助。

< P>我在我的C++代码中使用LAPACK,我没有这个问题。你可以检查库。看看源代码/ Matrim.IMP.CPP文件。我有一个<代码>外部“C”包含我需要的函数的块,以
\uucode>结尾。我已经针对lapack/blas以及MKL编译了这段代码,没有问题。我使用了gcc和intel编译器。它还使用
framework Accelerate
在我的mac上编译,供应商提供的blas和lapack实现通常包括带有tr的符号下划线有问题,因为Fortran 77编译器最初就是这样工作的。现代的gfortran行为也是为了兼容而添加尾随下划线,但是有
-fno下划线来关闭它

对于您自己使用gfortran编译的代码,例如引用BLAS和LAPACK,您可以选择是直接返回复杂值,还是使用间接
结果
指针参数。要获得间接行为,请使用
-ff2c
编译。默认的gfortran行为是直接返回复杂值

避免代码中出现宏和换行符的最简单方法是,在添加的第一个参数中,在名称和复杂结果的间接返回值中使用尾随下划线。这将与供应商库兼容。然后使用
-ff2c
编译BLAS和LAPACK,使其在那里工作

为了获得最大的灵活性,您可以使用wrap函数。在wrapper中,您只需要担心是否直接返回复杂参数,而不需要对每个不同的库进行特殊处理

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
}
复数zdotc_换行(int n,常数复数*x,int incx,常数复数*y,int incy)
{
#如果已定义(FORTRAN\u复杂函数\u返回\u无效)
复杂结果;
ZDOC(结果和n、x和incx、y和incy);
返回结果;
#否则
返回ZDOC(n、x和incx、y和incy);
#恩迪夫
}

在BLAS中,只有少数几个函数需要包装:
CDOTU-CDOTC-ZDOTU-ZDOTC
。在LAPACK中,只有
CLADIV-ZLADIV
(我想).

谢谢。对于dgemm、dgetrf和dgetri,这三个库具有相同的约定。而对于zdotc类型的函数,它们是不同的。我明白了。我想您需要使用宏。那么,为函数名定义宏包装器如何?例如,使用一个宏,可以在名称中添加或不添加
必须为每个函数编写宏。我已经在文章中使用宏了,
#define F77NAME(x)x###(uu)
。问题是
zdoct
接受MKL和默认blas中的不同参数。谢谢。这非常有用。通过使用
-ff2c
编译blas和LAPACK,我可以解决问题。在编写库的同时,我希望其他人可以灵活地使用我的库。重新编译blas和LAPACK有点间接。我是试图通过添加一个定义来解决这个问题,它在我的问题中被更新。你有什么建议吗?更新了我的答案。谢谢你,这就是我最初所做的。我想现在没有更好的方法了。
complex<double> result;
#ifndef FORTRAN_COMPLEX_FUNCTIONS_RETURN_VOID
result = zdotc(
#else
zdotc(&result,
#endif
&n, x, &incx, y, &incy);
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
}