c# 调用 intel MKL 实现矩阵逆运算
intel MKL 运算速度快,根据这篇文章,可以用来计算矩阵的逆,但没有提供c#版本。查了查intel官网提供了一些例子,但不包含LAPACK中的dgetrf和dgetri,然后就想把两个结合一下。
第一步,下载官网提供的例子,下载官网的安装包(先要填好表单)安装MKL,安装后找到C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019\windows\redist\intel64_win\mkl,里面包含官网例子中用到的mkl_rt.dll;
第二步,尝试跑官网的例子,Intel_MKL_C#_Examples.zip 和 intel-mkl-c#-examples_02.zip,失败,提示缺东西,经多次尝试发现需要把libiomp5md.dll,mkl_core.dll,mkl_def.dll,mkl_intel_thread.dll,mkl_rt.dll 5个文件都复制到exe同级目录下才行;
第三步,调用dgetrf和dgetri,期间遇到了System.AccessViolationException, 第4个参数错误等等问题,最后在日语文章中找到了正确的封装方法。
class Program { static void Main(string[] args) { int n = 3; int info; double[] a = { 3,-1,-1, 4,-2,-1, -3,2,1 }; int m = n; printMatrix("a", a, m, n); info = inverse(a, m); printMatrix("a", a, m, n); Console.WriteLine("TEST PASSED"); Console.WriteLine(); } /** Print the matrix X assuming row-major order of elements. */ private static void printMatrix(String prompt, double[] X, int I, int J) { Console.WriteLine(prompt); for (int i = 0; i < I; i++) { for (int j = 0; j < J; j++) Console.Write("\t" + X[i * J + j]); Console.WriteLine(); } } public static int inverse(double[] a, int m) { int n = m; int lda = m; int[] ipiv = new int[m]; int order = ORDER.RowMajor; int info = 0; info = LAPACKNative.dgetrf(order, m, n, a, lda, ipiv); info = LAPACKNative.dgetri(order,m, a, lda, ipiv); return info; } } internal sealed class LAPACKNative { [DllImport("mkl_rt.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "LAPACKE_dgetrf",ExactSpelling = true, SetLastError = false)] internal static extern int dgetrf(int Order, int m, int n, double[] a, int lda, int[] ipiv); [DllImport("mkl_rt.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "LAPACKE_dgetri", ExactSpelling = true, SetLastError = false)] internal static extern int dgetri(int Order, int m, double[] a, int lda, int[] ipiv); }
运行结果:
a
3 -1 -1
4 -2 -1
-3 2 1
a
0 1 1
1 0 1
-2 3 2
TEST PASSED

浙公网安备 33010602011771号