Параллельные и распределенные вычисления

Семинар 1

MPI

Пономаренко Роман
@rerand0m
rerandom@ispras.ru

Параллельные и распределенные вычисления

Message-Passing Interface

Спецификация, описывающая программный интерфейс передачи сообщений.

  • Версия 1.0 была опубликована 5 мая 1994г.

  • В настоящий момент актуальной является версия 4.0. (с 09.06.2021)

Ссылка-источник для сильных духом

Hello, world!

Как компилировать и запускать (в кластере) ?

$ ssh username@calc.cod.phystech.edu
$ module load intel/oneapi/mpi/2021.5.1
$ mpicxx -show
 g++ -I"/opt/modules/intel/oneapi/mpi/2021.5.1/include"
  -L"/opt/modules/intel/oneapi/mpi/2021.5.1/lib/release"
  -L"/opt/modules/intel/oneapi/mpi/2021.5.1/lib"
  -Xlinker --enable-new-dtags -Xlinker -rpath
  -Xlinker "/opt/modules/intel/oneapi/mpi/2021.5.1/lib/release"
  -Xlinker -rpath -Xlinker "/opt/modules/intel/oneapi/mpi/2021.5.1/lib"
  -lmpicxx -lmpifort -lmpi -lrt -lpthread -Wl,-z,now -Wl,-z,relro
  -Wl,-z,noexecstack -Xlinker --enable-new-dtags -ldl
$ mpicxx main.cpp
$ cat run.sh
 #!/bin/bash
 #
 #SBATCH --nodes=1 # Кол-во узлов
 #SBATCH --ntasks-per-node=4 # Кол-во процессов на узел
 #SBATCH --cpus-per-task=1 # Кол-во CPU на процесс (для многопоточности)
 #SBATCH --partition=RT #группа машин кластера
 #SBATCH --job-name=rerand0mzMPI # Имя задачи (обязательно напишите что-нибудь своё)
 #SBATCH --comment="Run student mpi from config" # Также обязательно к заполнению
 #SBATCH --output=out.txt # Файл для печати вывода
 #SBATCH --error=error.txt # Файл для печати ошибок
 mpirun ./a.out
$ sbatch run.sh
Submitted batch job 000001
$ squeue
              JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
$ cat out.txt
							

Как компилировать и запускать (локально) ?

$ mpic++ -show
  g++ -Wl,-rpath -Wl,/usr/lib -Wl,--enable-new-dtags -lmpi_cxx -lmpi
$ mpic++ main.cpp
$ mpiexec --use-hwthread-cpus --mca opal_warn_on_missing_libcuda 0 a.out
  Hello from processor rerand0m-main rank 10 out of 16
  Hello from processor rerand0m-main rank 12 out of 16
  Hello from processor rerand0m-main rank 13 out of 16
  Hello from processor rerand0m-main rank 14 out of 16
  Hello from processor rerand0m-main rank 1 out of 16
  Hello from processor rerand0m-main rank 2 out of 16
  Hello from processor rerand0m-main rank 5 out of 16
  Hello from processor rerand0m-main rank 6 out of 16
  Hello from processor rerand0m-main rank 9 out of 16
  Hello from processor rerand0m-main rank 11 out of 16
  Hello from processor rerand0m-main rank 15 out of 16
  Hello from processor rerand0m-main rank 0 out of 16
  Hello from processor rerand0m-main rank 3 out of 16
  Hello from processor rerand0m-main rank 7 out of 16
  Hello from processor rerand0m-main rank 4 out of 16
  Hello from processor rerand0m-main rank 8 out of 16
							

Как компилировать и запускать? (mac os)

$ mpic++ -show
  clang++ -I/opt/homebrew/Cellar/open-mpi/4.1.4_2/include -L/opt/homebrew/Cellar/open-mpi/4.1.4_2/lib -L/opt/homebrew/opt/libevent/lib -lmpi
$ mpic++ main.cpp
$ # fix mac os error "A system call failed during shared memory initialization..."
$ export TMPDIR=/tmp
$ mpiexec --use-hwthread-cpus --mca opal_warn_on_missing_libcuda 0 a.out
  Hello from processor MacBook-Pro-Roman.local rank 7 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 5 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 0 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 1 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 2 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 3 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 6 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 4 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 8 out of 10
  Hello from processor MacBook-Pro-Roman.local rank 9 out of 10
						

Hello, world!

Шаблон любой программы MPI

Что за Comm?

Что за Comm?

Отправка и получение сообщений


						int MPI_Send(const void *buf, int count, MPI_Datatype datatype,
						             int dest, int tag, MPI_Comm comm);

						int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag,
						             MPI_Comm comm, MPI_Status *status);
					

Отправка и получение сообщений

Задание

Написать программу, в которой первый процесс генерирует некое случайное число и передаёт его второму процессу.

Второй (и каждый последующий, кроме последнего) получает число, увеличивает его на свой номер и передаёт следующему по цепочке.

Последний, приняв число выводит его на экран.

Некоторые нюансы

  • Что, если принимающая сторона не готова принимать сообщения?
  • Что, если придёт сообщение меньшего размера, чем мы ожидаем в MPI_Recv?
  • А если большего?

Как узнать размер сообщения?


						int MPI_Get_count(const MPI_Status *status, MPI_Datatype datatype, int *count)

						int MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status)


						struct MPI_Status {
							int MPI_SOURCE;
							int MPI_TAG;
							int MPI_ERROR;
						};
					

Константы MPI_ANY_SOURCE и MPI_ANY_TAG

Асинхронные функции


						int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest,
									        int tag, MPI_Comm comm, MPI_Request *request)

						int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,
									        int source, int tag, MPI_Comm comm, MPI_Request *request)
					

						int MPI_Wait(MPI_Request *request, MPI_Status *status)

						int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)
					

						int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag,
						               MPI_Status *status)
					

Когда это необходимо?

Пример блокировки

Решение

Подсчёт времени работы

Какие методы измерения времени работы программы вы знаете?

Функция в MPI:
double MPI_Wtime()