У меня есть кластер, и я застрял с ним и 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
Как видите, иногда вместо 10000000 передается только 6 двойных значений. Этот журнал не полный - все последующие сообщения тоже имеют только 6 значений. Интересно, что результаты воспроизводимы: узел 2 всегда сначала отвечает правильным сообщением, а все остальные узлы отвечают неправильными.
Код отлично работает на одном узле того же кластера. Также он отлично работает в облаке Google (6 узлов по 32 ядра). Я пробовал разные приемы и получил тот же результат:
заменил Send / Recv на Isend / Irecv + Wait
использовал send / recv со стандартным рассолом и с рассолом из укропа. Этот код не может декодировать данные рассола.
пробовал библиотеки openmpi 2.1.1, 4.0.1 и intel mpi
попробовал исправить от Intel:
export I_MPI_SHM_LMT=shm
Возможно, возникла проблема с настройкой сети, но я действительно не знаю, что попробовать.
Установка представляет собой многоузловой кластер с межсоединением Mellanox 4x FDR Infiniband в толстом дереве с избыточной подпиской 2–1. Наборы из 24 узлов имеют 12 восходящих каналов к большому коммутатору Infiniband. Каждый узел имеет 64 ГиБ 4-канальной памяти DDR4 SDRAM 2133 МГц (68 ГБ / сек); два процессора Intel Xeon E5-2670 v3 (Haswell).
msgout = np.ones(10000000)
наmsgout = np.ones(10000000, np.double)
- person Gilles Gouaillardet   schedule 18.09.2019