首页 > 解决方案 > 如何在 Python 中使用 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

我从来没有使用过并行计算,所以它看起来有点让我困惑。我想知道是否有人可以帮助我解决这个问题。在此先感谢您的时间。

标签: python-3.xparallel-processingmpi

解决方案


您可以使用 aCreate_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)和之后的 2D 笛卡尔索引create_cart,它决定了它们使用“全局”数组的哪一部分。

一个更好的解决方案,更接近您在实践中的使用方式,可能是将大型矩阵的部分分散到许多进程,使用矩阵的该部分做一些工作并收集解决方案以获得完整的矩阵(再次,请参阅涵盖此类事情的示例)。


推荐阅读