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

140 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Лабораторная работа 8. Распределённые вычисления (MPI)
**Время на работу:** 2–3 пары. **Зависимости:** лабы 1, 4.
## Цель работы
Освоить модель передачи сообщений (MPI) — стандарт распределённых вычислений,
на котором работают суперкомпьютеры. Понять отличие «общей памяти»
(потоки/процессы Python) от «обмена сообщениями» между независимыми узлами.
## Теория
### Модель MPI
MPI (Message Passing Interface) — набор программ на нескольких **узлах**
(машинах или процессах), обменивающихся сообщениями. Нет общей памяти: любые
данные передаются явно, функциями отправки/приёма. Программа запускается
одновременно на N «рангах» (процессах):
```bat
mpiexec -n 4 python script.py # 4 копии script.py
```
Каждая копия узнаёт, кто она:
```python
from mpi4py import MPI
comm = MPI.COMM_WORLD # «мир» — все ранги
rank = comm.Get_rank() # мой номер: 0..size-1
size = comm.Get_size() # всего рангов
```
Ранг 0 обычно координатор: он делит работу и собирает результат.
### Операции: «точка-точка» и коллективные
**Точка-точка** (ранг ↔ ранг):
```python
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).
### Измерения для отчёта
```bat
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` — программа висит. Начинайте с
коллективных операций, они безопаснее.