在上一篇文章如何快过matlab?-MKL数值计算库的Fortran95接口使用及MKL文档下载中,我们简要介绍了Intel MKL库的Fortran95接口的使用。实际上,Intel MKL的C接口和Fortran77接口也经常使用,其主要原因在于,对于某些函数,目前的MKL库并不包含Fortran95接口,另外,当采用的语言是C或者C++时,调用C接口更为方便。
以lapack中的线性方程组求解为例,其调用Fortran77接口步骤如下:
(1)在vs中创建fortran项目,添加.f90源代码文件
(2)依据MKL的使用文档,确定所用函数的具体用法,在lapack中,求解线性方程组可通过两种方式进行:
(一)先调用Matrix Factorization下的函数,再调用Solving System of Linear Equations下的函数,对于常规线性方程组的求解,其调用的双精度的f77接口的函数为dgetrf和dgetrs,前者用于分解,后者用于求解;
(二)直接调用LAPACK Linear Equation Driver Routines下的dgesv,一步完成分解和求解的操作,本文采用该方式进行。
dgesv的函数具体说明如下:
依据文档中的参数的说明,在代码中定义相应参数即可。上述dgesv函数的参数中,n,nrhs,a和b分别是矩阵阶数,右端项列数,系数矩阵和右端向量,要求解的方程是a*x=b。要注意的是lda和ldb,其值应当>=max(1,n),实际中常取值n,ipiv为LU分解时的重排向量,是输出参数,info是表征求解是否成功的输出参数。
了解该函数的具体用法之后,编写的Fortran代码如下:
program Console1_MKL77
implicit none
integer,parameter::n=5,nrhs=1
real(kind=8)::a(n,n),rhs(n)
integer,parameter::lda=n,ldb=n
real(kind=8)::ipiv(n)
integer::info,i,j
do i=1,n
do j=1,n
a(i,j)=(i**2.0+j**2.0)**0.5
enddo
write(*,"(*(g0,3x))")a(i,:)
rhs(i)=1
enddo
call dgesv( n, nrhs, a, lda, ipiv, rhs, ldb, info )
write(*,*)"info",info
write(*,*)"solution:"
write(*,"(*(g0,3x))")rhs(:)
end program Console1_MKL77
(三)在vs中进行IntelMKL库使用的设置:对于Fortran77接口来说,其需要的设置十分简单,仅需在项目-属性-Fortran-Libraries设置使用MKL库即可(注意区分x64和x86工程):
(四)生成并运行代码:
由此可见,对于Fortran77接口,MKL库的使用仅需要在项目-属性-Fortran-Libraries设置使用MKL库,相对于Fortran95接口免去了手动填写lib名称及在代码里use相应的library,从设置方式上更易使用,但是函数的参数更多。
对于C接口,其与Fortran77接口的使用较为类似,也是仅需要在项目-属性-Intel Libraries for oneAPI设置使用MKL库即可
具体代码如下:
int main(int argc, char** argv)
{
lapack_int Rvalue;
int matrix_layout = LAPACK_COL_MAJOR;
const lapack_int n = 5,nrhs=1;
double* a = new double[n * n];
lapack_int lda = n;
lapack_int* ipiv = new lapack_int[n];
double* b = new double[n];
lapack_int ldb = n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
a[i + n * j] = pow(((i+1.0)*(i+1.0)
+ (j+1.0) * (j+1.0)), 0.5);
std::cout << a[i + n * j]<<" ";
}
std::cout<<std::endl;
b[i] = 1.0;
}
LAPACKE_dgesv(matrix_layout, n, nrhs, a, lda, ipiv, b, ldb);
std::cout << "solution:" << std::endl;
for (int i = 0; i < n; i++)
{
std::cout << b[i] << std::endl;
}
return 0;
}
计算结果:
以上,就是Intel MKL库的F77和C接口的配置过程,感谢您的阅读!
【完】