Coverage for pySDC/tutorial/step_6/C_MPI_parallelization.py: 100%
37 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-25 20:28 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-25 20:28 +0000
1import sys
2from pathlib import Path
4from mpi4py import MPI
6from pySDC.helpers.stats_helper import get_sorted
7from pySDC.implementations.controller_classes.controller_MPI import controller_MPI
8from pySDC.tutorial.step_6.A_run_non_MPI_controller import set_parameters_ml
11def main(fname='step_6_C_out.txt'):
12 """
13 Run PFASST with the MPI-parallel controller, one step per rank.
15 Run it the way you would run any MPI program, with as many ranks as you want steps::
17 mpirun -np 4 python C_MPI_parallelization.py
19 The number of parallel steps is simply the size of ``MPI.COMM_WORLD``, so nothing in here has to
20 be told how many there are.
22 Args:
23 fname (str): file under ``data/`` to append the results to
24 """
26 # set MPI communicator
27 comm = MPI.COMM_WORLD
29 # get parameters from Part A
30 description, controller_params, t0, Tend = set_parameters_ml()
32 # instantiate controllers
33 controller = controller_MPI(controller_params=controller_params, description=description, comm=comm)
34 # get initial values on finest level
35 P = controller.S.levels[0].prob
36 uinit = P.u_exact(t0)
38 # call main functions to get things done...
39 uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
41 # filter statistics by type (number of iterations)
42 iter_counts = get_sorted(stats, type='niter', sortby='time')
44 # combine statistics into list of statistics
45 iter_counts_list = comm.gather(iter_counts, root=0)
47 rank = comm.Get_rank()
48 size = comm.Get_size()
50 if rank == 0:
51 Path("data").mkdir(parents=True, exist_ok=True)
52 f = open('data/' + fname, 'a')
53 out = 'Working with %2i processes...' % size
54 f.write(out + '\n')
55 print(out)
57 # compute exact solutions and compare with both results
58 uex = P.u_exact(Tend)
59 err = abs(uex - uend)
61 out = 'Error vs. exact solution: %12.8e' % err
62 f.write(out + '\n')
63 print(out)
65 # build one list of statistics instead of list of lists, the sort by time
66 iter_counts_gather = [item for sublist in iter_counts_list for item in sublist]
67 iter_counts = sorted(iter_counts_gather, key=lambda tup: tup[0])
69 # compute and print statistics
70 for item in iter_counts:
71 out = 'Number of iterations for time %4.2f: %1i ' % (item[0], item[1])
72 f.write(out + '\n')
73 print(out)
75 f.write('\n')
76 print()
78 assert all(item[1] <= 8 for item in iter_counts), "ERROR: weird iteration counts, got %s" % iter_counts
81if __name__ == "__main__":
82 main(sys.argv[1] if len(sys.argv) == 2 else 'step_6_C_out.txt')