简单记录一个mpi4py.MPI并行计算代码
简单分享一个mpi4py.MPI入门的编程实例
最近需要优化电磁场仿真速度,本着学习一下mpi4py并行方面的知识,找了半天网上找不到编程实例,最后自己总结了一下稍微给大家分享一个小的并行计算实例,mpi4py的库安装以及一些常识大家可以在官网上找到,这里我不过多叙述了。
前言
大概讲一下要实现的程序功能:
我需要对一个建模好的结构进行参数扫描,每个参数之间互不影响,所以可以将传统串行更改为并行程序。
提示:以下是本篇文章正文内容,下面案例可供参考
一、原始串行代码
示例:假设我已经有一个写好的函数Unitcell(涉及专业知识,代码不放上去了),这个函数的输入是(结构参数1, 结构参数2, 入射波长, 结构参数3),输出是某个电磁相应,我的目标是对结构参数3进行扫描得到这个电磁响应的谱。
代码如下(示例):
from mpi4py import MPI
import numpy as np
import meep as mp
def Unitcell(gp, gh, lcen, gdc):
...
return phase
gh = 0.5
gp = 0.2
r = 0.632 # lcen
gdc = np.linspace(0.1, 0.9, 48) #结构参数3,参数扫描列表
for i in range(len(gdc)):
mode_tran = UnitCell(gp, gh, r, gdc[i]) # 扫描
二、使用mpi4py并行
1.简单写一个numpy.array拆分函数
代码如下(示例):
#自己简单写的一个numpy.array拆分函数,为了方便后面的散发操作,可以将一个一维数组根据并行进程数拆分
def Division(a):
comm = MPI.COMM_WORLD
size = comm.Get_size()
rol= len(a)/size
rol = int(rol)
Division_array = np.zeros((size, rol))
for i in range(rol):
Division_array[:, i] = a[i*size:(i+1)*size]
return Division_array
2.并行程序
代码如下(示例):
from mpi4py import MPI
import numpy as np
import meep as mp
def Unitcell(gp, gh, lcen, gdc):
...
return phase
def Division(a):
comm = MPI.COMM_WORLD
size = comm.Get_size()
rol= len(a)/size
rol = int(rol)
Division_array = np.zeros((size, rol))
for i in range(rol):
Division_array[:, i] = a[i*size:(i+1)*size]
return Division_array
gh = 0.5
gp = 0.2
r = 0.632
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
if rank == 0:
gdc = np.linspace(0.1, 0.9, 48)
gdc = Division(gdc)
else:
gdc = None
local_data = comm.scatter(gdc, root=0)
print(local_data)
for i in range(len(local_data)):
mode_tran = UnitCell(gp, gh, r, local_data[i])
all_max = comm.reduce(mode_tran, root=0, op=MPI.MAX)
if rank == 0:
print('maxis:%d' % all_max)
mpiexec -n 8 python mpi.py #使用8个进程
总结
使用8个进程并行后时间成本大约变为以前的1/8,在大型科学计算中效果显著。
如有错误,欢迎斧正和交流。