Skip to content
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 src/NLPModels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Base type for a nonlinear least-squares model.
"""
abstract type AbstractNLSModel{T, S} <: AbstractNLPModel{T, S} end

for f in ["utils", "api", "counters", "meta", "show", "tools"]
for f in ["counters", "utils", "api", "meta", "show", "tools"]
include("nlp/$f.jl")
include("nls/$f.jl")
end
Expand Down
30 changes: 28 additions & 2 deletions src/nlp/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,39 @@ function coo_sym_prod!(
end

"""
@default_counters Model inner
@default_counters Model inner [excluded]

Define functions relating counters of `Model` to counters of `Model.inner`.
Any function listed in `excluded` (which is an empty list by default), will
not be forwarded.

Examples:

@default_counters MyModel inner (sum_counters, neval_hprod,)
@default_counters MyModel inner (neval_hprod,)

Excluding a method from forwarding allows the user to redefine it without
overwriting an existing method. Note that a generic method will still be
defined as, e.g.,

neval_hprod(model) = model.inner.counters.neval_hprod

because the `counters` attribute itself is forwarded by `@default_counters`.
"""
macro default_counters(Model, inner)
macro default_counters(Model, inner, excluded = :())

# Normalize excluded to a set of symbols
excluded_set = if excluded == :()
Set{Symbol}()
elseif excluded isa Expr && excluded.head == :tuple
Set{Symbol}([excluded.args...])
else
throw(ArgumentError("`@default_counters`: third argument must be a tuple of functions"))
end

ex = Expr(:block)
for foo in fieldnames(Counters) ∪ [:sum_counters]
Symbol(foo) in excluded_set && continue
push!(ex.args, :(NLPModels.$foo(nlp::$(esc(Model))) = $foo(nlp.$inner)))
end
push!(ex.args, :(NLPModels.reset!(nlp::$(esc(Model))) = begin
Expand Down
3 changes: 2 additions & 1 deletion test/nlp/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ end
end

@testset "Increase coverage of default_NLPcounters" begin
@default_counters SuperNLPModel model
@default_counters SuperNLPModel model (neval_hprod,)
nlp = SuperNLPModel{Float64, Vector{Float64}}(SimpleNLPModel())
increment!(nlp, :neval_obj)
@test neval_obj(nlp.model) == 1
@test nlp.counters == nlp.model.counters
@test neval_hprod(nlp) == 0 # because counters are forwarded, even though neval_hprod has not been forwarded
end
Loading