From 43bc9cfa955887b9acfa0d60b65822f504be51f5 Mon Sep 17 00:00:00 2001 From: tmigot Date: Sun, 6 Jul 2025 09:02:00 -0400 Subject: [PATCH 1/3] Add modifier to remove fixed variables --- src/NLPModelsModifiers.jl | 1 + src/no-fixed.jl | 486 ++++++++++++++++++++++++++++++++++++++ test/allocs_test.jl | 4 + test/gpu_test.jl | 2 +- test/nlp/no-fixed.jl | 126 ++++++++++ test/runtests.jl | 1 + 6 files changed, 619 insertions(+), 1 deletion(-) create mode 100644 src/no-fixed.jl create mode 100644 test/nlp/no-fixed.jl diff --git a/src/NLPModelsModifiers.jl b/src/NLPModelsModifiers.jl index 2a81e16..d4a5fe7 100644 --- a/src/NLPModelsModifiers.jl +++ b/src/NLPModelsModifiers.jl @@ -14,6 +14,7 @@ macro notimplemented_use_nls(fun) )) end +include("no-fixed.jl") include("feasibility-form-nls.jl") include("feasibility-residual.jl") include("quasi-newton.jl") diff --git a/src/no-fixed.jl b/src/no-fixed.jl new file mode 100644 index 0000000..21b12fa --- /dev/null +++ b/src/no-fixed.jl @@ -0,0 +1,486 @@ +export NoFixedModel + +mutable struct NoFixedModel{ + T, + S, + M <: AbstractNLPModel{T, S}, + Meta <: AbstractNLPModelMeta{T, S}, +} <: AbstractNLPModel{T, S} + ifix_mask::BitVector + meta::Meta + model::M + x_copy::S + temp::S + temp2::S + is_implemented_hessian::Bool + new_rows::Vector{Int} + new_cols::Vector{Int} + mask::Vector{Int} + temp3::S + jac_lin_rows::Vector{Int} + jac_lin_cols::Vector{Int} + jac_nln_rows::Vector{Int} + jac_nln_cols::Vector{Int} + temp4::S + jac_lin_mask::Vector{Int} + jac_nln_mask::Vector{Int} +end + +function compute_ifix_mask(model::AbstractNLPModel) + n = get_nvar(model) + ifix = get_ifix(model) + mask = falses(n) # BitVector of length n + for i in ifix + mask[i] = true + end + return mask +end + +function NoFixedModel(model::AbstractNLPModel{T, S}) where {T, S} + x0_full = get_x0(model) + lvar_full = get_lvar(model) + uvar_full = get_uvar(model) + ifix_mask = compute_ifix_mask(model) + free_indices = findall(.!ifix_mask) + + nvar = get_nvar(model) - length(model.meta.ifix) + x0 = similar(x0_full, nvar) + lvar = similar(get_lvar(model), nvar) + uvar = similar(get_uvar(model), nvar) + x_copy = similar(x0_full) + + j = 0 + for i = 1:get_nvar(model) + if !ifix_mask[i] + j += 1 + x0[j] = x0_full[i] + lvar[j] = lvar_full[i] + uvar[j] = uvar_full[i] + else + x_copy[i] = lvar_full[i] + end + end + # Prepare hessian structure evaluation + new_rows = Vector{Int}(undef, get_nnzh(model)) + new_cols = Vector{Int}(undef, get_nnzh(model)) + mask = Vector{Int}(undef, get_nnzh(model)) + is_implemented_hessian = true + full_to_red = fill(0, get_nvar(model)) + for (j, i) in enumerate(free_indices) + full_to_red[i] = j + end + + count_nnzh = 0 + try + old_rows, old_cols = hess_structure(model) + for i=1:get_nnzh(model) + if !(ifix_mask[old_rows[i]] || ifix_mask[old_cols[i]]) + count_nnzh += 1 + mask[count_nnzh] = i + new_rows[count_nnzh] = full_to_red[old_rows[i]] + new_cols[count_nnzh] = full_to_red[old_cols[i]] + end + end + catch + is_implemented_hessian = false + end + resize!(new_rows, count_nnzh) + resize!(new_cols, count_nnzh) + resize!(mask, count_nnzh) + + jac_lin_rows = Vector{Int}(undef, get_lin_nnzj(model)) + jac_lin_cols = Vector{Int}(undef, get_lin_nnzj(model)) + jac_lin_mask = Vector{Int}(undef, get_lin_nnzj(model)) + jac_nln_rows = Vector{Int}(undef, get_nln_nnzj(model)) + jac_nln_cols = Vector{Int}(undef, get_nln_nnzj(model)) + jac_nln_mask = Vector{Int}(undef, get_nln_nnzj(model)) + + lin_rows, lin_cols = jac_lin_structure(model) + nln_rows, nln_cols = jac_nln_structure(model) + count_nnzj = 0 + count_lin_nnzj = 0 + count_nln_nnzj = 0 + + for (idx, (r, c)) in enumerate(zip(lin_rows, lin_cols)) + if !ifix_mask[c] + count_lin_nnzj+=1 + jac_lin_rows[count_lin_nnzj] = r + jac_lin_cols[count_lin_nnzj] = full_to_red[c] + jac_lin_mask[count_lin_nnzj] = idx + end + end + + for (idx, (r, c)) in enumerate(zip(nln_rows, nln_cols)) + if !ifix_mask[c] + count_nln_nnzj+=1 + jac_nln_rows[count_nln_nnzj] = r + jac_nln_cols[count_nln_nnzj] = full_to_red[c] + jac_nln_mask[count_nln_nnzj] = idx + end + end + count_nnzj = count_lin_nnzj + count_nln_nnzj + + resize!(jac_lin_rows, count_lin_nnzj) + resize!(jac_lin_cols, count_lin_nnzj) + resize!(jac_lin_mask, count_lin_nnzj) + resize!(jac_nln_rows, count_nln_nnzj) + resize!(jac_nln_cols, count_nln_nnzj) + resize!(jac_nln_mask, count_nln_nnzj) + + meta = NLPModelMeta{T, S}( + nvar; + x0 = x0, + lvar = lvar, + uvar = uvar, + nlvb = model.meta.nlvb, + nlvo = model.meta.nlvo, + nlvc = model.meta.nlvc, + ncon = model.meta.ncon, + y0 = model.meta.y0, + lcon = model.meta.lcon, + ucon = model.meta.ucon, + nnzo = model.meta.nnzo, + nnzj = count_nnzj, + lin_nnzj = count_lin_nnzj, + nln_nnzj = count_nln_nnzj, + nnzh = count_nnzh, + lin = model.meta.lin, + minimize = model.meta.minimize, + islp = model.meta.islp, + name = model.meta.name * " (no fixed variables)", + ) + return NoFixedModel(ifix_mask, meta, model, x_copy, similar(x_copy), similar(x_copy), is_implemented_hessian, new_rows, new_cols, mask, similar(x_copy, get_nnzh(model)), jac_lin_rows, jac_lin_cols, jac_nln_rows, jac_nln_cols, similar(x_copy, get_nnzj(model)), jac_lin_mask, jac_nln_mask) +end + +function transform_x(nlp::NoFixedModel{T, S}, x::S) where {T, S} + @lencheck nlp.meta.nvar x + x_full = nlp.x_copy + fixed_value = get_lvar(nlp.model) + j = 0 + @inbounds @simd for i in 1:get_nvar(nlp.model) + if nlp.ifix_mask[i] + x_full[i] = fixed_value[i] + else + j += 1 + x_full[i] = x[j] + end + end + return x_full +end + +function transform_v!(nlp::NoFixedModel{T, S}, v::S, v_long::S) where {T, S} + @lencheck nlp.meta.nvar v + @lencheck nlp.model.meta.nvar v_long + j = 0 + @inbounds @simd for i in 1:get_nvar(nlp.model) + if nlp.ifix_mask[i] + v_long[i] = zero(T) + else + j += 1 + v_long[i] = v[j] + end + end + return v_long +end +function get_from_temp!(nlp::NoFixedModel{T, S}, temp::S, g::S) where {T, S} + @lencheck nlp.meta.nvar g + j = 0 + @inbounds @simd for i in 1:get_nvar(nlp.model) + if !nlp.ifix_mask[i] + j += 1 + g[j] = temp[i] + end + end + return g +end + +NLPModels.show_header(io::IO, nlp::NoFixedModel) = + println(io, "$(typeof(nlp)) - A NLPModel without fixed variables") + +function Base.show(io::IO, nlp::NoFixedModel) + show_header(io, nlp) + show(io, nlp.meta) + show(io, nlp.model.counters) +end + +@default_counters NoFixedModel model + +# Rely on default hess and jac functions +for meth in ( + :obj, + :cons, + :cons_lin, + :cons_nln, +) + @eval NLPModels.$meth(nlp::NoFixedModel, x::AbstractVector; kwargs...) = + $meth(nlp.model, transform_x(nlp, x); kwargs...) +end +for meth in ( + :cons!, + :cons_lin!, + :cons_nln!, +) + @eval NLPModels.$meth(nlp::NoFixedModel, x::AbstractVector, y::AbstractVector; kwargs...) = + $meth(nlp.model, transform_x(nlp, x), y; kwargs...) +end + +for meth in ( + :jprod, + :jprod_lin, + :jprod_nln, +) + @eval function NLPModels.$meth( + nlp::NoFixedModel, + x::AbstractVector, + v::AbstractVector + ) + transform_v!(nlp, v, nlp.temp) + Jv = $meth(nlp.model, transform_x(nlp, x), nlp.temp) + return Jv + end +end +for meth in ( + :jprod!, + :jprod_lin!, + :jprod_nln!, +) + @eval function NLPModels.$meth( + nlp::NoFixedModel, + x::AbstractVector, + v::AbstractVector, + Jv::AbstractVector, + ) + transform_v!(nlp, v, nlp.temp) + $meth(nlp.model, transform_x(nlp, x), nlp.temp, Jv) + return Jv + end +end +for meth in ( + :jtprod, + :jtprod_lin, + :jtprod_nln, +) + @eval function NLPModels.$meth( + nlp::NoFixedModel, + x::AbstractVector, + v::AbstractVector + ) + Jtv = similar(nlp.meta.x0) + nlp.temp = $meth(nlp.model, transform_x(nlp, x), v) + get_from_temp!(nlp, nlp.temp, Jtv) + return Jtv + end +end +for meth in ( + :jtprod!, + :jtprod_lin!, + :jtprod_nln!, +) + @eval function NLPModels.$meth( + nlp::NoFixedModel, + x::AbstractVector, + v::AbstractVector, + Jtv::AbstractVector, + ) + $meth(nlp.model, transform_x(nlp, x), v, nlp.temp) + get_from_temp!(nlp, nlp.temp, Jtv) + return Jtv + end +end + +function NLPModels.grad(nlp::NoFixedModel, x::AbstractVector) + @lencheck nlp.meta.nvar x + g = similar(x) + grad!(nlp.model, transform_x(nlp, x), nlp.temp) + get_from_temp!(nlp, nlp.temp, g) + return g +end +function NLPModels.grad!(nlp::NoFixedModel, x::AbstractVector, g::AbstractVector) + @lencheck nlp.meta.nvar x g + grad!(nlp.model, transform_x(nlp, x), nlp.temp) + get_from_temp!(nlp, nlp.temp, g) +end +function NLPModels.objgrad(nlp::NoFixedModel, x::AbstractVector) + @lencheck nlp.meta.nvar x + g = similar(x) + fx, nlp.temp = objgrad!(nlp.model, transform_x(nlp, x), nlp.temp) + get_from_temp!(nlp, nlp.temp, g) + return (fx, g) +end +function NLPModels.objgrad!(nlp::NoFixedModel, x::AbstractVector, g::AbstractVector) + @lencheck nlp.meta.nvar x g + fx, nlp.temp = objgrad!(nlp.model, transform_x(nlp, x), nlp.temp) + get_from_temp!(nlp, nlp.temp, g) + return (fx, g) +end +function NLPModels.hprod( + nlp::NoFixedModel, + x::AbstractVector, + v::AbstractVector; + kwargs..., +) + @lencheck nlp.meta.nvar x v + Hv = similar(v) + transform_v!(nlp, v, nlp.temp2) + hprod!(nlp.model, transform_x(nlp, x), nlp.temp2, nlp.temp; kwargs...) + get_from_temp!(nlp, nlp.temp, Hv) + return Hv +end +function NLPModels.hprod!( + nlp::NoFixedModel, + x::AbstractVector, + v::AbstractVector, + Hv::AbstractVector; + kwargs..., +) + @lencheck nlp.meta.nvar x v + transform_v!(nlp, v, nlp.temp2) + hprod!(nlp.model, transform_x(nlp, x), nlp.temp2, nlp.temp; kwargs...) + get_from_temp!(nlp, nlp.temp, Hv) +end +function NLPModels.hprod( + nlp::NoFixedModel, + x::AbstractVector, + y::AbstractVector, + v::AbstractVector; + kwargs..., +) + @lencheck nlp.meta.nvar x v + @lencheck nlp.meta.ncon y + Hv = similar(v) + transform_v!(nlp, v, nlp.temp2) + hprod!(nlp.model, transform_x(nlp, x), y, nlp.temp2, nlp.temp; kwargs...) + get_from_temp!(nlp, nlp.temp, Hv) + return Hv +end +function NLPModels.hprod!( + nlp::NoFixedModel, + x::AbstractVector, + y::AbstractVector, + v::AbstractVector, + Hv::AbstractVector; + kwargs..., +) + @lencheck nlp.meta.nvar x v Hv + @lencheck nlp.meta.ncon y + transform_v!(nlp, v, nlp.temp2) + hprod!(nlp.model, transform_x(nlp, x), y, nlp.temp2, nlp.temp; kwargs...) + get_from_temp!(nlp, nlp.temp, Hv) +end + +function NLPModels.ghjvprod!( + nlp::NoFixedModel, + x::AbstractVector, + g::AbstractVector, + v::AbstractVector, + gHv::AbstractVector, +) + @lencheck nlp.meta.nvar x g v + transform_v!(nlp, g, nlp.temp) + transform_v!(nlp, v, nlp.temp2) + ghjvprod!(nlp.model, transform_x(nlp, x), nlp.temp, nlp.temp2, gHv) + return gHv +end + +function NLPModels.jac_lin_structure!(nlp::NoFixedModel, rows::AbstractVector{<:Integer}, cols::AbstractVector{<:Integer}) + rows .= nlp.jac_lin_rows + cols .= nlp.jac_lin_cols + return rows, cols +end +function NLPModels.jac_nln_structure!(nlp::NoFixedModel, rows::AbstractVector{<:Integer}, cols::AbstractVector{<:Integer}) + rows .= nlp.jac_nln_rows + cols .= nlp.jac_nln_cols + return rows, cols +end +function NLPModels.jac_lin_coord!(nlp::NoFixedModel, x::AbstractVector, vals::AbstractVector) + NLPModels.jac_lin_coord!(nlp.model, transform_x(nlp, x), view(nlp.temp4, 1:(get_lin_nnzj(nlp.model)))) + for (k, i) in enumerate(nlp.jac_lin_mask) + vals[k] = nlp.temp4[i] + end + return vals +end +function NLPModels.jac_nln_coord!(nlp::NoFixedModel, x::AbstractVector, vals::AbstractVector) + NLPModels.jac_nln_coord!(nlp.model, transform_x(nlp, x), view(nlp.temp4, 1:(get_nln_nnzj(nlp.model)))) + for (k, i) in enumerate(nlp.jac_nln_mask) + vals[k] = nlp.temp4[i] + end + return vals +end + +function NLPModels.hess_coord!( + nlp::NoFixedModel, + x::AbstractVector, + vals::AbstractVector; + kwargs..., +) + @lencheck nlp.meta.nvar x + if !nlp.is_implemented_hessian + throw(ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))")) + end + hess_coord!(nlp.model, transform_x(nlp, x), nlp.temp3; kwargs...) + @inbounds @simd for k in 1:length(nlp.mask) + vals[k] = nlp.temp3[nlp.mask[k]] +end + return vals +end +function NLPModels.hess_coord!( + nlp::NoFixedModel, + x::AbstractVector, + y::AbstractVector, + vals::AbstractVector; + kwargs..., +) + @lencheck nlp.meta.nvar x + @lencheck nlp.meta.ncon y + if !nlp.is_implemented_hessian + throw(ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))")) + end + hess_coord!(nlp.model, transform_x(nlp, x), y, nlp.temp3; kwargs...) + @inbounds @simd for k in 1:length(nlp.mask) + vals[k] = nlp.temp3[nlp.mask[k]] +end + return vals +end +function NLPModels.hess_structure!( + nlp::NoFixedModel, + rows::AbstractVector{<:Integer}, + cols::AbstractVector{<:Integer}, +) + if !nlp.is_implemented_hessian + throw(ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))")) + end + return nlp.new_rows, nlp.new_cols +end + +function NLPModels.jth_hess_coord!( + nlp::NoFixedModel, + x::AbstractVector, + j::Integer, + vals::AbstractVector; + kwargs..., +) + @lencheck nlp.meta.nvar x + @rangecheck 1 nlp.meta.ncon j + if !nlp.is_implemented_hessian + throw(ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))")) + end + jth_hess_coord!(nlp.model, transform_x(nlp, x), j, nlp.temp3; kwargs...) + @inbounds @simd for k in 1:length(nlp.mask) + vals[k] = nlp.temp3[nlp.mask[k]] + end + return vals +end +function NLPModels.jth_hprod!( + nlp::NoFixedModel, + x::AbstractVector, + v::AbstractVector, + j::Integer, + Hv::AbstractVector; + kwargs..., +) + @lencheck nlp.meta.nvar x v Hv + @rangecheck 1 nlp.meta.ncon j + transform_v!(nlp, v, nlp.temp2) + jth_hprod!(nlp.model, transform_x(nlp, x), nlp.temp2, j, nlp.temp; kwargs...) + get_from_temp!(nlp, nlp.temp, Hv) +end diff --git a/test/allocs_test.jl b/test/allocs_test.jl index 69c3402..b1af90f 100644 --- a/test/allocs_test.jl +++ b/test/allocs_test.jl @@ -1,4 +1,8 @@ @testset "Check allocations for model modifiers of NLP" begin + map( + nlp -> NLPModelsTest.test_zero_allocations(nlp, linear_api = true, exclude = []), + map(x -> NoFixedModel(eval(Symbol(x))()), NLPModelsTest.nlp_problems), + ) map( nlp -> NLPModelsTest.test_zero_allocations(nlp, linear_api = true, exclude = [hess]), map(x -> LBFGSModel(eval(Symbol(x))()), NLPModelsTest.nlp_problems), diff --git a/test/gpu_test.jl b/test/gpu_test.jl index 872eedd..f1df007 100644 --- a/test/gpu_test.jl +++ b/test/gpu_test.jl @@ -50,7 +50,7 @@ end ) end -@testset "Check GPU multiprecision for model modifiers $M of NLP" for M in [SlackModel] +@testset "Check GPU multiprecision for model modifiers $M of NLP" for M in [NoFixedModel, SlackModel] map(p -> nlp_gpu_tests(p, M, exclude = []), NLPModelsTest.nlp_problems) end diff --git a/test/nlp/no-fixed.jl b/test/nlp/no-fixed.jl new file mode 100644 index 0000000..d0a64d5 --- /dev/null +++ b/test/nlp/no-fixed.jl @@ -0,0 +1,126 @@ +@testset "NoFixedModel NLP tests" begin + @testset "API T=$T, M=$M" for T in [Float64, Float32], M in [NLPModelMeta] # , SimpleNLPMeta + f(x) = (x[1] - 2)^2 + (0 - 1)^2 + ∇f(x) = T[2 * (x[1] - 2)] + H(x) = 2 * ones(T, 1, 1) + c(x) = T[x[1] - 2 * 0 + 1; -x[1]^2 / 4 - 0 + 1] + J(x) = reshape(T[1, -0.5x[1]], 2, 1) + H(x, y) = H(x) + y[2] * T[-0.5] + + nlp = NoFixedModel(SimpleNLPModel(T, M, fixed_var = true)) + n = nlp.meta.nvar + m = nlp.meta.ncon + @test nlp.meta.x0[1:n] == T[2] + + x = randn(T, n) + y = randn(T, m) + v = randn(T, n) + w = randn(T, m) + Jv = zeros(T, m) + Jtw = zeros(T, n) + Hv = zeros(T, n) + Hvals = zeros(T, nlp.meta.nnzh) + + # Basic methods + @test obj(nlp, x) ≈ f(x) + @test grad(nlp, x) ≈ ∇f(x) + @test hess(nlp, x) ≈ H(x) + @test hprod(nlp, x, v) ≈ H(x) * v + @test cons(nlp, x) ≈ c(x) + @test jac(nlp, x) ≈ J(x) + @test jprod(nlp, x, v) ≈ J(x) * v + @test jtprod(nlp, x, w) ≈ J(x)' * w + @test hess(nlp, x, y) ≈ H(x, y) + @test hprod(nlp, x, y, v) ≈ H(x, y) * v + + # Increasing coverage + fx, cx = objcons(nlp, x) + @test fx ≈ f(x) + @test cx ≈ c(x) + fx, _ = objcons!(nlp, x, cx) + @test fx ≈ f(x) + @test cx ≈ c(x) + fx, gx = objgrad(nlp, x) + @test fx ≈ f(x) + @test gx ≈ ∇f(x) + fx, _ = objgrad!(nlp, x, gx) + @test fx ≈ f(x) + @test gx ≈ ∇f(x) + @test jprod!(nlp, jac_structure(nlp)..., jac_coord(nlp, x), v, Jv) ≈ J(x) * v + @test jtprod!(nlp, jac_structure(nlp)..., jac_coord(nlp, x), w, Jtw) ≈ J(x)' * w + Jop = jac_op!(nlp, x, Jv, Jtw) + @test Jop * v == J(x) * v + @test Jop' * w ≈ J(x)' * w + res = J(x) * v - w + @test mul!(w, Jop, v, one(T), -one(T)) ≈ res + res = J(x)' * w - v + @test mul!(v, Jop', w, one(T), -one(T)) ≈ res + Jop = jac_op!(nlp, jac_structure(nlp)..., jac_coord(nlp, x), Jv, Jtw) + @test Jop * v ≈ J(x) * v + @test Jop' * w ≈ J(x)' * w + res = J(x) * v - w + @test mul!(w, Jop, v, one(T), -one(T)) ≈ res + res = J(x)' * w - v + @test mul!(v, Jop', w, one(T), -one(T)) ≈ res + ghjv = zeros(T, m) + for j = 1:m + eⱼ = [i == j ? one(T) : zero(T) for i = 1:m] + Cⱼ(x) = H(x, eⱼ) - H(x) + ghjv[j] = dot(gx, Cⱼ(x) * v) + @test jth_hess(nlp, x, j) == Cⱼ(x) + @test jth_hprod(nlp, x, v, j) == Cⱼ(x) * v + end + @test ghjvprod(nlp, x, gx, v) ≈ ghjv + @test hess_coord!(nlp, x, Hvals) == hess_coord!(nlp, x, y * 0, Hvals) + @test hprod!(nlp, hess_structure(nlp)..., hess_coord(nlp, x), v, Hv) ≈ H(x) * v + Hop = hess_op(nlp, x) + @test Hop * v ≈ H(x) * v + Hop = hess_op!(nlp, x, Hv) + @test Hop * v ≈ H(x) * v + z = ones(T, nlp.meta.nvar) + res = H(x) * v - z + @test mul!(z, Hop, v, one(T), -one(T)) ≈ res + Hop = hess_op!(nlp, hess_structure(nlp)..., hess_coord(nlp, x), Hv) + @test Hop * v ≈ H(x) * v + res = H(x) * v - z + @test mul!(z, Hop, v, one(T), -one(T)) ≈ res + Hop = hess_op(nlp, x, y) + @test Hop * v ≈ H(x, y) * v + Hop = hess_op!(nlp, x, y, Hv) + @test Hop * v ≈ H(x, y) * v + res = H(x, y) * v - z + @test mul!(z, Hop, v, one(T), -one(T)) ≈ res + Hop = hess_op!(nlp, hess_structure(nlp)..., hess_coord(nlp, x, y), Hv) + @test Hop * v ≈ H(x, y) * v + end + + @testset "Show" begin + nlp = NoFixedModel(SimpleNLPModel()) + io = IOBuffer() + show(io, nlp) + showed = String(take!(io)) + expected = """NoFixedModel{Float64, Vector{Float64}, SimpleNLPModel{Float64, Vector{Float64}, NLPModelMeta{Float64, Vector{Float64}}}, NLPModelMeta{Float64, Vector{Float64}}} - A NLPModel without fixed variables + Problem name: Simple NLP Model (no fixed variables) + All variables: ████████████████████ 2 All constraints: ████████████████████ 2 + free: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 free: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + lower: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 lower: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 1 + upper: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 upper: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + low/upp: ████████████████████ 2 low/upp: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + fixed: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 fixed: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 1 + infeas: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 infeas: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + nnzh: ( 33.33% sparsity) 2 linear: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 1 + nonlinear: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 1 + nnzj: ( 0.00% sparsity) 4 + + Counters: + obj: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 grad: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 cons: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + cons_lin: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 cons_nln: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 jcon: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + jgrad: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 jac: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 jac_lin: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + jac_nln: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 jprod: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 jprod_lin: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + jprod_nln: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 jtprod: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 jtprod_lin: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + jtprod_nln: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 hess: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 hprod: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + jhess: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 jhprod: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0""" + + @test strip.(split(chomp(showed), "\n")) == strip.(split(chomp(expected), "\n")) + end +end diff --git a/test/runtests.jl b/test/runtests.jl index 4696795..3171ffc 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,6 +2,7 @@ using LinearAlgebra, SparseArrays, Test using LinearOperators, NLPModels, NLPModelsModifiers include("nlp/simple-model.jl") +include("nlp/no-fixed.jl") include("nlp/quasi-newton.jl") include("nlp/slack-model.jl") From b1229642f9178f660550099d0aafc5efa177079e Mon Sep 17 00:00:00 2001 From: tmigot Date: Sun, 6 Jul 2025 09:03:32 -0400 Subject: [PATCH 2/3] modify simple model --- test/nlp/simple-model.jl | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/test/nlp/simple-model.jl b/test/nlp/simple-model.jl index 56ab503..2201a43 100644 --- a/test/nlp/simple-model.jl +++ b/test/nlp/simple-model.jl @@ -153,13 +153,20 @@ end NLPModels.equality_constrained(meta::SimpleNLPMeta) = length(meta.jfix) == meta.ncon > 0 NLPModels.unconstrained(meta::SimpleNLPMeta) = meta.ncon == 0 && !has_bounds(meta) -function SimpleNLPModel(::Type{T}, ::Type{NLPModelMeta}) where {T} +function SimpleNLPModel(::Type{T}, ::Type{NLPModelMeta}; fixed_var = false) where {T} + if fixed_var + lvar = zeros(T, 2) + uvar = T[1; 0] + else + lvar = zeros(T, 2) + uvar = ones(T, 2) + end meta = NLPModelMeta{T, Vector{T}}( 2, nnzh = 2, ncon = 2, - lvar = zeros(T, 2), - uvar = ones(T, 2), + lvar = lvar, + uvar = uvar, x0 = T[2; 2], lcon = T[0; 0], ucon = T[0; Inf], @@ -170,13 +177,20 @@ function SimpleNLPModel(::Type{T}, ::Type{NLPModelMeta}) where {T} ) return SimpleNLPModel(meta, Counters()) end -function SimpleNLPModel(::Type{T}, ::Type{SimpleNLPMeta}) where {T} +function SimpleNLPModel(::Type{T}, ::Type{SimpleNLPMeta}; fixed_var = false) where {T} + if fixed_var + lvar = zeros(T, 2) + uvar = T[1; 0] + else + lvar = zeros(T, 2) + uvar = ones(T, 2) + end meta = SimpleNLPMeta{T, Vector{T}}( 2, nnzh = 2, ncon = 2, - lvar = zeros(T, 2), - uvar = ones(T, 2), + lvar = lvar, + uvar = uvar, x0 = T[2; 2], lcon = T[0; 0], ucon = T[0; Inf], @@ -187,7 +201,7 @@ function SimpleNLPModel(::Type{T}, ::Type{SimpleNLPMeta}) where {T} ) return SimpleNLPModel(meta, Counters()) end -SimpleNLPModel() = SimpleNLPModel(Float64, NLPModelMeta) +SimpleNLPModel(; kwargs...) = SimpleNLPModel(Float64, NLPModelMeta; kwargs...) function NLPModels.obj(nlp::SimpleNLPModel, x::AbstractVector) @lencheck 2 x From 58e1521445660357cc05d7e000aaa54588f3d606 Mon Sep 17 00:00:00 2001 From: tmigot Date: Sun, 6 Jul 2025 09:25:01 -0400 Subject: [PATCH 3/3] more fixes --- src/no-fixed.jl | 315 ++++++++++++++++++++++------------------------- test/gpu_test.jl | 3 +- 2 files changed, 147 insertions(+), 171 deletions(-) diff --git a/src/no-fixed.jl b/src/no-fixed.jl index 21b12fa..d5a133a 100644 --- a/src/no-fixed.jl +++ b/src/no-fixed.jl @@ -1,5 +1,9 @@ export NoFixedModel +@doc raw"""A model whose fixed variables are removed. + +Fixed variables are variables whose lower and upper bounds are equal. +""" mutable struct NoFixedModel{ T, S, @@ -13,8 +17,8 @@ mutable struct NoFixedModel{ temp::S temp2::S is_implemented_hessian::Bool - new_rows::Vector{Int} - new_cols::Vector{Int} + hess_rows::Vector{Int} + hess_cols::Vector{Int} mask::Vector{Int} temp3::S jac_lin_rows::Vector{Int} @@ -27,13 +31,13 @@ mutable struct NoFixedModel{ end function compute_ifix_mask(model::AbstractNLPModel) - n = get_nvar(model) - ifix = get_ifix(model) - mask = falses(n) # BitVector of length n - for i in ifix - mask[i] = true - end - return mask + n = get_nvar(model) + ifix = get_ifix(model) + mask = falses(n) + for i in ifix + mask[i] = true + end + return mask end function NoFixedModel(model::AbstractNLPModel{T, S}) where {T, S} @@ -61,8 +65,8 @@ function NoFixedModel(model::AbstractNLPModel{T, S}) where {T, S} end end # Prepare hessian structure evaluation - new_rows = Vector{Int}(undef, get_nnzh(model)) - new_cols = Vector{Int}(undef, get_nnzh(model)) + hess_rows = Vector{Int}(undef, get_nnzh(model)) + hess_cols = Vector{Int}(undef, get_nnzh(model)) mask = Vector{Int}(undef, get_nnzh(model)) is_implemented_hessian = true full_to_red = fill(0, get_nvar(model)) @@ -73,19 +77,19 @@ function NoFixedModel(model::AbstractNLPModel{T, S}) where {T, S} count_nnzh = 0 try old_rows, old_cols = hess_structure(model) - for i=1:get_nnzh(model) + for i = 1:get_nnzh(model) if !(ifix_mask[old_rows[i]] || ifix_mask[old_cols[i]]) count_nnzh += 1 mask[count_nnzh] = i - new_rows[count_nnzh] = full_to_red[old_rows[i]] - new_cols[count_nnzh] = full_to_red[old_cols[i]] + hess_rows[count_nnzh] = full_to_red[old_rows[i]] + hess_cols[count_nnzh] = full_to_red[old_cols[i]] end end catch is_implemented_hessian = false end - resize!(new_rows, count_nnzh) - resize!(new_cols, count_nnzh) + resize!(hess_rows, count_nnzh) + resize!(hess_cols, count_nnzh) resize!(mask, count_nnzh) jac_lin_rows = Vector{Int}(undef, get_lin_nnzj(model)) @@ -95,28 +99,32 @@ function NoFixedModel(model::AbstractNLPModel{T, S}) where {T, S} jac_nln_cols = Vector{Int}(undef, get_nln_nnzj(model)) jac_nln_mask = Vector{Int}(undef, get_nln_nnzj(model)) - lin_rows, lin_cols = jac_lin_structure(model) - nln_rows, nln_cols = jac_nln_structure(model) count_nnzj = 0 count_lin_nnzj = 0 count_nln_nnzj = 0 - for (idx, (r, c)) in enumerate(zip(lin_rows, lin_cols)) + if get_nlin(model) > 0 + lin_rows, lin_cols = jac_lin_structure(model) + for (idx, (r, c)) in enumerate(zip(lin_rows, lin_cols)) if !ifix_mask[c] count_lin_nnzj+=1 jac_lin_rows[count_lin_nnzj] = r jac_lin_cols[count_lin_nnzj] = full_to_red[c] - jac_lin_mask[count_lin_nnzj] = idx + jac_lin_mask[count_lin_nnzj] = idx end + end end - for (idx, (r, c)) in enumerate(zip(nln_rows, nln_cols)) + if get_nnln(model) > 0 + nln_rows, nln_cols = jac_nln_structure(model) + for (idx, (r, c)) in enumerate(zip(nln_rows, nln_cols)) if !ifix_mask[c] count_nln_nnzj+=1 jac_nln_rows[count_nln_nnzj] = r jac_nln_cols[count_nln_nnzj] = full_to_red[c] jac_nln_mask[count_nln_nnzj] = idx end + end end count_nnzj = count_lin_nnzj + count_nln_nnzj @@ -149,15 +157,39 @@ function NoFixedModel(model::AbstractNLPModel{T, S}) where {T, S} islp = model.meta.islp, name = model.meta.name * " (no fixed variables)", ) - return NoFixedModel(ifix_mask, meta, model, x_copy, similar(x_copy), similar(x_copy), is_implemented_hessian, new_rows, new_cols, mask, similar(x_copy, get_nnzh(model)), jac_lin_rows, jac_lin_cols, jac_nln_rows, jac_nln_cols, similar(x_copy, get_nnzj(model)), jac_lin_mask, jac_nln_mask) + return NoFixedModel( + ifix_mask, + meta, + model, + x_copy, + similar(x_copy), + similar(x_copy), + is_implemented_hessian, + hess_rows, + hess_cols, + mask, + similar(x_copy, get_nnzh(model)), + jac_lin_rows, + jac_lin_cols, + jac_nln_rows, + jac_nln_cols, + similar(x_copy, get_nnzj(model)), + jac_lin_mask, + jac_nln_mask, + ) end +""" + transform_x(nlp::NoFixedModel, x::AbstractVector) + +Given a vector `x` of length `nlp.meta.nvar`, return a vector with fixed variables included. +""" function transform_x(nlp::NoFixedModel{T, S}, x::S) where {T, S} @lencheck nlp.meta.nvar x x_full = nlp.x_copy fixed_value = get_lvar(nlp.model) j = 0 - @inbounds @simd for i in 1:get_nvar(nlp.model) + @inbounds @simd for i = 1:get_nvar(nlp.model) if nlp.ifix_mask[i] x_full[i] = fixed_value[i] else @@ -168,30 +200,41 @@ function transform_x(nlp::NoFixedModel{T, S}, x::S) where {T, S} return x_full end +""" + transform_v!(nlp::NoFixedModel, v::AbstractVector, v_long::AbstractVector) + +Given a vector `v` of length `nlp.meta.nvar`, return a vector filled with zeros for fixed variables indices. +""" function transform_v!(nlp::NoFixedModel{T, S}, v::S, v_long::S) where {T, S} @lencheck nlp.meta.nvar v @lencheck nlp.model.meta.nvar v_long j = 0 - @inbounds @simd for i in 1:get_nvar(nlp.model) + @inbounds @simd for i = 1:get_nvar(nlp.model) if nlp.ifix_mask[i] v_long[i] = zero(T) - else - j += 1 - v_long[i] = v[j] - end + else + j += 1 + v_long[i] = v[j] end - return v_long + end + return v_long end + +""" + get_from_temp!(nlp::NoFixedModel, temp::AbstractVector, g::AbstractVector) + +Given a vector `temp` of length `nlp.model.meta.nvar`, return a vector `g` with fixed variables removed. +""" function get_from_temp!(nlp::NoFixedModel{T, S}, temp::S, g::S) where {T, S} - @lencheck nlp.meta.nvar g - j = 0 - @inbounds @simd for i in 1:get_nvar(nlp.model) - if !nlp.ifix_mask[i] - j += 1 - g[j] = temp[i] - end + @lencheck nlp.meta.nvar g + j = 0 + @inbounds @simd for i = 1:get_nvar(nlp.model) + if !nlp.ifix_mask[i] + j += 1 + g[j] = temp[i] end - return g + end + return g end NLPModels.show_header(io::IO, nlp::NoFixedModel) = @@ -206,126 +249,49 @@ end @default_counters NoFixedModel model # Rely on default hess and jac functions -for meth in ( - :obj, - :cons, - :cons_lin, - :cons_nln, -) - @eval NLPModels.$meth(nlp::NoFixedModel, x::AbstractVector; kwargs...) = - $meth(nlp.model, transform_x(nlp, x); kwargs...) -end -for meth in ( - :cons!, - :cons_lin!, - :cons_nln!, -) +NLPModels.obj(nlp::NoFixedModel, x::AbstractVector; kwargs...) = + obj(nlp.model, transform_x(nlp, x); kwargs...) +for meth in (:cons!, :cons_lin!, :cons_nln!) @eval NLPModels.$meth(nlp::NoFixedModel, x::AbstractVector, y::AbstractVector; kwargs...) = $meth(nlp.model, transform_x(nlp, x), y; kwargs...) end -for meth in ( - :jprod, - :jprod_lin, - :jprod_nln, -) - @eval function NLPModels.$meth( - nlp::NoFixedModel, - x::AbstractVector, - v::AbstractVector - ) - transform_v!(nlp, v, nlp.temp) - Jv = $meth(nlp.model, transform_x(nlp, x), nlp.temp) - return Jv - end -end -for meth in ( - :jprod!, - :jprod_lin!, - :jprod_nln!, -) +for meth in (:jprod!, :jprod_lin!, :jprod_nln!) @eval function NLPModels.$meth( nlp::NoFixedModel, x::AbstractVector, v::AbstractVector, Jv::AbstractVector, ) - transform_v!(nlp, v, nlp.temp) - $meth(nlp.model, transform_x(nlp, x), nlp.temp, Jv) - return Jv - end -end -for meth in ( - :jtprod, - :jtprod_lin, - :jtprod_nln, -) - @eval function NLPModels.$meth( - nlp::NoFixedModel, - x::AbstractVector, - v::AbstractVector - ) - Jtv = similar(nlp.meta.x0) - nlp.temp = $meth(nlp.model, transform_x(nlp, x), v) - get_from_temp!(nlp, nlp.temp, Jtv) - return Jtv + transform_v!(nlp, v, nlp.temp) + $meth(nlp.model, transform_x(nlp, x), nlp.temp, Jv) + return Jv end end -for meth in ( - :jtprod!, - :jtprod_lin!, - :jtprod_nln!, -) +for meth in (:jtprod!, :jtprod_lin!, :jtprod_nln!) @eval function NLPModels.$meth( nlp::NoFixedModel, x::AbstractVector, v::AbstractVector, Jtv::AbstractVector, ) - $meth(nlp.model, transform_x(nlp, x), v, nlp.temp) - get_from_temp!(nlp, nlp.temp, Jtv) - return Jtv + $meth(nlp.model, transform_x(nlp, x), v, nlp.temp) + get_from_temp!(nlp, nlp.temp, Jtv) + return Jtv end end -function NLPModels.grad(nlp::NoFixedModel, x::AbstractVector) - @lencheck nlp.meta.nvar x - g = similar(x) - grad!(nlp.model, transform_x(nlp, x), nlp.temp) - get_from_temp!(nlp, nlp.temp, g) - return g -end function NLPModels.grad!(nlp::NoFixedModel, x::AbstractVector, g::AbstractVector) @lencheck nlp.meta.nvar x g grad!(nlp.model, transform_x(nlp, x), nlp.temp) get_from_temp!(nlp, nlp.temp, g) end -function NLPModels.objgrad(nlp::NoFixedModel, x::AbstractVector) - @lencheck nlp.meta.nvar x - g = similar(x) - fx, nlp.temp = objgrad!(nlp.model, transform_x(nlp, x), nlp.temp) - get_from_temp!(nlp, nlp.temp, g) - return (fx, g) -end function NLPModels.objgrad!(nlp::NoFixedModel, x::AbstractVector, g::AbstractVector) @lencheck nlp.meta.nvar x g fx, nlp.temp = objgrad!(nlp.model, transform_x(nlp, x), nlp.temp) get_from_temp!(nlp, nlp.temp, g) return (fx, g) end -function NLPModels.hprod( - nlp::NoFixedModel, - x::AbstractVector, - v::AbstractVector; - kwargs..., -) - @lencheck nlp.meta.nvar x v - Hv = similar(v) - transform_v!(nlp, v, nlp.temp2) - hprod!(nlp.model, transform_x(nlp, x), nlp.temp2, nlp.temp; kwargs...) - get_from_temp!(nlp, nlp.temp, Hv) - return Hv -end function NLPModels.hprod!( nlp::NoFixedModel, x::AbstractVector, @@ -338,21 +304,6 @@ function NLPModels.hprod!( hprod!(nlp.model, transform_x(nlp, x), nlp.temp2, nlp.temp; kwargs...) get_from_temp!(nlp, nlp.temp, Hv) end -function NLPModels.hprod( - nlp::NoFixedModel, - x::AbstractVector, - y::AbstractVector, - v::AbstractVector; - kwargs..., -) - @lencheck nlp.meta.nvar x v - @lencheck nlp.meta.ncon y - Hv = similar(v) - transform_v!(nlp, v, nlp.temp2) - hprod!(nlp.model, transform_x(nlp, x), y, nlp.temp2, nlp.temp; kwargs...) - get_from_temp!(nlp, nlp.temp, Hv) - return Hv -end function NLPModels.hprod!( nlp::NoFixedModel, x::AbstractVector, @@ -382,29 +333,45 @@ function NLPModels.ghjvprod!( return gHv end -function NLPModels.jac_lin_structure!(nlp::NoFixedModel, rows::AbstractVector{<:Integer}, cols::AbstractVector{<:Integer}) - rows .= nlp.jac_lin_rows - cols .= nlp.jac_lin_cols - return rows, cols +function NLPModels.jac_lin_structure!( + nlp::NoFixedModel, + rows::AbstractVector{<:Integer}, + cols::AbstractVector{<:Integer}, +) + rows .= nlp.jac_lin_rows + cols .= nlp.jac_lin_cols + return rows, cols end -function NLPModels.jac_nln_structure!(nlp::NoFixedModel, rows::AbstractVector{<:Integer}, cols::AbstractVector{<:Integer}) - rows .= nlp.jac_nln_rows - cols .= nlp.jac_nln_cols - return rows, cols +function NLPModels.jac_nln_structure!( + nlp::NoFixedModel, + rows::AbstractVector{<:Integer}, + cols::AbstractVector{<:Integer}, +) + rows .= nlp.jac_nln_rows + cols .= nlp.jac_nln_cols + return rows, cols end function NLPModels.jac_lin_coord!(nlp::NoFixedModel, x::AbstractVector, vals::AbstractVector) - NLPModels.jac_lin_coord!(nlp.model, transform_x(nlp, x), view(nlp.temp4, 1:(get_lin_nnzj(nlp.model)))) - for (k, i) in enumerate(nlp.jac_lin_mask) - vals[k] = nlp.temp4[i] - end - return vals + NLPModels.jac_lin_coord!( + nlp.model, + transform_x(nlp, x), + view(nlp.temp4, 1:(get_lin_nnzj(nlp.model))), + ) + for (k, i) in enumerate(nlp.jac_lin_mask) + vals[k] = nlp.temp4[i] + end + return vals end function NLPModels.jac_nln_coord!(nlp::NoFixedModel, x::AbstractVector, vals::AbstractVector) - NLPModels.jac_nln_coord!(nlp.model, transform_x(nlp, x), view(nlp.temp4, 1:(get_nln_nnzj(nlp.model)))) - for (k, i) in enumerate(nlp.jac_nln_mask) - vals[k] = nlp.temp4[i] - end - return vals + NLPModels.jac_nln_coord!( + nlp.model, + transform_x(nlp, x), + view(nlp.temp4, 1:(get_nln_nnzj(nlp.model))), + ) + for (k, i) in enumerate(nlp.jac_nln_mask) + vals[k] = nlp.temp4[i] + end + return vals end function NLPModels.hess_coord!( @@ -415,12 +382,14 @@ function NLPModels.hess_coord!( ) @lencheck nlp.meta.nvar x if !nlp.is_implemented_hessian - throw(ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))")) + throw( + ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))"), + ) end hess_coord!(nlp.model, transform_x(nlp, x), nlp.temp3; kwargs...) - @inbounds @simd for k in 1:length(nlp.mask) - vals[k] = nlp.temp3[nlp.mask[k]] -end + @inbounds @simd for k = 1:length(nlp.mask) + vals[k] = nlp.temp3[nlp.mask[k]] + end return vals end function NLPModels.hess_coord!( @@ -433,12 +402,14 @@ function NLPModels.hess_coord!( @lencheck nlp.meta.nvar x @lencheck nlp.meta.ncon y if !nlp.is_implemented_hessian - throw(ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))")) + throw( + ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))"), + ) end hess_coord!(nlp.model, transform_x(nlp, x), y, nlp.temp3; kwargs...) - @inbounds @simd for k in 1:length(nlp.mask) - vals[k] = nlp.temp3[nlp.mask[k]] -end + @inbounds @simd for k = 1:length(nlp.mask) + vals[k] = nlp.temp3[nlp.mask[k]] + end return vals end function NLPModels.hess_structure!( @@ -447,9 +418,11 @@ function NLPModels.hess_structure!( cols::AbstractVector{<:Integer}, ) if !nlp.is_implemented_hessian - throw(ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))")) + throw( + ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))"), + ) end - return nlp.new_rows, nlp.new_cols + return nlp.hess_rows, nlp.hess_cols end function NLPModels.jth_hess_coord!( @@ -462,10 +435,12 @@ function NLPModels.jth_hess_coord!( @lencheck nlp.meta.nvar x @rangecheck 1 nlp.meta.ncon j if !nlp.is_implemented_hessian - throw(ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))")) + throw( + ErrorException("Not implemented hess_structure! for original problem $(typeof(nlp.model))"), + ) end jth_hess_coord!(nlp.model, transform_x(nlp, x), j, nlp.temp3; kwargs...) - @inbounds @simd for k in 1:length(nlp.mask) + @inbounds @simd for k = 1:length(nlp.mask) vals[k] = nlp.temp3[nlp.mask[k]] end return vals diff --git a/test/gpu_test.jl b/test/gpu_test.jl index f1df007..3d38393 100644 --- a/test/gpu_test.jl +++ b/test/gpu_test.jl @@ -50,7 +50,8 @@ end ) end -@testset "Check GPU multiprecision for model modifiers $M of NLP" for M in [NoFixedModel, SlackModel] +@testset "Check GPU multiprecision for model modifiers $M of NLP" for M in + [NoFixedModel, SlackModel] map(p -> nlp_gpu_tests(p, M, exclude = []), NLPModelsTest.nlp_problems) end