我正在重写沟通瓶颈。我需要发送3d numpy
数组的子数组。
但是将子数组直接传递给MPI.Send()
会失败:
ValueError: ndarray is not contiguous
按MPI.Datatype.Create_vector
创建新数据类型没有帮助 - 它出于同样的原因失败了。
简化示例:
a = numpy.zeros([9,9])
sub = a[3:5, 3:5]
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
t = MPI.DOUBLE.Create_vector(2, 2, 9)
t.Commit()
if rank == 0:
sub.flat[:] = range(1,9)
comm.Send([sub, t], dest=1)
else:
comm.Recv([sub, t], source=0)
在实际代码中,我使用异步发送/接收。目前我通过将子数组复制到具有连续内存布局的临时数组来解决它。
问题是缓冲区往往非常大,它占用了所有内存和可用的交换。
我认为创建跨步数据类型是一种方法,但由于我无法访问具有连续内存的原始数组,因此无法创建跨步缓冲区。
同样使用小写版本的send / recv不是一个选项,因为我说我需要速度而且数据很大。
目前我唯一的想法是创建C模块扩展,在那里我做所有的指针计算并返回numpy数组,可以访问包含我的子数组的连续内存段。
答案 0 :(得分:0)
当我遇到同样的问题时,发现这个问题没有答案。您可以使用 Create_subarray(sizes, subsizes, starts, int order=ORDER_C)
来完成此操作:
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
a = np.zeros([9, 9])
if rank == 0:
a[3:5, 3:5] = np.ones([2, 2])
t = MPI.DOUBLE.Create_subarray([9, 9], [2, 2], [3, 3])
t.Commit()
if rank == 0:
comm.Send([a, t], dest=1)
else:
comm.Recv([a, t], source=0)
额外提示:据我所知,mpi4py
的文档非常少。我在网上找不到有关使用 mpi4py
创建派生数据类型的任何帮助。如果您想查看可以使用 mpi4py
创建的数据类型列表,请在 Python 控制台运行以下命令:
>>> from mpi4py import MPI
>>> help(MPI.DOUBLE)