【发布时间】:2020-01-18 15:17:18
【问题描述】:
我有一个集群,我被它和 mpi4py 困住了。我有一个相当复杂的代码,而 MPI 只是在传输数据时失败了。 为了让事情更清楚,我编写了一个简单的“hello world”代码,它只是在节点之间传输大型数组。 数组初始化为 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 总是首先回复正确的消息,而所有其他节点都回复不正确的消息。
代码在同一个集群的单个节点上完美运行。它还在谷歌云中完美运行(6 个节点,每个节点 32 个核心)。 我尝试了不同的技巧并得到了相同的结果:
将 Send/Recv 替换为 Isend/Irecv + Wait
将发送/接收与标准泡菜和莳萝泡菜一起使用。此代码在解码泡菜数据时失败。
试过 openmpi 2.1.1、4.0.1 和 intel mpi 库
尝试了英特尔的修复:
export I_MPI_SHM_LMT=shm
可能是网络设置有问题,但我真的不知道该尝试什么。
该设置是一个多节点集群,在 2-1 超额订阅胖树中具有 Mellanox 4x FDR Infiniband 互连。 24 个节点的集合有 12 个上行链路进入大型核心 Infiniband 交换机。每个节点具有 64 GiB 的 4 通道 2133 MHz DDR4 SDRAM(68 GB/秒)内存;两个 Intel Xeon E5-2670 v3 (Haswell) CPU。
【问题讨论】:
-
回复时,尝试将
msgout = np.ones(10000000)替换为msgout = np.ones(10000000, np.double) -
谢谢,我已经更正了——但是 numpy 使用 np.double 作为默认值,所以结果是一样的。
标签: python networking mpi cluster-computing mpi4py