Умножение матриц с параллельным программированием в numpy python

#python #numpy #matrix #parallel-processing #multiplication

#python #numpy #матрица #параллельная обработка #умножение

Вопрос:

Я новичок в python, но мне нужно преобразовать обычный код умножения матрицы в параллельный с помощью numpy, мне нужно преобразовать эту функцию в параллельный способ:

 
def RowByColumn(A, B):
    matrix=[]
    for i in range(len(A)):
        matrix.append([])
        for j in range(len(B)):
            matrix[i].append(matrix_multiplication(getRow(A,i),getColumn(B,j)))
    return matrix


 

Как я могу применить многопроцессорный модуль или другие модули параллельной обработки в python, кто-нибудь может мне помочь?

Комментарии:

1. Должна ли это быть общая матрица для умножения на матрицу или матрица на вектор?

2. Это просто упражнение в многопроцессорной обработке, или вы пытаетесь улучшить скорость AC@BC ?

3. Да, я пытаюсь увеличить скорость и сократить время, используя параллельное программирование с умножением матриц на python.

4. Вы пробовали искать что-то вроде «параллельная обработка с помощью numpy»?

5. Встроенное умножение матриц использует скомпилированные BLAS (или аналогичные библиотеки) функции. Они были оптимизированы и могут использовать низкоуровневую параллельную обработку (в зависимости от системы и библиотеки). Многопроцессорная обработка на уровне Python вряд ли улучшит это.

Ответ №1:

Я не рекомендую многопроцессорную обработку, поскольку процессы создаются медленно, а также требуют больших затрат на связь. Вы можете использовать numba, который скомпилирует вашу функцию и сделает ее действительно быстрой. Библиотека действительно хорошо работает с numpy. Кроме того, очень легко включить распараллеливание с потоками:

 import numpy as np
from numba import njit, prange

@njit(parallel=True)
def mat_mult(A, B):
    assert A.shape[1] == B.shape[0]
    res = np.zeros((A.shape[0], B.shape[1]), )
    for i in prange(A.shape[0]):
        for k in range(A.shape[1]):
            for j in range(B.shape[1]):
                res[i,j]  = A[i,k] * B[k,j]
    return res

m, n, c = 1000, 1500, 1200
A = np.random.randint(1, 50, size = (m, n))
B = np.random.randint(1, 50, size = (n, c))

res = mat_mult(A, B)
 

Используется prange для распараллеливания циклов. Я распараллелил только внешний цикл, но вы также можете применить это к внутренним циклам.

Обратите также внимание на порядок циклов, которые я использовал, что позволяет осуществлять непрерывный доступ к памяти, уменьшая промахи кэша.

На моем ноутбуке выполнение параллельной функции занимает около 1,4 секунды, в то время как умножение матрицы numpy A@B занимает 4,4 секунды, так что есть некоторое улучшение.

Комментарии:

1. Спасибо, вы объяснили это самым простым способом!