# -*- coding: utf-8 -*- """Демо: π методом Монте-Карло в MPI (reduce). Запуск из корня курса: mpiexec -n 4 python lab08_mpi/examples/04_pi_reduce_mpi.py Каждый ранг бросает свою порцию «точек» со СВОИМ зерном (rank-зависимым), reduce(SUM) сворачивает попадания. Число рангов не меняет формулу — меняется только распределение бросков. """ import random import time from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() N_PER_RANK = 500_000 def count_inside(n: int, seed: int) -> int: rng = random.Random(seed) # зерно зависит от ранга inside = 0 for _ in range(n): x = rng.random() y = rng.random() if x * x + y * y <= 1.0: inside += 1 return inside t0 = time.perf_counter() my_inside = count_inside(N_PER_RANK, seed=1000 + rank) total_inside = comm.reduce(my_inside, op=MPI.SUM, root=0) dt = time.perf_counter() - t0 if rank == 0: total = N_PER_RANK * size pi = 4.0 * total_inside / total print(f"рангов: {size}, бросков на ранг: {N_PER_RANK:,} (всего {total:,})") print(f"π ≈ {pi:.6f} (погрешность {abs(pi - 3.141592653589793):.6f})") print(f"время: {dt:.2f} c") if size == 1: print("\nПопробуйте: mpiexec -n 4 python lab08_mpi/examples/04_pi_reduce_mpi.py") print("Каждый ранг добавляет 500k бросков: точность растёт, время — нет.")