mpi4py 进阶之 mpipool

上一篇中我们介绍了 caput 中的 memh5 模块,下面我们将介绍一个建立在 mpi4py 基础之上的有用工具 mpipool,允许我们非常方便地将一个函数并行地应用到一系列数据上。

下载与安装 mpipool

前往 https://github.com/adrn/mpipool 下载 mpipool。可以直接下载 .zip 格式的压缩包,并解压,或者使用 git 将该软件 clone 到本地:

$ git clone https://github.com/adrn/mpipool.git

进入软件顶层目录,使用以下命令进行安装:

$ python setup.py install [--user]

使用 mpipool

mpipool 软件包提供了 MPIPool 类,其定义及主要方法接口如下:

class MPIPool(object)

MPIPool 类。

__init__(self, comm=None, debug=False, loadbalance=False)

MPIPool 类初始化函数。参数 comm 如果非 None,则应该是一个有效的 mpi4py 通信子对象,否则使用 MPI.COMM_WORLD,debug 如果为 True,会输出很多执行过程信息,loadbalance 如果为 True,当 task 的数目比 worker 进程的数目多时,会首先给每个 worker 进程分配一个 task,然后只要某个 worker 进程完成了其 task,则会给其分配一个新的 task,直到所有的 task 都被分配完为止;如果为 False,则会将所有的 task 按照一种循环的方式分配给各个 worker 进程,此时所有 task 完成的时间会由计算最慢的那一个 worker 进程决定。

is_master(self)

master 进程(rank 为 0)会返回 True,worker 进程(所有其它进程)会返回 False。

wait(self)

worker 进程调用该方法后会在一个循环中等待 master 进程发送过来的指令并完成相应的动作。具体来说,worker 进程如果收到 master 进程发送过来的一个函数,则会用该函数替换其自身将要作用到 task 上的函数,如果收到一个 task,则会将函数作用到该 task上得到计算结果,如果收到一个结束消息,则会跳出循环结束该函数的调用。master 进程调用该方法则会出错。

map(self, function, tasks, callback=None)

一般由 master 进程调用,将一个函数 function 并行地应用到一系列数据 tasks 上,结果会按顺序组成一个列表返回,callback 如果非 None 则应该是一个接受一个参数的函数,在返回结果列表之前会在结果列表的每个元素上调用该函数。该方法在内部会首先将 function 发送给每个 worker,然后将 tasks 中的元素 task 按照一定的方式(取决于初始化时 loadbalance 的值) 分配给各个 worker 进程,每个 worker 进程收到一个 task 后就会将 function 作用到 task 上并将其返回值发送给 master 进程,master 进程收集到所有结果后组成一个列表返回。

close(self)

master 进程给所有 worker 进程发送一个结束消息使其退出 wait 中的循环。

另外 mpipool 软件包中定义了 MPIPoolException 异常,MPIPool 类的 map 方法在计算错误时会抛出该异常。

例程

下面给出简单的使用例程。

# mpipool_demo.py

import sys
import numpy as np
from mpipool import MPIPool


# define the function that will be applied to tasks
def worker(task):
    x, y = task
    return x**2 + 2*y


# create the pool
pool = MPIPool()

# only run map() on the master process, all other processes wait for their work
if not pool.is_master():
    pool.wait()
    # worker processes exit after they have done their work
    sys.exit(0)

# the following code is executed by the master process only
# create some random input data
x = np.random.uniform(size=10)
y = np.random.uniform(size=10)
tasks = list(zip(x, y))

# crate a callback function
def cb(x):
    print x

# map the function worker to tasks
# and execute them parallel by processes other than the master
results = pool.map(worker, tasks, callback=cb)

# close the pool
pool.close()

print 'results:', results

运行结果如下:

$ mpiexec -n 4 python mpipool_demo.py
1.57878266266
1.3217051898
1.01841188873
0.105959488365
0.468227329147
1.43413524955
2.36051906039
2.75875975664
0.343832407757
2.16220071718
results: [1.5787826626560353, 1.3217051897978418, 1.0184118887282427, 0.10595948836453307, 0.4682273291469893, 1.4341352495458153, 2.3605190603946116, 2.758759756642663, 0.34383240775747825, 2.1622007171816713]

mpipool 类定义了 __enter__() 和 __exit__() 方法,所以它也是一个上下文管理器,可以使用类似下面的 with 语句,在退出该 with 语句时会自动调用 MPIPool 类的 close() 方法。在上一个例程中,我们让worker 进程完成工作后就退出,当然也可以保留这些进程以执行后面的语句,如下面的例程所示:

# mpipool_demo1.py

import numpy as np
from mpipool import MPIPool


# define the function that will be applied to tasks
def worker(task):
    x,y = task
    return 5*x + y**2


with MPIPool() as pool:
    # only run map() on the master process, all other processes wait for their work
    if not pool.is_master():
        pool.wait()
    else:
        # the following code is executed by the master process only
        # create some random input data
        x = np.random.uniform(size=10)
        y = np.random.uniform(size=10)
        tasks = list(zip(x, y))

        # crate a callback function
        def cb(x):
            print x

        # map the function worker to tasks
        # and execute them parallel by processes other than the master
        results = pool.map(worker, tasks, callback=cb)

print 'Done!'

运行结果如下:

$ mpiexec -n 4 python mpipool_demo3.py
1.44172730818
1.17103049432
1.11841437626
3.94003914985
4.40300079589
4.07541181493
4.48560962925
5.16898092718
2.26724097853
3.01897745495
Done!
Done!
Done!
Done!

更通用的 pool

以上介绍的 mpipool 软件包只包含 MPIPool,在另一个软件包 schwimmbad 中提供了若干个 pool 工具,包括我们已经介绍了的 MPIPool(实现有些不同,但用法几乎一致),此外还包括 SerialPool,MultiPool 和 JoblibPool。SerialPool 仅仅只是普通的 Python map 函数的一个类包装,MultiPool 是用 Python 的 multiprocessing 模块实现的一个并行 pool 工具,允许利用单台机器的多个处理器完成并行的 map 运算,JoblibPool 则是利用 joblib.Parallel 模块实现的一个并行 pool 工具,而 MPIPool 则是利用 MPI 实现的一个可以在多节点集群或者超级计算机上运行的分布式并行 pool。这些 pool 工具都提供了统一的使用接口,因此可以很容易地由一个转换到另一个。这些 pool 工具的使用详见其文档,在此不作更多的介绍,感兴趣或者有需要的读者可以前往 https://github.com/adrn/schwimmbad 下载并安装使用。

以上我们介绍了一个非常实用的工具 mpipool,在下一篇中我们将简要地介绍并行分布式线性代数运算工具 ScaLAPACK,然后我们会介绍在 python 中使用 ScaLAPACK 的工具 scalapy。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,394评论 25 707
  • 一个人,87天,627英里(相当于1009公里)。 缘起一个普通早晨的一封来信,这是一封二十多年未联系的前同事的来...
    陇西读书与写作阅读 261评论 0 2
  • 在这个影视发展如此玲琅满目的时代,却已经很少有作品能走进心里。电影速成,对观众来说也只是过眼云烟,毫无感触...
    一枚四月阅读 535评论 0 1
  • 八皇后问题解法 什么事八皇后问题 国际象棋中的皇后,可以横向、纵向、斜向移动。如何在一个8X8的棋盘上放置8个皇后...
    guijianshi阅读 649评论 0 0
  • 上周末看了当下热播的电影《星际穿越》,这部近三小时的大作着实让人意犹未尽。回来后跟朱就剧情、背景、科幻、悬疑的地方...
    蜗牛独独阅读 17,143评论 1 3