MPI_Barrier не работает должным образом - PullRequest
1 голос
/ 22 ноября 2011

Я написал приложение C ниже, чтобы помочь мне понять MPI и почему MPI_Barrier () не работает в моем огромном приложении C ++.Тем не менее, я смог воспроизвести мою проблему в моем огромном приложении с гораздо меньшим C-приложением.По сути, я вызываю MPI_Barrier () внутри цикла for, а MPI_Barrier () видим для всех узлов, но после 2 итераций цикла программа заходит в тупик.Есть мысли?

#include <mpi.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
    MPI_Init(&argc, &argv);
    int i=0, numprocs, rank, namelen;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Get_processor_name(processor_name, &namelen);
    printf("%s: Rank %d of %d\n", processor_name, rank, numprocs);
    for(i=1; i <= 100; i++) {
            if (rank==0) printf("Before barrier (%d:%s)\n",i,processor_name);
            MPI_Barrier(MPI_COMM_WORLD);
            if (rank==0) printf("After barrier (%d:%s)\n",i,processor_name);
    }

    MPI_Finalize();
    return 0;
}

Вывод:

alienone: Rank 1 of 4
alienfive: Rank 3 of 4
alienfour: Rank 2 of 4
alientwo: Rank 0 of 4
Before barrier (1:alientwo)
After barrier (1:alientwo)
Before barrier (2:alientwo)
After barrier (2:alientwo)
Before barrier (3:alientwo)

Я использую GCC 4.4, Open MPI 1.3 из репозиториев Ubuntu 10.10.

Также в моем огромномПриложение C ++, MPI Broadcasts не работают.Только половина узлов получает широковещательную рассылку, остальные застряли, ожидая ее.

Заранее благодарим за любую помощь или советы!

Обновление: Обновление до Open MPI1.4.4, скомпилированный из исходного кода в / usr / local / .

Обновление: Присоединение GDB к запущенному процессу показывает интересный результат.Мне кажется, что система MPI умерла на барьере, но MPI все еще думает, что программа работает:

Присоединение GDB дает интересный результат.Кажется, что все узлы умерли на барьере MPI, но MPI все еще думает, что они работают:

0x00007fc235cbd1c8 in __poll (fds=0x15ee360, nfds=8, timeout=<value optimized out>) at   ../sysdeps/unix/sysv/linux/poll.c:83
83  ../sysdeps/unix/sysv/linux/poll.c: No such file or directory.
    in ../sysdeps/unix/sysv/linux/poll.c
(gdb) bt
#0  0x00007fc235cbd1c8 in __poll (fds=0x15ee360, nfds=8, timeout=<value optimized out>) at ../sysdeps/unix/sysv/linux/poll.c:83
#1  0x00007fc236a45141 in poll_dispatch () from /usr/local/lib/libopen-pal.so.0
#2  0x00007fc236a43f89 in opal_event_base_loop () from /usr/local/lib/libopen-pal.so.0
#3  0x00007fc236a38119 in opal_progress () from /usr/local/lib/libopen-pal.so.0
#4  0x00007fc236eff525 in ompi_request_default_wait_all () from /usr/local/lib/libmpi.so.0
#5  0x00007fc23141ad76 in ompi_coll_tuned_sendrecv_actual () from /usr/local/lib/openmpi/mca_coll_tuned.so
#6  0x00007fc2314247ce in ompi_coll_tuned_barrier_intra_recursivedoubling () from /usr/local/lib/openmpi/mca_coll_tuned.so
#7  0x00007fc236f15f12 in PMPI_Barrier () from /usr/local/lib/libmpi.so.0
#8  0x0000000000400b32 in main (argc=1, argv=0x7fff5883da58) at barrier_test.c:14
(gdb) 

Обновление : У меня также есть этот код:

#include <mpi.h>
#include <stdio.h>
#include <math.h>
int main( int argc, char *argv[] )  {
int n = 400, myid, numprocs, i;
double PI25DT = 3.141592653589793238462643;
double mypi, pi, h, sum, x;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
printf("MPI Rank %i of %i.\n", myid, numprocs);
while (1) {
    h   = 1.0 / (double) n;
    sum = 0.0;
    for (i = myid + 1; i <= n; i += numprocs) {
        x = h * ((double)i - 0.5);
        sum += (4.0 / (1.0 + x*x));
    }
    mypi = h * sum;
    MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
    if (myid == 0)
        printf("pi is approximately %.16f, Error is %.16f\n",  pi, fabs(pi - PI25DT));
}
MPI_Finalize();
return 0;
}

И несмотря на бесконечный цикл, в цикле printf () есть только один вывод:

mpirun -n 24 --machinefile /etc/machines a.out 
MPI Rank 0 of 24.
MPI Rank 3 of 24.
MPI Rank 1 of 24.
MPI Rank 4 of 24.
MPI Rank 17 of 24.
MPI Rank 15 of 24.
MPI Rank 5 of 24.
MPI Rank 7 of 24.
MPI Rank 16 of 24.
MPI Rank 2 of 24.
MPI Rank 11 of 24.
MPI Rank 9 of 24.
MPI Rank 8 of 24.
MPI Rank 20 of 24.
MPI Rank 23 of 24.
MPI Rank 19 of 24.
MPI Rank 12 of 24.
MPI Rank 13 of 24.
MPI Rank 21 of 24.
MPI Rank 6 of 24.
MPI Rank 10 of 24.
MPI Rank 18 of 24.
MPI Rank 22 of 24.
MPI Rank 14 of 24.
pi is approximately 3.1415931744231269, Error is 0.0000005208333338

Есть мысли?

Ответы [ 2 ]

2 голосов
/ 25 марта 2012

MPI_Barrier () в OpenMPI иногда зависает, когда процессы сталкиваются с барьером в разное время, прошедшее после последнего барьера, однако, как я вижу, это не ваш случай. В любом случае, попробуйте использовать MPI_Reduce () вместо или перед реальным вызовом MPI_Barrier (). Это не является прямым эквивалентом барьера, но любой синхронный вызов почти без полезной нагрузки, охватывающий все процессы в коммуникаторе, должен работать как барьер. Я не видел такого поведения MPI_Barrier () в LAM / MPI или MPICH2 или даже WMPI, но это была реальная проблема с OpenMPI.

1 голос
/ 04 мая 2012

Какое у вас соединение?Это специализированный, например, InfiniBand или Myrinet, или вы просто используете обычный TCP через Ethernet?Есть ли у вас несколько настроенных сетевых интерфейсов при работе с транспортом TCP?

Кроме того, Open MPI является модульным - есть много модулей, которые предоставляют алгоритмы, реализующие различные коллективные операции.Вы можете попытаться поработать с ними, используя параметры MCA, например, вы можете начать отладку поведения вашего приложения с увеличением многословия компонента btl, передавая mpirun что-то вроде --mca btl_base_verbose 30.Найдите что-то похожее на:

[node1:19454] btl: tcp: attempting to connect() to address 192.168.2.2 on port 260
[node2:29800] btl: tcp: attempting to connect() to address 192.168.2.1 on port 260
[node1:19454] btl: tcp: attempting to connect() to address 192.168.109.1 on port 260
[node1][[54886,1],0][btl_tcp_endpoint.c:638:mca_btl_tcp_endpoint_complete_connect] connect() to 192.168.109.1 failed: Connection timed out (110)

В этом случае некоторые (или все) узлы имеют более одного настроенного сетевого интерфейса, который работает, но не все узлы доступны через все интерфейсы.Это может произойти, например, если на узлах запущен последний дистрибутив Linux с включенной по умолчанию поддержкой Xen (RHEL?) Или на них установлено другое программное обеспечение для виртуализации, которое вызывает виртуальные сетевые интерфейсы.

По умолчанию Open MPI является ленивым,то есть connectinos открываются по требованию.Первая передача / прием может быть успешной, если выбран правильный интерфейс, но последующие операции могут выбрать один из альтернативных путей для максимизации пропускной способности.Если другой узел недоступен через второй интерфейс, вероятно, истечет время ожидания, и связь не будет установлена, так как Open MPI сочтет другой узел неработоспособным или проблемным.

Решение состоит в том, чтобы изолировать не соединяющиеся сетиили сетевые интерфейсы, использующие параметры MCA модуля TCP btl:

  • принудительно открывать MPI для использования только определенной IP-сети для связи: --mca btl_tcp_if_include 192.168.2.0/24
  • принудительно использовать открытый MPIтолько некоторые из сетевых интерфейсов, которые, как известно, обеспечивают полное сетевое подключение: --mca btl_tcp_if_include eth0,eth1
  • принудительно открывают MPI для , а не используют сетевые интерфейсы, которые, как известно, являются частными / виртуальными или принадлежатдругие сети, которые не соединяют узлы (если вы решите сделать это, вы должны исключить петлю lo): --mca btl_tcp_if_exclude lo,virt0

См. Откройте FAQ по настройке TCP MPI во время выполнения для получения более подробной информации.

...