以Python并行计算PI值为例,本文中用到了python并行库mpi4py,在运行前安装对应的操作系统版本MPI,本文以Windows操作系统为例。
该段为求PI值的串行程序:
from mpi4py import MPI
import numpy as np
import time
def pi_comput(step):
partial_pi = 0
dx = 1/step
for i in np.arange(0,1,dx):
partial_pi += 4/(1+i*i)
return partial_pi*dx
pi=pi_comput(100000)
程序中利用了高等数学中PI值求值公式。
接下来将求值分为分为6个进程,进程0为主进程,负责汇集各进程计算出的结果;其余5个进程每个进程计算总区间的1/5。
from mpi4py import MPI
import numpy as np
import time
def pi_comput(start,end,step):
# if end-start>0&&end<1&&start>0:
partial_pi = 0
dx = (end-start)/step
for i in np.arange(start,end,dx):
partial_pi += 4/(1+i*i)
return partial_pi*dx
# else:
# print("Bad value! try again: ")
comm = MPI.COMM_WORLD#初始化
size = comm.Get_size()
rank = comm.Get_rank()
t0 = time.perf_counter_ns()
if rank == 1:#进程1,以下类推
send_data = pi_comput(0,0.2,10000)
print ("process {} send data {} to root".format(rank, send_data))
elif rank == 2:
send_data = pi_comput(0.2,0.4,10000)
print ("process {} send data {} to root".format(rank, send_data))
elif rank == 3:
send_data=pi_comput(0.4,0.6,10000)
print ("process {} send data {} to root".format(rank, send_data))
elif rank == 4:
send_data = pi_comput(0.6,0.8,10000)
print ("process {} send data {} to root".format(rank, send_data))
elif rank == 5:
send_data = pi_comput(0.8,1,10000)
print ("process {} send data {} to root".format(rank, send_data))
elif rank == 0:
send_data=0
recv_data = comm.gather(send_data, root=0)#计算结果汇总
if rank == 0:
print ("process {} gather all data {}, the sum is {}".format(rank, recv_data,np.sum(recv_data)))#将各进程计算结果求和并打印
t1 = time.perf_counter_ns()
print('time cost: %s processor cycles'%(t1-t0))
MPI.Finalize()
上述文件保存为PI.py,计算文件保存位置,执行时在Powershell 或cmd,Anaconda Prompt等控制台中输入:
mpiexec -np 6 python 文件路径(此处为文件保存路径,执行时替换为你的保存位置)/PI.py