Многопроцессорная диагонализация Python - PullRequest
0 голосов
/ 31 мая 2018

Я ищу помощи, потому что, кажется, я не могу найти какие-либо решения.

Задача, которая меня интересует, состоит в диагонализации (больших) матриц, которые зависят от параметра (назовем его m).Сначала я выполнил вычисления на своем ноутбуке Mac, используя простой цикл for, и он по умолчанию использует все доступные ядра (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 голосов
/ 01 июня 2018

Это то, что я сделал для теста, посмотрите.

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])

Итак, небольшое сравнение скорости.Я не получил многопроцессорный аспект для Джулии, однако это делало в 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.Это решает часть эффективности.Следующим будет получение функции карты, тестирующей ее в Julia из-за GIL в Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...