Skip to content

Commit

Permalink
default_parameters now dispatches on Val types (#379)
Browse files Browse the repository at this point in the history
  • Loading branch information
abelsiqueira authored Jan 3, 2024
1 parent a1827d4 commit 3d0d8a8
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 9 deletions.
1 change: 1 addition & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
MetaGraphsNext = "fa8bd995-216d-47f1-8a91-f3b68fbeb377"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Expand Down
61 changes: 58 additions & 3 deletions src/solve-model.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,68 @@
export solve_model!, solve_model
export solve_model!, solve_model, default_parameters

"""
default_parameters(Val(optimizer_name_symbol))
default_parameters(optimizer)
default_parameters(optimizer_name_symbol)
default_parameters(optimizer_name_string)
Returns the default parameters for a given JuMP optimizer.
Falls back to `Dict()` for undefined solvers.
## Arguments
There are four ways to use this function:
- `Val(optimizer_name_symbol)`: This uses type dispatch with the special `Val` type.
Just give the solver name as a Symbol (e.g., `Val(:HiGHS)`).
- `optimizer`: The JuMP optimizer type (e.g., `HiGHS.Optimizer`).
- `optimizer_name_symbol` or `optimizer_name_string`: Just give the name in Symbol
or String format and we will convert to `Val`.
Using `Val` is necessary for the dispatch.
All other cases will convert the argument and call the `Val` version, which might lead to some type instability.
## Examples
```jldoctest
using HiGHS
default_parameters(HiGHS.Optimizer)
# output
Dict{String, Any} with 1 entry:
"output_flag" => false
```
This also
```jldoctest
default_parameters(Val(:SCIP))
# output
Dict{String, Any} with 1 entry:
"display/verblevel" => 0
```
```jldoctest
default_parameters(:SCIP) == default_parameters("SCIP") == default_parameters(Val(:SCIP))
# output
true
```
"""
default_parameters(::Type{T}) where {T<:MathOptInterface.AbstractOptimizer} = Dict{String,Any}()
default_parameters(::Type{HiGHS.Optimizer}) = Dict{String,Any}("output_flag" => false)
default_parameters(::Any) = Dict{String,Any}()
default_parameters(::Val{:HiGHS}) = Dict{String,Any}("output_flag" => false)
default_parameters(::Val{:SCIP}) = Dict{String,Any}("display/verblevel" => 0)

function default_parameters(::Type{T}) where {T<:MathOptInterface.AbstractOptimizer}
solver_name = split(string(T), ".")[1]
return default_parameters(Val(Symbol(solver_name)))
end

default_parameters(optimizer::Union{String,Symbol}) = default_parameters(Val(Symbol(optimizer)))

"""
solution = solve_model!(energy_problem[, optimizer; parameters])
Expand Down
3 changes: 0 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ using SCIP
using Test
using TulipaEnergyModel

TulipaEnergyModel.default_parameters(::Type{SCIP.Optimizer}) =
Dict{String,Any}("display/verblevel" => 0)

# Folders names
const INPUT_FOLDER = joinpath(@__DIR__, "inputs")
const OUTPUT_FOLDER = joinpath(@__DIR__, "outputs")
Expand Down
29 changes: 26 additions & 3 deletions test/test-options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,32 @@
)
end

@testset "Test dummy solver" begin
struct DummySolver <: MathOptInterface.AbstractOptimizer end
@test TulipaEnergyModel.default_parameters(DummySolver) == Dict{String,Any}()
@testset "Test default_parameters usage" begin
@testset "HiGHS" begin
expected = Dict{String,Any}("output_flag" => false)
@test default_parameters(Val(:HiGHS)) == expected
@test default_parameters(HiGHS.Optimizer) == expected
@test default_parameters(:HiGHS) == expected
@test default_parameters("HiGHS") == expected
end

@testset "Undefined values" begin
expected = Dict{String,Any}()
@test default_parameters(Val(:blah)) == expected
@test default_parameters(:blah) == expected
@test default_parameters("blah") == expected
struct DummySolver <: MathOptInterface.AbstractOptimizer end
@test default_parameters(Val(:DummySolver)) == expected
end

@testset "New definition" begin
expected = Dict{String,Any}("dummy" => true, "use" => :testing)
struct NewSolver <: MathOptInterface.AbstractOptimizer end
TulipaEnergyModel.default_parameters(::Val{:NewSolver}) = expected
@test TulipaEnergyModel.default_parameters(NewSolver) == expected
@test TulipaEnergyModel.default_parameters(:NewSolver) == expected
@test TulipaEnergyModel.default_parameters("NewSolver") == expected
end
end

@testset "Test that bad options throw errors" begin
Expand Down

0 comments on commit 3d0d8a8

Please sign in to comment.