Это моя первая программа MPI на языке python, и я очень благодарен за помощь в оптимизации кода. В частности, у меня есть два вопроса относительно рассеяния и сбора, если кто-то может помочь. Эта программа намного медленнее, чем традиционный подход без MPI.Распределение параметров для коллективов MPI
Я пытаюсь разбить один массив, выполнить некоторую работу над узлами, которые заполняют другой набор массивов, и собрать их. Мои вопросы в первую очередь касаются установки и сбора разделов кода.
- Нужно ли выделять память для массива на всех узлах? (
A
,my_A
,xset
,yset
,my_xset
,my_yset
)? Некоторые из них могут стать большими. - Является ли массив лучшей структурой для сбора данных, которые я использую? Когда я разбрасываю А, он относительно мал. Однако
xset
иyset
могут получить очень большие (по крайней мере, более миллиона элементов).
Вот код:
#!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()