|
1 | | -struct HybridPSOLBFGS |
2 | | - pso::PSOAlgorithm |
3 | | - lbfgs::LBFGS |
4 | | -end |
5 | | - |
6 | | -function HybridPSOLBFGS(; pso = PSOGPU.ParallelPSOKernel(100 ; global_update = false), lbfgs = LBFGS()) |
7 | | - HybridPSOLBFGS(pso, lbfgs) |
8 | | -end |
9 | | - |
10 | | -@kernel function lbfgs_run!(nlcaches, x0s, result) |
11 | | - i = @index(Global, Linear) |
12 | | - # nlcache = reinit!(nlcaches[i], x0s[i]) |
13 | | - # @show nlcache.u |
14 | | - res = solve!(nlcaches[i]) |
15 | | - # @show res |
16 | | - # @show res.resid |
17 | | - result[i] = res |
18 | | -end |
19 | | - |
20 | | -@kernel function simplelbfgs_run!(nlprob, x0s, result) |
| 1 | +@kernel function simplebfgs_run!(nlprob, x0s, result, opt, maxiters, abstol, reltol) |
21 | 2 | i = @index(Global, Linear) |
22 | 3 | nlcache = remake(nlprob; u0 = x0s[i]) |
23 | | - result[i] = solve(nlcache, SimpleLimitedMemoryBroyden(; threshold = 10)) |
24 | | -end |
25 | | - |
26 | | -@kernel function simplebfgs_run!(nlprob, x0s, result, opt, maxiters) |
27 | | - i = @index(Global, Linear) |
28 | | - nlcache = remake(nlprob; u0 = x0s[i]) |
29 | | - sol = SciMLBase.__solve(nlcache, opt, maxiters = maxiters, abstol = 1f-6, reltol = 1f-6) |
| 4 | + sol = solve(nlcache, opt; maxiters, abstol, reltol) |
30 | 5 | result[i] = sol.u |
31 | 6 | end |
32 | 7 |
|
33 | | -function SciMLBase.__solve(prob::SciMLBase.OptimizationProblem, opt::HybridPSOLBFGS, args...; maxiters = 1000, kwargs...) |
| 8 | +function SciMLBase.__solve(prob::SciMLBase.OptimizationProblem, |
| 9 | + opt::HybridPSO{Backend, LocalOpt}, |
| 10 | + args...; |
| 11 | + abstol = nothing, |
| 12 | + reltol = nothing, |
| 13 | + maxiters = 100, |
| 14 | + local_maxiters = 10, |
| 15 | + kwargs...) where {Backend, LocalOpt <: Union{LBFGS, BFGS}} |
34 | 16 | t0 = time() |
35 | 17 | psoalg = opt.pso |
36 | | - lbfgsalg = opt.lbfgs |
| 18 | + local_opt = opt.local_opt |
| 19 | + backend = opt.backend |
37 | 20 |
|
38 | 21 | sol_pso = solve(prob, psoalg, args...; maxiters, kwargs...) |
39 | | - |
40 | | - # @show sol_pso.u |
41 | | - |
42 | 22 | x0s = sol_pso.original |
43 | | - # @show prob.u0 |
44 | | - # @show x0s |
45 | 23 | prob = remake(prob, lb = nothing, ub = nothing) |
46 | | - # @show length(x0s) |
47 | | - # f = Optimization.instantiate_function(prob.f, prob.u0, prob.f.adtype, prob.p, 0) |
48 | 24 | f = Base.Fix2(prob.f.f, prob.p) |
49 | | - function _g(θ, _p = nothing) |
50 | | - return ForwardDiff.gradient(f , θ) |
51 | | - end |
52 | | - # @show prob.u0 |
53 | | - # nlcaches = [init(NonlinearProblem(NonlinearFunction(_g), x0), LimitedMemoryBroyden(; threshold = lbfgsalg.m, linesearch = LiFukushimaLineSearch())) |
54 | | - # for x0 in x0s |
55 | | - # ] |
56 | | - # @show nlcaches[1] |
57 | | - # @show ismutable(nlcaches[1]) |
58 | | - backend = lbfgsalg.backend |
59 | | - # kernel = lbfgs_run!(backend) |
60 | | - # result = KernelAbstractions.allocate(lbfgsalg.backend, SciMLBase.NonlinearSolution, length(x0s)) |
61 | | - |
62 | | - # kernel(nlcaches, x0s, result; ndrange = length(x0s)) |
63 | | - |
64 | | - # kernel = simplelbfgs_run!(backend) |
65 | | - # result = KernelAbstractions.allocate(backend, SciMLBase.NonlinearSolution, length(x0s)) |
66 | | - # nlprob = NonlinearProblem(NonlinearFunction(_g), prob.u0) |
67 | | - # kernel(nlprob, x0s, result; ndrange = length(x0s)) |
| 25 | + ∇f = instantiate_gradient(f, prob.f.adtype) |
68 | 26 |
|
69 | 27 | kernel = simplebfgs_run!(backend) |
70 | 28 | result = KernelAbstractions.allocate(backend, typeof(prob.u0), length(x0s)) |
71 | | - nlprob = NonlinearProblem{false}(_g, prob.u0) |
| 29 | + nlprob = NonlinearProblem{false}(∇f, prob.u0) |
| 30 | + |
| 31 | + nlalg = LocalOpt isa LBFGS ? |
| 32 | + SimpleLimitedMemoryBroyden(; |
| 33 | + threshold = local_opt.threshold, |
| 34 | + linesearch = Val(true)) : SimpleBroyden(; linesearch = Val(true)) |
| 35 | + |
| 36 | + kernel(nlprob, |
| 37 | + x0s, |
| 38 | + result, |
| 39 | + nlalg, |
| 40 | + local_maxiters, |
| 41 | + abstol, |
| 42 | + reltol; |
| 43 | + ndrange = length(x0s)) |
72 | 44 |
|
73 | | - kernel(nlprob, x0s, result, SimpleLimitedMemoryBroyden(; threshold = lbfgsalg.m, linesearch = Val(true)), maxiters; ndrange = length(x0s)) |
74 | | - |
75 | | - # @show result |
76 | 45 | t1 = time() |
77 | 46 | sol_bfgs = (x -> prob.f(x, prob.p)).(result) |
78 | | - # sol_bfgs = [prob.f(θ, prob.p) for θ in result] |
79 | | - # @show typeof(sol_bfgs) |
80 | | - |
81 | | - sol_bfgs = (x -> isnan(x) ? Inf32 : x).(sol_bfgs) |
82 | | - # @show minimum(sol_bfgs) |
| 47 | + sol_bfgs = (x -> isnan(x) ? convert(eltype(prob.u0), Inf) : x).(sol_bfgs) |
83 | 48 |
|
84 | 49 | minobj, ind = findmin(sol_bfgs) |
85 | 50 |
|
86 | 51 | SciMLBase.build_solution(SciMLBase.DefaultOptimizationCache(prob.f, prob.p), opt, |
87 | | - view(result, ind) , minobj) |
| 52 | + view(result, ind), minobj) |
88 | 53 | end |
0 commit comments