HPX минимальный пример с двумя узлами?

Начало работы с HPX руководство
предполагает, что вы используете PBS или slurm. Они могут быть довольно распространены в сообществе HPC, но как разработчик я более привык к сценарию, здесь есть пара машин, на которые можно устанавливать вещи.

Не сразу очевидно, нужен ли планировщик типа slurm для использования нескольких физических машин или просто удобен для управления кластером.

Я знаю, что вы можете имитировать несколько населенных пунктов, используя флаг -l при запуске приложения HPX (см., Например, этот вопрос) я хочу запустить одно и то же приложение на 2 узлах и заставить их общаться друг с другом.

Какой минимум необходим, чтобы сказать HPX:
Вот еще один компьютер с этим IP-адресом, на который вы можете отправлять задания?

В качестве альтернативы, какова минимальная конфигурация грязи для достижения этой стадии?

Установить slurm было легко, если бы найти простой пример с двумя узлами. эта ссылка на подкаст может помочь

Я также предполагаю, что порт посылки HPX будет работать только через TCP, не устанавливая ничего лишнего (например, MPI). Это правильно?


Обновить
Я думаю, что все ближе, но я все еще что-то упускаю.
Сначала я использую пример hello_world. Может быть, это слишком просто для теста 2 узла?
Я надеюсь на вывод, похожий на запуск 2 локаций на одном узле:

APP=$HPX/bin/hello_world
$APP --hpx:node 0 --hpx:threads 4 -l2 &
$APP --hpx:node 1 --hpx:threads 4

образец вывода:

привет мир из ОС-нити 2 на местности 0
привет мир из OS-нить 0 на местности 0
привет мир из ОС-нить 1 на местности 1
привет мир из ОС-нить 3 на местности 1
привет мир из ОС-нити 2 на местности 1
привет мир из ОС-нить 1 на местности 0
привет мир из ОС-нити 0 на местности 1
привет мир из ОС-нить 3 на местности 0

но когда я пытаюсь удалить его, оба процесса зависают:

$APP --hpx:localities=2 --hpx:agas=$NODE0:7910 --hpx:hpx=$NODE0:7910 --hpx:threads 4 &
ssh $NODE1 $APP --hpx:localities=2 --hpx:agas=$NODE0:7910 --hpx.hpx=$NODE1:7910 --hpx:threads 4

Я открыл порт 7910 на обеих машинах.
Путь к $ APP одинаков на обоих узлах.
Я не уверен, как проверить, взаимодействует ли второй процесс с сервером agas.

Если я использую «—hpx: debug-agas-log = agas.log» и «—hpx: debug-hpx-log = hpx.log» & Я получил:

> кошка hpx.log
(T00000000 /----------------.----/----------------) P ------- - / ----------------.---- 14: 18.29.042 [0000000000000001] [ERR] создано исключение: HPX (успех)
(T00000000 /----------------.----/----------------) P ------- - / ----------------.---- 14: 18.29.042 [0000000000000002] [ERR] создано исключение: HPX (успех)

на обеих машинах. Я не уверен, как это интерпретировать.

Я пробовал несколько других вариантов, таких как —hpx: run-agas-server
(Я думаю, что это возможно при использовании —hpx: agas =)

Я тоже пробовал

ssh $NODE1 $APP --hpx:nodes="$NODE0 $NODE1" &
$APP --hpx:nodes="$NODE0 $NODE1"

как подсказал другой (сейчас удаленный?) ответ без удачи.


обновление 2

Я думал, что это может быть проблема с брандмауэром, даже если брандмауэр отключен, кажется, ничего не происходит. Я попытался выполнить трассировку системных вызовов, но нет ничего очевидного:

echo "start server on agas master: node0=$NODE0"strace -o node0.strace $APP \
--hpx:localities=2 --hpx:agas=$NODE0:7910 --hpx:hpx=$NODE0:7910 --hpx:threads 4 &
cat agas.log hpx.log
echo "start worker on slave: node1=$NODE1"ssh $NODE1 \
strace -o node1.strace $APP \
--hpx:worker --hpx:agas=$NODE0:7910 --hpx.hpx=$NODE1:7910
echo "done"exit 0

хвост узла0.strace:

15:13:31 bind (7, {sa_family = AF_INET, sin_port = htons (7910), sin_addr = inet_addr ("172.29.0.160")}, 16) = 0
15:13:31 прослушать (7, 128) = 0
15:13:31 ioctl (7, FIONBIO, [1]) = 0
15:13:31 accept (7, 0, NULL) = -1 EAGAIN (ресурс временно недоступен)
...
15:13:32 mprotect (0x7f12b2bff000, 4096, PROT_NONE) = 0
15:13:32 клон (child_stack = 0x7f12b33feef0, флаги = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID, parent_tidptr = 0x7f12b33ff9d0, 0x7f12b33ff700 = TLS, child_tidptr = 0x7f12b33ff9d0) = 22394
15:13:32 futex (0x7ffe2c5df60c, FUTEX_WAIT_PRIVATE, 1, NULL) = 0
15:13:32 futex (0x7ffe2c5df5e0, FUTEX_WAKE_PRIVATE, 1) = 0
15:13:32 futex (0x7ffe2c5df4b4, FUTEX_WAIT_PRIVATE, 1, NULL

хвост node1.strace:

6829 15:13:32 bind (7, {sa_family = AF_INET, sin_port = htons (7910), sin_addr = inet_addr ("127.0.0.1")}, 16) = 0
16829 15:13:32 прослушать (7, 128) = 0
16829 15:13:32 ioctl (7, FIONBIO, [1]) = 0
16829 15:13:32 accept (7, 0, NULL) = -1 EAGAIN (ресурс временно недоступен)
16829 15:13:32 uname ({sys = "Linux", node = "kmlwg-tddamstest3.grpitsrv.com", ...}) = 0
16829 15:13:32 eventfd2 (0, O_NONBLOCK | O_CLOEXEC) = 8
16829 15:13:32 epoll_create1 (EPOLL_CLOEXEC) = 9
16829 15:13:32 timerfd_create (CLOCK_MONOTONIC, 0x80000 / * TFD _ ??? * /) = 10
16829 15:13:32 epoll_ctl (9, EPOLL_CTL_ADD, 8, {EPOLLIN | EPOLLERR | EPOLLET, {u32 = 124005464, u64 = 140359655238744}}) = 0
16829 15:13:32 запись (8, "\ 1 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0", 8) = 8
16829 15:13:32 epoll_ctl (9, EPOLL_CTL_ADD, 10, {EPOLLIN | EPOLLERR, {u32 = 124005476, u64 = 140359655238756}}) = 0
16829 15:13:32 futex (0x7fa8006f2d24, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fa8006f2d20, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
16830 15:13:32) = 0
16829 15:13:32 сокет (PF_INET, SOCK_STREAM, IPPROTO_TCP
16830 15:13:32 futex (0x7fa8076432f0, FUTEX_WAKE_PRIVATE, 1) = 0
16829 15:13:32) = 11
16830 15:13:32 epoll_wait (9,
16829 15:13:32 epoll_ctl (9, EPOLL_CTL_ADD, 11, {EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLET, {u32 = 124362176, u64 = 140359655595456}}
16830 15:13:32 {{EPOLLIN, {u32 = 124005464, u64 = 140359655238744}}}, 128, -1) = 1
16829 15:13:32) = 0
16830 15:13:32 epoll_wait (9,
16829 15:13:32 connect (11, {sa_family = AF_INET, sin_port = htons (7910), sin_addr = inet_addr ("172.29.0.160")}, 16
16830 15:13:32 {{EPOLLHUP, {u32 = 124362176, u64 = 140359655595456}}}, 128, -1) = 1
16830 15:13:32 epoll_wait (9,

Если я выполняю strace -f на мастере, его дочерний процесс зацикливается, делая что-то вроде этого:

22050 15:12:46 сокет (PF_INET, SOCK_STREAM, IPPROTO_TCP) = 12
22050 15:12:46 epoll_ctl (5, EPOLL_CTL_ADD, 12, {EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLET, {u32 = 2395115776, u64 = 140516545171712}}) = 0
22041 15:12:46 {{EPOLLHUP, {u32 = 2395115776, u64 = 140516545171712}}}, 128, -1) = 1
22050 15:12:46 connect (12, {sa_family = AF_INET, sin_port = htons (7910), sin_addr = inet_addr ("127.0.0.1")}, 16
22041 15:12:46 epoll_wait (5,
22050 15:12:46) = -1 ECONNREFUSED (соединение отказано)
22041 15:12:46 {{EPOLLHUP, {u32 = 2395115776, u64 = 140516545171712}}}, 128, -1) = 1
22050 15:12:46 futex (0x7fcc9cc20504, FUTEX_WAIT_BITSET_PRIVATE | FUTEX_CLOCK_REALTIME, 1703, {1455808366, 471644000}, ffffffff
22041 15:12:46 epoll_wait (5,
22050 15:12:46) = -1 ETIMEDOUT (Тайм-аут соединения)
22050 15:12:46 futex (0x7fcc9cc204d8, FUTEX_WAKE_PRIVATE, 1) = 0
22050 15:12:46 close (12) = 0
22050 15:12:46 сокет (PF_INET, SOCK_STREAM, IPPROTO_TCP) = 12
22050 15:12:46 epoll_ctl (5, EPOLL_CTL_ADD, 12, {EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLET, {u32 = 2395115776, u64 = 140516545171712}}) = 0
22050 15:12:46 connect (12, {sa_family = AF_INET, sin_port = htons (7910), sin_addr = inet_addr ("127.0.0.1")}, 16
22041 15:12:46 {{EPOLLHUP, {u32 = 2395115776, u64 = 140516545171712}}}, 128, -1) = 1
22050 15:12:46) = -1 ECONNREFUSED (соединение отказано)
22041 15:12:46 epoll_wait (5,
22050 15:12:46 futex (0x7fcc9cc20504, FUTEX_WAIT_BITSET_PRIVATE | FUTEX_CLOCK_REALTIME, 1705, {1455808366, 572608000}, ffffffff
22041 15:12:46 {{EPOLLHUP, {u32 = 2395115776, u64 = 140516545171712}}}, 128, -1) = 1

Обновление 3

Проницательный из вас, возможно, заметил, что в обновлении 2 я случайно написал
—hpx.hpx вместо —hpx: hpx.
Угадай, что! Изменение, которое исправило это. Так что технически первый ответ был правильным, и я просто тупой.
Я ожидал бы ошибку от парсера параметров командной строки, но я предполагаю, что когда вы выполняете массивно параллельную среду выполнения, у вас не может быть всего :).

Спасибо всем за помощь.

8

Решение

Вариант 1. При использовании TCP / IP для сетевого уровня (обычно по умолчанию):

Чтобы приложение HPX могло найти все подключенные узлы, необходимо предоставить следующую информацию вне пакетных сред:

locality 0:
./yourapp --hpx:localities=2 --hpx:agas=node0:7910 --hpx:hpx=node0:7910

locality 1:
./yourapp --hpx:agas=node0:7910 --hpx:hpx=node1:7910 --hpx:worker

куда node0 а также node1 являются именами узлов этих узлов и 7910 является (произвольным) портом TCP / IP для использования.

Другими словами,

  • на node0 вы указываете порт, где HPX будет прослушивать входящие сообщения на этом узле (--hpx:hpx=node0:7910) и порт, где будет прослушиваться основной экземпляр механизма активного глобального адресного пространства (AGAS) (это будет использоваться для других узлов для установления начального соединения (--hpx:agas=node0:7910). Вы также указываете, что в целом 2 населенные пункты будут подключаться (--hpx:localities=2).
  • на узле 1 (и на всех других узлах, которые вы хотите подключить) вы указываете порт, где HPX будет прослушивать входящие сообщения на этом узле (--hpx:hpx=node1:7910) и порт, где основной двигатель AGAS может быть достигнут в точке 0 (--hpx:agas=node0:7910). Вы также указываете, что это место является рабочим (а не «консолью»), что выполняется --hpx:worker опция командной строки.

Обратите внимание, что все эти опции имеют однобуквенные сочетания клавиш (--hpx:localities == -l, --hpx:hpx == -x, --hpx:agas == -a, а также --hpx:worker == -w)

Вы также можете запустить несколько мест на одном физическом вычислительном узле (или на вашем ноутбуке). В этом случае немного менее утомительно определять вещи, например:

./yourapp -l2 -0 &
./yourapp -1

Если вы хотите использовать расширенные параметры командной строки в этом случае, убедитесь, что порты, используемые для -x являются уникальными во всех местах, которые работают на одном узле.

Вариант 2. При использовании MPI (требуется специальная настройка времени сборки):

Просто используйте mpirun для выполнения вашего приложения. Он выберет настройки либо из вашей пакетной среды, либо будет использовать параметры командной строки для запуска. Например:

mpirun -N1 -np2 ./yourapp

это запустит два экземпляра вашего приложения на текущем вычислительном узле.

7

Другие решения

Я не могу прокомментировать существующий ответ, поэтому я повторю некоторую информацию из ответа @hkaiser: на узле консоли / мастера или того, что мы обычно называем rank0, вы должны использовать команду вида

`bin/hello_world -l2 --hpx:agas=xx.xx.xx.AA:7910 --hpx:hpx=xx.xx.xx.AA:7910 `

и на рабочем узле вы должны использовать

`bin/hello_world --hpx:agas=xx.xx.xx.AA:7910 --hpx:hpx=xx.xx.xx.BB:7910 --hpx:worker`

Но важно, чтобы используемый вами IP-адрес возвращался внешней сетью узлов, а не внутренней сетью (в случае нескольких NIC / IP-адресов). Чтобы убедиться, что я получаю правильный адрес, я обычно запускаю команду

ip route get 8.8.8.8 | awk 'NR==1 {print $NF}'

на каждом узле и использовать вывод этого при тестировании.

Обратите внимание, что эта спецификация IP-адреса необходима только при запуске заданий рукой не использовать mpirun или srun для запуска заданий, так как эти команды порождают задания на узлах, выделенных пакетной системой, и связь будет правильно обрабатываться внутренними компонентами HPX.
При использовании пакетной системы, но в любом случае запуска заданий вручную (например, из интерактивной оболочки, вы обнаружите, что добавление опции --hpx:ignore-batch-env в вашей командной строке поможет остановить HPX от сбора нежелательных параметров.

Этим утром я попытался с git commit 0c3174572ef5d2c из репозитория HPX, и мой результат выглядит следующим образом

Мастер Узел

bin/hello_world --hpx:agas=148.187.68.38:7910 --hpx:hpx=148.187.68.38:7910 -l2 --hpx:threads=4
hello world from OS-thread 3 on locality 1
hello world from OS-thread 6 on locality 1
hello world from OS-thread 2 on locality 1
hello world from OS-thread 7 on locality 1
hello world from OS-thread 5 on locality 1
hello world from OS-thread 0 on locality 1
hello world from OS-thread 4 on locality 1
hello world from OS-thread 1 on locality 1
hello world from OS-thread 0 on locality 0
hello world from OS-thread 2 on locality 0
hello world from OS-thread 1 on locality 0
hello world from OS-thread 3 on locality 0

Рабочий узел

bin/hello_world --hpx:agas=148.187.68.38:7910 --hpx:hpx=148.187.68.36:7910 --hpx:worker --hpx:threads=8

Обратите внимание, что можно использовать разное количество потоков на разных узлах, как я это делал здесь (но обычно узлы однородны, поэтому вы используете одинаковое количество потоков).

Parcelport

если вы скомпилировали с поддержкой MPI (например) и хотите убедиться, что используется TCP parcelport, добавьте

-Ihpx.parcel.tcp.enable=1 -Ihpx.parcel.mpi.enable=0

в вашей командной строке (на всех узлах), чтобы HPX выбирал TCP parcelport.

5

По вопросам рекламы [email protected]