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

posted @ 2019-10-11 14:37  易得云  阅读(1284)  评论(0)    收藏  举报