-
Notifications
You must be signed in to change notification settings - Fork 0
/
benchmark.py
89 lines (69 loc) · 2.7 KB
/
benchmark.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# =============================================================================
# benchmark.py
#
# Functions for benchmarking metpy functions with dask and numpy arrays
# as arguments.
#
# Author: Russell Manser
# Created: 12/15/2020
# =============================================================================
import time
from pathlib import Path
import xarray as xr
import metpy.calc as mpcalc
from metpy.units import units
def dewpoint_from_relative_humidity(temperature, relative_humidity):
"""Similar to `metpy.calc.dewpoint_from_relative_humidity`, but without
a check for values greater than 120%"""
return mpcalc.dewpoint(
relative_humidity * mpcalc.saturation_vapor_pressure(temperature)
)
def test(type):
"""Run a single benchmark test for computation of meteorological fields
across a forecast ensemble.
Parameters
----------
type : str
The type of array to test; either 'numpy' or 'dask'.
Returns
-------
tuple of floats
The total wall and process times.
"""
refpath = Path("/lustre/scratch/rmanser/wrfref/wrfoutREFd02")
mempath = Path("/lustre/scratch/rmanser/test_ens/2016052812/")
ref = xr.open_dataset(refpath)
# All members are loaded implicitly as dask arrays, regardless of `type`
members = xr.open_mfdataset(
mempath.glob("mem*/wrfout_d02_2016-05-30_12:00:00"),
concat_dim='members',
combine='nested',
)
# For dask arrays, we select the individual variable dask arrays
if type == 'dask':
pressure = (members.P + ref.PB).data * units(ref.PB.units)
theta = (members.T + ref.T00).data * units(ref.T00.units)
mixing_ratio = members.QVAPOR.data * units('dimensionless')
# For numpy arrays, we force variable arrays to be loaded into memory
elif type == 'numpy':
pressure = (members.P + ref.PB).values * units(ref.PB.units)
theta = (members.T + ref.T00).values * units(ref.T00.units)
mixing_ratio = members.QVAPOR.values * units('dimensionless')
start_wall = time.time()
start_proc = time.process_time()
temperature = mpcalc.temperature_from_potential_temperature(pressure, theta)
relative_humidity = mpcalc.relative_humidity_from_mixing_ratio(
mixing_ratio,
temperature,
pressure
)
# We don't call metpy's function here because it implicitly triggers
# a dask.compute() call
dewpoint = dewpoint_from_relative_humidity(temperature, relative_humidity)
if type == 'dask':
td = dewpoint.compute()
end_wall = time.time()
end_proc = time.process_time()
total_wall = end_wall - start_wall
total_proc = end_proc - start_proc
return total_wall, total_proc