Как реализовать рекурсивный Фибоначчи с помощью openMPI

это мой первый вопрос на StackOverflow :-) Извините, если я задаю вопрос неправильно...

Это моя проблема: мне нужно сравнить рекурсивный алгоритм Фибоначчи с другой моделью параллельного программирования: Cilk, openMP... и openMPI.

Cilk и OpenMP были тривиальны, но openMPI для меня немного сложнее...

Я нашел реализацию рекурсивного Фибоначчи, которая использует MPI_Comm_spawn, и она работает, но примитив MPI_Comm_spawn создает и выполняет новые процессы только на главном узле. Таким образом, кластер не используется.

Итак... мой вопрос: есть ли способ выполнить порожденные процессы во всем кластере? В противном случае, есть ли другие решения для реализации рекурсивного Фибоначчи с помощью openMPI?

Спасибо за помощь мне! :-)

Это код, который на самом деле работает только на главном узле:

[ВЛАДЕЛЕЦ]

int main (int argc, char **argv){
  long n, fibn;
  int world_size, flag;
  int universe_size = 10;
  int myrank;
  char command[] = "slave_fib";
  MPI_Comm children_comm;
  MPI_Status status;
  int errcodes[1];

  MPI_Init (&argc, &argv);
  MPI_Comm_size (MPI_COMM_WORLD, &world_size);
  MPI_Comm_rank (MPI_COMM_WORLD, &myrank);

  MPI_Info local_info;
  MPI_Info_create (&local_info);

  if (world_size != 1)
    perror ("Top heavy with management");

  MPI_Comm_get_attr (MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, &universe_size,              &flag);
  if (universe_size == 1)
    perror ("No room to start workers");

  // Prepare argv for spawning the recursive process
  argv += 1;
  n = atol (argv[0]);

  if (n < 2){
      printf ("fib(%ld)=%ld\n", n, n);
      exit (0);
  }else{
      sprintf (argv[0], "%ld", n);
      MPI_Comm_spawn (command, argv, 1, local_info, myrank, MPI_COMM_SELF,
                      &children_comm, errcodes);
  }
  MPI_Recv (&fibn, 1, MPI_LONG, MPI_ANY_SOURCE, 1, children_comm,
            MPI_STATUS_IGNORE);

  printf ("fib(%ld)=%ld\n", n, fibn);
  fflush(stdout);

  MPI_Finalize ();
}


##### SPAWNED BYNARY #####

int main (int argc, char **argv){
  long n, fibn, x, y;
  int myrank, size;
  char command[] = "slave_fib";
  MPI_Comm children_comm[2];
  MPI_Comm parent;
  MPI_Info local_info;
  int world_size,flag;
  int universe_size=10;
  int errcodes[1];

  MPI_Init (&argc, &argv);
  MPI_Comm_get_parent (&parent);
  MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
  MPI_Info_create (&local_info);

  MPI_Comm_size (MPI_COMM_WORLD, &world_size);

  if (parent == MPI_COMM_NULL)
    perror ("No parent!");

  if (parent != MPI_COMM_NULL)
    MPI_Comm_remote_size (parent, &size);

  if (size != 1)
    perror ("Something's wrong with the parent");

  MPI_Comm_get_attr (MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, &universe_size, &flag);

  argv += 1;
  n = atol (argv[0]);
  if (n < 2){

      MPI_Send (&n, 1, MPI_LONG, 0, 1, parent);

  }else{

      sprintf (argv[0], "%ld", (n - 1));

      MPI_Comm_spawn (command, argv, 1, local_info, myrank,
                      MPI_COMM_SELF, &children_comm[0], errcodes);

      sprintf (argv[0], "%ld", (n - 2));

      MPI_Comm_spawn (command, argv, 1, local_info, myrank,
                      MPI_COMM_SELF, &children_comm[1], errcodes);

      MPI_Recv (&y, 1, MPI_LONG, MPI_ANY_SOURCE, 1,
                children_comm[1], MPI_STATUS_IGNORE);

      fibn = x + y;             // computation

      MPI_Send (&fibn, 1, MPI_LONG, 0, 1, parent);
    }

  MPI_Finalize ();
}

Как это выполнить: mpirun -np 1 bynary name fib_num

Единственный способ выполнить это с -np 1, если вы установите np > 1, выполнение вернет ошибку (для MPI_Comm_spawn)


person colbacc8    schedule 16.03.2018    source источник
comment
Вы работаете под пакетным менеджером? Который из ?   -  person Gilles Gouaillardet    schedule 20.03.2018
comment
Неа. Я пытаюсь установить и проверить крутящий момент PBS прямо сейчас... как вы думаете, этот крутящий момент решит проблему? Или я должен использовать другой пакетный менеджер?   -  person colbacc8    schedule 20.03.2018
comment
Любой пакетный менеджер должен помочь. При этом вы можете mpirun --host host1:n1,host2:n2,... -np 1 ... использовать более одного узла   -  person Gilles Gouaillardet    schedule 20.03.2018
comment
Пробовал на новой установке openMPI, без крутящего момента и других пакетных менеджеров. Теперь процессы порождаются среди узлов, но я получил эту ошибку: [[6022,0],0] ОШИБКА: сообщение для [[2048,34327],0] требует маршрутизации, и OOB не знает об этом процессе. я исследую это... может быть, мне нужно добавить больше информации в среду MPI   -  person colbacc8    schedule 20.03.2018


Ответы (1)


После новой установки Ubuntu 16.04 и libopenmpi-dev 1.10.2 в кластере из 4 узлов вычисление Фибоначчи работает, и порожденные процессы распространяются на все узлы (без Torque).

Но когда я хочу вычислить число Фибоначчи больше 10, я получаю некоторые ошибки... 1) иногда выполнение ожидает вечного окончания порожденного процесса 2) иногда я получаю эту ошибку:

 Child job 67 terminated normally, but 1 process returned a non-zero
 exit code..

Более того, я получаю много таких сообщений при каждом выполнении:

[[30037,42],0] dpm_base_disconnect_init: error -12 in isend to process 0

Эти сообщения появляются при сбое вычислений, а также при их успешном завершении. Возможно, я неправильно использую comm_spawn и send/recv?

person colbacc8    schedule 29.03.2018
comment
Убедитесь, что main() возвращает 0 или кого-то exit(0) после MPI_Finalize() - person Gilles Gouaillardet; 29.03.2018
comment
Я попытался вернуть 0 и выйти 0, но я все еще получаю изнашивание во время выполнения (это правильно): [[30037,42],0] dpm_base_disconnect_init: ошибка -12 в isend для обработки 0 - person colbacc8; 03.04.2018
comment
Порожденные задачи MPI должны быть MPI_Comm_disconnect() от родителя до MPI_Finalize() - person Gilles Gouaillardet; 03.04.2018
comment
Теперь я не получаю никаких предупреждающих сообщений! Кроме того, исполнение кажется лучше! Большое спасибо! Я прохожу через это! - person colbacc8; 03.04.2018