Files
parallel-programming/lab08_mpi/методичка.md
T
2026-10-07 13:06:47 +05:00

7.0 KiB
Raw Blame History

Лабораторная работа 8. Распределённые вычисления (MPI)

Время на работу: 2–3 пары. Зависимости: лабы 1, 4.

Цель работы

Освоить модель передачи сообщений (MPI) — стандарт распределённых вычислений, на котором работают суперкомпьютеры. Понять отличие «общей памяти» (потоки/процессы Python) от «обмена сообщениями» между независимыми узлами.

Теория

Модель MPI

MPI (Message Passing Interface) — набор программ на нескольких узлах (машинах или процессах), обменивающихся сообщениями. Нет общей памяти: любые данные передаются явно, функциями отправки/приёма. Программа запускается одновременно на N «рангах» (процессах):

mpiexec -n 4 python script.py      # 4 копии script.py

Каждая копия узнаёт, кто она:

from mpi4py import MPI
comm = MPI.COMM_WORLD              # «мир» — все ранги
rank = comm.Get_rank()             # мой номер: 0..size-1
size = comm.Get_size()             # всего рангов

Ранг 0 обычно координатор: он делит работу и собирает результат.

Операции: «точка-точка» и коллективные

Точка-точка (ранг ↔ ранг):

comm.send(data, dest=1, tag=0)     # блокирующая отправка
data = comm.recv(source=0, tag=0)  # блокирующий приём

Коллективные (все ранги сразу — проще и обычно быстрее):

Операция Что делает
bcast один раздает всем (broadcast)
scatter список режется на части: ранг i получает i-ю часть
gather части собираются в список на одном ранге
reduce части сворачиваются операцией (sum/max/…) на одном ранге
barrier все ждут, пока все дойдут до этой точки

Схема параллельной задачи в MPI

ранг 0: build -> split -> scatter ─┐
ранги 1..N:        получают кусок  │-> kernel -> gather -> combine -> checksum
ранг 0: собирает                   ┘

Это ровно ваша схема split→kernel→combine из лаб 1–4, только обмен данными — через сеть/IPC, а не общую память.

Установка (Windows)

  1. MS-MPI: скачать и установить msmpisetup.exe и msmpires.msi (https://www.microsoft.com/en-us/download/details.aspx?id=105289).
  2. pip install mpi4py
  3. Проверка: mpiexec -n 2 python -c "from mpi4py import MPI; print(MPI.COMM_WORLD.Get_rank())"

На macOS/Linux: brew install open-mpi / apt install libopenmpi-dev, затем pip install mpi4py, запуск mpiexec (или mpirun).

Важно: запускать mpiexec -n 4 — тогда solution.py выполнится 4 раза параллельно. Запуск без mpiexec допустим: программа работает как один ранг (полезно для отладки и автотестов).

Задание

Заполните solution.py:

  1. mpi_run(task_name, params) — параллельное выполнение вашей CPU-задачи: ранг 0 строит данные и делит на size кусков, scatter раздаёт, каждый ранг считает kernel (используя dispatch_kernel не нужно — в MPI функции не пиккелятся, только данные), gather собирает, ранг 0 возвращает checksum. Для задачи «Жизнь» — цикл по поколениям (см. подсказку в заготовке).
  2. mpi_pi(N) — учебный пример: π методом Монте-Карло на всех рангах, сборка через reduce (сумма попаданий). Каждый ранг использует random.Random(100 + rank) — свои броски.
  3. main() — checksum и время mpi_run на текущем числе рангов (size), печать с ранга 0. Запустите при -n 1, 2, 4 — получите T(p).

Ожидаемые результаты

  • checksum совпадает с последовательным запуском (лаба 1).
  • T(p) на одном компьютере ≈ результатам multiprocessing из лабы 4 (плюс небольшие расходы на обмен).
  • На настоящих нескольких машинах код не меняется — меняется только запуск (это главный смысл MPI).

Измерения для отчёта

mpiexec -n 1 python lab08_mpi\solution.py
mpiexec -n 2 python lab08_mpi\solution.py
mpiexec -n 4 python lab08_mpi\solution.py

Контрольные вопросы

  1. Чем модель передачи сообщений отличается от модели общей памяти?
  2. Что делает scatter и чем она отличается от bcast?
  3. Почему в MPI функции не нужно пиккелить, а в multiprocessing — нужно?
  4. Что такое ранг? Как ранг 0 узнаёт, сколько всего рангов?
  5. Когда MPI выгоднее multiprocessing, даже на одном компьютере?

Что сдаётся

solution.py + отчёт: вывод при -n 1/2/4, таблица T(p), сравнение с лабой 4, ответы на вопросы.

Критерии оценки

Пункт Баллы
mpi_run: checksum корректен при -n 1 и -n 4 3
mpi_pi через reduce 2
Замеры при разном числе рангов 2
Отчёт и ответы на вопросы 3

Типичные ошибки

  • Код с веткой «если rank == 0» выполняется ВСЕМИ рангами — не заворачивайте всю программу в if rank == 0.
  • Разные random на разных рангах без фиксации зерна — невоспроизводимый результат.
  • Заблокированный recv без парной send — программа висит. Начинайте с коллективных операций, они безопаснее.