Skip to content

Improve documentation of IndexMap #1530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 13, 2021
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
1 change: 1 addition & 0 deletions docs/src/reference/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ write_to_file
read_from_file
supports_incremental_interface
copy_to
IndexMap
```

## Model attributes
Expand Down
93 changes: 69 additions & 24 deletions src/MathOptInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,23 +124,41 @@ This is used in two places to determine whether to add a cache:
supports_incremental_interface(::ModelLike, ::Bool) = false

"""
copy_to(dest::ModelLike, src::ModelLike; copy_names=true, warn_attributes=true)

Copy the model from `src` into `dest`. The target `dest` is emptied, and all
previous indices to variables or constraints in `dest` are invalidated. Returns
a dictionary-like object that translates variable and constraint indices from
the `src` model to the corresponding indices in the `dest` model.

If `copy_names` is `false`, the `Name`, `VariableName` and `ConstraintName`
attributes are not copied even if they are set in `src`. If a constraint that
is copied from `src` is not supported by `dest` then an
[`UnsupportedConstraint`](@ref) error is thrown. Similarly, if a model, variable
or constraint attribute that is copied from `src` is not supported by `dest`
then an [`UnsupportedAttribute`](@ref) error is thrown. Unsupported *optimizer*
attributes are treated differently:

* If `warn_attributes` is `true`, a warning is displayed, otherwise,
* the attribute is silently ignored.
copy_to(
dest::ModelLike,
src::ModelLike;
copy_names::Bool = true,
Copy link
Member Author

Choose a reason for hiding this comment

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

Remind me why we need copy_names? Why can't we just try by default, and skip if they aren't supported?

warn_attributes::Bool = true,
Copy link
Member Author

Choose a reason for hiding this comment

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

@blegat do we really use this warn_attributes thing? Perhaps we should just remove? We don't really copy optimizer attributes.

Copy link
Member

@blegat blegat Aug 13, 2021

Choose a reason for hiding this comment

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

We should remove in MOI v0.10. It was left for when we implement copy of optimizer attributes but since CachingOptimizer don't use copy_to for that, I don't thing we will copy optimizer attributes in copy_to.

)::IndexMap

Copy the model from `src` into `dest`.

The target `dest` is emptied, and all previous indices to variables and
constraints in `dest` are invalidated.

Returns an [`IndexMap`](@ref) object that translates variable and constraint
indices from the `src` model to the corresponding indices in the `dest` model.

## Notes

* If `copy_names == false`, the [`Name`](@ref), [`VariableName`](@ref) and
[`ConstraintName`](@ref) attributes are not copied, even if they are set in
`src`.
* If a constraint that in `src` is not supported by `dest`, then an
[`UnsupportedConstraint`](@ref) error is thrown.
* If an [`AbstractModelAttribute`](@ref), [`AbstractVariableAttribute`](@ref),
or [`AbstractConstraintAttribute`](@ref) is set in `src` but not supported by
`dest`, then an [`UnsupportedAttribute`](@ref) error is thrown.
* Unsupported [`AbstractOptimizerAttribute`](@ref)s are treated differently:
* If `warn_attributes == true`, a warning is displayed, otherwise, the
attribute is silently ignored.

## IndexMap

Implementations of `copy_to` must return an [`IndexMap`](@ref). For technical
reasons, this type is defined in the Utilties submodule as
`MOI.Utilities.IndexMap`. However, since it is an integral part of the MOI API,
we provide `MOI.IndexMap` as an alias.

### Example

Expand All @@ -160,16 +178,26 @@ is_valid(dest, index_map[x]) # true
function copy_to end

"""
copy_to_and_optimize!(dest::ModelLike, src::ModelLike; copy_names=true, warn_attributes=true)
copy_to_and_optimize!(
dest::AbstractOptimizer,
src::ModelLike;
kwargs...
)::IndexMap

Same as [`copy_to`](@ref) followed [`optimize!`](@ref). An optimizer
can decide to implement this function and not implement [`copy_to`](@ref) and
[`optimize!`](@ref).
A single call equivalent to calling [`copy_to`](@ref) followed by
[`optimize!`](@ref). Like [`copy_to`](@ref), it returns an [`IndexMap`].

**WARNING** This is an experimental new feature of MOI v0.10 that may break in MOI v1.0.
Keyword arguments are passed to [`copy_to`](@ref).

An optimizer can decide to implement this function instead of implementing
[`copy_to`](@ref) and [`optimize!`](@ref) individually.

!!! warning
This is an experimental new feature of MOI v0.10 that may break in MOI v1.0.
"""
function copy_to_and_optimize!(dest, src; kws...)
index_map = copy_to(dest, src; kws...)
function copy_to_and_optimize!(dest, src; kwargs...)
# The arguments above are untyped to avoid ambiguities.
index_map = copy_to(dest, src; kwargs...)
optimize!(dest)
return index_map
end
Expand Down Expand Up @@ -199,4 +227,21 @@ include("instantiate.jl")
include("deprecate.jl")
include("DeprecatedTest/DeprecatedTest.jl")

"""
IndexMap(number_of_variables::Int = 0)

The dictionary-like object returned by [`copy_to`](@ref).

If known in advance, pass `number_of_variables` to preallocate the necessary
space for the variables.

## IndexMap

Implementations of [`copy_to`](@ref) must return an [`IndexMap`](@ref). For
technical reasons, the `IndexMap` type is defined in the Utilties submodule as
`MOI.Utilities.IndexMap`. However, since it is an integral part of the MOI API,
we provide this `MOI.IndexMap` as an alias.
"""
const IndexMap = Utilities.IndexMap

end
21 changes: 15 additions & 6 deletions src/Utilities/copy/index_map.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# IndexMap is defined here because there is a boostrapping problem.
# * IndexMap requires `Utilities.CleverDicts` and `Utilities.DoubleDicts`, so
# if it were to be defined in MOI proper, it must be included after
# Utilities.
# * However, Utilities requires IndexMap, so it must be defined before
# Utilities.jl is included.
# To work around this issue, we define `IndexMap` here.

struct IndexMap <: AbstractDict{MOI.Index,MOI.Index}
var_map::CleverDicts.CleverDict{
MOI.VariableIndex,
Expand All @@ -9,17 +17,18 @@ struct IndexMap <: AbstractDict{MOI.Index,MOI.Index}
end

"""
IndexMap(n::Int = 0)
IndexMap(number_of_variables::Int = 0)
The dictionary-like object returned by [`MathOptInterface.copy_to`](@ref).
Dictionary-like object returned by [`MathOptInterface.copy_to`](@ref) that
contains the mapping between variable indices in `.var_map` and between
constraint indices in `.con_map`.
If known in advance, pass `number_of_variables` to preallocate the necessary
space for the variables.
"""
function IndexMap(n::Int = 0)
function IndexMap(number_of_variables::Int = 0)
var_map = CleverDicts.CleverDict{MOI.VariableIndex,MOI.VariableIndex}(
CleverDicts.key_to_index,
CleverDicts.index_to_key,
n,
number_of_variables,
)
con_map = DoubleDicts.IndexDoubleDict()
return IndexMap(var_map, con_map)
Expand Down