Skip to content

Commit 4dc69dd

Browse files
authored
Merge pull request #93 from thabbott/ar/benchmarks
2 parents 1f8ea50 + 00d35bb commit 4dc69dd

File tree

7 files changed

+349
-33
lines changed

7 files changed

+349
-33
lines changed

benchmarks/benchmark_cfl.jl

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using Printf
2+
3+
using BenchmarkTools
4+
using CUDA
5+
using DataFrames
6+
using PrettyTables
7+
8+
using Oceananigans
9+
using Oceananigans.Architectures
10+
using JULES
11+
12+
using BenchmarkTools: prettytime, prettymemory
13+
14+
Archs = [CPU]
15+
@hascuda Archs = [CPU, GPU]
16+
17+
Ns = [32, 128]
18+
Tvars = [Energy, Entropy]
19+
Gases = [DryEarth, DryEarth3]
20+
21+
tags = ["arch", "N", "gases", "tvar"]
22+
23+
suite = BenchmarkGroup(
24+
"cfl" => BenchmarkGroup(),
25+
"acoustic_cfl" => BenchmarkGroup()
26+
)
27+
28+
_cfl(model) = cfl(model, 1)
29+
_cfl(model::CompressibleModel{GPU}) = CUDA.@sync cfl(model, 1)
30+
_acoustic_cfl(model) = acoustic_cfl(model, 1)
31+
_acoustic_cfl(model::CompressibleModel{GPU}) = CUDA.@sync acoustic_cfl(model, 1)
32+
33+
for Arch in Archs, N in Ns, Gas in Gases, Tvar in Tvars
34+
@info "Running CFL benchmark [$Arch, N=$N, $Tvar, $Gas]..."
35+
36+
grid = RegularCartesianGrid(size=(N, N, N), extent=(1, 1, 1))
37+
model = CompressibleModel(architecture=Arch(), grid=grid, thermodynamic_variable=Tvar(),
38+
gases=Gas())
39+
40+
# warmup
41+
_cfl(model)
42+
_acoustic_cfl(model)
43+
44+
b_cfl = @benchmark _cfl($model) samples=10
45+
display(b_cfl)
46+
47+
b_acfl = @benchmark _acoustic_cfl($model) samples=10
48+
display(b_acfl)
49+
50+
key = (Arch, N, Gas, Tvar)
51+
suite["cfl"][key] = b_cfl
52+
suite["acoustic_cfl"][key] = b_acfl
53+
end
54+
55+
function benchmarks_to_dataframe(suite)
56+
df = DataFrame(architecture=[], size=[], gases=[],
57+
thermodynamic_variable=[], min=[], median=[],
58+
mean=[], max=[], memory=[], allocs=[])
59+
60+
for Arch in Archs, N in Ns, Gas in Gases, Tvar in Tvars
61+
b = suite[Arch, N, Gas, Tvar]
62+
63+
d = Dict(
64+
"architecture" => Arch,
65+
"size" => "$(N)³",
66+
"gases" => Gas,
67+
"thermodynamic_variable" => Tvar,
68+
"min" => minimum(b.times) |> prettytime,
69+
"median" => median(b.times) |> prettytime,
70+
"mean" => mean(b.times) |> prettytime,
71+
"max" => maximum(b.times) |> prettytime,
72+
"memory" => prettymemory(b.memory),
73+
"allocs" => b.allocs
74+
)
75+
76+
push!(df, d)
77+
end
78+
79+
return df
80+
end
81+
82+
header = ["Arch" "Size" "Gases" "ThermoVar" "min" "median" "mean" "max" "memory" "allocs"]
83+
84+
df = benchmarks_to_dataframe(suite["cfl"])
85+
pretty_table(df, header, title="CFL benchmarks", nosubheader=true)
86+
87+
df = benchmarks_to_dataframe(suite["acoustic_cfl"])
88+
pretty_table(df, header, title="Acoustic CFL benchmarks", nosubheader=true)
89+
90+
function gpu_speedups(suite)
91+
df = DataFrame(size=[], gases=[], thermodynamic_variable=[], speedup=[])
92+
93+
for N in Ns, Gas in Gases, Tvar in Tvars
94+
b_cpu = suite[CPU, N, Gas, Tvar] |> median
95+
b_gpu = suite[GPU, N, Gas, Tvar] |> median
96+
b_ratio = ratio(b_cpu, b_gpu)
97+
98+
d = Dict(
99+
"size" => "$(N)³",
100+
"gases" => Gas,
101+
"thermodynamic_variable" => Tvar,
102+
"speedup" => @sprintf("%.3fx", b_ratio.time)
103+
)
104+
105+
push!(df, d)
106+
end
107+
108+
return df
109+
end
110+
111+
header = ["Size" "Gases" "ThermoVar" "speedup"]
112+
113+
df = gpu_speedups(suite["cfl"])
114+
pretty_table(df, header, title="CFL speedups", nosubheader=true)
115+
116+
df = gpu_speedups(suite["acoustic_cfl"])
117+
pretty_table(df, header, title="Acoustic CFL speedups", nosubheader=true)

benchmarks/benchmark_diagnosis.jl

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using BenchmarkTools
2+
using DataFrames
3+
using PrettyTables
4+
using CUDA
5+
6+
using Oceananigans
7+
using Oceananigans.Architectures
8+
using JULES
9+
10+
using BenchmarkTools: prettytime, prettymemory
11+
using JULES: intermediate_thermodynamic_field, compute_temperature!
12+
13+
Archs = [CPU]
14+
@hascuda Archs = [CPU, GPU]
15+
16+
Ns = [32, 64]
17+
@hascuda Ns = [32, 192]
18+
19+
Tvars = [Energy, Entropy]
20+
Gases = [DryEarth, DryEarth3]
21+
22+
tags = ["arch", "N", "gases", "tvar"]
23+
24+
suite = BenchmarkGroup(
25+
"temperature" => BenchmarkGroup(),
26+
"pressure" => BenchmarkGroup()
27+
)
28+
29+
_compute_temperature!(model) = compute_temperature!(model)
30+
_compute_temperature!(model::CompressibleModel{GPU}) = CUDA.@sync compute_temperature!(model)
31+
32+
for Arch in Archs, N in Ns, Gases in Gases, Tvar in Tvars
33+
@info "Running temperature computation benchmark [$Arch, N=$N, $Tvar, $Gases]..."
34+
35+
grid = RegularCartesianGrid(size=(N, N, N), extent=(1, 1, 1))
36+
model = CompressibleModel(architecture=Arch(), grid=grid, thermodynamic_variable=Tvar(),
37+
gases=Gases())
38+
39+
_compute_temperature!(model) # warmup
40+
41+
b = @benchmark _compute_temperature!($model) samples=10
42+
43+
key = (Arch, N, Gases, Tvar)
44+
suite["temperature"][key] = b
45+
end
46+
47+
function benchmarks_to_dataframe(suite)
48+
df = DataFrame(architecture=[], size=[], gases=[],
49+
thermodynamic_variable=[], min=[], median=[],
50+
mean=[], max=[], memory=[], allocs=[])
51+
52+
for (key, b) in suite
53+
Arch, N, Gases, Tvar = key
54+
55+
d = Dict(
56+
"architecture" => Arch,
57+
"size" => "$(N)³",
58+
"gases" => Gases,
59+
"thermodynamic_variable" => Tvar,
60+
"min" => minimum(b.times) |> prettytime,
61+
"median" => median(b.times) |> prettytime,
62+
"mean" => mean(b.times) |> prettytime,
63+
"max" => maximum(b.times) |> prettytime,
64+
"memory" => prettymemory(b.memory),
65+
"allocs" => b.allocs
66+
)
67+
68+
push!(df, d)
69+
end
70+
71+
return df
72+
end
73+
74+
header = ["Arch" "Size" "Gases" "ThermoVar" "min" "median" "mean" "max" "memory" "allocs"]
75+
76+
df = benchmarks_to_dataframe(suite["temperature"])
77+
pretty_table(df, header, title="Temperature computation benchmarks", nosubheader=true)
78+
79+
function gpu_speedups(suite)
80+
df = DataFrame(size=[], gases=[], thermodynamic_variable=[], speedup=[])
81+
82+
for N in Ns, Gas in Gases, Tvar in Tvars
83+
b_cpu = suite[CPU, N, Gas, Tvar] |> median
84+
b_gpu = suite[GPU, N, Gas, Tvar] |> median
85+
b_ratio = ratio(b_cpu, b_gpu)
86+
87+
d = Dict(
88+
"size" => "$(N)³",
89+
"gases" => Gas,
90+
"thermodynamic_variable" => Tvar,
91+
"speedup" => @sprintf("%.3fx", b_ratio.time)
92+
)
93+
94+
push!(df, d)
95+
end
96+
97+
return df
98+
end
99+
100+
header = ["Size" "Gases" "ThermoVar" "speedup"]
101+
102+
df = gpu_speedups(suite["temperature"])
103+
pretty_table(df, header, title="Temperature computation speedups", nosubheader=true)
+79-14
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,97 @@
11
using Printf
2-
using TimerOutputs
2+
3+
using BenchmarkTools
4+
using CUDA
5+
using DataFrames
6+
using PrettyTables
37

48
using Oceananigans
59
using Oceananigans.Architectures
610
using JULES
711

8-
const timer = TimerOutput()
9-
10-
Ns = (32, 256)
11-
Tvars = (Energy, Entropy)
12-
Gases = (DryEarth, DryEarth3)
12+
using BenchmarkTools: prettytime, prettymemory
1313

1414
Archs = [CPU]
1515
@hascuda Archs = [CPU, GPU]
1616

17-
for Arch in Archs, N in Ns, Tvar in Tvars, Gas in Gases
17+
Ns = [32, 192]
18+
Tvars = [Energy, Entropy]
19+
Gases = [DryEarth, DryEarth3]
20+
21+
suite = BenchmarkGroup()
1822

19-
bname = "$N×$N×$N [$Arch, $Tvar, $Gas]"
20-
@info "Benchmarking $bname..."
23+
sync_step!(model) = time_step!(model, 1)
24+
sync_step!(model::CompressibleModel{GPU}) = CUDA.@sync time_step!(model, 1)
2125

22-
grid = RegularCartesianGrid(size=(N, N, N), extent=(1, 1, 1), halo=(2, 2, 2))
26+
for Arch in Archs, N in Ns, Gas in Gases, Tvar in Tvars
27+
@info "Running static atmosphere benchmark [$Arch, N=$N, $Tvar, $Gas]..."
28+
29+
grid = RegularCartesianGrid(size=(N, N, N), halo=(2, 2, 2), extent=(1, 1, 1))
2330
model = CompressibleModel(architecture=Arch(), grid=grid, thermodynamic_variable=Tvar(), gases=Gas())
24-
time_step!(model, 1) # warmup to compile
2531

26-
for i in 1:10
27-
@timeit timer bname time_step!(model, 1)
32+
sync_step!(model) # warmup
33+
34+
b = @benchmark sync_step!($model) samples=10
35+
display(b)
36+
37+
key = (Arch, N, Gas, Tvar)
38+
suite[key] = b
39+
end
40+
41+
function benchmarks_to_dataframe(suite)
42+
df = DataFrame(architecture=[], size=[], gases=[],
43+
thermodynamic_variable=[], min=[], median=[],
44+
mean=[], max=[], memory=[], allocs=[])
45+
46+
for Arch in Archs, N in Ns, Gas in Gases, Tvar in Tvars
47+
b = suite[Arch, N, Gas, Tvar]
48+
49+
d = Dict(
50+
"architecture" => Arch,
51+
"size" => "$(N)³",
52+
"gases" => Gas,
53+
"thermodynamic_variable" => Tvar,
54+
"min" => minimum(b.times) |> prettytime,
55+
"median" => median(b.times) |> prettytime,
56+
"mean" => mean(b.times) |> prettytime,
57+
"max" => maximum(b.times) |> prettytime,
58+
"memory" => prettymemory(b.memory),
59+
"allocs" => b.allocs
60+
)
61+
62+
push!(df, d)
2863
end
2964

65+
return df
3066
end
3167

32-
print_timer(timer, title="Static atmosphere benchmarks", sortby=:name)
68+
header = ["Arch" "Size" "Gases" "ThermoVar" "min" "median" "mean" "max" "memory" "allocs"]
69+
70+
df = benchmarks_to_dataframe(suite)
71+
pretty_table(df, header, title="Static atmosphere benchmarks", nosubheader=true)
72+
73+
function gpu_speedups(suite)
74+
df = DataFrame(size=[], gases=[], thermodynamic_variable=[], speedup=[])
75+
76+
for N in Ns, Gas in Gases, Tvar in Tvars
77+
b_cpu = suite[CPU, N, Gas, Tvar] |> median
78+
b_gpu = suite[GPU, N, Gas, Tvar] |> median
79+
b_ratio = ratio(b_cpu, b_gpu)
80+
81+
d = Dict(
82+
"size" => "$(N)³",
83+
"gases" => Gas,
84+
"thermodynamic_variable" => Tvar,
85+
"speedup" => @sprintf("%.3fx", b_ratio.time)
86+
)
87+
88+
push!(df, d)
89+
end
90+
91+
return df
92+
end
93+
94+
header = ["Size" "Gases" "ThermoVar" "speedup"]
95+
96+
df = gpu_speedups(suite)
97+
pretty_table(df, header, title="Static atmosphere speedups", nosubheader=true)

src/utils.jl

+27-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,29 @@ end
3030
@inbounds p_over_ρ[i, j, k] = diagnose_p_over_ρ(i, j, k, grid, thermodynamic_variable, gases, gravity, total_density, momenta, tracers)
3131
end
3232

33+
@kernel function compute_temperature!(temperature, grid, thermodynamic_variable, gases, gravity, total_density, momenta, tracers)
34+
i, j, k = @index(Global, NTuple)
35+
36+
@inbounds temperature[i, j, k] = diagnose_temperature(i, j, k, grid, thermodynamic_variable, gases, gravity, total_density, momenta, tracers)
37+
end
38+
39+
function compute_temperature!(model)
40+
temperature = intermediate_thermodynamic_field(model)
41+
42+
temperature, total_density, momenta, tracers =
43+
datatuples(temperature, model.total_density, model.momenta, model.tracers)
44+
45+
compute_temperature_event =
46+
launch!(model.architecture, model.grid, :xyz, compute_temperature!,
47+
temperature, model.grid, model.thermodynamic_variable, model.gases,
48+
model.gravity, total_density, momenta, tracers,
49+
dependencies=Event(device(model.architecture)))
50+
51+
wait(device(model.architecture), compute_temperature_event)
52+
53+
return temperature
54+
end
55+
3356
#####
3457
##### CFL
3558
#####
@@ -52,9 +75,9 @@ function cfl(model, Δt)
5275

5376
wait(device(model.architecture), velocity_event)
5477

55-
u_max = maximum(velocities.u)
56-
v_max = maximum(velocities.v)
57-
w_max = maximum(velocities.w)
78+
u_max = maximum(velocities.u.parent)
79+
v_max = maximum(velocities.v.parent)
80+
w_max = maximum(velocities.w.parent)
5881

5982
Δx, Δy, Δz = model.grid.Δx, model.grid.Δy, model.grid.Δz
6083
CFL = Δt / min(Δx/u_max, Δy/v_max, Δz/w_max)
@@ -81,7 +104,7 @@ function acoustic_cfl(model, Δt)
81104

82105
wait(device(model.architecture), compute_p_over_ρ_event)
83106

84-
p_over_ρ_max = maximum(p_over_ρ)
107+
p_over_ρ_max = maximum(p_over_ρ.parent)
85108

86109
γ_max = maximum(gas.cₚ / gas.cᵥ for gas in model.gases)
87110
c_max = (γ_max * p_over_ρ_max)

0 commit comments

Comments
 (0)