44 lines
2.1 KiB
Python
44 lines
2.1 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""Демо: коллективные операции scatter / gather / reduce / bcast.
|
||
|
||
Запуск из корня курса:
|
||
mpiexec -n 4 python lab08_mpi/examples/03_collectives_mpi.py
|
||
|
||
Показывает все четыре коллективные операции на маленьком примере.
|
||
"""
|
||
from mpi4py import MPI
|
||
|
||
comm = MPI.COMM_WORLD
|
||
rank = comm.Get_rank()
|
||
size = comm.Get_size()
|
||
|
||
# --- bcast: один -> всем ------------------------------------------------
|
||
config = {"task": "summa_kvadratov", "n": 100} if rank == 0 else None
|
||
config = comm.bcast(config, root=0)
|
||
print(f"ранг {rank}: config = {config}")
|
||
|
||
# --- scatter: СПИСОК КУСКОВ (ровно size штук), ранг i получает i-й --------
|
||
if rank == 0:
|
||
# каждый кусок — свой список; scatter ждёт список из size кусков!
|
||
numbers = [[i * 10 + j for j in range(10)] for i in range(size)]
|
||
else:
|
||
numbers = None
|
||
my_chunk = comm.scatter(numbers, root=0) # ранг i получает свой кусок
|
||
print(f"ранг {rank}: мой кусок {my_chunk[0]}..{my_chunk[-1]} ({len(my_chunk)} шт.)")
|
||
|
||
# --- каждый ранг считает СВОЮ часть --------------------------------------
|
||
my_sum = sum(x * x for x in my_chunk)
|
||
print(f"ранг {rank}: сумма квадратов моего куска = {my_sum}")
|
||
|
||
# --- gather: все части -> список на ранге 0 ------------------------------
|
||
partial_sums = comm.gather(my_sum, root=0)
|
||
if rank == 0:
|
||
print(f"ранг 0: частичные суммы = {partial_sums}")
|
||
print(f"ранг 0: итого через sum(gather) = {sum(partial_sums)}")
|
||
|
||
# --- reduce: то же самое, но сразу со свёрткой (проще и быстрее) ----------
|
||
total = comm.reduce(my_sum, op=MPI.SUM, root=0)
|
||
if rank == 0:
|
||
print(f"ранг 0: итого через reduce(MPI.SUM) = {total}")
|
||
print("\ngather+sum и reduce(SUM) дали одно и то же — reduce короче.")
|
||
print("В задании mpi_pi вы используете reduce для суммы попаданий.") |