mpi4py使用自定义vector数据类型传输矩阵非首列的问题
错误原因
你之前的写法comm.Send([matrix[0,1], 1, column], 1)出错的核心原因是:matrix[0,1]返回的是单个int标量值,而非从该元素位置开始的内存缓冲区,mpi4py只能拿到这个单个值的内存地址,后续读取的内存都是非法的,因此会出现乱码。
你定义的column vector类型本身是可用的,只需要给MPI提供正确的缓冲区起始地址(即目标列第一个元素的内存地址,和C语言中&matrix[0][1]等价)即可。
解决方案
有两种常用实现方式,都不需要修改你已经定义好的column类型:
方式1:使用numpy切片构造目标地址视图
利用numpy切片不拷贝数据、仅创建内存视图的特性,取第0行从第1列开始的切片,它的起始内存地址刚好是第二列第一个元素的地址:
# 发送端 发第二列 comm.Send([matrix[0, 1:], 1, column], dest=1) # 接收端 收进第二列 comm.Recv([matrix[0, 1:], 1, column], source=0)
方式2:直接指定字节偏移量
mpi4py的通信接口支持传入第四个偏移量参数(单位为字节),直接指定从缓冲区起始位置偏移多少字节开始读取数据,逻辑和C语言的指针加法完全一致:
# 每个intc占4字节,第二列首元素相对于矩阵首地址偏移4字节 comm.Send([matrix, 1, column, 4], dest=1) # 接收端同理 comm.Recv([matrix, 1, column, 4], source=0)
完整可运行示例
from mpi4py import MPI import numpy as np comm = MPI.COMM_WORLD rank = comm.Get_rank() # 沿用你定义的column类型 column = MPI.INT.Create_vector(4, 1, 4) column.Commit() if rank == 0: matrix = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]], dtype=np.intc) # 发送第二列 comm.Send([matrix[0, 1:], 1, column], dest=1) else: matrix = np.array([[-1, -1, -1, -1], [-2, -2, -2, -2], [-3, -3, -3, -3], [-4, -4, -4, -4]], dtype=np.intc) # 接收进第二列 comm.Recv([matrix[0, 1:], 1, column], source=0) print(matrix)
运行后输出为:
[[ -1 2 -1 -1] [ -2 6 -2 -2] [ -3 10 -3 -3] [ -4 14 -4 -4]]
内容的提问来源于stack exchange,提问作者lukeg
相关产品推荐
相关产品推荐

