MPI集体的参数分配

时间:2016-04-15 12:50:51

标签: python mpi mpi4py

这是我的第一个python MPI程序,我非常感谢帮助优化代码。具体来说,如果有人可以提供帮助,我有两个关于散射和聚集的问题。该程序比没有MPI的传统方法慢得多。

我正在尝试分散一个数组,在填充另一组数组的节点上做一些工作,然后收集它们。我的问题主要在于设置和收集代码部分。

  • 是否有必要在所有节点上为阵列分配内存? (Amy_Axsetysetmy_xsetmy_yset)?其中一些可能会变大。
  • 数组是我收集的数据的最佳结构吗?当我分散A时,它相对较小。但是,xsetyset会变得非常大(至少超过一百万个元素)。

以下是代码:

#!usr/bin/env python

#Libraries
import numpy as py
import matplotlib.pyplot as plt
from mpi4py import MPI

comm = MPI.COMM_WORLD
print "%d nodes running."% (comm.size)

#Variables
cmin = 0.0
cmax = 4.0
cstep = 0.005
run = 300
disc = 100

#Setup
if comm.rank == 0:
    A = py.arange(cmin, cmax + cstep, cstep)
else:
    A = py.arange((cmax - cmin) / cstep, dtype=py.float64)

my_A = py.empty(len(A) / comm.size, dtype=py.float64)
xset = py.empty(len(A) * (run - disc) * comm.size, dtype=py.float64)
yset = py.empty(len(A) * (run - disc) * comm.size, dtype=py.float64)
my_xset = py.empty(0, dtype=py.float64)
my_yset = py.empty(0, dtype=py.float64)

#Scatter
comm.Scatter( [A, MPI.DOUBLE], [my_A, MPI.DOUBLE] )

#Work
for i in my_A:
    x = 0.5
    for j in range(0, run):
        x = i * x * (1 - x)
        if j >= disc:
            my_xset = py.append(my_xset, i)
            my_yset = py.append(my_yset, x)

#Gather
comm.Allgather( [my_xset, MPI.DOUBLE], [xset, MPI.DOUBLE])
comm.Allgather( [my_yset, MPI.DOUBLE], [yset, MPI.DOUBLE])

#Export Results
if comm.rank == 0:
    f = open('points.3d', 'w+')
    for k in range(0, len(xset)-1):
        f.write('(' + str(round(xset[k],2)) + ',' + str(round(yset[k],2)) + ',0)\n')
    f.close()

1 个答案:

答案 0 :(得分:0)

  • 您无需在非根进程上分配A。如果您没有使用Allgather,而只使用简单Gather,则还可以省略xsetyset。基本上,您只需要分配集合实际使用的数据 - 其他参数仅在根上有效。

  • 是的,numpy数组是这种大型数组的合适数据结构。对于不是性能关键的小数据,使用全小写方法并与Python对象(列表等)进行通信可能更方便和pythonic。