具有特征的高效块稀疏矩阵乘法

Efficient block-sparse matrix multiplication with Eigen

本文关键字:特征 高效      更新时间:2023-10-16

假设我有一个矩阵,它是稀疏的,除了沿对角线的块(固定大小)。

Eigen::SparseMatrix<float> lhs;

lhs约为2%非稀疏,但可能非常大。然后,假设有一个向量:

Eigen::MatrixXf rhs = Eigen::MatrixXf::Random(SomeSz, 1);

现在,我们假设它是稠密的

我想高效地计算:

result.noalias() = lhs * rhs;

如果我使用-O3 -march=native -mtune=native(使用Clang)进行编译,这会产生最佳结果吗?

如果rhs是稀疏的呢:

Eigen::SparseMatrix<float> rhs; rhs.resize(SomeSz, 1); rhs.reserve(SomeSz/SomeFactor);

:

result = lhs * rhs;

仍然最优/不佳?

我想我要问的是,Eigen是否会利用块稀疏结构,只执行必要的计算。

首先,在rhs的密集情况下,如果rhs是一个向量,那么请使用VectorXf告诉Eigen。然后,在Eigen 3.3中,您可以通过使用-fopenmp编译并使用lhs的行为主存储来利用多线程。

在稀疏情况下,yes Eigen将同时考虑lhs和rhs的稀疏性。与具有密集rhs的rhs.size()*average_nnz_per_col_of_lhs相比,复杂性实际上是rhs.nonZeros()*average_nnz_per_col_of_lhs。如果rhs真的很稀疏,那么值得一试。只考虑lhs中有用的一列。在这种情况下,最好保持lhs列为主。