码迷,mamicode.com
首页 > 编程语言 > 详细

Python 高性能并行计算之 mpi4py

时间:2018-08-16 00:48:26      阅读:1053      评论:0      收藏:0      [点我收藏+]

标签:poi   details   存在   拷贝   cal   target   规约   3.1   sdn   

MPI  和    MPI4PY   的搭建上一篇文章已经介绍,这里面介绍一些基本用法。

 

mpi4py  的  helloworld

from mpi4py import MPI
print("hello world")

 

mpiexec      -n     5    python3    x.py

技术分享图片

 

 

 

2.   点对点通信

因为  mpi4py 中点对点的 通信  send 语句  在数据量较小的时候是把发送数据拷贝到缓存区,是非堵塞的操作,   然而在数据量较大时候是堵塞操作,由此如下:

在 发送较小数据时:

import mpi4py.MPI as MPI
 
comm = MPI.COMM_WORLD
comm_rank = comm.Get_rank()
comm_size = comm.Get_size()
 
# point to point communication
data_send = [comm_rank]*5

comm.send(data_send,dest=(comm_rank+1)%comm_size)

data_recv =comm.recv(source=(comm_rank-1)%comm_size)

print("my rank is %d, and Ireceived:" % comm_rank)
print(data_recv)

技术分享图片

 

 

 

在数据量较大时,  比如发送  :

# point to point communication
data_send = [comm_rank]*1000000

这时候就会造成各个进程之间的死锁。(因为这时候各个进程是堵塞执行,每个进程都在等待另一个进程的发送数据)

 

 

 

修改后的代码,所有进程顺序执行, 0进程发送给1,1接收然后发送给2,以此类推:

import mpi4py.MPI as MPI
     
comm = MPI.COMM_WORLD
comm_rank = comm.Get_rank()
comm_size = comm.Get_size()
     
data_send = [comm_rank]*1000000

if comm_rank == 0:
   comm.send(data_send, dest=(comm_rank+1)%comm_size)

if comm_rank > 0:
   data_recv = comm.recv(source=(comm_rank-1)%comm_size)
   comm.send(data_send, dest=(comm_rank+1)%comm_size)

if comm_rank == 0:
   data_recv = comm.recv(source=(comm_rank-1)%comm_size)

print("my rank is %d, and Ireceived:" % comm_rank)
print(data_recv)

 

 

3   群体通信

3.1  广播bcast

一个进程把数据发送给所有进程

import mpi4py.MPI as MPI
 
comm = MPI.COMM_WORLD
comm_rank = comm.Get_rank()
comm_size = comm.Get_size()
 
if comm_rank == 0:
   data = range(comm_size)

dat = comm.bcast(data if comm_rank == 0 else None, root=0)

print(rank %d, got: % (comm_rank))
print(dat)

 

技术分享图片

发送方 也会收到  这部分数据,当然发送方这份数据并不是网络传输接受的,而是本身内存空间中就是存在的。

 

 

3.2   散播scatter

 

import mpi4py.MPI as MPI
 
comm = MPI.COMM_WORLD
comm_rank = comm.Get_rank()
comm_size = comm.Get_size()
 
if comm_rank == 0:
   data = range(comm_size)
else:
   data = None

local_data = comm.scatter(data, root=0)

print(rank %d, got: % comm_rank)
print(local_data)

 

 

 

技术分享图片

 

3.3  收集gather

将所有数据搜集回来

 

import mpi4py.MPI as MPI
 
comm = MPI.COMM_WORLD
comm_rank = comm.Get_rank()
comm_size = comm.Get_size()
 
if comm_rank == 0:
   data = range(comm_size)
else:
   data = None

local_data = comm.scatter(data, root=0)
local_data = local_data * 2

print(rank %d, got and do: % comm_rank)
print(local_data)

combine_data = comm.gather(local_data,root=0)

if comm_rank == 0:
    print("root recv {0}".format(combine_data))

 

技术分享图片

 

 

 

3.4  规约reduce

import mpi4py.MPI as MPI
 
comm = MPI.COMM_WORLD
comm_rank = comm.Get_rank()
comm_size = comm.Get_size()

if comm_rank == 0:
   data = range(comm_size)
else:
   data = None

local_data = comm.scatter(data, root=0)
local_data = local_data * 2

print(rank %d, got and do: % comm_rank)
print(local_data)

all_sum = comm.reduce(local_data, root=0,op=MPI.SUM)

if comm_rank == 0:
    print(sum is:%d % all_sum)

SUM   MAX   MIN  等操作在数据搜集是在各个进程中进行一次操作后汇总到  root 进程中再进行一次总的操作。

op=MPI.SUM

op=MPI.MAX

op=MPI.MIN

 

技术分享图片

 

 

 

 

 

 

 

 

参考文章:

Python多核编程mpi4py实践

https://blog.csdn.net/zouxy09/article/details/49031845

Python 高性能并行计算之 mpi4py

标签:poi   details   存在   拷贝   cal   target   规约   3.1   sdn   

原文地址:https://www.cnblogs.com/devilmaycry812839668/p/9484644.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!