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

Rethrow errors instead of returning FORCED_STOP #194

Merged
merged 8 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext/NLoptMathOptInterfaceExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ end
function fill_gradient!(grad, x, var::MOI.VariableIndex)
fill!(grad, 0.0)
grad[var.value] = 1.0
return retur
return
end

function fill_gradient!(grad, x, aff::MOI.ScalarAffineFunction{Float64})
Expand Down
20 changes: 13 additions & 7 deletions src/NLopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ function chk(o::Opt, result::Result)
elseif result == FORCED_STOP
global nlopt_exception
e = nlopt_exception
nlopt_exception = nothing
if e !== nothing && !isa(e, ForcedStop)
nlopt_exception = nothing
rethrow(e)
throw(e)
end
else
error("nlopt failure $result", _errmsg(o))
Expand Down Expand Up @@ -391,8 +391,11 @@ function nlopt_callback_wrapper(n::Cuint, x::Ptr{Cdouble},
: unsafe_wrap(Array, grad, (convert(Int, n),))))
return res::Cdouble
catch e
global nlopt_exception
nlopt_exception = e
if e isa ForcedStop
global nlopt_exception = e
else
global nlopt_exception = CapturedException(e, catch_backtrace())
end
force_stop!(d.o::Opt)
return 0.0 # ignored by nlopt
end
Expand Down Expand Up @@ -451,8 +454,11 @@ function nlopt_vcallback_wrapper(m::Cuint, res::Ptr{Cdouble},
grad == C_NULL ? empty_jac
: unsafe_wrap(Array, grad, (convert(Int, n),convert(Int, m))))
catch e
global nlopt_exception
nlopt_exception = e
if e isa ForcedStop
global nlopt_exception = e
else
global nlopt_exception = CapturedException(e, catch_backtrace())
end
force_stop!(d.o::Opt)
end
nothing
Expand Down Expand Up @@ -621,7 +627,7 @@ function optimize!(o::Opt, x::Vector{Cdouble})
ret = ccall((:nlopt_optimize,libnlopt), Result, (_Opt, Ptr{Cdouble},
Ptr{Cdouble}),
o, x, opt_f)
ret == INVALID_ARGS && chk(o, ret)
chk(o, ret)
return (opt_f[1], x, Symbol(ret))
end

Expand Down
32 changes: 32 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,38 @@ end
@test_throws err opt.initial_step
end

@testset "Fix #156" begin
@testset "Test that CapturedException is thrown" begin
f(x, g=[]) = (error("test error"); x[1]^2)
opt = Opt(:LN_SBPLX, 1)
opt.min_objective = f
@test_throws CapturedException optimize(opt, [0.1234])
@test NLopt.nlopt_exception === nothing
try
optimize(opt, [0.1234])
catch e
# Check that the backtrace is being printed
@test length(sprint(show, e)) > 100
end
end
@testset "Test that ForcedStop does not rethrow" begin
f(x, g=[]) = (throw(NLopt.ForcedStop()); x[1]^2)
opt = Opt(:LN_SBPLX, 1)
opt.min_objective = f
fmin, xmin, ret = optimize(opt, [0.1234])
@test ret == :FORCED_STOP
@test NLopt.nlopt_exception === nothing
end
@testset "Test that no error works correctly" begin
f(x, g=[]) = (x[1]^2)
opt = Opt(:LN_SBPLX, 1)
opt.min_objective = f
fmin, xmin, ret = optimize(opt, [0.1234])
@test ret ∈ (:SUCCESS, :FTOL_REACHED, :XTOL_REACHED)
@test NLopt.nlopt_exception === nothing
end
end

@testset "invalid algorithms" begin
@test_throws ArgumentError("unknown algorithm BILL") Algorithm(:BILL)
@test_throws ArgumentError("unknown algorithm BILL") Opt(:BILL, 420)
Expand Down
Loading