Skip to content

Commit

Permalink
Merge pull request #955 from SciML/ChrisRackauckas-patch-2
Browse files Browse the repository at this point in the history
Reformat RCCircuit a bit
  • Loading branch information
ChrisRackauckas authored Jun 15, 2024
2 parents d5d9051 + d1f8120 commit 70523b5
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .buildkite/launch_benchmarks.yml.signature
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Salted__���O�������*��Ԏ�J�>X:p��L`�8��x��*)ޡ�Y� �r�wj�O�C��U�~^�¥M�VɃ�S�v�E%
Salted__j(`�$~���Ic h��B'6����C�E����"c2>꿄���XW�m.Ɲ6��K_���5L�FV‚�Xp�sE���
2 changes: 1 addition & 1 deletion benchmarks/ModelingToolkit/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OrdinaryDiffEq = "6.80.0"
Polynomials = "4.0.8"
PreferenceTools = "0.1.2"
SciMLBenchmarks = "0.1.3"
Symbolics = "5.28.0"
Symbolics = "5.30.1"

[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
Expand Down
112 changes: 68 additions & 44 deletions benchmarks/ModelingToolkit/RCCircuit.jmd
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ title: RC Circuit
author: Avinash Subramanian, Yingbo Ma, Chris Elrod
---

When a model is defined using repeated components, JuliaSimCompiler is able to take advantage of this to scale efficiently by rerolling equations into loops. This option can be disabled by setting `loop=false`. Here, we build an RC circuit model with variable numbers of components to show scaling of compile and runtimes of MTK vs JuliaSimCompiler's three backends with and without loop rerolling.
When a model is defined using repeated components, JuliaSimCompiler is able to take advantage of this
to scale efficiently by rerolling equations into loops. This option can be disabled by setting `loop=false`.
Here, we build an RC circuit model with variable numbers of components to show scaling of compile and
runtimes of MTK vs JuliaSimCompiler's three backends with and without loop rerolling.

## Setup Model Code

```julia
using JuliaSimCompiler, ModelingToolkit, OrdinaryDiffEq, BenchmarkTools, ModelingToolkitStandardLibrary, OMJulia, CairoMakie
using ModelingToolkitStandardLibrary.Blocks
using ModelingToolkitStandardLibrary.Electrical
```

```julia
# ModelingToolkit and JuliaSimCompiler
const t = Blocks.t

Expand Down Expand Up @@ -58,21 +65,6 @@ end
const C = JuliaSimCompiler.CTarget();
const LLVM = JuliaSimCompiler.llvm.LLVMTarget();

# OMJ
const omod = OMJulia.OMCSession();
OMJulia.sendExpression(omod, "getVersion()")
OMJulia.sendExpression(omod, "installPackage(Modelica)")
const modelicafile = joinpath(@__DIR__, "RC_Circuit.mo")

function time_open_modelica(n::Int)
totaltime = @elapsed res = begin
ModelicaSystem(omod, modelicafile, "RC_Circuit.Test.RC_Circuit_MTK_test_$n")
sendExpression(omod, "simulate(RC_Circuit.Test.RC_Circuit_MTK_test_$n)")
end
@assert res["messages"][1:11] == "LOG_SUCCESS"
return totaltime
end

function run_and_time_julia!(ss_times, times, max_sizes, i, n)
sys, u0, ps = build_system(n);
if n <= max_sizes[1]
Expand All @@ -94,15 +86,9 @@ function run_and_time_julia!(ss_times, times, max_sizes, i, n)
total_times[i, j] = ss_time + t_fode + t_solve
end
end
```

function run_and_time!(ss_times, times, max_sizes, i, n)
run_and_time_julia!(ss_times, times, max_sizes, i, n)
if n <= max_sizes[8]
total_times[i, 8] = time_open_modelica(n)
end
@views println("n = $(n)\nstructural_simplify_times = $(ss_times[i,:])\ncomponent times = $(times[i, :])\ntotal times = $(total_times[i, :])")
end

```julia
N = [5, 10, 20, 40, 60, 80, 160, 320, 480, 640, 800, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000];

# max size we test per method
Expand All @@ -112,13 +98,70 @@ max_sizes = [4_000, 8_000, 20_000, 20_000, 20_000, 20_000, 20_000, 9000];
ss_times = fill(NaN, length(N), 3);
times = fill((NaN,NaN,NaN), length(N), length(max_sizes) - 1);
total_times = fill(NaN, length(N), length(max_sizes));
```

## Julia Timings

```julia
@time run_and_time_julia!(ss_times, times, max_sizes, 1, 4); # precompile
```

## OpenModelica Timings

```julia
# OMJ
const omod = OMJulia.OMCSession();
OMJulia.sendExpression(omod, "getVersion()")
OMJulia.sendExpression(omod, "installPackage(Modelica)")
const modelicafile = joinpath(@__DIR__, "RC_Circuit.mo")

function time_open_modelica(n::Int)
totaltime = @elapsed res = begin
@sync ModelicaSystem(omod, modelicafile, "RC_Circuit.Test.RC_Circuit_MTK_test_$n")
sendExpression(omod, "simulate(RC_Circuit.Test.RC_Circuit_MTK_test_$n)")
end
@assert res["messages"][1:11] == "LOG_SUCCESS"
return totaltime
end

function run_and_time_om!(ss_times, times, max_sizes, i, n)
run_and_time_julia!(ss_times, times, max_sizes, i, n)
if n <= max_sizes[8]
total_times[i, 8] = time_open_modelica(n)
end
@views println("n = $(n)\nstructural_simplify_times = $(ss_times[i,:])\ncomponent times = $(times[i, :])\ntotal times = $(total_times[i, :])")
end

for (i, n) in enumerate(N)
@time run_and_time!(ss_times, times, max_sizes, i, n)
@time run_and_time_om!(ss_times, times, max_sizes, i, n)
end

OMJulia.quit(omod)
```

## Dymola Timings

Dymola requires a license server and thus cannot be hosted. This was run locally for the
following times:

```julia
translation_and_total_times = [
7.027, 7.237
11.295, 11.798
16.681, 17.646
22.125, 23.839
27.529, 29.82
33.282, 36.622
39.007, 43.088
44.825, 51.601
50.281, 56.676
] # TODO: I will add other times once the Dymola license server is back up.
#total_times[:, 6] = translation_and_total_times[1:length(N_x),2]
```

## Results

```julia
f = Figure(size=(800,1200));
ss_names = ["MTK", "JSIR-Scalar", "JSIR-Loop"];
let ax = Axis(f[1, 1]; yscale = log10, xscale = log10, title="Structural Simplify Time")
Expand All @@ -142,7 +185,6 @@ let method_names_m = vcat(method_names, "OpenModelica");
Legend(f[5, 2], _lines, method_names_m)
end
f
OMJulia.quit(omod)
```

All three backends compiled more quickly with loops, but the C and LLVM backends are so much quicker to compile than the Julia backend that this made much less difference for them.
Expand All @@ -154,21 +196,3 @@ The impact on runtime was more varied.
using SciMLBenchmarks
SciMLBenchmarks.bench_footer(WEAVE_ARGS[:folder],WEAVE_ARGS[:file])
```

Dymola requires a license server and thus cannot be hosted. This was run locally for the
following times:

```julia
translation_and_total_times = [
7.027, 7.237
11.295, 11.798
16.681, 17.646
22.125, 23.839
27.529, 29.82
33.282, 36.622
39.007, 43.088
44.825, 51.601
50.281, 56.676
] # TODO: I will add other times once the Dymola license server is back up.
#total_times[:, 6] = translation_and_total_times[1:length(N_x),2]
```

0 comments on commit 70523b5

Please sign in to comment.