-
Notifications
You must be signed in to change notification settings - Fork 1
Support SolverBenchmarks #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 24 commits
0556eed
eb4e67e
2466b3e
abf030c
74e0fa6
7ca2063
4d1e738
7da9942
64984a2
502ca44
7653dd4
d87b0ee
115938a
72e3551
7c62433
cdb59b8
b1a04d9
fb4418b
932b79d
fe4663f
99f1006
ad89d3d
c792b41
2ab42e6
fc96c52
1fbb7e2
aa5866b
9ba1afe
2f68612
f081bf7
b9e56bf
b7138c6
202282c
5d177f3
3672468
d74a81b
953196e
420d48d
0444f42
c2b88c7
94b9018
7c5c6a8
05ac796
9c21ce3
a7269f2
970f9ed
46ab940
8db47ed
4546cf7
732654f
3c89a5c
63e8c6f
57ed7fd
0701786
7a1f03e
6e9eae2
7513b75
59f07a0
cd479ca
306d837
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| function run_solver_benchmarks( | ||
| repo_name::AbstractString, | ||
| bmark_dir::AbstractString; | ||
| reference_branch::AbstractString = "main", | ||
| gist_url::Union{AbstractString, Nothing} = nothing, | ||
| script = "benchmarks.jl", | ||
| values = [(:elapsed_time, "CPU Time"), (:neval_obj, "# Objective Evals"), (:neval_grad, "# Gradient Evals")], | ||
| ) | ||
|
|
||
| update_gist = gist_url !== nothing | ||
| is_git = isdir(joinpath(bmark_dir, "..", ".git")) | ||
| @info "" is_git update_gist | ||
|
|
||
| local gist_id | ||
| if update_gist | ||
| gist_id = split(gist_url, "/")[end] | ||
| @info "" gist_id | ||
| end | ||
|
|
||
| # if we are running these benchmarks from the git repository | ||
| # we want to develop the package instead of using the release | ||
| if is_git | ||
| Pkg.develop(PackageSpec(path = joinpath(bmark_dir, ".."))) | ||
| else | ||
| Pkg.activate(bmark_dir) | ||
| end | ||
| Pkg.instantiate() | ||
|
|
||
| # name the benchmark after the repo or the sha of HEAD | ||
| bmarkname = is_git ? readchomp(`$git rev-parse HEAD`) : lowercase(repo_name) | ||
| @info "" bmarkname | ||
|
|
||
| # Run the benchmark script on this commit | ||
| this_commit = Base.include(Main, joinpath(bmark_dir, script)) | ||
| @assert this_commit isa Dict{Symbol, DataFrame} "Expected the benchmark script to return a Dict{Symbol, DataFrame}, but got $(typeof(this_commit)). Make sure your benchmark script returns a dict resulting from BenchmarkSolver.bmark_solver function" | ||
|
MaxenceGollier marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Run the benchmark script on the reference branch | ||
| local reference | ||
| if is_git | ||
| repo_dir = joinpath(bmark_dir, "..") | ||
| repo = LibGit2.GitRepo(repo_dir) | ||
| println("repo_dir : $repo_dir") | ||
| println("bmark_dir : $bmark_dir") | ||
| reference = _withcommit(joinpath(bmark_dir, script), repo, reference_branch) | ||
|
MaxenceGollier marked this conversation as resolved.
Outdated
|
||
| end | ||
|
Comment on lines
+84
to
+95
|
||
|
|
||
| #TODO: save in a jld2 file: see run_benchmarks | ||
|
|
||
| # Plotting | ||
| files_dict = Dict{String, Any}() | ||
| svgs = String[] | ||
| if is_git | ||
| for key in keys(this_commit) | ||
| if haskey(reference, key) | ||
| @info "Plotting $key" | ||
| stats_subset = Dict(:this_commit => this_commit[key], :reference => reference[key]) | ||
| solved(df) = (df.status .== :first_order) | ||
| costs = [df -> .!solved(df) * Inf + getproperty(df, value[1]) for value in values] | ||
| costnames = [value[2] for value in values] | ||
|
|
||
| p = profile_solvers(stats_subset, costs, costnames;xlabel = "", ylabel = "") | ||
| fname = "this_commit_vs_reference_$(key)" | ||
| savefig("$(fname).svg") | ||
| push!(svgs, "$(fname).svg") | ||
| content = read("$(fname).svg", String) | ||
| files_dict["$(fname).svg"] = Dict("content" => content) | ||
| else | ||
| @warn "$(reference_branch) branch benchmarks do not run the solver $key. Please update the benchmark solver list in a separate PR and rebase." | ||
| end | ||
| end | ||
| end | ||
|
|
||
| @info "creating or updating gist" | ||
| # json description of gist | ||
| json_dict = Dict{String, Any}( | ||
| "description" => "$(repo_name) repository benchmark", | ||
| "public" => true, | ||
| "files" => files_dict, | ||
| ) | ||
|
|
||
| if update_gist | ||
| json_dict["gist_id"] = gist_id | ||
| end | ||
|
|
||
| gist_json = "$(bmarkname).json" | ||
| open(gist_json, "w") do f | ||
| JSON.print(f, json_dict) | ||
| end | ||
|
|
||
| readme = "# $(repo_name) Solver Benchmarks\n\n" | ||
| readme *= "Comparison between current commit and $(reference_branch).\n\n" | ||
|
|
||
| files_dict["README.md"] = Dict("content" => readme) | ||
|
MaxenceGollier marked this conversation as resolved.
Outdated
|
||
|
|
||
| local new_gist_url | ||
| if update_gist | ||
| update_gist_from_json_dict(gist_id, json_dict) | ||
| else | ||
| new_gist = create_gist_from_json_dict(json_dict) | ||
| new_gist_url = string(new_gist.html_url) | ||
| end | ||
|
|
||
| @info "preparing simple Markdown report" | ||
| is_git && | ||
| write_simple_md_report( | ||
| "bmark_$(bmarkname).md", | ||
| nothing, | ||
| nothing, | ||
| nothing, | ||
| new_gist_url, | ||
| svgs, | ||
| ) | ||
|
MaxenceGollier marked this conversation as resolved.
Outdated
|
||
|
|
||
| @info "finished" | ||
| return nothing | ||
| end | ||
|
|
||
|
|
||
| # Runs a script at a commit on a repo and afterwards goes back | ||
| # to the original commit / branch. | ||
| # This code is based on https://github.com/JuliaCI/PkgBenchmark.jl/blob/master/src/util.jl | ||
| function _withcommit(script, repo, commit) | ||
| println(repo) | ||
| original_commit = string(LibGit2.GitHash(LibGit2.GitObject(repo, "HEAD"))) | ||
|
MaxenceGollier marked this conversation as resolved.
Outdated
|
||
| local result | ||
| LibGit2.transact(repo) do r | ||
| branch = try LibGit2.branch(r) catch err; nothing end | ||
| try | ||
| LibGit2.checkout!(r, _shastring(r, commit)) | ||
| result = Base.include(Main, script) | ||
| @assert result isa Dict{Symbol, DataFrame} "Expected the benchmark script to return a Dict{Symbol, DataFrame}, but got $(typeof(result)). Make sure your benchmark script returns a dict resulting from BenchmarkSolver.bmark_solver function" | ||
|
MaxenceGollier marked this conversation as resolved.
Outdated
|
||
| catch err | ||
| rethrow(err) | ||
| finally | ||
| if branch !== nothing | ||
| LibGit2.branch!(r, branch) | ||
| else | ||
| LibGit2.checkout!(r, original_commit) | ||
| end | ||
| end | ||
| end | ||
| return result | ||
| end | ||
|
|
||
| function _shastring(r::LibGit2.GitRepo, targetname) | ||
| branch = LibGit2.lookup_branch(r, targetname) | ||
| branch = branch === nothing ? LibGit2.lookup_branch(r, targetname, true) : branch # Search remote as well if not found locally. | ||
| branch = branch === nothing ? LibGit2.lookup_branch(r, "origin/$(targetname)") : branch | ||
| branch = branch === nothing ? LibGit2.lookup_branch(r, "origin/$(targetname)", true) : branch # Search remote as well if not found locally. | ||
| @assert branch !== nothing "Branch $(targetname) not found in repository." | ||
| return string(LibGit2.GitHash(LibGit2.GitObject(r, LibGit2.name(branch)))) | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.