Skip to content

Use generated functions in optimization container #19

@luke-kiernan

Description

@luke-kiernan

There's a dozen places where we have things like

function get_foo(
   container::SomeContainerType,
   ::T,
   ...
) where {T <: VariableType, ...}
     return [1-line expression]
end

# similar for AuxVariable, ConstraintType, ParameterType, ExpressionType

Replace with generated functions. The fields and type depend on each other in a very predictable way, so if we just define

field_for_key(::Type{<:VariableKey}) = :variables
field_for_key(::Type{<:ConstraintKey}) = :duals
field_for_key(::Type{<:AuxVarKey}) = :aux_variables
field_for_key(::Type{<:ParameterKey}) = :parameters
field_for_key(::Type{<:ExpressionKey}) = :expressions

field_for_type(::Type{<:VariableType}) = :variables
field_for_type(::Type{<:ConstraintType}) = :duals
field_for_type(::Type{<:AuxVariableType}) = :aux_variables
field_for_type(::Type{<:ParameterType}) = :parameters
field_for_type(::Type{<:ExpressionType}) = :expressions

key_for_type(::Type{<:VariableType}) = VariableKey
key_for_type(::Type{<:ConstraintType}) = ConstraintKey
key_for_type(::Type{<:AuxVariableType}) = AuxVarKey
key_for_type(::Type{<:ParameterType}) = ParameterKey
key_for_type(::Type{<:ExpressionType}) = ExpressionKey

we can then do things like

@generated function get_foo(
    store::AbstractModelStore,
    ::T,
    ::Type{U},
) where {T <: OptimizationKeyType, U <: InfrastructureSystemsType}
    return :(return getfield(store, field_for_type(T))[key_for_type(T)(T, U)])
    # becomes e.g. return get_variables(store)[VariableKey(T, U)]
end

edit: we lose a little readibility with going to generated functions, but a comment like the above remedies that pretty easily.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions