专栏首页sktjpython mpi4py(并行编程 23)

python mpi4py(并行编程 23)

https://www.cnblogs.com/zhbzz2007/p/5827059.html

1.概述

MPI(Message Passing Interface),消息传递接口,是一个标准化和轻便的能够运行在各种各样并行计算机上的消息传递系统。消息传递指的是并行执行的各个进程拥有自己独立的堆栈和代码段,作为互不相关的多个程序独立执行,进程之间的信息交互完全通过显示地调用通信函数来完成。

mpi4py是构建在MPI之上的Python非官方库,使得Python的数据可以在进程之间进行传递。

2.MPI执行模型

并行程序是指一组独立、同一的处理过程;

  • 所有的进程包含相同的代码;
  • 进程可以在不同的节点或者不同的计算机;
  • 当使用Python,使用n个Python解释器; mpirun -np 32 python parallel_script.py

并行执行模型如下所示,

2.1 MPI基本概念

rank:给予每个进程的id;

  • 可通过rank进行查询;
  • 根据rank,进程可以执行不同的任务;

Communicator:包含进程的群组;

  • mpi4py中基本的对象,通过它来调用方法;
  • MPI_COMM_WORLD,包含所有的进程(mpi4py中是MPI.COMM_WORLD);

2.2 数据模型

所有的变量和数据结构都是进程的局部值;

进程之间通过发送和接收消息来交换数据;

image

2.3 使用mpi4py

from mpi4py import MPI
comm = MPI.COMM_WORLD   #Communicator对象包含所有进程
size = comm.Get_size()
rank = comm.Get_rank()
print "rank = %d,size = %d"%(rank,size)

2.4 安装mpi4py

MPI Python环境搭建

MPI Windows集群环境搭建

3.工作方式

工作方式主要有点对点和群体通信两种;点对点通信就是一对一,群体通信是一对多;

3.1 点对点

example 1

点对点发送Python内置dict对象;

#Broadcasting a Python dict
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()

if rank == 0:
    data = {"a":7,"b":3.14}
    comm.send(data,dest = 1,tag = 11)
    print "send data = ",data
elif rank == 1:
    data = comm.recv(source = 0,tag = 11)
    print "recv data = ",data

任意的Python内置对象可以通过send和recv进行通信,目标rank和源rank和tag都要互相匹配;

send(data,dest,tag)

  • data,待发送的Python内置对象;
  • dest,目标rank;
  • tag,发送消息的id;

recv(source,tag)

  • source,源rank;
  • tag,发送消息的id;

example 2

点对点发送Python内置dict对象,非阻塞通信;

#point to point communication Python objects with non-blocking communication
from mpi4py import MPI

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

if rank ==0:
    data = {"a":7,"b":3.14}
    req = comm.isend(data,dest = 1,tag = 11)
    req.wait()
    print "send data = ",data
elif rank == 1:
    req = comm.irecv(source = 0,tag = 11)
    data = req.wait()
    print "recv data = ",data

example 3

发送Numpy数组;

#point to point communication Python objects Numpy arrays
from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

# automatic MPI datatypes discovery
if rank == 0:
    data = np.arange(100,dtype = np.int)
    comm.Send(data, dest = 1,tag = 13)
    print "send data = ",data
elif rank == 1:
    data = np.empty(100,dtype = np.int)
    comm.Recv(data, source = 0,tag = 13)
    print "recv data = ",data

当发送消息时,任意的Python对象转换为字节流; 当接收消息时,字节流被转换为Python对象;

Send(data,dest,tag),Recv(data,source,tag),连续型数组,速度快;

send(data,dest,tag),recv(source,tag),Python内置对象,速度慢;

3.2 群体通信

群体通信分为发送和接收,发送是一次性把数据发给所有人,接收是一次性从所有人那里回收结果;

example 1

root进程新建data dict,然后将data数据广播给所有的进程,这样所有的进程都拥有这个data dict;

#Broadcasting a Python dict
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()

if rank == 0:
    data = {"key1":[7,2.72,2+3j],"key2":("abc","xyz")}
else:
    data = None

data = comm.bcast(data,root = 0)
print "rank = ",rank," data = ",data

example 2

root进程新建了一个list,然后将它散播给所有的进程,相当于对这个list做了划分,每个进程获得等分的数据,这里就是list中的每一个数字(主要根据list的索引来划分,list索引为第i份的数据就发送给第i个进程),如果是矩阵,那么久等分的划分行,每个进程获得相同的行数进行处理;

MPI的工作方式是每个进程都会执行所有的代码,每个进程都会执行scatter这个指令,但是只有root进程执行它的时候,它才兼备发送者和接收者的身份(root进程也会得到数据它自己的那份数据),对于其他进程来说,他们都只是接收者而已;

#Scattering Python objects
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

if rank == 0:
    data = [(i+1)**2 for i in range(size)]
else:
    data = None

data = comm.scatter(data,root = 0)
assert data == (rank+1)**2
print "rank = ",rank," data = ",data

example 3

gather是将所有进程的数据收集回来,然后合并成一个列表;

#Gathering Python objects
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

data = (rank+1)**2
data = comm.gather(data,root = 0)
if rank == 0:
    for i in range(size):
        assert(data[i] == (i+1)**2)
    print "data = ",data
else:
    assert data is None

example 4

广播Numpy数组;

#Broadcasting Numpy array
from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

if rank == 0:
    data = np.arange(100, dtype = 'i')
else:
    data = np.empty(100,dtype = 'i')
comm.Bcast(data,root = 0)
for i in range(100):
    assert(data[i] == i)
print "rank = ",rank," data = ",data

example 5

散播Numpy数组;

#Scattering Numpy arrays
from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

senbuf = None
if rank == 0:
    senbuf = np.empty([size,100],dtype = 'i')
    senbuf.T[:,:] = range(size)
recvbuf = np.empty(100,dtype = 'i')
comm.Scatter(senbuf,recvbuf,root = 0)
assert np.allclose(recvbuf,rank)
print "rank = ",rank," recvbuf = ",recvbuf

example 6

收集Numpy数组;

#Gathering Numpy array
from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

sendbuf = np.zeros(100, dtype='i') + rank
recvbuf = None
if rank == 0:
    recvbuf = np.empty([size, 100], dtype='i')
comm.Gather(sendbuf, recvbuf, root=0)
if rank == 0:
    for i in range(size):
        assert np.allclose(recvbuf[i,:], i)

4.Reference

mpi4py tutorial

Python多核编程mpi4py实践

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python性能测试locust(三)

    既然是多真实用户登陆,那我们系统里就要真实的存在这些用户,如果系统有创建用户的接口,直接调用即可

    周萝卜
  • NBA球星都喜欢在哪个位置出手?看见科比的统计图我惊呆了

    导读:NBA 2018-19 赛季已经落下帷幕,猛龙击败勇士,成为新科冠军球队。近日各队纷纷发布2019-20季前赛赛程,迎接新赛季。

    华章科技
  • 因为Python的这3个优点,我的薪资涨了一倍

    如果你对数据分析有所了解,一定听说过一些亲民的工具如Excel、Tableau、PowerBI等,都能成为数据分析的得力助手。但它们的不足也是显而易见的:操作繁...

    华章科技
  • Python可视化Dash教程简译(一)

    “ 作为数据分析的重要一环,把得到的数据或者分析结果以图表的方式展示,是一种直观、优雅的方式。Dash是基于Flask的Python可视化工具,我在学习之余尝试...

    周萝卜
  • 30行Python代码,再次撬动女人的心

    上一篇文章介绍了怎么给心上人推送微信消息,但是总是感觉还不够呀,毕竟自己的女人,怎么宠着都不算过分

    周萝卜
  • 3 行代码 5 秒抠图的 AI 神器,根本无需 PS

    开始文章之前先告知一下,文末点击阅读原文可以查看这个月的送书活动,我的送书活动只送给支持公众号的老铁,所以人人都有机会拿到书,别再说自己中奖绝缘体了.

    叫我龙总
  • 对比 C++ 和 Python,谈谈指针与引用

    花下猫语:本文是学习群内樱雨楼小姐姐的投稿。之前已发布过她的一篇作品《当谈论迭代器时,我谈些什么?》,大受好评。本文依然是对比 C++ 与 Python,来探讨...

    Python猫
  • 对Python开发者而言,IPython仍然是Jupyter Notebook的核心

    导读:Jupyter 项目提供的魔法般的开发体验很大程度上得益于它的 IPython 基因。

    华章科技
  • 小型的编程项目有哪些值得推荐?这本神书写了 22 个,个个了不得

    在开始正题之前,先介绍一下它所属的系列。该系列叫 AOSA,是“The Architecture of Open Source Applications”的简称...

    Python猫
  • 不会js逆向,你是找不到爬虫工作的!

    最后通知一下: 各位老铁请点击阅读原文,填写送书资料,今天下午1点,确定送书名额,下午发快递,除偏远地方外三天内书就到你的手上了!

    叫我龙总

扫码关注云+社区

领取腾讯云代金券