Как реализовать простые параллельные вычисления на разных ядрах, используя MPI в Python - PullRequest
0 голосов
/ 02 февраля 2019

Я хочу реализовать простую вычислительную задачу параллельно.Допустим, у меня есть два массива, включая 2 компонента в каждом, и я хочу суммировать компоненты этого массива один за другим и сохранять их в новом массиве.Есть 4 комбинации компонентов (2х2).Простой код может быть записан в последовательном порядке , который использует только 1 ядро ​​, и операция суммирования выполняется на этом ядре 4 раза.Вот код:

a = [1 , 5]
b = [10 , 20]

d = []

for i in range(2):
    for j in range(2):

        c = a[i] + b[j]
        d.append(c)

print (d)

Теперь я хочу использовать MPI , чтобы запустить вышеуказанный код параллельно , чтобы использовать 4 разных ядра на моем ПК, чтобы сделать егоБыстрее.С учетом сказанного я хочу, чтобы каждая комбинация была реализована на назначенном ядре (например, 4 операции суммирования на 4 разных ядрах).Вот как я могу импортировать MPI:

from mpi4py import MPI
mpi_comm = MPI.COMM_WORLD
rank_process = mpi_comm.rank

Я никогда не использовал параллельные вычисления, поэтому это немного сбивает меня с толку.Мне было интересно, может ли кто-нибудь помочь мне с этим.Заранее спасибо за ваше время.

1 Ответ

0 голосов
/ 04 февраля 2019

Вы можете использовать Create_cart, чтобы назначить процессы MPI частям матрицы, чтобы им могли быть присвоены индексы i и j, как в вашем последовательном примере.Вот решение,

from mpi4py import MPI
mpi_comm = MPI.COMM_WORLD
rank = mpi_comm.rank
root = 0

#Define data
a = [1 , 5]
b = [10 , 20]
d = []

#Print serial solution
if rank == 0:
    for i in range(2):
        for j in range(2):
            c = a[i] + b[j]
            d.append(c) 

    print("Serial soln = ", d)

#Split domain into 2 by 2 comm and run an element on each process
cart_comm = mpi_comm.Create_cart([2, 2])
i, j = cart_comm.Get_coords(rank)
d = a[i] + b[j]

#Print solns on each process, note this will be jumbled
# as all print as soon as they get here
print("Parallel soln = ", d)

# Better to gather and print on root
ds = mpi_comm.gather(d, root=root)
if rank == root:
    print("Parallel soln gathered = ", ds)

, где вы получите что-то вроде,

('Serial soln = ', [11, 21, 15, 25])
('Parallel ('Parallel soln = '('Parallel soln = 'soln = ', 11)
, 21)
('Parallel soln = ', 15)
, 25)
('Parallel soln gathered = ', [11, 21, 15, 25])

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

mpiexec -n 4 python script_name.py

, где script_name.py - это имя вашего скрипта.

Я не уверен, что это очень хороший пример того, как выиспользовал бы MPI.Стоит прочитать MPI в целом и взглянуть на некоторые канонические примеры.В частности, обратите внимание, что, поскольку каждый процесс независим от своих собственных данных, вы должны работать над проблемами, которые можно разбить на части.В вашем примере все списки a и b определяются индивидуально для каждого процесса, и каждый процесс использует только небольшую их часть.Единственное различие между каждым процессом - это ранг (от 0 до 3), а затем и двумерные декартовы индексы из create_cart, которые определяют, какую часть «глобального» массива они используют.

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

...