2016-04-15 62 views
1

這是我的第一個Python MPI程序,我非常感謝一些優化代碼的幫助。具體來說,我有兩個關於分散和聚集的問題,如果任何人都可以幫忙。這個程序比沒有MPI的傳統方法慢得多。MPI集體參數分配

我想分散一個數組,在填充另一組數組的節點上做一些工作,然後收集這些數組。我的問題主要在代碼的設置和收集部分。

  • 是否有必要爲所有節點上的陣列分配內存? (Amy_A,xset,yset,my_xset, my_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() 

回答

0
  • 你並不需要在非根進程分配A。如果您不使用Allgather,而是使用簡單的Gather,則還可以省略xsetyset。基本上你只需要分配集體實際使用的數據 - 其他參數是,只在根上有意義。

  • 是的,一個numpy數組是適合這種大型數組的數據結構。對於性能不重要的小數據,使用全小寫方法並與Python對象(列表等)進行通信可能會更方便和pythonic。