KeyError
происходит потому, что Scatter
не может обрабатывать данные любого типа, загружаемые из вашего входного файла.
Mpi4py предоставляет два типа коммуникационных функций, имена которых начинаются с заглавной буквы, например. Scatter
и те, чьи имена начинаются со строчной буквы, например. scatter
. Из документации Mpi4py:
В MPI для Python методы Bcast(), Scatter(), Gather(), Allgather() и Alltoall() экземпляров Comm обеспечивают поддержку коллективной связи буферов памяти. Варианты bcast(), scatter(), collect(), allgather() и alltoall() могут передавать общие объекты Python.
Что неясно из этого, так это то, что, хотя массивы numpy предположительно выставляют буферы памяти, буферы, по-видимому, должны относиться к одному из небольшого набора примитивных типов данных и, конечно, не работать с универсальными объектами. Сравните следующие два фрагмента кода:
from mpi4py import MPI
import numpy
Comm = MPI.COMM_WORLD
Size = Comm.Get_size()
Rank = Comm.Get_rank()
if Rank == 0:
Data = numpy.empty(Size, dtype=object)
else:
Data = None
Data = Comm.scatter(Data, 0) # I work fine!
print("Data on rank %d: " % Rank, Data)
а также
from mpi4py import MPI
import numpy
Comm = MPI.COMM_WORLD
Size = Comm.Get_size()
Rank = Comm.Get_rank()
if Rank == 0:
Data = numpy.empty(Size, dtype=object)
else:
Data = None
Datb = numpy.empty(1, dtype=object)
Comm.Scatter(Data, Datb, 0) # I throw KeyError!
print("Datb on rank %d: " % Rank, Datb)
Вы должны просто использовать scatter
в своем коде без дополнительных изменений:
d_loc = comm.scatter(d)
или полностью исключить d_loc
, поскольку scatter
не нуждается в отдельном приемном буфере, как Scatter
, и просто использует
d = comm.scatter(d)
Кроме того, как сказал Зулан, вам нужно убедиться, что dtype
s ваших массивов numpy d
и d_loc
совпадают, и что m
передается процессам без ранга 0.
Запуск вашего кода в точности, за исключением замены df = pickle.load(open('lipad0406.p', 'rb'))
на df = range(size)
, поскольку у меня нет и не может быть особых предположений о содержимом вашего файла, не перестает печатать d
в процессе ранга-0, поэтому я могу только предположить, что эта конкретная проблема имеет какое-то отношение к загрузке файла.
Минимально измененная рабочая версия вашего кода, за исключением загрузки файла,
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
df = range(size)
else:
df = None
p = size
d = np.array(df)
n = d.size
m = comm.bcast(n/p)
d_loc = np.zeros(m)
d_loc = comm.scatter(d)
print "process", rank, "x:", d
print "process", rank, "x_local:", d_loc.size
person
calavicci
schedule
07.08.2017