Skip to content

Commit e94e3c2

Browse files
fix: use eval instead of RGFs
1 parent f715b57 commit e94e3c2

File tree

2 files changed

+92
-40
lines changed

2 files changed

+92
-40
lines changed

benchmarks/Symbolics/BCR.jmd

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ rn = complete(prnbng.rn; split = false)
3333
obs = [eq.lhs for eq in observed(rn)]
3434
osys = convert(ODESystem, rn)
3535

36-
rhs = [eq.rhs for eq in full_equations(osys)]
36+
rhs = [eq.rhs for eq in full_equations(osys)][1:10]
3737
vars = unknowns(osys)
3838
pars = parameters(osys)
3939

@@ -55,10 +55,13 @@ args = (vars, pars, ModelingToolkit.get_iv(osys))
5555
# out of place versions run into an error saying the expression is too large
5656
# due to the `SymbolicUtils.Code.create_array` call. `iip_config` prevents it
5757
# from trying to build the function.
58-
kwargs = (; iip_config = (false, true), expression = Val{false})
58+
kwargs = (; iip_config = (false, true), expression = Val{true})
5959
@timeit to "Build jacobian - no CSE" _, jac_nocse_iip = build_function(jac, args...; cse = false, kwargs...);
6060
@timeit to "Build jacobian - CSE" _, jac_cse_iip = build_function(jac, args...; cse = true, kwargs...);
6161

62+
jac_nocse_iip = eval(jac_nocse_iip)
63+
jac_cse_iip = eval(jac_cse_iip)
64+
6265
defs = defaults(osys)
6366
u = Float64[Symbolics.fixpoint_sub(var, defs) for var in vars]
6467
buffer_cse = similar(jac, Float64)
@@ -81,7 +84,7 @@ We'll also measure scaling.
8184

8285

8386
```julia
84-
function run_and_time!(rhs, vars, pars, iv, u0, p, t0, N, i, jac_times, jac_allocs, build_times, first_call_times, second_call_times)
87+
function run_and_time_construct!(rhs, vars, pars, iv, N, i, jac_times, jac_allocs, build_times, functions)
8588
outputs = rhs[1:N]
8689
SymbolicUtils.ENABLE_HASHCONSING[] = false
8790
jac_result = @be Symbolics.sparsejacobian(outputs, vars)
@@ -99,46 +102,70 @@ function run_and_time!(rhs, vars, pars, iv, u0, p, t0, N, i, jac_times, jac_allo
99102
@assert isequal(jac_nohc, jac_hc)
100103
jac = jac_hc
101104
args = (vars, pars, iv)
102-
kwargs = (; iip_config = (false, true), expression = Val{false})
105+
kwargs = (; iip_config = (false, true), expression = Val{true})
103106

104107
build_result = @be build_function(jac, args...; cse = false, kwargs...);
105108
build_times[1][i] = minimum(x -> x.time, build_result.samples)
106-
jacfn_nocse = build_function(jac, args...; cse = false, kwargs...)[2]
109+
jacfn_nocse = eval(build_function(jac, args...; cse = false, kwargs...)[2])
107110

108111
build_result = @be build_function(jac, args...; cse = true, kwargs...);
109112
build_times[2][i] = minimum(x -> x.time, build_result.samples)
110-
jacfn_cse = build_function(jac, args...; cse = true, kwargs...)[2]
113+
jacfn_cse = eval(build_function(jac, args...; cse = true, kwargs...)[2])
114+
115+
functions[1][i] = let buffer = similar(jac, Float64), fn = jacfn_nocse
116+
function nocse(u, p, t)
117+
fn(buffer, u, p, t)
118+
buffer
119+
end
120+
end
121+
functions[2][i] = let buffer = similar(jac, Float64), fn = jacfn_cse
122+
function cse(u, p, t)
123+
fn(buffer, u, p, t)
124+
buffer
125+
end
126+
end
127+
128+
return nothing
129+
end
130+
131+
function run_and_time_call!(i, u, p, tt, functions, first_call_times, second_call_times)
132+
jacfn_nocse = functions[1][i]
133+
jacfn_cse = functions[2][i]
111134

112-
buffer = similar(jac, Float64)
113-
call_result = @timed jacfn_nocse(buffer, u0, p, t0)
135+
call_result = @timed jacfn_nocse(u, p, tt)
114136
first_call_times[1][i] = call_result.time
115-
call_result = @timed jacfn_cse(buffer, u0, p, t0)
137+
call_result = @timed jacfn_cse(u, p, tt)
116138
first_call_times[2][i] = call_result.time
117139

118-
call_result = @be jacfn_nocse(buffer, u0, p, t0)
140+
call_result = @be jacfn_nocse(u, p, tt)
119141
second_call_times[1][i] = minimum(x -> x.time, call_result.samples)
120-
call_result = @be jacfn_cse(buffer, u0, p, t0)
142+
call_result = @be jacfn_cse(u, p, tt)
121143
second_call_times[2][i] = minimum(x -> x.time, call_result.samples)
122-
123-
return nothing
124144
end
125145
```
126146

127147
# Run benchmark
128148

129149
```julia
130-
N = [10, 20, 40, 60, 100, 200, 300, 400]
150+
N = [10, 20, 40, 80]
131151
jacobian_times = [zeros(Float64, length(N)), zeros(Float64, length(N))]
132152
jacobian_allocs = copy.(jacobian_times)
153+
functions = [Vector{Any}(undef, length(N)), Vector{Any}(undef, length(N))]
133154
# [without_cse_times, with_cse_times]
134155
build_times = copy.(jacobian_times)
135156
first_call_times = copy.(jacobian_times)
136157
second_call_times = copy.(jacobian_times)
137158

138159
iv = ModelingToolkit.get_iv(osys)
139-
run_and_time!(rhs, vars, pars, iv, u, p, tt, 10, 1, jacobian_times, jacobian_allocs, build_times, first_call_times, second_call_times)
160+
run_and_time_construct!(rhs, vars, pars, iv, 10, 1, jacobian_times, jacobian_allocs, build_times, functions)
161+
run_and_time_call!(1, u, p, tt, functions, first_call_times, second_call_times)
162+
for (i, n) in enumerate(N)
163+
@info i n
164+
run_and_time_construct!(rhs, vars, pars, iv, n, i, jacobian_times, jacobian_allocs, build_times, functions)
165+
end
140166
for (i, n) in enumerate(N)
141-
run_and_time!(rhs, vars, pars, iv, u, p, tt, n, i, jacobian_times, jacobian_allocs, build_times, first_call_times, second_call_times)
167+
@info i n
168+
run_and_time_call!(i, u, p, tt, functions, first_call_times, second_call_times)
142169
end
143170
```
144171

benchmarks/Symbolics/ThermalFluid.jmd

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ function call(fn, args...)
251251
fn(args...)
252252
end
253253

254-
function run_and_time!(jacobian_times, jacobian_gctimes, jacobian_allocs, build_times, first_call_times, second_call_times, i, N)
254+
function run_and_time_construction!(jacobian_times, jacobian_gctimes, jacobian_allocs, build_times, functions, i, N)
255255
@mtkbuild sys = TestBenchPreinsulated(L=470, N=N, dn=0.3127, t_layer=[0.0056, 0.058])
256-
@info "Built system" N
256+
@info "Built system"
257257
SymbolicUtils.ENABLE_HASHCONSING[] = false
258258
jac_result = @be calculate_jacobian(sys; sparse = true)
259259
@info "No hashconsing benchmark"
@@ -287,39 +287,58 @@ function run_and_time!(jacobian_times, jacobian_gctimes, jacobian_allocs, build_
287287
buffer_cse = similar(jac, Float64)
288288
buffer_cse.nzval .= 0.0
289289

290-
f_jac_nocse = build_function(jac, dvs, ps, t; iip_config = (false, true), expression = Val{false}, cse = false)[2]
290+
f_jac_nocse = eval(build_function(jac, dvs, ps, t; iip_config = (false, true), expression = Val{true}, cse = false)[2])
291+
functions[1][i] = let buffer_nocse = buffer_nocse, u0 = u0, p = p, t0 = t0, f_jac_nocse = f_jac_nocse
292+
function nocse()
293+
f_jac_nocse(buffer_nocse, u0, p, t0)
294+
buffer_nocse
295+
end
296+
end
291297
@info "No CSE build_function result"
292-
build_result_nocse = @be build_function(jac, dvs, ps, t; iip_config = (false, true), expression = Val{false}, cse = false)
298+
build_result_nocse = @be build_function(jac, dvs, ps, t; iip_config = (false, true), expression = Val{true}, cse = false)
293299
@info "No CSE build_function benchmark"
294300
build_times[1][i] = mean(x -> x.time, build_result_nocse.samples)
295-
@info "time" build_times[1][i]
296-
first_call_result_nocse = @timed call(f_jac_nocse, buffer_nocse, u0, p, t0)
297-
first_call_times[1][i] = first_call_result_nocse.time
298-
@info "time" first_call_times[1][i]
299-
second_call_result_nocse = @be call(f_jac_nocse, buffer_nocse, u0, p, t0)
300-
second_call_times[1][i] = mean(x -> x.time, second_call_result_nocse.samples)
301-
@info "time" second_call_times[1][i]
302-
303-
f_jac_cse = build_function(jac, dvs, ps, t; iip_config = (false, true), expression = Val{false}, cse = true)[2]
301+
@info "build_function time" build_times[1][i]
302+
303+
f_jac_cse = eval(build_function(jac, dvs, ps, t; iip_config = (false, true), expression = Val{true}, cse = true)[2])
304+
functions[2][i] = let buffer_cse = buffer_cse, u0 = u0, p = p, t0 = t0, f_jac_cse = f_jac_cse
305+
function nocse()
306+
f_jac_cse(buffer_cse, u0, p, t0)
307+
buffer_cse
308+
end
309+
end
304310
@info "CSE build_function result"
305-
build_result_cse = @be build_function(jac, dvs, ps, t; iip_config = (false, true), expression = Val{false}, cse = true)
311+
build_result_cse = @be build_function(jac, dvs, ps, t; iip_config = (false, true), expression = Val{true}, cse = true)
306312
@info "CSE build_function benchmark"
307313
build_times[2][i] = mean(x -> x.time, build_result_cse.samples)
308-
@info "time" build_times[2][i]
309-
first_call_result_cse = @timed call(f_jac_cse, buffer_cse, u0, p, t0)
310-
first_call_times[2][i] = first_call_result_cse.time
311-
@info "time" first_call_times[2][i]
312-
second_call_result_cse = @be call(f_jac_cse, buffer_cse, u0, p, t0)
313-
second_call_times[2][i] = mean(x -> x.time, second_call_result_cse.samples)
314-
@info "time" second_call_times[2][i]
314+
@info "build_function time" build_times[2][i]
315315

316316
return nothing
317317
end
318+
319+
function run_and_time_call!(functions, first_call_times, second_call_times, i)
320+
fnocse = functions[1][i]
321+
fcse = functions[2][i]
322+
first_call_result_nocse = @timed fnocse()
323+
first_call_times[1][i] = first_call_result_nocse.time
324+
@info "First call time" first_call_times[1][i]
325+
second_call_result_nocse = @be fnocse()
326+
second_call_times[1][i] = mean(x -> x.time, second_call_result_nocse.samples)
327+
@info "Runtime" second_call_times[1][i]
328+
329+
first_call_result_cse = @timed fcse()
330+
first_call_times[2][i] = first_call_result_cse.time
331+
@info "First call time" first_call_times[2][i]
332+
second_call_result_cse = @be fcse()
333+
second_call_times[2][i] = mean(x -> x.time, second_call_result_cse.samples)
334+
@info "Runtime" second_call_times[2][i]
335+
end
318336
```
319337

320338
```julia
321-
N = [5, 10, 20, 40, 80, 160, 320];
339+
N = [5, 10, 20, 40];
322340
jacobian_times = [zeros(Float64, length(N)), zeros(Float64, length(N))]
341+
functions = [Vector{Any}(undef, length(N)), Vector{Any}(undef, length(N))]
323342
jacobian_gctimes = copy.(jacobian_times)
324343
jacobian_allocs = copy.(jacobian_times)
325344
# [without_cse_times, with_cse_times]
@@ -332,10 +351,16 @@ second_call_times = copy.(jacobian_times)
332351

333352
```julia
334353
# compile
335-
run_and_time!(jacobian_times, jacobian_gctimes, jacobian_allocs, build_times, first_call_times, second_call_times, 1, 5)
354+
run_and_time_construction!(jacobian_times, jacobian_gctimes, jacobian_allocs, build_times, functions, 1, 5)
355+
run_and_time_call!(functions, first_call_times, second_call_times, 1)
356+
for (i, n) in enumerate(N)
357+
@info i n
358+
@time run_and_time_construction!(jacobian_times, jacobian_gctimes, jacobian_allocs, build_times, functions, i, n)
359+
end
360+
336361
for (i, n) in enumerate(N)
337362
@info i n
338-
@time run_and_time!(jacobian_times, jacobian_gctimes, jacobian_allocs, build_times, first_call_times, second_call_times, i, n)
363+
run_and_time_call!(functions, first_call_times, second_call_times, i)
339364
end
340365
```
341366

0 commit comments

Comments
 (0)