-
Notifications
You must be signed in to change notification settings - Fork 27
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
Enh/options #110
Enh/options #110
Conversation
since scs-2.* these tests weren't testing anything as solver obtained accuracy of 1e-5 without effort
I tried the tests with the Direct option: diff --git a/test/MOIWrapper.jl b/test/MOIWrapper.jl
index 84aa941..2999cd1 100644
--- a/test/MOIWrapper.jl
+++ b/test/MOIWrapper.jl
@@ -14,7 +14,7 @@ MOIU.@model(SCSModelData,
(MOI.ScalarAffineFunction,),
(MOI.VectorOfVariables,),
(MOI.VectorAffineFunction,))
-const optimizer = MOIU.CachingOptimizer(SCSModelData{Float64}(), SCS.Optimizer())
+const optimizer = MOIU.CachingOptimizer(SCSModelData{Float64}(), SCS.Optimizer(linear_solver=SCS.Direct))
# linear9test needs 1e-3 with SCS < 2.0 and 5e-1 with SCS 2.0
# linear2test needs 1e-4 and it passes all the tests while showing |
btw. if tests fail on SCS-2.* because of instability You may always set |
The whole code would be much cleaner if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making this update. Some comments below.
src/MOIWrapper.jl
Outdated
@@ -282,7 +284,15 @@ function MOI.optimize!(optimizer::Optimizer) | |||
objconstant = optimizer.data.objconstant | |||
c = optimizer.data.c | |||
optimizer.data = nothing # Allows GC to free optimizer.data before A is loaded to SCS | |||
sol = SCS_solve(SCS.Indirect, m, n, A, b, c, cone.f, cone.l, cone.qa, cone.sa, cone.ep, cone.ed, cone.p) | |||
|
|||
T = SCS.Indirect # the default method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Please use a more descriptive variable name than T
. Maybe linear_solver_method
or just linear_solver
.
src/c_wrapper.jl
Outdated
end | ||
|
||
for param in keys(opts) | ||
# when dropping support for 0.6 could be replaced with setproperty! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What could be replaced exactly? To make sure this happens, you could use a VERSION if/else.
src/types.jl
Outdated
@@ -37,7 +37,7 @@ SCSMatrix(m::ManagedSCSMatrix) = | |||
SCSMatrix(pointer(m.values), pointer(m.rowval), pointer(m.colptr), m.m, m.n) | |||
|
|||
|
|||
struct SCSSettings | |||
mutable struct SCSSettings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this change is valid. SCSSettings
needs to mirror the C struct in order for the ccall
s to be correct. mutable struct
s can't be used to mirror C structs AFAIK.
test/MOIWrapper.jl
Outdated
# linear9test needs 1e-3 with SCS < 2.0 and 5e-1 with SCS 2.0 | ||
# linear2test needs 1e-4 | ||
const config = MOIT.TestConfig(atol=1e-4, rtol=1e-4) | ||
# linear9test needs 1e-3 with SCS < 2.0 and 5e-1 with SCS 2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we care about tolerances for an SCS version that we don't use anymore? (Not needed in the comment.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tolerance needed for SCS < 2.0 is mentionned to show that this is a regression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unlikely that this code will handle SCS < 2.0 in the future, so this isn't the right place to discuss regressions.
src/types.jl
Outdated
@@ -37,7 +37,7 @@ SCSMatrix(m::ManagedSCSMatrix) = | |||
SCSMatrix(pointer(m.values), pointer(m.rowval), pointer(m.colptr), m.m, m.n) | |||
|
|||
|
|||
struct SCSSettings | |||
mutable struct SCSSettings | |||
normalize::Int # boolean, heuristic data rescaling: 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update these comments to reflect that the default parameters are set by SCS_set_default_settings!
(i.e., remove the values because we have no way to make sure they are correct).
src/c_wrapper.jl
Outdated
@@ -86,6 +100,11 @@ end | |||
# Take Ref{}s because SCS might modify the structs | |||
for (T, lib) in zip([SCS.Direct, SCS.Indirect], [SCS.direct, SCS.indirect]) | |||
@eval begin | |||
|
|||
function SCS_set_default_settings!(::Type{$T}, data::Ref{SCSData}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming nit: The name implies modification, so JuMP style recommends dropping the !
from the name (http://www.juliaopt.org/JuMP.jl/latest/style.html#Use-of-!-1). This is also consistent with SCS_init
, SCS_solve
, and SCS_finish
.
test/MOIWrapper.jl
Outdated
end | ||
@testset "Continuous linear problems" begin | ||
# AlmostSuccess for linear9 with SCS 2 | ||
MOIT.contlineartest(MOIB.SplitInterval{Float64}(optimizer), config, ["linear9"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reasonable parameter setting that gets linear9
passing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to set tolerance to 5e-1 last time I tested but it seems a bit restrictive to set it for all tests.
linear9test(optimizer, MOIT.TestConfig(atol=0.5, rtol=0.5)
could be run separately in the line below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SCS.Optimizer(linear_solver=T, eps=1e-8))
config = MOIT.TestConfig(atol=1e-5)
passes MOIT.contlineartest(MOIB.SplitInterval{Float64}(optimizer), config)
with both Direct
and Indirect
solver;
btw. You need to add some tests for passing options to SCS.Optimizer
. only playing with this allowed me to catch missing ;
in the argument list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I just ran into the same issue where SCS.Optimizer
does not accept solver options.
the intermediate _SCS_user_settings function serves as a check that user supplied only recognized options
if user supplies a wrong kwarg it will result in SCSSettings(SCS.Indirect, eps=1e-12, epps=0.1)
ERROR: MethodError: no method matching _SCS_user_settings(::SCS.SCSSettings; epps=0.1, eps=1.0e-12)
Closest candidates are:
_SCS_user_settings(::Any; normalize, scale, rho_x, max_iters, eps, alpha, cg_rate, verbose, warm_start, acceleration_lookback) at /home/kalmar/.julia/v0.6/SCS/src/types.jl:70 got unsupported keyword argument "epps"
.... I think it is informative enough |
Not really, see the style discussion here. Please at least add a TODO to improve the error message. |
I don't think there is a particularly good reason for that choice, and it should probably just take the settings struct, but changing it now would be breaking. |
is |
@bodono It'd be great if it could be changed the next release, but it's definitely not critical |
|
julia> SCSSettings(SCS.Indirect, epps=0.1, e=0.3, eps=1e-12)
ERROR: ArgumentError: Unrecognized options passed to the SCSSolver: epps, e
Stacktrace:
.... |
src/types.jl
Outdated
catch err | ||
if err isa MethodError | ||
SCS_kwargs = fieldnames(default_settings[]) | ||
kwargs = [err.args[1][i*2-1] for i in 1:(length(err.args[1]) ÷ 2)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a number of ways that this code could stop working unintentionally, so please add tests. The structure of err
could be changed across Julia versions or _SCS_user_settings
could be changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can @test_throws ArgumentError ...
against misspelled options, but that's it.
_SCS_user_settings
is an internal function, it won't change beyond our control (btw. why is SCSSettings
exported? I had always assumed that user is not supposed to construct it?)
I'd use the standard MethodError
which actually tells exactly which options were not recognized, but that clashes with the style guide. What are Your suggestions on handling this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can @test_throws ArgumentError ... against misspelled options, but that's it.
That would make good tests :)
it won't change beyond our control
yes but when we change it we might forget to change MOIWrapper.jl
.
add test to check the behaviour
m = MathProgBase.ConicModel(s) | ||
MathProgBase.loadproblem!(m, -obj, A, rowub, [(:NonNeg,1:3)],[(:NonNeg,1:5)]) | ||
|
||
@test_throws ArgumentError MathProgBase.optimize!(m) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there some way to test the text of the error message? That's pretty important in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/JuliaLang/julia/blob/e7d15d4a013a43442b75ba4e477382804fa4ac49/stdlib/Test/src/Test.jl#L532
@test_throws
wants type, not an instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, @test_throws
is probably not the way to do it. It may need a try/catch
where you test the error message inside the catch
and test that the catch
block executed.
Just as a general comment. There were some fairly big changes in the algorithm's performance since the last version. The change in the default behavior led my CI to hang indefinitely while waiting for SCS to converge. In the end adding the parameter |
@ccoffrin its a known issue: cvxgrp/scs#93
|
update the attained precision add "eps=1e-7" to SCSSolver which tests MPBWrapper codepaths responsible for cleaning options
linear9 passes
I separated the option checking into please have a look again |
Would be great if someone could test it on the MOI side;
I took a simple route of extracting the
Direct
/Indirect
type fromoptions
inoptimize!
(as it was done in MPB), but that could be easily changed toOptimizer
(andSCSMathProgModel
) parametrized by the typeEdit by mlubin@: Closes #94