Skip to content

Commit

Permalink
CompatHelper: bump compat for OptimizationOptimJL to 0.2, (keep exist…
Browse files Browse the repository at this point in the history
…ing compat) (#175)

* CompatHelper: bump compat for OptimizationOptimJL to 0.2, (keep existing compat)

* Drop support for Optimization 0.1

* Use new Optimization callback API

* Update tests

* Increment patch number

* Restore support for old OptimizationOptimJL versio

* Add OptimizationCallback

* Update callback test

* Remove the 1.10 release client from CI

Now that v1.10 is released, this is redundant.

---------

Co-authored-by: CompatHelper Julia <[email protected]>
Co-authored-by: Seth Axen <[email protected]>
  • Loading branch information
3 people authored Jan 15, 2024
1 parent 26641dc commit c5990eb
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 22 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ jobs:
num_threads:
- 1
- 2
include:
- version: '^1.10.0-rc1'
os: ubuntu-latest
arch: x64
num_threads: 1
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Pathfinder"
uuid = "b1d3bc72-d0e7-4279-b92f-7fa5d6d2d454"
authors = ["Seth Axen <[email protected]> and contributors"]
version = "0.8.1"
version = "0.8.2"

[deps]
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Expand Down Expand Up @@ -47,7 +47,7 @@ LogDensityProblems = "2"
MCMCChains = "5, 6"
Optim = "1.4"
Optimization = "3"
OptimizationOptimJL = "0.1"
OptimizationOptimJL = "0.1, 0.2"
PDMats = "0.11.26"
PSIS = "0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9"
ProgressLogging = "0.1.4"
Expand Down
70 changes: 63 additions & 7 deletions src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,75 @@ function optimize_with_trace(
xs = typeof(u0)[]
fxs = typeof(fun.f(u0, nothing))[]
∇fxs = typeof(u0)[]
_callback = _make_optimization_callback(
xs, fxs, ∇fxs, ∇f; progress_name, progress_id, maxiters, callback, fail_on_nonfinite
_callback = OptimizationCallback(
xs, fxs, ∇fxs, ∇f, progress_name, progress_id, maxiters, callback, fail_on_nonfinite
)
sol = Optimization.solve(prob, optimizer; callback=_callback, maxiters, kwargs...)
return sol, OptimizationTrace(xs, fxs, ∇fxs)
end

function _make_optimization_callback(
xs, fxs, ∇fxs, ∇f; progress_name, progress_id, maxiters, callback, fail_on_nonfinite
)
return function (x, nfx, args...)
struct OptimizationCallback{X,FX,∇FX,∇F,ID,CB}
xs::X
fxs::FX
∇fxs::∇FX
∇f::∇F
progress_name::String
progress_id::ID
maxiters::Int
callback::CB
fail_on_nonfinite::Bool
end

@static if isdefined(Optimization, :OptimizationState)
# Optimization v3.21.0 and later
function (cb::OptimizationCallback)(state::Optimization.OptimizationState, args...)
@unpack (
xs,
fxs,
∇fxs,
∇f,
progress_name,
progress_id,
maxiters,
callback,
fail_on_nonfinite,
) = cb
ret = callback !== nothing && callback(state, args...)
iteration = state.iter
Base.@logmsg ProgressLogging.ProgressLevel progress_name progress =
iteration / maxiters _id = progress_id

x = copy(state.u)
fx = -state.objective
∇fx = state.grad === nothing ? ∇f(x) : -state.grad

# some backends mutate x, so we must copy it
push!(xs, x)
push!(fxs, fx)
push!(∇fxs, ∇fx)

if fail_on_nonfinite && !ret
ret = (isnan(fx) || fx == Inf || any(!isfinite, ∇fx))::Bool
end

return ret
end
else
# Optimization v3.20.X and earlier
function (cb::OptimizationCallback)(x, nfx, args...)
@unpack (
xs,
fxs,
∇fxs,
∇f,
progress_name,
progress_id,
maxiters,
callback,
fail_on_nonfinite,
) = cb
ret = callback !== nothing && callback(x, nfx, args...)
iteration = length(xs)
iteration = length(cb.xs)
Base.@logmsg ProgressLogging.ProgressLevel progress_name progress =
iteration / maxiters _id = progress_id

Expand Down
28 changes: 20 additions & 8 deletions test/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ end
@test prob.p === nothing
end

@testset "_make_optimization_callback" begin
@testset "OptimizationCallback" begin
@testset "callback return value" begin
progress_name = "Optimizing"
progress_id = nothing
Expand All @@ -57,22 +57,34 @@ end
g[end] = gval
return g
end
callback = (x, fx, args...) -> cbfail
cb = Pathfinder._make_optimization_callback(
should_fail =
cbfail ||
(fail_on_nonfinite && (isnan(fval) || fval == Inf || !isfinite(gval)))
if isdefined(Optimization, :OptimizationState)
# Optimization v3.21.0 and later
callback = (state, args...) -> cbfail
state = Optimization.OptimizationState(;
iter=0, u=x, objective=-fval, grad=-∇f(x)
)
cb_args = (state, -fval)
else
# Optimization v3.20.X and earlier
callback = (x, fx, args...) -> cbfail
cb_args = (x, -fval)
end
cb = Pathfinder.OptimizationCallback(
xs,
fxs,
∇fxs,
∇f;
∇f,
progress_name,
progress_id,
maxiters,
callback,
fail_on_nonfinite,
)
should_fail =
cbfail ||
(fail_on_nonfinite && (isnan(fval) || fval == Inf || !isfinite(gval)))
@test cb(x, -fval) == should_fail
@test cb isa Pathfinder.OptimizationCallback
@test cb(cb_args...) == should_fail
end
end
end
Expand Down

2 comments on commit c5990eb

@sethaxen
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/98899

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.8.2 -m "<description of version>" c5990eb4b8e2ef5bce84a0f0d74a571fb4e03667
git push origin v0.8.2

Please sign in to comment.