如何在Python中使用MPI在不同的内核上实现简单的并行计算

时间:2019-02-02 20:01:44

标签: python-3.x parallel-processing mpi

我想并行实现一个简单的计算任务。可以说我有两个数组,每个数组包含2个组件,我想将这些数组的组件一一求和,然后将它们存储在新数组中。组件有4种组合(2x2)。可以使用仅使用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 并行运行以上代码,在我的PC上使用4个不同的内核,以使其更快。话虽这么说,我希望每个组合都在指定的内核上实现(例如,在4个不同的内核上进行4次求和操作)。这是我导入MPI的方法:

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

我从没使用过并行计算,因此对我来说有点困惑。我想知道是否有人可以帮助我。预先感谢您的宝贵时间。

1 个答案:

答案 0 :(得分:1)

您可以使用Create_cart将MPI进程分配给矩阵的各个部分,以便像在串行示例中一样,为它们分配索引ij。这是解决方案,

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,并看一些典型示例。特别要注意的是,由于每个流程都独立于其自己的数据,因此您应该研究可以将其拆分为多个部分的问题。在您的示例中,所有列表ab都是在每个进程上单独定义的,每个进程仅使用一小部分。每个进程之间的唯一区别是等级(0到3)以及后来来自create_cart的2D笛卡尔索引,它们确定了它们使用的“全局”数组的哪一部分。

一个更好的解决方案,更接近于您在实践中的使用方式,可能是将大型矩阵的一部分分散到许多过程中,使用矩阵的那一部分做一些工作,然后收集解决方案以获取完整的矩阵(同样,请参见涵盖此类内容的示例)。