Skip to content
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

UnitsUsageDict -> UnitsUsage #522

Merged
merged 5 commits into from
Jun 1, 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
2 changes: 1 addition & 1 deletion src/Algorithm/Algorithm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ export AbstractOptimizationAlgorithm, TreeSearchAlgorithm, ColCutGenConquer, Col
export PartialSolutionUnit, PreprocessingUnit

# Unit functions
export getstorageunit, add_to_solution!, add_to_localpartialsol!
export add_to_solution!, add_to_localpartialsol!

end
4 changes: 2 additions & 2 deletions src/Algorithm/basic/solveipform.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function get_units_usage(
# (deactivating artificial vars and enforcing integrality)
# are reverted before the end of the algorithm,
# so the state of the formulation remains the same
units_usage = Tuple{AbstractModel, UnitType, UnitAccessMode}[]
units_usage = Tuple{AbstractModel, UnitType, UnitPermission}[]
push!(units_usage, (form, StaticVarConstrUnit, READ_ONLY))
if Duty <: MathProg.AbstractMasterDuty
push!(units_usage, (form, PartialSolutionUnit, READ_ONLY))
Expand All @@ -130,7 +130,7 @@ get_units_usage(algo::SolveIpForm, reform::Reformulation) =

# get_units_usage of UserOptimize
function get_units_usage(::UserOptimize, spform::Formulation{DwSp})
units_usage = Tuple{AbstractModel, UnitType, UnitAccessMode}[]
units_usage = Tuple{AbstractModel, UnitType, UnitPermission}[]
push!(units_usage, (spform, StaticVarConstrUnit, READ_ONLY))
return units_usage
end
Expand Down
2 changes: 1 addition & 1 deletion src/Algorithm/basic/solvelpform.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function get_units_usage(
# we use units in the read only mode, as relaxing integrality
# is reverted before the end of the algorithm,
# so the state of the formulation remains the same
units_usage = Tuple{AbstractModel, UnitType, UnitAccessMode}[]
units_usage = Tuple{AbstractModel, UnitType, UnitPermission}[]
push!(units_usage, (form, StaticVarConstrUnit, READ_ONLY))
if Duty <: MathProg.AbstractMasterDuty
push!(units_usage, (form, MasterColumnsUnit, READ_ONLY))
Expand Down
2 changes: 1 addition & 1 deletion src/Algorithm/benders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ end
# to solve the subproblems

function get_units_usage(algo::BendersCutGeneration, reform::Reformulation)
units_usage = Tuple{AbstractModel, UnitType, UnitAccessMode}[]
units_usage = Tuple{AbstractModel, UnitType, UnitPermission}[]
master = getmaster(reform)
push!(units_usage, (master, MasterCutsUnit, READ_AND_WRITE))

Expand Down
10 changes: 4 additions & 6 deletions src/Algorithm/branching/branchingalgo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ function perform_strong_branching_with_phases!(
if length(groups) <= nb_candidates_for_next_phase
continue
end
end
end

conquer_units_to_restore = UnitsUsageDict()
conquer_units_to_restore = UnitsUsage()
collect_units_to_restore!(
conquer_units_to_restore, current_phase.conquer_algo, reform
)
)

#TO DO : we need to define a print level parameter
println("**** Strong branching phase ", phase_index, " is started *****");
Expand All @@ -124,11 +124,9 @@ function perform_strong_branching_with_phases!(
max_descr_length = length(description)
end
end

a_candidate_is_conquered::Bool = false

for (group_index,group) in enumerate(groups)
#TO DO: verify if time limit is reached

if phase_index == 1
generate_children!(group, env, reform, parent)
else
Expand Down
9 changes: 5 additions & 4 deletions src/Algorithm/branching/varbranching.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ function generate_children(
candidate::VarBranchingCandidate, lhs::Float64, env::Env, reform::Reformulation, parent::Node
)
master = getmaster(reform)
var = getvar(master, candidate.varid)

@logmsg LogLevel(-1) string(
"Chosen branching variable : ",
getname(master, candidate.varid), " with value ", lhs, "."
)

units_to_restore = UnitsUsageDict(
(master, MasterBranchConstrsUnit) => READ_AND_WRITE
#(master, BasisUnit) => READ_AND_WRITE) # not yet implemented
units_to_restore = UnitsUsage()
set_permission!(
Copy link
Collaborator

Choose a reason for hiding this comment

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

It makes sense here only to indicate units which will be restored with read-and-write permission (others will be restored with read-only permission). Thus we may rename units_to_restore to units_to_write, and set_permission!() to set_write_permission!(). The latter would take only two parameters instead of three.

units_to_restore,
getstoragewrapper(master, MasterBranchConstrsUnit),
READ_AND_WRITE
)

#adding the first branching constraints
Expand Down
2 changes: 1 addition & 1 deletion src/Algorithm/colgen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function get_child_algorithms(algo::ColumnGeneration, reform::Reformulation)
end

function get_units_usage(algo::ColumnGeneration, reform::Reformulation)
units_usage = Tuple{AbstractModel,UnitType,UnitAccessMode}[]
units_usage = Tuple{AbstractModel,UnitType,UnitPermission}[]
master = getmaster(reform)
push!(units_usage, (master, MasterColumnsUnit, READ_AND_WRITE))
push!(units_usage, (master, PartialSolutionUnit, READ_ONLY))
Expand Down
8 changes: 4 additions & 4 deletions src/Algorithm/conquer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ in the input so that it is not obtained each time the conquer algorithm runs.
"""
struct ConquerInput <: AbstractInput
node::Node
units_to_restore::UnitsUsageDict
units_to_restore::UnitsUsage
end

getnode(input::ConquerInput) = input.node

ColunaBase.restore_from_records!(input::ConquerInput) = restore_from_records!(input.units_to_restore, input.node.recordids)
ColunaBase.restore_from_records!(input::ConquerInput) = restore_from_records!(input.units_to_restore, input.node.recordids)

"""
AbstractConquerAlgorithm
Expand All @@ -34,7 +34,7 @@ function run!(algo::AbstractConquerAlgorithm, env::Env, reform::Reformulation, i
error(string("Method run! which takes as parameters Reformulation and ConquerInput ",
"is not implemented for algorithm $algotype.")
)
end
end

# this function is needed in strong branching (to have a better screen logging)
isverbose(algo::AbstractConquerAlgorithm) = false
Expand All @@ -45,7 +45,7 @@ exploits_primal_solutions(algo::AbstractConquerAlgorithm) = false
# returns the optimization part of the output of the conquer algorithm
function apply_conquer_alg_to_node!(
node::Node, algo::AbstractConquerAlgorithm, env::Env, reform::Reformulation,
units_to_restore::UnitsUsageDict, opt_rtol::Float64 = Coluna.DEF_OPTIMALITY_RTOL,
units_to_restore::UnitsUsage, opt_rtol::Float64 = Coluna.DEF_OPTIMALITY_RTOL,
opt_atol::Float64 = Coluna.DEF_OPTIMALITY_ATOL
)
nodestate = getoptstate(node)
Expand Down
7 changes: 0 additions & 7 deletions src/Algorithm/data.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@

function ColunaBase.getstorageunit(form::AbstractModel, pair)
storagecont = get(form.storage.units, pair, nothing)
storagecont === nothing && error("No storage unit for pair $pair in $(typeof(form)) with id $(getuid(form)).")
return storagecont.storage_unit
end

function store_records!(form::Formulation, records::RecordsVector)
storagedict = form.storage.units
for (_, storagecont) in storagedict
Expand Down
11 changes: 6 additions & 5 deletions src/Algorithm/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ each child algorithm is applied.
get_child_algorithms(::AbstractAlgorithm, ::AbstractModel) = Tuple{AbstractAlgorithm, AbstractModel}[]

"""
get_units_usage(algo::AbstractAlgorithm, model::AbstractModel)::Vector{Tuple{AbstractModel, UnitType, UnitAccessMode}}
get_units_usage(algo::AbstractAlgorithm, model::AbstractModel)::Vector{Tuple{AbstractModel, UnitType, UnitPermission}}

Every algorithm should communicate the storage units it uses (so that these units
are created in the beginning) and the usage mode (read only or read-and-write). Usage mode is needed for
in order to restore units before running a worker algorithm.
"""
get_units_usage(algo::AbstractAlgorithm, model::AbstractModel) = Tuple{AbstractModel, UnitType, UnitAccessMode}[]
get_units_usage(algo::AbstractAlgorithm, model::AbstractModel) = Tuple{AbstractModel, UnitType, UnitPermission}[]

"""
run!(algo::AbstractAlgorithm, model::AbstractModel, input::AbstractInput)::AbstractOutput
Expand Down Expand Up @@ -114,11 +114,12 @@ exploits_primal_solutions(algo::AbstractOptimizationAlgorithm) = false
# this function collects storage units to restore for an algorithm and all its child worker algorithms,
# child manager algorithms are skipped, as their restore units themselves
function collect_units_to_restore!(
global_units_usage::UnitsUsageDict, algo::AbstractAlgorithm, model::AbstractModel
global_units_usage::UnitsUsage, algo::AbstractAlgorithm, model::AbstractModel
)
local_units_usage = get_units_usage(algo, model)
for (unit_model, unit_pair, unit_usage) in local_units_usage
add_unit_usage!(global_units_usage, unit_model, unit_pair, unit_usage)
for (unit_model, unit_type, unit_usage) in local_units_usage
storage = getstoragewrapper(unit_model, unit_type)
set_permission!(global_units_usage, storage, unit_usage)
end

child_algos = get_child_algorithms(algo, model)
Expand Down
4 changes: 2 additions & 2 deletions src/Algorithm/preprocessing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function get_units_usage(algo::PreprocessAlgorithm, form::Formulation)
end

function get_units_usage(algo::PreprocessAlgorithm, reform::Reformulation)
units_usage = Tuple{AbstractModel, UnitType, UnitAccessMode}[]
units_usage = Tuple{AbstractModel, UnitType, UnitPermission}[]
push!(units_usage, (reform, PreprocessingUnit, READ_AND_WRITE))

master = getmaster(reform)
Expand All @@ -188,7 +188,7 @@ function run!(algo::PreprocessAlgorithm, env::Env, reform::Reformulation, input:

unit = getstorageunit(reform, PreprocessingUnit)

infeasible = init_new_constraints!(algo, unit)
infeasible = init_new_constraints!(algo, unit)

master = getmaster(reform)
!infeasible && (infeasible = fix_local_partial_solution!(algo, unit, master))
Expand Down
4 changes: 2 additions & 2 deletions src/Algorithm/treesearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ mutable struct TreeSearchRuntimeData{Sense}
optstate::OptimizationState
exploitsprimalsolutions::Bool
Sense::Type{<:Coluna.AbstractSense}
conquer_units_to_restore::UnitsUsageDict
conquer_units_to_restore::UnitsUsage
worst_db_of_pruned_node::DualBound{Sense}
end

Expand All @@ -99,7 +99,7 @@ function TreeSearchRuntimeData(algo::TreeSearchAlgorithm, reform::Reformulation,
getmaster(reform), getoptstate(input), exploitsprimalsols, false
)

conquer_units_to_restore = UnitsUsageDict()
conquer_units_to_restore = UnitsUsage()
collect_units_to_restore!(conquer_units_to_restore, algo.conqueralg, reform)
# divide algorithms are always manager algorithms, so we do not need to restore storage units for them

Expand Down
9 changes: 5 additions & 4 deletions src/ColunaBase/ColunaBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Printf

# interface.jl
export AbstractModel, AbstractProblem, AbstractSense, AbstractMinSense, AbstractMaxSense,
AbstractSpace, AbstractPrimalSpace, AbstractDualSpace
AbstractSpace, AbstractPrimalSpace, AbstractDualSpace, getstorage

# nestedenum.jl
export NestedEnum, @nestedenum, @exported_nestedenum
Expand All @@ -29,9 +29,10 @@ export TerminationStatus, SolutionStatus, OPTIMAL, INFEASIBLE, TIME_LIMIT,

# Storages (TODO : clean)
export RecordsVector, UnitType, Storage, AbstractStorageUnit, AbstractRecord,
UnitsUsageDict, UnitAccessMode, READ_AND_WRITE, READ_ONLY, NOT_USED, StorageUnitWrapper,
add_unit_usage!, store_record!, restore_from_records!, getstorageunit, copy_records,
restore_from_record!, remove_records!, check_records_participation, record_type
UnitsUsage, UnitPermission, READ_AND_WRITE, READ_ONLY, NOT_USED, StorageUnitWrapper,
set_permission!, store_record!, restore_from_records!, copy_records,
restore_from_record!, remove_records!, check_records_participation, record_type,
getstorageunit, getstoragewrapper

include("interface.jl")
include("nestedenum.jl")
Expand Down
7 changes: 7 additions & 0 deletions src/ColunaBase/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ abstract type AbstractSpace end
abstract type AbstractPrimalSpace <: AbstractSpace end
abstract type AbstractDualSpace <: AbstractSpace end

# AbstractModel interface

"Return the storage of a model."
getstorage(m::AbstractModel) = error("Model of type $(typeof(m)) does not have getstorage implemented.")

# misc

function remove_until_last_point(str::String)
lastpointindex = findlast(isequal('.'), str)
shortstr = SubString(
Expand Down
Loading