Skip to content
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

Re-write the MOI wrapper #101

Merged
merged 18 commits into from
Aug 13, 2019
Merged
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Manifest.toml
*.json
perf/Project.toml
97 changes: 97 additions & 0 deletions Manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# This file is machine-generated - editing it directly is not advised

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[BenchmarkTools]]
deps = ["JSON", "Printf", "Statistics", "Test"]
git-tree-sha1 = "5d1dd8577643ba9014574cd40d9c028cd5e4b85a"
uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
version = "0.4.2"

[[BinaryProvider]]
deps = ["Libdl", "SHA"]
git-tree-sha1 = "c7361ce8a2129f20b0e05a89f7070820cfed6648"
uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232"
version = "0.5.4"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[JSON]]
deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"]
git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.20.0"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MathOptInterface]]
deps = ["BenchmarkTools", "LinearAlgebra", "OrderedCollections", "SparseArrays", "Test", "Unicode"]
git-tree-sha1 = "bb9af760fef8eb5d0dea3823b055037cda1c8cc5"
repo-rev = "od/cleverdict"
repo-url = "https://github.com/JuliaOpt/MathOptInterface.jl.git"
uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
version = "0.9.0"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[OrderedCollections]]
deps = ["Random", "Serialization", "Test"]
git-tree-sha1 = "c4c13474d23c60d20a67b217f1d7f22a40edf8f1"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.1.0"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[Test]]
deps = ["Distributed", "InteractiveUtils", "Logging", "Random"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ version = "0.10.0"
[deps]
BinaryProvider = "b99e7846-7c00-51b0-8f62-c81ae34c0232"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
LinQuadOptInterface = "f8899e07-120b-5979-ab1d-7b97bb9e1a48"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[compat]
BinaryProvider = "≥ 0.3.0"
LinQuadOptInterface = "0.6"
MathOptInterface = "0.9"
julia = "1"

[extras]
Expand Down
40 changes: 18 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
Julia GLPK module
=================
# GLPK.jl


| **Documentation** | **Build Status** |
|:-------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------:|
| [![][docs-stable-img]][docs-stable-url] [![][docs-latest-img]][docs-latest-url] | [![][travis-img]][travis-url] [![][appveyor-img]][appveyor-url] [![][coveralls-img]][coveralls-url] |
| **Build Status** |
|:---------------------------------------------------------------------------------------------------:|
| [![][travis-img]][travis-url] [![][appveyor-img]][appveyor-url] [![][coveralls-img]][coveralls-url] |


GLPK.jl is a wrapper for the [GNU Linear Programming Kit library](http://www.gnu.org/software/glpk).
It makes it possible to access nearly all of GLPK functionality from within Julia programs.

See also the [GLPKMathProgInterface.jl](https://github.com/JuliaOpt/GLPKMathProgInterface.jl) package for using it with
[MathProgBase.jl](https://github.com/JuliaOpt/MathProgBase.jl) and [JuMP.jl](https://github.com/JuliaOpt/JuMP.jl).

This package is part of [the JuliaOpt project](http://www.juliaopt.org/).

## Installation
Expand All @@ -39,16 +34,22 @@ in GLPK's source folder.

Note that the custom binaries will not be overwritten by subsequent builds of the currently installed version of GLPK.jl. However, if GLPK.jl is updated and the update includes new BinaryProvider versions of the GLPK binaries, then the custom binaries will be overwritten by the new BinaryProvider versions.

## Documentation
## `GLPK.Optimizer`

- [**STABLE**][docs-stable-url] — **most recently tagged version of the documentation.**
- [**LATEST**][docs-latest-url] — *in-development version of the documentation.*

[docs-latest-img]: https://img.shields.io/badge/docs-latest-blue.svg
[docs-latest-url]: https://gplkjl.readthedocs.org/en/latest/glpk.html
Use `GLPK.Optimizer` to create a new optimizer object:
```julia
using GLPK
model = GLPK.Optimizer(tm_lim = 60.0, msg_lev = GLPK.OFF)
```
For JuMP, use:
```julia
using JuMP, GLPK
model = Model(
with_optimizer(GLPK.Optimizer, tm_lim = 60.0, msg_lev = GLPK.OFF)
)
```

[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg
[docs-stable-url]: https://gplkjl.readthedocs.org/en/stable/glpk.html
**Note: previous versions of `GLPK.jl` required you to choose either `GLPKSolverLP` or `GLPKSolverMIP`. This is no longer needed; just use `GLPK.Optimizer`.**

[travis-img]: https://api.travis-ci.org/JuliaOpt/GLPK.jl.svg?branch=master
[travis-url]: https://travis-ci.org/JuliaOpt/GLPK.jl
Expand All @@ -58,8 +59,3 @@ Note that the custom binaries will not be overwritten by subsequent builds of th

[coveralls-img]: https://img.shields.io/coveralls/JuliaOpt/GLPK.jl.svg
[coveralls-url]: https://coveralls.io/r/JuliaOpt/GLPK.jl

[pkg-0.6-img]: http://pkg.julialang.org/badges/GLPK_0.6.svg
[pkg-0.6-url]: http://pkg.julialang.org/?pkg=GLPK
[pkg-0.7-img]: http://pkg.julialang.org/badges/GLPK_0.7.svg
[pkg-0.7-url]: http://pkg.julialang.org/?pkg=GLPK
194 changes: 194 additions & 0 deletions perf/perf.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
using GLPK, BenchmarkTools

const MOI = GLPK.MOI
function new_model()
return GLPK.Optimizer()
end

suite = BenchmarkGroup()

function add_variable()
model = new_model()
for i in 1:10_000
MOI.add_variable(model)
end
return model
end
suite["add_variable"] = @benchmarkable add_variable()

function add_variables()
model = new_model()
MOI.add_variables(model, 10_000)
return model
end
suite["add_variables"] = @benchmarkable add_variables()

function add_variable_constraint()
model = new_model()
x = MOI.add_variables(model, 10_000)
for (i, xi) in enumerate(x)
MOI.add_constraint(model, MOI.SingleVariable(xi), MOI.LessThan(1.0 * i))
end
return model
end
suite["add_variable_constraint"] = @benchmarkable add_variable_constraint()

function add_variable_constraints()
model = new_model()
x = MOI.add_variables(model, 10_000)
MOI.add_constraints(
model,
MOI.SingleVariable.(x),
MOI.LessThan.(1.0:10_000.0)
)
return model
end
suite["add_variable_constraints"] = @benchmarkable add_variable_constraints()

function delete_variable()
model = new_model()
x = MOI.add_variables(model, 1_000)
MOI.add_constraint.(model, MOI.SingleVariable.(x), Ref(MOI.LessThan(1.0)))
MOI.delete.(model, x)
return model
end
suite["delete_variable"] = @benchmarkable delete_variable()

function delete_variable_constraint()
model = new_model()
x = MOI.add_variables(model, 1_000)
cons = MOI.add_constraint.(model, MOI.SingleVariable.(x), Ref(MOI.LessThan(1.0)))
for con in cons
MOI.delete(model, con)
end
cons = MOI.add_constraint.(model, MOI.SingleVariable.(x), Ref(MOI.LessThan(1.0)))
MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)
MOI.set(model,
MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),
MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(1.0, x), 0.0)
)
MOI.optimize!(model)
for con in cons
MOI.delete(model, con)
end
return model
end
suite["delete_variable_constraint"] = @benchmarkable delete_variable_constraint()

function add_constraint()
model = new_model()
index = MOI.add_variables(model, 10_000)
for (i, x) in enumerate(index)
MOI.add_constraint(
model,
MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0),
MOI.LessThan(1.0 * i)
)
end
return model
end
suite["add_constraint"] = @benchmarkable add_constraint()

function add_constraints()
model = new_model()
x = MOI.add_variables(model, 10_000)
MOI.add_constraints(
model,
[MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, xi)], 0.0) for xi in x],
MOI.LessThan.(1:1.0:10_000)
)
return model
end
suite["add_constraints"] = @benchmarkable add_constraints()

function delete_constraint()
model = new_model()
index = MOI.add_variables(model, 1_000)
cons = Vector{
MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}}
}(undef, 1_000)
for (i, x) in enumerate(index)
cons[i] = MOI.add_constraint(
model,
MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0),
MOI.LessThan(1.0 * i)
)
end
for con in cons
MOI.delete(model, con)
end
return model
end
suite["delete_constraint"] = @benchmarkable delete_constraint()

function new_test(suite, params_filename, results_filename)
tune!(suite)
BenchmarkTools.save(params_filename, params(suite))
results = run(suite, verbose = true)
BenchmarkTools.save(results_filename, results)
end

function compare_test(suite, params_filename, results_filename)
if !isfile(params_filename) || !isfile(results_filename)
error("You must run with --new first.")
end
loadparams!(
suite,
BenchmarkTools.load(params_filename)[1],
:evals, :samples
)
new_results = run(suite, verbose = true)
old_results = BenchmarkTools.load(results_filename)[1]
println(stdout)
println("========== Results ==========")
println(stdout)
for key in keys(new_results)
judgement = judge(
BenchmarkTools.median(new_results[key]),
BenchmarkTools.median(old_results[key])
)
println(stdout, key)
show(stdout, MIME"text/plain"(), judgement)
println(stdout)
end
end

function print_help()
println("""
Usage
perf.jl [arg] [name]

[arg]
--new Begin a new benchmark comparison
--compare Run another benchmark and compare to existing

[name] A name for the benchmark test. Will create a folder in /perf.

Examples
git checkout master
julia perf.jl --new master
git checkout approach_1
julia perf.jl --new approach_1
git checkout approach_2
julia perf.jl --compare master
julia perf.jl --compare approach_1
""")
end

if length(ARGS) != 2
print_help()
else
test_path = joinpath(@__DIR__, ARGS[2])
if !isdir(test_path)
mkdir(test_path)
end
params_filename = joinpath(test_path, "params.json")
results_filename = joinpath(test_path, "results.json")
if ARGS[1] == "--new"
new_test(suite, params_filename, results_filename)
elseif ARGS[1] == "--compare"
compare_test(suite, params_filename, results_filename)
else
print_help()
end
end
Loading