首页 > 解决方案 > 通过 C++ Eigen 库使用英特尔 MKL Sparse BLAS 扩展

问题描述

我想通过 Eigen C++ 库使用 Intel MKL Sparse BLAS。我检查了 Eigen https://eigen.tuxfamily.org/dox/TopicUsingIntelMKL.html的文档。这似乎不适用于英特尔 MKL Sparse BLAS。我发现的唯一 MKL Sparse 示例是英特尔 MKL PARDISO 接口。

因此,我想问这个问题是否支持?

非常感谢!

标签: c++11sparse-matrixeigenintel-mkl

解决方案


Eigen 目前不支持 MKL Sparse BLAS 例程。然而,有人开始集成更新的 MKL Inspector-Executor 界面,尽管它自 2018 年以来一直没有激活。我自己没有尝试过。

https://bitbucket.org/eigen/eigen/pull-requests/473/add-support-of-intel-r-mkl-inspector/diff

或者,您可以为您的 Eigen 矩阵创建一个 MKL 稀疏矩阵句柄并在其上执行一些 MKL 操作。我的解决方案并不优雅,但足以进行测试。

static void EigenToMKLSparseCSR(const SparseMatrix<double> &A_Eigen, sparse_matrix_t &A_MKL)
{
    int m = (int)A_Eigen.rows();
    int n = (int)A_Eigen.cols();
    double *values = (double*)A_Eigen.valuePtr();

    if (A_Eigen.IsRowMajor)
    {
        int *rows_start = (int*)A_Eigen.outerIndexPtr();
        int *rows_end = (int*)A_Eigen.outerIndexPtr() + 1;
        int *col_indx = (int*)A_Eigen.innerIndexPtr();
        mkl_sparse_d_create_csr(&A_MKL, SPARSE_INDEX_BASE_ZERO, m, n, rows_start, rows_end, col_indx, values);
        mkl_sparse
    }
    else
    {
        int *cols_start = (int*)A_Eigen.outerIndexPtr();
        int *cols_end = (int*)A_Eigen.outerIndexPtr() + 1;
        int *row_indx = (int*)A_Eigen.innerIndexPtr();
        mkl_sparse_d_create_csc(&A_MKL, SPARSE_INDEX_BASE_ZERO, m, n, cols_start, cols_end, row_indx, values);
        mkl_sparse_convert_csr(A_MKL, SPARSE_OPERATION_NON_TRANSPOSE, &A_MKL);
    }
    mkl_sparse_set_memory_hint(A_MKL, SPARSE_MEMORY_AGGRESSIVE);
    mkl_sparse_optimize(A_MKL);
}

请注意,我假设您的标量类型是双精度。您可以将其设为接受 float、double、MKL_Complex8 和 MKL_Complex16 的模板。老实说,我不知道是什么SPARSE_MEMORY_AGGRESSIVE,但我把它扔在那里是为了很好的衡量标准。

请注意,Eigen 默认为列优先存储,而 MKL(大多数情况下)要求您使用行优先存储。具有讽刺意味的是,此例程不适用于 intel 编译器!它确实适用于 Visual Studio 2017。


推荐阅读