mpi4py的MPI数据传输错误

2024-10-16 17:23:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个集群,我被它和mpi4py困住了。我有一个相当复杂的代码和MPI只是在传输数据失败。 为了让事情更清楚,我编写了一个简单的“helloworld”代码,它只是在节点之间传输大型数组。 数组用0初始化,然后用来自另一个节点的数组填充。你知道吗

import dill
from mpi4py import MPI
MPI.pickle.__init__(dill.dumps, dill.loads)

comm = MPI.COMM_WORLD
rank = comm.rank

import numpy as np

for k in range(5):
    if rank == 0:
        # node 0 sends hi to other nodes
        for i in range(1, comm.size):
            msg = np.ones(10000000, np.double)
            comm.Send([msg, MPI.DOUBLE], dest=i, tag=0)
    else:
        # other nodes receive hi
        msgin = np.zeros(10000000, np.double)
        comm.Recv([msgin, MPI.DOUBLE], source=0, tag=0)
        with open('solution1.txt', 'a') as f:
            f.write(f'{rank} hi, {msgin[:10]} {np.average(msgin)}\n')
        # and then send reply to 0 node
        msgout = np.ones(10000000)
        comm.Send([msgout, MPI.DOUBLE], dest=0, tag=1)

    if rank == 0:
        # node 0 receives replies
        for i in range(1, comm.size):
            msgin = np.zeros(10000000, np.double)
            comm.Recv([msgin, MPI.DOUBLE], tag=1, source=i)
            with open('solution1.txt', 'a') as f:
                f.write(f'{rank} reply, {msgin[:10]} {np.average(msgin)}\n')


结果如下:

1 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
2 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
3 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
4 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
5 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
1 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
2 reply [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
3 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
4 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
5 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
1 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
2 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
3 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
4 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
5 hi [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 1.0
1 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
2 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
3 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
4 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
5 reply [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08
1 hi [1. 1. 1. 1. 1. 1. 0. 0. 0. 0.] 6e-08

如您所见,有时只有6个双值被传输,而不是10000000。 此日志不完整-所有后续消息也只有6个值。 有趣的是,结果是可重复的:节点2总是首先用正确的消息回复,而所有其他节点用错误的消息回复。你知道吗

代码在同一集群的单个节点上完美运行。而且它在google云中运行得非常好(6个节点,每个32核)。 我尝试了不同的技巧,得到了相同的结果:

  • 将Send/Recv替换为Isend/Irecv+Wait

  • 用于标准泡菜和莳萝泡菜的发送/接收。此代码在解码pickle数据时失败。

  • 已试用openmpi 2.1.1、4.0.1和英特尔mpi库

  • 尝试了英特尔的修复程序:

export I_MPI_SHM_LMT=shm

可能是网络设置有问题,但我真的不知道该怎么办。你知道吗

该设置是一个多节点集群,在2-1超额订阅fat树中具有Mellanox 4x FDR Infiniband互连。一组24个节点有12个上行链路到大型核心Infiniband交换机。每个节点有64 GiB的4通道2133 MHz DDR4 SDRAM(68 GB/秒)内存;两个Intel Xeon E5-2670 v3(Haswell)CPU。你知道吗


Tags: 代码import节点tagnp集群数组hi
1条回答
网友
1楼 · 发布于 2024-10-16 17:23:27

在我的设置中,我发现总是使用相同的缓冲区来接收结果很有用。你知道吗

因此,我们可以尝试在代码的早期声明msgin = np.zeros(10000000, np.double),然后反复使用它。每次收到消息时,您都可以执行msgin.fill(np.nan)来“清除”缓冲区。你知道吗

我不知道为什么它对我有效,但问题似乎消失了。你知道吗

祝你好运!你知道吗

相关问题 更多 >