7.0 KiB
Лабораторная работа 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)
- MS-MPI: скачать и установить msmpisetup.exe и msmpires.msi (https://www.microsoft.com/en-us/download/details.aspx?id=105289).
pip install mpi4py- Проверка:
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:
mpi_run(task_name, params)— параллельное выполнение вашей CPU-задачи: ранг 0 строит данные и делит наsizeкусков,scatterраздаёт, каждый ранг считаетkernel(используяdispatch_kernelне нужно — в MPI функции не пиккелятся, только данные),gatherсобирает, ранг 0 возвращает checksum. Для задачи «Жизнь» — цикл по поколениям (см. подсказку в заготовке).mpi_pi(N)— учебный пример: π методом Монте-Карло на всех рангах, сборка черезreduce(сумма попаданий). Каждый ранг используетrandom.Random(100 + rank)— свои броски.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
Контрольные вопросы
- Чем модель передачи сообщений отличается от модели общей памяти?
- Что делает
scatterи чем она отличается отbcast? - Почему в MPI функции не нужно пиккелить, а в multiprocessing — нужно?
- Что такое ранг? Как ранг 0 узнаёт, сколько всего рангов?
- Когда 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— программа висит. Начинайте с коллективных операций, они безопаснее.