【问题标题】:Matrix (scipy sparse) - Matrix (dense; numpy array) multiplication efficiencyMatrix (scipy sparse) - 矩阵(dense; numpy array) 乘法效率
【发布时间】:2017-09-18 16:08:25
【问题描述】:

我是一名从事地球物理反演的研究员。这需要求解线性系统:Au = rhs。这里 A 通常是稀疏矩阵,但 rhs 和 u 可以是密集矩阵或向量。为了进行基于梯度的反演,我们需要进行灵敏度计算,并且需要大量的矩阵-矩阵和矩阵-向量乘法。最近在矩阵(稀疏)-矩阵(密集)乘法中发现了一个奇怪的行为,下面是一个例子:

import numpy as np
import scipy.sparse as sp
n = int(1e6)
m = int(100)
e = np.ones(n)
A = sp.spdiags(np.vstack((e, e, e)), np.array([-1, 0, 1]), n, n)
A = A.tocsr()
u = np.random.randn(n,m)

%timeit rhs = A*u[:,0]
#10 loops, best of 3: 22 ms per loop    
%timeit rhs = A*u[:,:10]
#10 loops, best of 3: 98.4 ms per loop
%timeit rhs = A*u
#1 loop, best of 3: 570 ms per loop​

当我增加密集矩阵 u 乘以稀疏矩阵 A 的大小时,我预计计算时间几乎是线性增加的(例如第二个 A*u[:,:10] 对我来说应该是 220 毫秒,最后一个 @987654325 @ 2.2 秒)。但是,它比我预期的要快得多。相反,矩阵向量乘法比矩阵矩阵乘法慢得多。有人可以解释为什么吗?此外,有没有一种有效的方法来提高矩阵向量乘法与矩阵矩阵乘法相似的效率水平?

【问题讨论】:

  • 你/我必须深入挖掘函数调用堆栈来进行这些乘法运算。这不是一项微不足道的任务。显然,它不仅仅是遍历u 的列并收集值。这是一个sparse*dense=>dense 案例,与sparse*sparsedense*dense 不同。

标签: python numpy scipy


【解决方案1】:

如果您查看source code,您可以看到csr_matvec(实现矩阵-向量乘法)在C 代码中实现为简单的求和循环,而csr_matvecs(实现矩阵-矩阵乘法)被实现为对axpy BLAS 例程的调用。根据您的安装链接到的 BLAS 库,这样的调用可能比用于矩阵向量乘法的直接 C 实现更有效。这可能就是您看到矩阵向量乘法如此缓慢的原因。

更改 scipy 以便它在矩阵向量情况下调用 BLAS 可能是对包的有用贡献。

【讨论】:

  • 我明白了。这就说得通了!感谢 jaekvdp。我想改变它,但没有使用 C,所以我不确定我是否可以为此做出贡献。嗯...但仍然是认识到我们可以改变的地方是一个好的开始!
猜你喜欢
  • 2013-12-26
  • 2013-10-21
  • 2013-01-06
  • 2018-11-16
  • 1970-01-01
  • 2017-07-21
  • 2016-05-08
  • 1970-01-01
  • 2011-04-22
相关资源
最近更新 更多