LINUX.ORG.RU

Зачем нужен mpirun?

 ,


0

1

Вопрос не касается продвинутых опций данной утилиты. Речь о самых примитивных вещах
1) Я могу запускать программы, использующие mpi просто как библиотеку. Итак у меня есть некая утилита использующая mpi - a.out. Чем отличается

$./a.out
от

$ mpirun -np 1 a.out

(не спешить возмущаться «а зачем запускать одно mpi приложение?!», прочтите следующий режим)?
2) А что если a.out внутри себя порождает параллельные процессы,чем тогда эти два случая будут отличаться?
3) А что если a.out порождает параллельные процессы, которые не используют mpi, но запускается при помощи mpirun (как вот тут например например stackoverflow.com/questions/25772289/python-multiprocessing-within-mpi) ?

★★★

1) думаю, ничем

2) смотря, какие процессы он порождает. Если такие, какие требуются для mpi, то ничем от -np X. Просто фактически руками закодировано то же, что и в mpirun.

gag ★★★★★ ()

3) ./a.out с 4-мя не mpi процессами и mpirun -np 4 ? Тогда mpirun будет с 4*4 процессами: в каждом mpi по 4 самопальных.

gag ★★★★★ ()
Ответ на: комментарий от gag

Стоп, флаг -np X не обозначает, что программе a.out разрешается породить Х процессов, он обозначает, что mpirun запустит на исполнение X копий программы a.out, и каждая из этих копий будет внутри себя что-то там порождать.

LIKAN ★★★ ()
Ответ на: комментарий от gag

Нет, у меня везде -np 1. Т е a.out внутри себя порождает не mpi процессы, чем

$ ./a.out
отлчиется от
$ mpirun -np 1 a.out
Если не понятно - прйдите по ссылке в шапке темы, там питоновскую программу с multiprocessing запускают именно с помощью mpirun -np 1.

LIKAN ★★★ ()
Ответ на: комментарий от LIKAN

Стоп, флаг -np X не обозначает, что программе a.out разрешается породить Х процессов

Я этого и не говорил.

он обозначает, что mpirun запустит на исполнение X копий программы a.out,

Да.

и каждая из этих копий будет внутри себя что-то там порождать.

Нет, в общем случае не будет.

gag ★★★★★ ()
Ответ на: комментарий от LIKAN

Если не понятно - прйдите по ссылке в шапке темы

Ну, лучше попытайся мне объяснить, что там по ссылке. Это самый лучший способ разобраться в чём-то.

Зачем нужен mpirun?

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

gag ★★★★★ ()
Ответ на: комментарий от LIKAN

mpirun -np 1

А если имеешь ввиду, что прибить тут единицу, то и отличий от ./a.out нет.

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

gag ★★★★★ ()
Последнее исправление: gag (всего исправлений: 1)
Ответ на: комментарий от gag

отличия есть. Точно не знаю, что за это отвечает (возможно, устанавливаемые при вызове mpirun переменные окружения), но перенаправление вывода в файл в случае mpirun не буферизуется (по крайней мере, там, где я использую mpi).

Sahas ★★★★★ ()
Ответ на: комментарий от LIKAN

Буквально вчера обратил внимание.

Условие: а.out внтри себя использует дополнительно распараллеливание через openmp, а распараллеливание через openmpi возможно на 2 процесса т.к., в задаче две расчётные сетки.

Так вот ./a.out загружает все 8 ядер процессора.

 Mesh      1 is assigned to MPI Process      0
 Mesh      2 is assigned to MPI Process      0
 OpenMP thread   0 of   7 assigned to MPI process      0 of      0
 OpenMP thread   1 of   7 assigned to MPI process      0 of      0
 OpenMP thread   2 of   7 assigned to MPI process      0 of      0
 OpenMP thread   3 of   7 assigned to MPI process      0 of      0
 OpenMP thread   4 of   7 assigned to MPI process      0 of      0
 OpenMP thread   7 of   7 assigned to MPI process      0 of      0
 OpenMP thread   6 of   7 assigned to MPI process      0 of      0
 OpenMP thread   5 of   7 assigned to MPI process      0 of      0
 Completed Initialization Step  1
 Completed Initialization Step  2
 Completed Initialization Step  3
 Completed Initialization Step  4

Запуск через mpirun -np 2 a.out загружает только два ядра, хотя видно, что openmp тоже активен

 Mesh      1 is assigned to MPI Process      0
 Mesh      2 is assigned to MPI Process      1
 OpenMP thread   4 of   7 assigned to MPI process      0 of      1
 OpenMP thread   7 of   7 assigned to MPI process      0 of      1
 OpenMP thread   6 of   7 assigned to MPI process      0 of      1
 OpenMP thread   5 of   7 assigned to MPI process      0 of      1
 OpenMP thread   3 of   7 assigned to MPI process      0 of      1
 OpenMP thread   2 of   7 assigned to MPI process      0 of      1
 OpenMP thread   1 of   7 assigned to MPI process      0 of      1
 OpenMP thread   0 of   7 assigned to MPI process      0 of      1
 OpenMP thread   4 of   7 assigned to MPI process      1 of      1
 OpenMP thread   7 of   7 assigned to MPI process      1 of      1
 OpenMP thread   6 of   7 assigned to MPI process      1 of      1
 OpenMP thread   5 of   7 assigned to MPI process      1 of      1
 OpenMP thread   3 of   7 assigned to MPI process      1 of      1
 OpenMP thread   2 of   7 assigned to MPI process      1 of      1
 OpenMP thread   1 of   7 assigned to MPI process      1 of      1
 OpenMP thread   0 of   7 assigned to MPI process      1 of      1
 Completed Initialization Step  1
 Completed Initialization Step  2
 Completed Initialization Step  3
 Completed Initialization Step  4

mpirun -np 1 a.out загружает, соответственно, только одно ядро, при 8-ми расчётных потоках.

mpirun -np 1 fds plume_s1.fds  
 Mesh      1 is assigned to MPI Process      0
 Mesh      2 is assigned to MPI Process      0
 OpenMP thread   4 of   7 assigned to MPI process      0 of      0
 OpenMP thread   7 of   7 assigned to MPI process      0 of      0
 OpenMP thread   6 of   7 assigned to MPI process      0 of      0
 OpenMP thread   5 of   7 assigned to MPI process      0 of      0
 OpenMP thread   3 of   7 assigned to MPI process      0 of      0
 OpenMP thread   2 of   7 assigned to MPI process      0 of      0
 OpenMP thread   1 of   7 assigned to MPI process      0 of      0
 OpenMP thread   0 of   7 assigned to MPI process      0 of      0
 Completed Initialization Step  1
 Completed Initialization Step  2
 Completed Initialization Step  3
 Completed Initialization Step  4

Jurik_Phys ★★★★★ ()
Последнее исправление: Jurik_Phys (всего исправлений: 1)
Ответ на: комментарий от gag

В python единственный способ параллелизации - запуск новых процессов. Для облегчения этого процесса есть стандартная библиотека multiprocessing, благодаря которой работа с процессами внешне не отличается от работы с потоками в других языках.

 #nproc - количество порождаемых процессов
 pool = multiprocessing.Pool(processes=nproc)
 result = pool.map(some_function)
В итоге some_function будет выполнятся параллельно в nproc процессов (потоков, как сказали б в другом языке). multiprocessing не использует mpi Т е у нас УЖЕ есть какая-то параллелизация. Но проблема в том, что порожденные процессы неплохо б отправить на другие узлы кластрера. Поэтому советуют запускать данную программу вот таким образом
mpirun -np 1 --bind-to none test.py
Повторюсь, что внутри multiprocessing никакого mpi нет. Будет ли от использования этой mpirun процессами легче связыватся?

LIKAN ★★★ ()
Ответ на: комментарий от gag

ВОТ, это почти и сама соль вопроса. Что вы имеете ввиду, говоря «обеспечивать связь между ними» в тех случаях когда никакого mpi-йного кода в параллельных процессах нет?

LIKAN ★★★ ()
Ответ на: комментарий от Jurik_Phys

Может я вас неверно понял, но первый и третий логи выглядят одинаково. По поводу второго лога, вы, как я понял из документации, должны просто получить две копии ./a.out в оперативке, делающих одно и тоже.

LIKAN ★★★ ()
Ответ на: комментарий от LIKAN

Т е у нас УЖЕ есть какая-то параллелизация. Но проблема в том, что порожденные процессы неплохо б отправить на другие узлы кластрера.

Я вижу попытку сесть на два стула. Но, может, ParallelProcessing спасёт, как тут рекомендуют.

Поэтому советуют запускать данную программу вот таким образом

Этот совет про другое: касается потоков/ядер процессора на одном узле, а не на нескольких.

gag ★★★★★ ()
Ответ на: комментарий от LIKAN

Даже если воспользоваться mpirun только для того чтобы получить процессы на нескольких узлах (но тогда с -np X), т.е. для связи между процессами не пользоваться функциями mpi, придётся писать и отлаживать весь коммуникационный код самому. И получится не очень хорошо.

Стили параллелизации аля openmp и mpi - это совершенно разные вещи. Если есть openmp-код, то его нельзя один к одному превратить в mpi: т.к. обращения к данным становятся очень дорогой операцией. В общем случае надо будет адаптировать алгоритм, учитывая этот факт.

gag ★★★★★ ()
Ответ на: комментарий от gag

Этот совет про другое: касается потоков/ядер процессора на одном узле, а не на нескольких.

Тогда я вообще в непонятках, на своей машине (которую можно считать какбе кластером из 1 узла) я просто запускаю в таком случае питоновский файл и иду любоваться на равномерную загрузку всех ядер, зачем тогда

mpirun -np 1 --bind-to none test.py
?

LIKAN ★★★ ()
Ответ на: комментарий от gag

Да, спасибо, я в общем-то как раз смотрел в пользу таких решений. Я как раз пытался разобраться с mpirun для того чтоб параллелить только строго определенные операции с копированием необходимых данных на узлы.

LIKAN ★★★ ()
Ответ на: комментарий от LIKAN

Правильно, mpirun для кластера из одного узла практически не нужен (если не тестируешь прогу, которая потом будет запускаться таки на многоузловом кластере).

А проблема там в том, что с mpirun питоновский скрипт стал работать медленнее (а должен был с той же скоростью). mpirun -np 1 форсирует использование только одного ядра. Я как-то был уверен, что это не касается пользовательских fork, openmp, и был удивлён посту Jurik_Phys выше. И чтобы это ограничение убрать и позволить пользовательскую параллелизацию, нужно добавить --bind-to none.

gag ★★★★★ ()
Ответ на: комментарий от LIKAN

Т.к. у меня была сишная mpi прога, то для питона я пробовал mpi4py. Как раз можно воспользоваться mpi для распределения данных, дальше считать как нужно, а потом с mpi собрать где надо.

А вот идея использовать mpirun, если внутри не используется mpi, мне не нравится (если не окажется, что такое практикуется в нескольких проектах).

gag ★★★★★ ()
Ответ на: комментарий от LIKAN

Приведены логи, но различия в комментариях. В первом случае загружаются все 8 ядер процессора, в третьем только одно, а во втором два. Таким образом, порожденные потоки программы запущенной через mpirun оказались привязаны к одному ядру.

П.С. выше уже объяснили ситуацию

Jurik_Phys ★★★★★ ()
Последнее исправление: Jurik_Phys (всего исправлений: 1)

при наличии нескольких узлов mpirun будет давать расползаться задачам по узлам с балансировкой нагрузки.

dn2010 ★★★★★ ()
Ответ на: комментарий от gag

Спасибо большое, теперь вроде разобрался. Один вопрос, немного отходящий от темы, остался. Вот используем мы модель spmd.

$mpirun -np 4 a.out
Как сделать так, чтоб порожденные процессы использовали разные данные. Я понимаю, что подоходов вообще много может быть, просто не хочеться велосипедить...

LIKAN ★★★ ()
Ответ на: комментарий от LIKAN

Если коротко, то в каждом процессе опрашивается его номер, полученный от MPI, и вот по этому номеру алгоритм должен решить, где его данные, а где соседские.

gag ★★★★★ ()
Ответ на: комментарий от LIKAN

В общем случае да, но тогда какой смысл запускать их через mpirun?

mpirun по-идее, знает все о распределенном кластере, на котором запускается числодробилка.

Если вычислительных узлов больше одного, есть смысл использовать MPI (и OpenMP для вычислений внутри узла), иначе использовать только OpenMP.

eagleivg ★★★★★ ()
Ответ на: комментарий от LIKAN

Да, можно обычные юниксовые бинарники запускать, они на разных нодах будут стартовать, MPI нужен в основном чтобы они потом между собой общаться могли.

dn2010 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.