def main(): """ Program to demonstrate usage of PETSc data structures and spatial parallelization, combined with parallelization in time. """ # set MPI communicator comm = MPI.COMM_WORLD world_rank = comm.Get_rank() world_size = comm.Get_size() # split world communicator to create space-communicators if len(sys.argv) >= 2: color = int(world_rank / int(sys.argv[1])) else: color = int(world_rank / 1) space_comm = comm.Split(color=color) space_size = space_comm.Get_size() space_rank = space_comm.Get_rank() # split world communicator to create time-communicators if len(sys.argv) >= 2: color = int(world_rank % int(sys.argv[1])) else: color = int(world_rank / world_size) time_comm = comm.Split(color=color) time_size = time_comm.Get_size() time_rank = time_comm.Get_rank() print("IDs (world, space, time): %i / %i -- %i / %i -- %i / %i" % (world_rank, world_size, space_rank, space_size, time_rank, time_size)) # initialize level parameters level_params = dict() level_params['restol'] = 1E-08 level_params['dt'] = 0.125 level_params['nsweeps'] = [1] # initialize sweeper parameters sweeper_params = dict() sweeper_params['collocation_class'] = CollGaussRadau_Right sweeper_params['num_nodes'] = [5] sweeper_params['QI'] = ['LU'] # For the IMEX sweeper, the LU-trick can be activated for the implicit part sweeper_params['spread'] = False # initialize problem parameters problem_params = dict() problem_params['nu'] = 1.0 # diffusion coefficient problem_params['freq'] = 2 # frequency for the test value problem_params['nvars'] = [(129, 129), (65, 65)] # number of degrees of freedom for each level problem_params['comm'] = space_comm # pass space-communicator to problem class problem_params['sol_tol'] = 1E-12 # set tolerance to PETSc' linear solver # initialize step parameters step_params = dict() step_params['maxiter'] = 50 # initialize space transfer parameters space_transfer_params = dict() space_transfer_params['rorder'] = 2 space_transfer_params['iorder'] = 2 space_transfer_params['periodic'] = False # initialize controller parameters controller_params = dict() controller_params['logger_level'] = 30 if space_rank == 0 else 99 # set level depending on rank controller_params['dump_setup'] = False controller_params['predict'] = False # fill description dictionary for easy step instantiation description = dict() description['problem_class'] = heat2d_petsc_forced # pass problem class description['problem_params'] = problem_params # pass problem parameters description['dtype_u'] = petsc_data # pass PETSc data type for u description['dtype_f'] = rhs_imex_petsc_data # pass PETSc data type for f description['sweeper_class'] = imex_1st_order # pass sweeper (see part B) description['sweeper_params'] = sweeper_params # pass sweeper parameters description['level_params'] = level_params # pass level parameters description['step_params'] = step_params # pass step parameters description['space_transfer_class'] = mesh_to_mesh_petsc_dmda # pass spatial transfer class description['space_transfer_params'] = space_transfer_params # pass paramters for spatial transfer # set time parameters t0 = 0.0 Tend = 3.0 # instantiate controller controller = allinclusive_classic_MPI(controller_params=controller_params, description=description, comm=time_comm) # get initial values on finest level P = controller.S.levels[0].prob uinit = P.u_exact(t0) # call main function to get things done... uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend) # compute exact solution and compare uex = P.u_exact(Tend) err = abs(uex - uend) # filter statistics by type (number of iterations) filtered_stats = filter_stats(stats, type='niter') # convert filtered statistics to list of iterations count, sorted by process iter_counts = sort_stats(filtered_stats, sortby='time') niters = np.array([item[1] for item in iter_counts]) # limit output to space-rank 0 (as before when setting the logger level) if space_rank == 0: out = 'This is time-rank %i...' % time_rank print(out) # compute and print statistics for item in iter_counts: out = 'Number of iterations for time %4.2f: %2i' % item print(out) out = ' Mean number of iterations: %4.2f' % np.mean(niters) print(out) out = ' Range of values for number of iterations: %2i ' % np.ptp(niters) print(out) out = ' Position of max/min number of iterations: %2i -- %2i' % \ (int(np.argmax(niters)), int(np.argmin(niters))) print(out) out = ' Std and var for number of iterations: %4.2f -- %4.2f' % (float(np.std(niters)), float(np.var(niters))) print(out) timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time') out = 'Time to solution: %6.4f sec.' % timing[0][1] print(out) out = 'Error vs. PDE solution: %6.4e' % err print(out)
from tutorial.step_6.A_classic_vs_multigrid_controller import set_parameters if __name__ == "__main__": """ A simple test program to do MPI-parallel PFASST runs """ # set MPI communicator comm = MPI.COMM_WORLD # get parameters from Part A description, controller_params, t0, Tend = set_parameters() # instantiate controllers controller_classic = allinclusive_classic_MPI( controller_params=controller_params, description=description, comm=comm) controller_multigrid = allinclusive_multigrid_MPI( controller_params=controller_params, description=description, comm=comm) # get initial values on finest level P = controller_classic.S.levels[0].prob uinit = P.u_exact(t0) # call main functions to get things done... uend_classic, stats_classic = controller_classic.run(u0=uinit, t0=t0, Tend=Tend) uend_multigrid, stats_multigrid = controller_multigrid.run(u0=uinit, t0=t0,
def run_variant(nsweeps): """ Routine to run particular SDC variant Args: Returns: """ # set MPI communicator comm = MPI.COMM_WORLD world_rank = comm.Get_rank() world_size = comm.Get_size() # split world communicator to create space-communicators if len(sys.argv) >= 3: color = int(world_rank / int(sys.argv[2])) else: color = int(world_rank / 1) space_comm = comm.Split(color=color) space_size = space_comm.Get_size() space_rank = space_comm.Get_rank() # split world communicator to create time-communicators if len(sys.argv) >= 3: color = int(world_rank % int(sys.argv[2])) else: color = int(world_rank / world_size) time_comm = comm.Split(color=color) time_size = time_comm.Get_size() time_rank = time_comm.Get_rank() print( "IDs (world, space, time): %i / %i -- %i / %i -- %i / %i" % (world_rank, world_size, space_rank, space_size, time_rank, time_size)) # load (incomplete) default parameters description, controller_params = setup_parameters(nsweeps=nsweeps) # setup parameters "in time" t0 = 0.0 Tend = 0.032 # instantiate controller controller = allinclusive_classic_MPI(controller_params=controller_params, description=description, comm=time_comm) # get initial values on finest level P = controller.S.levels[0].prob uinit = P.u_exact(t0) # call main function to get things done... uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend) # filter statistics by variant (number of iterations) filtered_stats = filter_stats(stats, type='niter') # convert filtered statistics to list of iterations count, sorted by process iter_counts = sort_stats(filtered_stats, sortby='time') # compute and print statistics niters = np.array([item[1] for item in iter_counts]) out = ' Mean number of iterations: %4.2f' % np.mean(niters) print(out) out = ' Range of values for number of iterations: %2i ' % np.ptp(niters) print(out) out = ' Position of max/min number of iterations: %2i -- %2i' % \ (int(np.argmax(niters)), int(np.argmin(niters))) print(out) out = ' Std and var for number of iterations: %4.2f -- %4.2f' % (float( np.std(niters)), float(np.var(niters))) print(out) timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time') maxtiming = comm.allreduce(sendobj=timing[0][1], op=MPI.MAX) if time_rank == time_size - 1 and space_rank == 0: print('Time to solution: %6.4f sec.' % maxtiming) # if time_rank == time_size - 1: # fname = 'data/AC_reference_FFT_Tend{:.1e}'.format(Tend) + '.npz' # loaded = np.load(fname) # uref = loaded['uend'] # # err = np.linalg.norm(uref - uend.values, np.inf) # print('Error vs. reference solution: %6.4e' % err) # print() return stats