Skip to content

Commit a80853b

Browse files
authored
Add silent_solver keyword argument and tweak CI (#404)
* Add `silent_solver` keyword argument * Rm benchmark stage from Travis * Bump CI version
1 parent ea709c0 commit a80853b

File tree

7 files changed

+65
-26
lines changed

7 files changed

+65
-26
lines changed

.travis.yml

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,11 @@ os:
55
- osx
66
julia:
77
- 1.0
8-
- 1.4
8+
- 1.5
99
if: branch = master OR tag IS present OR type = pull_request
1010
notifications:
1111
email: false
1212
jobs:
13-
include:
14-
- name: "Benchmark"
15-
julia: 1.4
16-
os: linux
17-
before_script:
18-
- git fetch origin '+refs/heads/master:refs/remotes/origin/master'
19-
- git branch baseline origin/master
20-
# Run benchmark outside `script` so that it's hidden by default:
21-
- julia --project=benchmark -e '
22-
using Pkg; Pkg.instantiate();
23-
include("benchmark/runjudge.jl");'
24-
25-
script:
26-
- julia --project=benchmark -e '
27-
using Pkg; Pkg.instantiate();
28-
include("benchmark/pprintjudge.jl");'
29-
after_success: skip
30-
if: type = pull_request
3113
- stage: Documentation
3214
julia: 1.0
3315
script: julia --project=docs -e '

NEWS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
# Changes in v0.13.7
2+
3+
* fix [#403](https://github.com/jump-dev/Convex.jl/issues/403) by adding the keyword argument `silent_solver` to `solve!`.
4+
15
# Changes in v0.13.6
26

37
* fix [#401](https://github.com/jump-dev/Convex.jl/issues/401) by allowing `diagm(x)`.
4-
*
8+
59
# Changes in v0.13.5
610

711
* fix [#398](https://github.com/jump-dev/Convex.jl/issues/398) by allowing `fix!`'d variables in `quadform`.

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "Convex"
22
uuid = "f65535da-76fb-5f13-bab9-19810c17039a"
3-
version = "0.13.6"
3+
version = "0.13.7"
44

55
[deps]
66
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"

docs/src/reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ Functions:
2323
Convex.fix!
2424
Convex.free!
2525
Convex.evaluate
26+
Convex.solve!
2627
```

src/solution.jl

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,30 @@ function solve!(problem::Problem{T}, optimizer; kwargs...) where {T}
195195
end
196196
end
197197

198+
"""
199+
solve!(problem::Problem{T}, optimizer::MOI.ModelLike;
200+
check_vexity::Bool = true,
201+
verbose::Bool = true,
202+
warmstart::Bool = false,
203+
silent_solver::Bool = false) where {T}
204+
205+
Solves the problem, populating `problem.optval` with the optimal value,
206+
as well as the values of the variables (accessed by [`evaluate`](@ref))
207+
and constraint duals (accessed by `cons.dual`), where applicable.
208+
209+
Optional keyword arguments:
210+
211+
* `check_vexity` (default: `true`): emits a warning if the problem is not DCP
212+
* `verbose` (default: `true`): emits a warning if the problem was not solved optimally or `warmstart=true` but is not supported by the solver.
213+
* `warmstart` (default: `false`): whether the solver should start the optimization from a previous optimal value (according to the current value of the variables in the problem, which can be set by [`value!`](@ref) and accessed by [`evaluate`](@ref)).
214+
* `silent_solver`: whether the solver should be silent (and not emit output or logs) during the solution process.
215+
216+
"""
198217
function solve!(problem::Problem{T}, optimizer::MOI.ModelLike;
199-
check_vexity = true,
200-
verbose = true,
201-
warmstart = false) where {T}
218+
check_vexity::Bool = true,
219+
verbose::Bool = true,
220+
warmstart::Bool = false,
221+
silent_solver::Bool = false) where {T}
202222

203223
if check_vexity
204224
vex = vexity(problem)
@@ -217,7 +237,11 @@ function solve!(problem::Problem{T}, optimizer::MOI.ModelLike;
217237
if warmstart
218238
warmstart_variables!(model, var_to_indices, id_to_variables, T, verbose)
219239
end
220-
240+
241+
if silent_solver
242+
MOI.set(model, MOI.Silent(), true)
243+
end
244+
221245
MOI.optimize!(model)
222246
problem.model = model
223247

src/variable.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,12 @@ sign!(x::AbstractVariable, s::Sign) = x.sign = s
9898

9999

100100
"""
101-
evaluate(x::AbstractVariable)
101+
evaluate(x::AbstractExpr)
102102
103103
Returns the current value of `x` if assigned; errors otherwise.
104104
"""
105+
evaluate
106+
105107
evaluate(x::AbstractVariable) = _value(x) === nothing ? error("Value of the variable is yet to be calculated") : output(_value(x))
106108

107109
"""

test/test_utilities.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
using Convex: AbstractExpr, ConicObj
22

3+
# It's not super easy to capture the output
4+
# I ended up using this pattern from Suppressor:
5+
# https://github.com/JuliaIO/Suppressor.jl/blob/b4ff08f0fe795a2ce9e592734a758c9e6d8e2bc4/src/Suppressor.jl#L124-L152
6+
function solve_and_return_output(problem, solver; kwargs...)
7+
original_stdout = stdout
8+
rd, wr = redirect_stdout()
9+
out_task = @async read(rd, String)
10+
try
11+
solve!(problem, solver; kwargs...)
12+
finally
13+
Base.Libc.flush_cstdio() # https://github.com/JuliaLang/julia/issues/31236
14+
redirect_stdout(original_stdout)
15+
close(wr)
16+
end
17+
return fetch(out_task)
18+
end
19+
320
@testset "Utilities" begin
421

522
@testset "`solve!` does not return anything" begin
@@ -9,6 +26,15 @@ using Convex: AbstractExpr, ConicObj
926
@test output === nothing
1027
end
1128

29+
@testset "`silent_solver` works" begin
30+
x = Variable()
31+
p = satisfy(x >= 0)
32+
output_non_silent = solve_and_return_output(p, () -> SCS.Optimizer(eps=1e-6))
33+
@test output_non_silent != ""
34+
output_silent = solve_and_return_output(p, () -> SCS.Optimizer(eps=1e-6), silent_solver=true)
35+
@test output_silent == ""
36+
end
37+
1238
# This might get deprecated later.
1339
@testset "`solve!` can take an optimizer directly" begin
1440
x = Variable()

0 commit comments

Comments
 (0)