Subduction Zone Benchmark#
Author: Cian Wilson
Under Construction!
Parallel Scaling#
In the previous notebook we tested that the error in our implementation of a steady-state thermal convection problem in two-dimensions converged towards the published benchmark value as the resolution scale (resscale) decreased (the number of elements increased). We also wish to test for parallel scaling of this problem, assessing if the simulation wall time decreases as the number of processors used to solve it is increases.
Here we perform strong scaling tests on our functions solve_benchmark_case1 and solve_benchmark_case2 from the previous notebook.
Preamble#
We start by loading all the modules we will require.
import sys, os
basedir = ''
if "__file__" in globals(): basedir = os.path.dirname(__file__)
path = os.path.join(basedir, os.path.pardir, os.path.pardir, 'python')
sys.path.append(path)
import utils.ipp
import matplotlib.pyplot as pl
import numpy as np
import pathlib
output_folder = pathlib.Path(os.path.join(basedir, "output"))
output_folder.mkdir(exist_ok=True, parents=True)
Implementation#
We perform the strong parallel scaling test using a utility function (from python/utils/ipp.py) that loops over a list of the number of processors calling our function for a given number of elements, ne, and pressure and temperature polynomial orders pp and pT. It runs our function solve_blankenbach a specified number of times and evaluates and returns the time taken for each of a number of requested steps.
# the list of the number of processors we will use
nprocs_scale = [1, 2,]
# the number of elements to solve the problem on
resscale = 1
# perform the calculation a set number of times
number = 1
# We are interested in the time to create the mesh,
# declare the functions, assemble the problem and solve it.
# From our implementation in `solve_poisson_2d` it is also
# possible to request the time to declare the Dirichlet and
# Neumann boundary conditions and the forms.
steps = [
'Assemble Temperature', 'Assemble Stokes',
'Solve Temperature', 'Solve Stokes'
]
Case 1#
# declare a dictionary to store the times each step takes
maxtimes_1 = {}
maxtimes_1['Direct Stokes'] = utils.ipp.profile_parallel(nprocs_scale, steps, path,
'sz_problems.sz_benchmark', 'solve_benchmark_case1',
resscale, number=number,
output_filename=output_folder / 'sz_benchmark_scaling_direct_1a.png')
=========================
1 2
Assemble Temperature 0.12 0.08
Assemble Stokes 0.28 1.7
Solve Temperature 1.05 1
Solve Stokes 2.57 0.78
=========================
*********** profiling figure in output/sz_benchmark_scaling_direct_1a.png
# the list of the number of processors to test the convergence on
nprocs_conv = [1, 2,]
# List of resolutions to try
resscales = [2,]
diagnostics = []
for resscale in resscales:
diagnostics.append(utils.ipp.run_parallel(nprocs_conv, path,
'sz_problems.sz_benchmark',
'solve_benchmark_case1',
resscale))
print('')
print('{:<12} {:<12} {:<12} {:<12} {:<12} {:<12} {:<12}'.format('nprocs', 'resscale', 'T_ndof', 'T_{200,-100}', 'Tbar_s', 'Tbar_w', 'Vrmsw'))
for resscale, diag_all in zip(resscales, diagnostics):
for i, nproc in enumerate(nprocs_conv):
print('{:<12d} {:<12.4g} {:<12d} {:<12.4f} {:<12.4f} {:<12.4f} {:<12.4f}'.format(nproc, resscale, *diag_all[i].values()))
nprocs resscale T_ndof T_{200,-100} Tbar_s Tbar_w Vrmsw
1 2 32749 516.9332 451.6764 926.2604 34.6379
2 2 32749 516.9332 451.6764 926.2604 34.6379