mpi4py - 使用矩阵列的类型

Posted

技术标签:

【中文标题】mpi4py - 使用矩阵列的类型【英文标题】:mpi4py - using a type for matrix column 【发布时间】:2022-01-03 06:34:42 【问题描述】:

使用 mpi4py,我创建了一个代码,它定义了一个新的数据类型来保存矩阵的列并将其发送到其他 MPI 进程:

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, 1, column], 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, 1, column], source=0)
        print(matrix)

只要只关注矩阵的第一列,这就是有效的。程序打印:

[[ 1 -1 -1 -1]
 [ 5 -2 -2 -2]
 [ 9 -3 -3 -3]
 [13 -4 -4 -4]]

如何将第二列矩阵从进程 0 发送到进程 1?当我尝试使用comm.Send([matrix[0,1], 1, column], 1) 发送它时,接收进程会将值[2, -136678432, 0, 0] 插入其矩阵中。因此我相信我以错误的方式访问了 ndarray 的内存。

如果我将此代码翻译为 C 并使用 MPI_Send (&matrix[0][1], 1, column, 1, 123, MPI_COMM_WORLD) 发送,一切正常,第二列转移到进程 1。如何使代码在 Python/mpi4py 中工作?另请注意,我希望该解决方案仍使用第一行中声明的矢量 MPI 类型 (column = MPI.INT.Create_vector(4, 1, 4))。

【问题讨论】:

@VictorEijkhout 至于第一栏,请看我的编辑。我也相信 numpy 同时支持 C 和 Fortran 顺序,至少我在numpy.org/doc/stable/reference/generated/numpy.array.html 上看到的文档是这样的(指定数组的内存布局。如果对象不是数组,则新创建的数组将在C 顺序(行主要)除非指定了“F”,在这种情况下它将是 Fortran 顺序(列主要)) 我的评论完全错误,现已删除。问题是派生类型(subarray 除外,它将解决您的问题)必须从缓冲区的开头开始。因此,您明确需要掌握这么多元素的地址,这就是您在解决方案中所做的。或者使用subarray 类型。 【参考方案1】:

我的解决方案是更改示例代码中的Send 部分,如下所示:comm.Send([np.frombuffer(matrix.data, np.intc, offset=4), 1, column], 1)

经过实验,我发现Sendmatrix[0,1] 给出时,从内存缓冲区读取时出现问题。我们必须明确告诉它从矩阵(matrix.data 部分)持有的内存中读取,并在该内存中给出一个偏移量。由于 numpy 默认按 C 顺序存储数据,我们必须向前移动 4 个字节。

【讨论】:

以上是关于mpi4py - 使用矩阵列的类型的主要内容,如果未能解决你的问题,请参考以下文章

如何让 mpi4py 在 Windows 上工作

让 Pycuda 在 2 gpus 上使用 Mpi4py [关闭]

安装 mpi4py 时出错

mpi4py 点到点通信总结

通过 MPI [MPI4py] 发送复数时的 MPI_ERR_TRUNCATE

mpi4py | comm.bcast 不起作用