Closed mitchphillipson closed 4 months ago
The termination_status(model)
should be OTHER_ERROR
, and raw_status(model)
should be "License could not be found"
.
Is it not clear what is happening if you do solution_summary(model)
?
If you use the C API, then the return is MCP_LicenseError
:
https://github.com/chkwon/PATHSolver.jl/blob/d91e9b15418e9f81288946d306525b50337196a6/src/C_API.jl#L728
The general approach in MOI is to avoid erroring where possible on optimize!
and return useful information via statuses, so I'm hesitant to make a change here.
The issue was in a GitHub test. One of the test cases was too large (which I didn't check, my fault). However, I am receiving a Segmentation Fault error.
I know this is in the call to optimize!
because I've surrounded it in print statements, just to isolate. This is an example PR with the error. The error occurs in the test_orientation.jl
test. I have observed that the test can't be isolated, if it's the only test it fails gracefully, as expected.
Getting a MWE is kind of tricky because it would involve changing my local workflow which is a little dangerous for me.
Hmm. We shouldn't segfault. Let me take a look.
This might actually be because of https://github.com/chkwon/PATHSolver.jl/pull/114.
Let me make a new release.
Try v1.7.6.
I don't think this is a license error. Even on v1.7.5, we should have returned before we initialized the output:
That's interesting. I "solved" the error by including the license.
On Tue, May 28, 2024, 7:03 PM Oscar Dowson @.***> wrote:
Try v1.7.6.
I don't think this is a license error. Even on v1.7.5, we should have returned before we initialized the output:
— Reply to this email directly, view it on GitHub https://github.com/chkwon/PATHSolver.jl/issues/116#issuecomment-2136242805, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEVAPXPROUUMCNUZS47OOKTZEUEKNAVCNFSM6AAAAABIHWIBGSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMZWGI2DEOBQGU . You are receiving this because you authored the thread.Message ID: @.***>
That still could be consistent. Without the license we return early, and GC happens at a bad time. With the license, we solve, and the GC cleans things up okay. Dunno. I guess see if the new version fixes things first.
Any update?
Sorry, I've been traveling. I have time today to test this.
I've updated PATHSolver to 1.7.6 and JuMP to 1.22.1 and still get a segfault here is a link to the output in GitHub, I think you're able to see this.
I'm a little constrained on time at the moment, but I'm going to try to get a local MWE of this issue. This may take me a some time. Luckily, this issue isn't pressing and seems to be a fairly edge case.
I'd be fine with this being a low priority, at least for you, until I can more accurately explain what makes this happen.
I'm back with testing and some strange behavior. For context, everything is up-to-date and I'm running locally without a license. If the first model I run fails due a license error, everything behaves as expected.
using JuMP
using PATHSolver
M2 = Model(PATHSolver.Optimizer)
I = Symbol.("a",1:500)
@variable(M2, x[I])
@constraint(M2, [i=I], x[i]^2-2*x[i]+1 ⟂ x[i])
optimize!(M2)
termination_status(M2)
This shows OTHER_ERROR::TerminationStatusCode = 24
, which is expected.
However, if that model is NOT solved first, then we get unexpected behavior
using JuMP
using PATHSolver
M1 = Model(PATHSolver.Optimizer)
@variable(M1, x)
@constraint(M1, x^2-2*x+1 ⟂ x)
optimize!(M1)
M2 = Model(PATHSolver.Optimizer)
I = Symbol.("a",1:500)
@variable(M2, x[I])
@constraint(M2, [i=I], x[i]^2-2*x[i]+1 ⟂ x[i])
optimize!(M2)
termination_status(M2)
This has some variation. Either the model will hang on optimize!
, fail to display any issues, or throw a helpful "Demo license: size restriction of 300 variables or 2000 nonzeros exceeded." message.
In the example above, the model hangs. To get the "Demo license" message I need to optimize the M2 model with fewer than 300 variables, then increase to above 300. Further testing shows this to be unreliable.
I also received this error once:
TypeError: in typeassert, expected PATHSolver.OutputData, got a value of type PATHSolver.Options(Ptr{Nothing} @0x0000020352eb3630)
which feels like a kinder segfault.
These errors all go away if I include the license. This could also be an error in PATH itself, perhaps it doesn't explicitly check for a license after the first solve but still fails due to lack of license on subsequent solves.
Is this on Linux? Or Windows?
I cannot reproduce on Mac:
julia> using JuMP, PATHSolver
julia> begin
model = Model(PATHSolver.Optimizer)
@variable(model, x)
@constraint(model, x^2 - 2 * x + 1 ⟂ x)
optimize!(model)
end
Path 5.0.03 (Fri Jun 26 09:58:07 2020)
Written by Todd Munson, Steven Dirkse, Youngdae Kim, and Michael Ferris
Crash Log
major func diff size residual step prox (label)
0 0 1.0000e+00 0.0e+00 ()
1 1 0 1 2.5000e-01 1.0e+00 0.0e+00 ()
pn_search terminated: no basis change.
Major Iteration Log
major minor func grad residual step type prox inorm (label)
0 0 2 2 2.5000e-01 I 0.0e+00 2.5e-01 ()
1 1 3 3 6.2500e-02 1.0e+00 SO 0.0e+00 6.2e-02 ()
2 1 4 4 1.5625e-02 1.0e+00 SO 0.0e+00 1.6e-02 ()
3 1 5 5 3.9062e-03 1.0e+00 SO 0.0e+00 3.9e-03 ()
4 1 6 6 9.7656e-04 1.0e+00 SO 0.0e+00 9.8e-04 ()
5 1 7 7 2.4414e-04 1.0e+00 SO 0.0e+00 2.4e-04 ()
6 1 8 8 6.1035e-05 1.0e+00 SO 0.0e+00 6.1e-05 ()
7 1 9 9 1.5259e-05 1.0e+00 SO 0.0e+00 1.5e-05 ()
8 1 10 10 3.8147e-06 1.0e+00 SO 0.0e+00 3.8e-06 ()
9 1 11 11 9.5367e-07 1.0e+00 SO 0.0e+00 9.5e-07 ()
Major Iterations. . . . 9
Minor Iterations. . . . 9
Restarts. . . . . . . . 0
Crash Iterations. . . . 1
Gradient Steps. . . . . 0
Function Evaluations. . 11
Gradient Evaluations. . 11
Basis Time. . . . . . . 0.000022
Total Time. . . . . . . 0.001435
Residual. . . . . . . . 9.536743e-07
julia> begin
model_2 = Model(PATHSolver.Optimizer)
@variable(model_2, x[1:500])
@constraint(model_2, [i in 1:500], x[i]^2 - 2 * x[i] + 1 ⟂ x[i])
optimize!(model_2)
termination_status(model_2)
end
OTHER_ERROR::TerminationStatusCode = 24
julia> using JuMP, PATHSolver
julia> begin
model = Model(PATHSolver.Optimizer)
@variable(model, x)
@constraint(model, x^2 - 2 * x + 1 ⟂ x)
optimize!(model)
end
Path 5.0.03 (Fri Jun 26 09:58:07 2020)
Written by Todd Munson, Steven Dirkse, Youngdae Kim, and Michael Ferris
Crash Log
major func diff size residual step prox (label)
0 0 1.0000e+00 0.0e+00 ()
1 1 0 1 2.5000e-01 1.0e+00 0.0e+00 ()
pn_search terminated: no basis change.
Major Iteration Log
major minor func grad residual step type prox inorm (label)
0 0 2 2 2.5000e-01 I 0.0e+00 2.5e-01 ()
1 1 3 3 6.2500e-02 1.0e+00 SO 0.0e+00 6.2e-02 ()
2 1 4 4 1.5625e-02 1.0e+00 SO 0.0e+00 1.6e-02 ()
3 1 5 5 3.9062e-03 1.0e+00 SO 0.0e+00 3.9e-03 ()
4 1 6 6 9.7656e-04 1.0e+00 SO 0.0e+00 9.8e-04 ()
5 1 7 7 2.4414e-04 1.0e+00 SO 0.0e+00 2.4e-04 ()
6 1 8 8 6.1035e-05 1.0e+00 SO 0.0e+00 6.1e-05 ()
7 1 9 9 1.5259e-05 1.0e+00 SO 0.0e+00 1.5e-05 ()
8 1 10 10 3.8147e-06 1.0e+00 SO 0.0e+00 3.8e-06 ()
9 1 11 11 9.5367e-07 1.0e+00 SO 0.0e+00 9.5e-07 ()
Major Iterations. . . . 9
Minor Iterations. . . . 9
Restarts. . . . . . . . 0
Crash Iterations. . . . 1
Gradient Steps. . . . . 0
Function Evaluations. . 11
Gradient Evaluations. . 11
Basis Time. . . . . . . 0.000017
Total Time. . . . . . . 0.001030
Residual. . . . . . . . 9.536743e-07
julia> begin
model_2 = Model(PATHSolver.Optimizer)
@variable(model_2, x[1:500])
@constraint(model_2, [i in 1:500], x[i]^2 - 2 * x[i] + 1 ⟂ x[i])
optimize!(model_2)
termination_status(model_2)
end
OTHER_ERROR::TerminationStatusCode = 24
julia> using JuMP, PATHSolver
julia> begin
model = Model(PATHSolver.Optimizer)
@variable(model, x)
@constraint(model, x^2 - 2 * x + 1 ⟂ x)
optimize!(model)
end
Path 5.0.03 (Fri Jun 26 09:58:07 2020)
Written by Todd Munson, Steven Dirkse, Youngdae Kim, and Michael Ferris
Crash Log
major func diff size residual step prox (label)
0 0 1.0000e+00 0.0e+00 ()
1 1 0 1 2.5000e-01 1.0e+00 0.0e+00 ()
pn_search terminated: no basis change.
Major Iteration Log
major minor func grad residual step type prox inorm (label)
0 0 2 2 2.5000e-01 I 0.0e+00 2.5e-01 ()
1 1 3 3 6.2500e-02 1.0e+00 SO 0.0e+00 6.2e-02 ()
2 1 4 4 1.5625e-02 1.0e+00 SO 0.0e+00 1.6e-02 ()
3 1 5 5 3.9062e-03 1.0e+00 SO 0.0e+00 3.9e-03 ()
4 1 6 6 9.7656e-04 1.0e+00 SO 0.0e+00 9.8e-04 ()
5 1 7 7 2.4414e-04 1.0e+00 SO 0.0e+00 2.4e-04 ()
6 1 8 8 6.1035e-05 1.0e+00 SO 0.0e+00 6.1e-05 ()
7 1 9 9 1.5259e-05 1.0e+00 SO 0.0e+00 1.5e-05 ()
8 1 10 10 3.8147e-06 1.0e+00 SO 0.0e+00 3.8e-06 ()
9 1 11 11 9.5367e-07 1.0e+00 SO 0.0e+00 9.5e-07 ()
Major Iterations. . . . 9
Minor Iterations. . . . 9
Restarts. . . . . . . . 0
Crash Iterations. . . . 1
Gradient Steps. . . . . 0
Function Evaluations. . 11
Gradient Evaluations. . 11
Basis Time. . . . . . . 0.000019
Total Time. . . . . . . 0.001248
Residual. . . . . . . . 9.536743e-07
julia> begin
model_2 = Model(PATHSolver.Optimizer)
@variable(model_2, x[1:500])
@constraint(model_2, [i in 1:500], x[i]^2 - 2 * x[i] + 1 ⟂ x[i])
optimize!(model_2)
termination_status(model_2)
end
OTHER_ERROR::TerminationStatusCode = 24
julia> using JuMP, PATHSolver
julia> begin
model = Model(PATHSolver.Optimizer)
@variable(model, x)
@constraint(model, x^2 - 2 * x + 1 ⟂ x)
optimize!(model)
end
Path 5.0.03 (Fri Jun 26 09:58:07 2020)
Written by Todd Munson, Steven Dirkse, Youngdae Kim, and Michael Ferris
Crash Log
major func diff size residual step prox (label)
0 0 1.0000e+00 0.0e+00 ()
1 1 0 1 2.5000e-01 1.0e+00 0.0e+00 ()
pn_search terminated: no basis change.
Major Iteration Log
major minor func grad residual step type prox inorm (label)
0 0 2 2 2.5000e-01 I 0.0e+00 2.5e-01 ()
1 1 3 3 6.2500e-02 1.0e+00 SO 0.0e+00 6.2e-02 ()
2 1 4 4 1.5625e-02 1.0e+00 SO 0.0e+00 1.6e-02 ()
3 1 5 5 3.9062e-03 1.0e+00 SO 0.0e+00 3.9e-03 ()
4 1 6 6 9.7656e-04 1.0e+00 SO 0.0e+00 9.8e-04 ()
5 1 7 7 2.4414e-04 1.0e+00 SO 0.0e+00 2.4e-04 ()
6 1 8 8 6.1035e-05 1.0e+00 SO 0.0e+00 6.1e-05 ()
7 1 9 9 1.5259e-05 1.0e+00 SO 0.0e+00 1.5e-05 ()
8 1 10 10 3.8147e-06 1.0e+00 SO 0.0e+00 3.8e-06 ()
9 1 11 11 9.5367e-07 1.0e+00 SO 0.0e+00 9.5e-07 ()
Major Iterations. . . . 9
Minor Iterations. . . . 9
Restarts. . . . . . . . 0
Crash Iterations. . . . 1
Gradient Steps. . . . . 0
Function Evaluations. . 11
Gradient Evaluations. . 11
Basis Time. . . . . . . 0.000020
Total Time. . . . . . . 0.001310
Residual. . . . . . . . 9.536743e-07
julia> begin
model_2 = Model(PATHSolver.Optimizer)
@variable(model_2, x[1:500])
@constraint(model_2, [i in 1:500], x[i]^2 - 2 * x[i] + 1 ⟂ x[i])
optimize!(model_2)
termination_status(model_2)
end
OTHER_ERROR::TerminationStatusCode = 24
julia> using JuMP, PATHSolver
julia> begin
model = Model(PATHSolver.Optimizer)
@variable(model, x)
@constraint(model, x^2 - 2 * x + 1 ⟂ x)
optimize!(model)
end
Path 5.0.03 (Fri Jun 26 09:58:07 2020)
Written by Todd Munson, Steven Dirkse, Youngdae Kim, and Michael Ferris
Crash Log
major func diff size residual step prox (label)
0 0 1.0000e+00 0.0e+00 ()
1 1 0 1 2.5000e-01 1.0e+00 0.0e+00 ()
pn_search terminated: no basis change.
Major Iteration Log
major minor func grad residual step type prox inorm (label)
0 0 2 2 2.5000e-01 I 0.0e+00 2.5e-01 ()
1 1 3 3 6.2500e-02 1.0e+00 SO 0.0e+00 6.2e-02 ()
2 1 4 4 1.5625e-02 1.0e+00 SO 0.0e+00 1.6e-02 ()
3 1 5 5 3.9062e-03 1.0e+00 SO 0.0e+00 3.9e-03 ()
4 1 6 6 9.7656e-04 1.0e+00 SO 0.0e+00 9.8e-04 ()
5 1 7 7 2.4414e-04 1.0e+00 SO 0.0e+00 2.4e-04 ()
6 1 8 8 6.1035e-05 1.0e+00 SO 0.0e+00 6.1e-05 ()
7 1 9 9 1.5259e-05 1.0e+00 SO 0.0e+00 1.5e-05 ()
8 1 10 10 3.8147e-06 1.0e+00 SO 0.0e+00 3.8e-06 ()
9 1 11 11 9.5367e-07 1.0e+00 SO 0.0e+00 9.5e-07 ()
Major Iterations. . . . 9
Minor Iterations. . . . 9
Restarts. . . . . . . . 0
Crash Iterations. . . . 1
Gradient Steps. . . . . 0
Function Evaluations. . 11
Gradient Evaluations. . 11
Basis Time. . . . . . . 0.000026
Total Time. . . . . . . 0.001290
Residual. . . . . . . . 9.536743e-07
julia> begin
model_2 = Model(PATHSolver.Optimizer)
@variable(model_2, x[1:500])
@constraint(model_2, [i in 1:500], x[i]^2 - 2 * x[i] + 1 ⟂ x[i])
optimize!(model_2)
termination_status(model_2)
end
OTHER_ERROR::TerminationStatusCode = 24
(path) pkg> st
Status `/private/tmp/path/Project.toml`
[4076af6c] JuMP v1.22.1
[f5f7c340] PATHSolver v1.7.6
TypeError: in typeassert, expected PATHSolver.OutputData, got a value of type PATHSolver.Options(Ptr{Nothing} @0x0000020352eb3630)
I don't understand this at all.
PATH is passing the pointer of the options struct to the print method, instead of the output data.
That seems like a bug in PATH, not in PATHSolver.jl
I'm on windows.
A bug in PATH is the most likely.
On Tue, Jun 11, 2024, 5:31 PM Oscar Dowson @.***> wrote:
TypeError: in typeassert, expected PATHSolver.OutputData, got a value of type PATHSolver.Options(Ptr{Nothing} @0x0000020352eb3630)
I don't understand this at all.
PATH is passing the pointer of the options struct to the print method, instead of the output data.
That seems like a bug in PATH, not in PATHSolver.jl
— Reply to this email directly, view it on GitHub https://github.com/chkwon/PATHSolver.jl/issues/116#issuecomment-2161709264, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEVAPXJPYSKILXL2XBP5AH3ZG53E3AVCNFSM6AAAAABIHWIBGSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNRRG4YDSMRWGQ . You are receiving this because you authored the thread.Message ID: @.***>
This doesn't explain your CI failure, but I guess it's related. I assume the answer is just don't forget the license.
I'll email Michael Ferris this thread with a bit more info. He might be interested.
Hello. I am Michael's student. I will create an issue about this in the internal PATH codebase for you. But first, could you try something for me? I saw that you call c_api_Path_CheckLicense in the solve_mcp routine, and I was wondering if you could make this check be done after you set the c_api_Output_SetInterface. This is just a wild shot because c_api_Path_CheckLicense will print out messages for the demo license limit if violated, but it requires the output_interface to be set already. I think maybe the fact that the pointer to the print function PATH calls in the output_interface is not set can lead to some weird behaviors.
This does appear to solve the issues I've been having. I've opened PR and linked this issue.
because c_api_Path_CheckLicense will print out messages for the demo license limit if violated, but it requires the output_interface to be set already.
Ahhhhhh. I didn't consider this. This makes sense
Hah. I obviously ran into this at some point, and then forgot about it:
I should have asked Michael at the time, but I guess I forgot about this.
Fixed the test: https://github.com/chkwon/PATHSolver.jl/pull/120
Issue
The solver silently fails when a model has more than ~300 variables and no license. Since the PATH license needs to be updated on a yearly basis it's possible it expires unknowingly. This leads to many issues debugging models when the license has silently lapsed.
Proposed Solution
Throw an error when a model does not solve due to a license error.