Введение в использование MPI

  • MPI - аббревиатура 'Message Passing Interface'. Предоставляет интерфейс обмена данными между процессами, в том числе работающими на разных серверах.
  • Использование MPI в программах на языке Python описано на этой странице.
  • На вычислительном комплексе установлено несколько реализаций MPI, каждая включает свой набор библиотек и утилит. Просмотреть их список можно командой:
    mpi-selector --list
  • Основные реализации (каждая имеет несколько версий):
    • intel_mpi - версия от Intel;
    • openmpi_gcc - Open Source версия OpenMPI, собранная компилятором GCC;
    • openmpi_intel - OpenMPI, собранная компилятором от Intel.


  • Выбрать используемую реализацию:
    mpi-selector --set <название>

    Внимание: данная команда повлияет только на те сессии SSH, которые будут открыты после её выполнения. В текущей сессии используемая реализация не изменится, хотя команда

    mpi-selector --query

    будет отображать уже новое значение.


  • После этого для компиляции программ на языке 'C' используется команда mpicc, для языка 'C++' - команды mpicxx, mpiCC или mpic++, для языка 'Fortran' - mpif77 или mpif90. Обратите внимание, что эти команды - не сами компиляторы, а скрипты, вызывающие настоящие компиляторы. Например, даже при выборе реализации MPI от Intel, по умолчанию используются компиляторы GCC. Компилятор при необходимости можно сменить через переменные окружения, более подробное описание для Intel MPI находится на этой странице.
  • Создадим файл hello_mpi_world.c, содержащий программу на языке C:
    #include <mpi.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char** argv)
    {
        int  size, rank;
        char host[32];
    
        MPI_Init(&argc,&argv);
        MPI_Comm_size(MPI_COMM_WORLD,&size);
        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    
        gethostname(host,32);
        printf("Hello, MPI world! I'm number %d from %d and I run on host %s.\n",rank,size,host);
    
        MPI_Finalize();
        return 0;
    }
  • Процедура MPI_Init инициализирует параллельную часть приложения
  • MPI_Finalize - завершает
  • Все остальные процедуры MPI могут использоваться только между этими двумя вызовами.
  • Процедуры MPI_Comm_size и MPI_Comm_rank возвращают количество параллельных процессов и индивидуальный номер конкретного процесса соответственно.


  • Выберем реализацию MPI:
    mpi-selector --set openmpi_gcc-1.4.3
  • Перезапустим SSH сессию и проверим, какой файл будет использоваться в качестве компилятора:
    which mpicc
    /opt/shared/openmpi/1.4.3-gcc/bin/mpicc
  • Версию компилятора можно узнать с помощью ключа '-v':
    mpicc -v
    gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux)


  • Откомпилируем в исполняемый файл hello_mpi_world.a:
    mpicc hello_mpi_world.c -o hello_mpi_world.a


  • Создадим в той же директории определяющий параметры задачи скрипт submit.sh следующего вида:
    #!/bin/bash
    
    #PBS -l walltime=00:01:00
    #PBS -l select=2:ncpus=4:mpiprocs=4:mem=2000m,place=free
    #PBS -m n
    
    cd $PBS_O_WORKDIR
    MPI_NP=$(wc -l $PBS_NODEFILE | awk '{ print $1 }')
    
    echo "Number of MPI process: $MPI_NP"
    echo 'File $PBS_NODEFILE:'
    cat  $PBS_NODEFILE
    echo 
    
    mpirun -hostfile $PBS_NODEFILE -np $MPI_NP ./hello_mpi_world.a
  • Запуск программы производится командой mpirun, которая получает выделенные задаче узлы из файла, на который указывает переменная окружения $PBS_NODEFILE.
  • Для intel_mpi ключ '-hostfile' необходимо заменить на '-machinefile'


  • Командой qsub поставим задачу в очередь:
    qsub submit.sh
    13485.hpc-suvir1.hpc

    '13485' - идентификатор нашей задачи.


  • После завершения работы задачи в текущей директории появлятся файлы submit.sh.e13485 (должен быть нулевого размера, если программа отработала без ошибок) и submit.sh.o13485, содержащий примерно следущее:
    Number of MPI process: 8
    File $PBS_NODEFILE:
    cn04
    cn04
    cn04
    cn04
    cn39
    cn39
    cn39
    cn39
    
    Hello, MPI world! I'm number 1 from 8 and I run on host cn04.
    Hello, MPI world! I'm number 0 from 8 and I run on host cn04.
    Hello, MPI world! I'm number 3 from 8 and I run on host cn04.
    Hello, MPI world! I'm number 5 from 8 and I run on host cn39.
    Hello, MPI world! I'm number 6 from 8 and I run on host cn39.
    Hello, MPI world! I'm number 7 from 8 and I run on host cn39.
    Hello, MPI world! I'm number 2 from 8 and I run on host cn04.
    Hello, MPI world! I'm number 4 from 8 and I run on host cn39.