Python多处理对角化

时间:2018-05-31 09:00:02

标签: python data-structures linear-algebra python-multiprocessing

我正在寻求帮助,因为我似乎无法找到任何解决方案。

我感兴趣的任务是对依赖于参数的(大)矩阵进行对角化(让我们称之为m)。我首先使用一个简单的for循环在我的Mac笔记本电脑上进行了计算,它似乎默认使用所有availbale核心(4)。但是现在我想在我的Linux机器(Ubuntu 18.04)上做同样的事情,有16个内核,但是由于GIL,程序只使用一个内核。

第一个问题,不同之处在于Mac Python解释器或numpy / scipy使用的线性代数库在Mac上而不是在Linux上自动并行化? 目前,我没有调查库(LAPACK,BLAS)问题。

然后,使用Python multiprocessing,我没有遇到任何问题,但我遇到的是数据结构。实际上,对于所有这些矩阵,我需要特征值和特征向量(以及m标签,但输入的顺序是自动保留的),但由于pool.map(或pool.starmap的结构在多个参数的情况下)我似乎无法找到收集整组特征值和特征向量的最有效方法。

你知道怎么做或任何好的参考? 我也非常感谢这个BLAS / LAPACK问题的帮助。

提前致谢,

PS:请参阅下面的天真代码示例。

def Diagonalize(m):

    Mat = np.array([[0, m+1],[m+1, 0]])
    eigenvalues, eigenvectors = np.linalg.eigh(Mat)

    return list([eigenvalues, eigenvectors]) # using list() was one of my attempts

Nprocesses = 4 # or whatever number

if __name__ == '__main__':

    with Pool(processes = Nprocesses) as pool:

         pool.map(Diagonalize, m_values) # EDIT m_values being whatever list

1 个答案:

答案 0 :(得分:0)

这是我为测试所做的,检查出来。

from multiprocessing import Pool
import scipy.sparse as sparse 
from scipy.sparse.linalg import eigs, eigsh
import time

def diagon(X):
    vals, vecs = eigs(X)
    return vals, vecs
if __name__ == "__main__":
    n = 10;
    p= .5;
    A = sparse.random(n,n,p)

    dataset = [A,A,A,A]
    n1 = len(dataset)
    eigvals =[]
    eigvecs = []
    t1 = time.time()

    p =Pool(processes = 4)

    result = p.map(diagon,dataset)
    p.close()
    p.join()

    print("Pool took:", time.time() - t1)
    for i in range(0,n1):
        eigvals.append(result[i][0])
        eigvecs.append(result[i][1])

好的,所以一些小的速度比较。我没有为Julia带来多处理方面,但是这在Python中花费的时间超过了100倍。

function gen_matrix(n,m)
%
%
    A = sparse((m+1)*eye(n))
    return A

end
n = 10;
m =6;

A = gen_matrix(n,m)

10×10 SparseMatrixCSC{Float64,Int64} with 10 stored entries:
  [1 ,  1]  =  7.0
  [2 ,  2]  =  7.0
  [3 ,  3]  =  7.0
  [4 ,  4]  =  7.0
  [5 ,  5]  =  7.0
  [6 ,  6]  =  7.0
  [7 ,  7]  =  7.0
  [8 ,  8]  =  7.0
  [9 ,  9]  =  7.0
  [10, 10]  =  7.0

t1 = time_ns()
(eigvals, eigvecs) = eigs(A)
t2 = time_ns()
elapsedTime = (t2-t1)/1.0e9
0.001311208

因为我还没能让PySparse部分运行。这解决了部分问题 效率。由于Python中的GIL,接下来将获得在Julia中测试它的map函数。