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

3.5   对一个文件的多个行并行处理

#!usr/bin/env python
#-*- coding: utf-8 -*-
import sys
import os
import mpi4py.MPI as MPI
import numpy as np # Global variables for MPI
# instance for invoking MPI relatedfunctions
comm = MPI.COMM_WORLD
# the node rank in the whole community
comm_rank = comm.Get_rank()
# the size of the whole community, i.e.,the total number of working nodes in the MPI cluster
comm_size = comm.Get_size() if __name__ == '__main__':
if comm_rank == 0:
sys.stderr.write("processor root starts reading data...\n")
all_lines = sys.stdin.readlines() all_lines = comm.bcast(all_lines if comm_rank == 0 else None, root = 0) num_lines = len(all_lines)
local_lines_offset = np.linspace(0, num_lines, comm_size +1).astype('int') local_lines = all_lines[local_lines_offset[comm_rank] :local_lines_offset[comm_rank + 1]] sys.stderr.write("%d/%d processor gets %d/%d data \n" %(comm_rank, comm_size, len(local_lines), num_lines)) for line in local_lines:
output = line.strip() + ' : process every line here'
print(output)

3.6   对多个文件并行处理

#!usr/bin/env python
#-*- coding: utf-8 -*-
import sys
import os
import mpi4py.MPI as MPI
import numpy as np # Global variables for MPI
# instance for invoking MPI relatedfunctions
comm = MPI.COMM_WORLD
# the node rank in the whole community
comm_rank = comm.Get_rank()
# the size of the whole community, i.e.,the total number of working nodes in the MPI cluster
comm_size = comm.Get_size() if __name__ == '__main__':
if len(sys.argv) != 2:
sys.stderr.write("Usage: python *.py directoty_with_files\n")
sys.exit(1) path = sys.argv[1] if comm_rank == 0:
file_list = os.listdir(path)
sys.stderr.write("......%d files......\n" % len(file_list)) file_list = comm.bcast(file_list if comm_rank == 0 else None, root = 0)
num_files = len(file_list)
local_files_offset = np.linspace(0, num_files, comm_size +1).astype('int')
local_files = file_list[local_files_offset[comm_rank] :local_files_offset[comm_rank + 1]] sys.stderr.write("%d/%d processor gets %d/%d data \n" %(comm_rank, comm_size, len(local_files), num_files)) sys.stderr.write("processor %d has %s files \n"%(comm_rank, local_files))

3.7    联合numpy对矩阵的多个行或者多列并行处理

import os, sys, time
import numpy as np
import mpi4py.MPI as MPI # instance for invoking MPI relatedfunctions
comm = MPI.COMM_WORLD
# the node rank in the whole community
comm_rank = comm.Get_rank()
# the size of the whole community, i.e.,the total number of working nodes in the MPI cluster
comm_size = comm.Get_size() # test MPI
if __name__ == "__main__":
#create a matrix
if comm_rank == 0:
all_data = np.arange(20).reshape(4, 5)
print("************ data start******************")
print(all_data)
print("************ data end******************") #broadcast the data to all processors
all_data = comm.bcast(all_data if comm_rank == 0 else None, root = 0) #divide the data to each processor
num_samples = all_data.shape[0]
local_data_offset = np.linspace(0, num_samples, comm_size + 1).astype('int') #get the local data which will be processed in this processor
local_data = all_data[local_data_offset[comm_rank] :local_data_offset[comm_rank + 1]]
print("****** %d/%d processor gets local data ****" %(comm_rank, comm_size))
print(local_data) #reduce to get sum of elements
local_sum = local_data.sum()
all_sum = comm.reduce(local_sum, root = 0, op = MPI.SUM) #process in local
local_result = local_data ** 2 #gather the result from all processors and broadcast it
result = comm.allgather(local_result)
result = np.vstack(result) if comm_rank == 0:
print("*** sum: ", all_sum)
print("************ result ******************")
print(result)

参考文章:

Python多核编程mpi4py实践

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

Python 高性能并行计算之 mpi4py的更多相关文章

  1. Python猫荐书系列之五:Python高性能编程

    稍微关心编程语言的使用趋势的人都知道,最近几年,国内最火的两种语言非 Python 与 Go 莫属,于是,隔三差五就会有人问:这两种语言谁更厉害/好找工作/高工资…… 对于编程语言的争论,就是猿界的生 ...

  2. 《Python高性能编程》——列表、元组、集合、字典特性及创建过程

    这里的内容仅仅是本人阅读<Python高性能编程>后总结的一些知识,用于自己更好的了解Python机制.本人现在并不从事计算密集型工作:人工智能.数据分析等.仅仅只是出于好奇而去阅读这本书 ...

  3. 进阶《Python高性能编程》中文PDF+英文PDF+源代码

    入门使用高性能 Python,建议参考<Python高性能编程>,例子给的很多,讲到高性能就会提到性能监控,里面有cpu mem 方法的度量,网络讲了一点异步,net profiler 没 ...

  4. python高性能编程方法一

    python高性能编程方法一   阅读 Zen of Python,在Python解析器中输入 import this. 一个犀利的Python新手可能会注意到"解析"一词, 认为 ...

  5. python并行计算之mpi4py的安装与基本使用

    技术背景 在之前的博客中我们介绍过concurrent等python多进程任务的方案,而之所以我们又在考虑MPI等方案来实现python并行计算的原因,其实是将python的计算任务与并行计算的任务调 ...

  6. Python高性能编程

    一.进程池和线程池 1.串行 import time import requests url_lists = [ 'http://www.baidu.com', 'http://fanyi.baidu ...

  7. python高性能web框架——Japronto

    近期做了一个简单的demo需求,搭建一个http server,支持简单的qa查询.库中有10000个qa对,需要支持每秒10000次以上的查询请求. 需求比较简单,主要难点就是10000+的RPS. ...

  8. python高性能编程方法一-乾颐堂

    阅读 Zen of Python,在Python解析器中输入 import this. 一个犀利的Python新手可能会注意到"解析"一词, 认为Python不过是另一门脚本语言. ...

  9. 两款高性能并行计算引擎Storm和Spark比較

    对Spark.Storm以及Spark Streaming引擎的简明扼要.深入浅出的比較,原文发表于踏得网. Spark基于这种理念.当数据庞大时,把计算过程传递给数据要比把数据传递给计算过程要更富效 ...

随机推荐

  1. WebDriver API 实例详解(一)

    一.访问某网页地址 被测试网页的网址: http://www.baidu.com Java语言版本的API实例代码: 方法1: package test; import org.testng.anno ...

  2. chrome 调试 ios的 H5 页面

    原文地址http://www.cnblogs.com/kelsen/p/6402477.html 本文重点讨论如何在 Windows 系统中通过chrome 浏览器调试运行在 iPhone Safar ...

  3. hdu5102 枚举每条边的长度

    题意 给了 一颗 有 100000 个节点的树, 他们构成的边有 n*(n-1)/2 种. 每条边有一个长度,长度排序后 取前K条的 和, 枚举每条长度为1 的边 放进队列,然后通过成都为1 的表去 ...

  4. java--jvm启动的参数

    java启动参数共分为三类其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容:其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保 ...

  5. 在Linux系统下统计当前文件夹下的文件个数、目录个数

    1.统计当前文件夹下文件的个数,包括子文件夹里的 ls -lR|grep "^-"|wc -l 如下图: 2.统计文件夹下目录的个数,包括子文件夹里的 ls -lR|grep &q ...

  6. php5.4一下 json_encode 不转义中文

    转载地址:http://www.nowamagic.net/php/php_FunctionJsonEncode.php 在 php 中使用 json_encode() 内置函数(php > 5 ...

  7. 20155201 2016-2017-2 《Java程序设计》第四周学习总结

    20155201 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 - 第六章要点: 继承:面向对象中,子类继承父类,避免重复的行为定义.继承基本上就是避免多个 ...

  8. VC++使用HOOK API 屏蔽PrintScreen键截屏以及QQ和微信默认热键截屏

    转载:http://blog.csdn.net/easysec/article/details/8833457 转载:http://www.vckbase.com/module/articleCont ...

  9. ZOJ 2314 Reactor Cooling(无源汇上下界网络流)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2314 题意: 给出每条边流量的上下界,问是否存在可行流,如果存在则输出. ...

  10. eclipse中下载maven插件解决办法

    https://blog.csdn.net/qq_30546099/article/details/71195446 解决Eclipse Maven插件的最佳方案 https://www.cnblog ...