2016-04-15 6 views
1

Dies ist mein erstes Python-MPI-Programm, und ich würde wirklich etwas Hilfe bei der Optimierung des Codes zu schätzen wissen. Genauer gesagt, habe ich zwei Fragen bezüglich Streuen und Sammeln, wenn jemand helfen kann. Dieses Programm ist viel langsamer als ein herkömmlicher Ansatz ohne MPI.Parameterzuordnung für MPI-Kollektive

Ich versuche, ein Array zu zerstreuen, arbeiten an den Knoten, die einen anderen Satz von Arrays füllt, und sammeln diese. Meine Fragen beziehen sich hauptsächlich auf das Einrichten und Sammeln von Code.

  • Ist es erforderlich, Speicher für ein Array auf allen Knoten zuzuweisen? (A, my_A, xset, yset, my_xset, my_yset)? Einige davon können groß werden.
  • Ist ein Array die beste Struktur für die Daten, die ich verwende? Wenn ich A streue, ist es relativ klein. xset und yset können jedoch sehr groß werden (mindestens über eine Million Elemente). Hier

ist der Code:

#!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() 

Antwort

0
  • Sie brauchen nicht A auf die Nicht-Root-Prozesse zuzuordnen. Wenn Sie nicht Allgather, sondern einen einfachen Gather verwenden, können Sie auch xset und yset weglassen. Im Grunde müssen Sie nur Daten zuweisen, die tatsächlich von den Kollektiven verwendet werden - die anderen Parameter sind nur signifikant bei Root.

  • Ja, ein numpy Array ist eine geeignete Datenstruktur für solche großen Arrays. Für kleine Daten, bei denen es nicht performancekritisch ist, kann es bequemer und pythonischer sein, die Kleinbuchstaben-Methoden zu verwenden und mit Python-Objekten (Listen usw.) zu kommunizieren.

Verwandte Themen