MPI_Send застрять при выполнении с разными узлами

У меня есть очень простая программа MPI, в которой узел 0 отправляет символ на узел 1, но отправка и получение зависают, когда я использую две или более разных машин. Программа отлично работает, когда я использую несколько процессов только на одной машине. Кажется, это проблема со связью, но я не могу понять, что это такое.....

Вот код:

int main(int argc, char *argv[]) {
    int numtasks, rank, tag = 1;
    char inmsg, outmsg = 'x';

    MPI_Status stat;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if ( rank == 0 ) {
        MPI_Send(&outmsg, 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
    }

    else if ( rank == 1 ) {
        MPI_Recv(&inmsg, 1, MPI_CHAR, 0, tag, MPI_COMM_WORLD, &stat);
    }

    MPI_Finalize();
}

Кроме того, вот несколько важных замечаний:

  1. Я использую кластер из 2 виртуальных машин в Google Compute Engine: mpi-test-uaiw и mpi -test-130b;
  2. Я уже настроил ssh без пароля между двумя виртуальными машинами, то есть из mpi-test-uaiw я могу просто набрать ssh mpi-test-130b, и он отлично работает (работает и обратное);
  3. Простой "Hello World", использующий MPI, работает с этим кластером, но он не содержит никаких операций отправки или получения;
  4. Брандмауэр деактивирован.

Любая помощь будет оценена. Спасибо!

1 ответ

Решение

Я нашел решение своей проблемы:

Я использовал MPICH и запустил мою программу с mpirun. Проблема в том, что mpich использовал неправильный сетевой интерфейс. Каждый узел имеет два интерфейса: lo и ens4. Из того, что я видел в других статьях, похоже, что lo используется для передачи данных от одного узла к себе, а ens4 используется для связи с другими узлами. Я проверил это с помощью следующих команд ping:

  • $ ifconfig -a: показывает доступные интерфейсы;
  • Из mpi-test-uaiw: $ ping -I lo mpi-test-130b -> ОШИБКИ
  • Из mpi-test-uaiw: $ ping -I ens4 mpi-test-130b -> УСПЕХ
  • Из mpi-test-uaiw: $ ping -I lo mpi-test-uaiw -> УСПЕХ
  • Из mpi-test-uaiw: $ ping -I ens4 mpi-test-uaiw -> ОШИБКИ

Одним из возможных решений является использование mpirun --mca btl_tcp_if_include ens4, чтобы убедиться, что mpirun использует интерфейс ens4 для связи с другим узлом. Но это не сработало для меня, поскольку MPICH не распознает параметр --mca. Поэтому я сделал следующее:

  1. Удалены пакеты, которые я использовал для установки MPICH (в обоих узлах): $ sudo apt-get remove libcr-dev mpich mpich-doc;
  2. Установил OpenMPI (в обоих узлах): $ sudo apt install openmpi-bin openmpi-doc libopenmpi-dev;

Установив OpenMPI, мой код заработал. Надеюсь, это поможет любому, кто сталкивается с этой же проблемой!

Другие вопросы по тегам