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
undyset
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()