我是MPI和mpi4py的新手。我有以下代码的两个问题。例如,排名0的数据不打印,而其他排名的非类型数据打印。
其次,我从comm.Scatter()函数得到一个KeyError'0'错误,我无法解释。
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
df = pickle.load(open('lipad0406.p', 'rb'))
else:
df = None
p = size
d = np.array(df)
n = d.size
m = n/p
d_loc = np.zeros(m)
comm.Scatter(d,d_loc)
print "process", rank, "x:", d
print "process", rank, "x_local:", d_loc.size
答案 0 :(得分:1)
虽然我无法重现您的特定错误,但此处的问题是非根列d
上的错误是单个元素None
,因此n=1
和{{1}将是假的。如果您不知道非根级别的大小,则需要先将其广播:
m
还要确保数据类型匹配。
答案 1 :(得分:0)
KeyError
正在发生,因为Scatter
无法处理从输入文件加载的任何数据类型。
Mpi4py提供两种通信功能,名称以大写字母开头的通信功能,例如: Scatter
,以及名称以小写字母开头的人,例如scatter
。 From the Mpi4py documentation:
在MPI for Python中,Comm实例的Bcast(),Scatter(),Gather(),Allgather()和Alltoall()方法为内存缓冲区的集体通信提供支持。变种bcast(),scatter(),gather(),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)
此外,正如Zulan所说,你需要确保你的numpy数组dtype
和d
的{{1}}匹配,并且d_loc
被广播到非秩0进程。
完全运行您的代码,m
替换为df = pickle.load(open('lipad0406.p', 'rb'))
,因为我没有并且无法猜测文件的内容,因此无法打印df = range(size)
rank-0进程,所以我只能推测这个特定问题与加载文件有关。
代码的最低修改工作版本(文件加载除外)是
d