From 3b0fc2def6232eecc7dc8cd84955143fe39e47b0 Mon Sep 17 00:00:00 2001 From: Eric <5846501+ericphanson@users.noreply.github.com> Date: Sat, 31 Aug 2019 23:57:20 +0100 Subject: [PATCH 1/5] Remove global `id_to_variables` --- src/Convex.jl | 7 ++++--- src/atoms/affine/stack.jl | 2 +- src/conic_form.jl | 9 ++++++++- src/problems.jl | 8 +++++--- src/solution.jl | 20 +++++++++++--------- src/variable.jl | 32 -------------------------------- src/variable_conic_form.jl | 26 ++++++++++++++++++++++++++ test/test_utilities.jl | 6 ++---- 8 files changed, 57 insertions(+), 53 deletions(-) create mode 100644 src/variable_conic_form.jl diff --git a/src/Convex.jl b/src/Convex.jl index 64dea6779..4d37fe15c 100644 --- a/src/Convex.jl +++ b/src/Convex.jl @@ -9,8 +9,11 @@ global DEFAULT_SOLVER = nothing ### modeling framework include("dcp.jl") include("expressions.jl") -include("conic_form.jl") +# need to define `Variable` before `UniqueConicForms` include("variable.jl") +include("conic_form.jl") +# need to define `conic_form!` for `Variable`s after `UniqueConicForms` +include("variable_conic_form.jl") include("constant.jl") include("constraints/constraints.jl") include("constraints/signs_and_sets.jl") @@ -85,8 +88,6 @@ include("utilities/broadcast.jl") #Temporary workaround for memory leak (https://github.com/JuliaOpt/Convex.jl/issues/83) function clearmemory() - global id_to_variables - empty!(id_to_variables) global conic_constr_to_constr empty!(conic_constr_to_constr) GC.gc() diff --git a/src/atoms/affine/stack.jl b/src/atoms/affine/stack.jl index 124e8aa76..7420c433a 100644 --- a/src/atoms/affine/stack.jl +++ b/src/atoms/affine/stack.jl @@ -54,7 +54,7 @@ function conic_form!(x::HcatAtom, unique_conic_forms::UniqueConicForms=UniqueCon if id == objectid(:constant) variable_to_sizes[id] = 1 else - variable_to_sizes[id] = length(id_to_variables[id]) + variable_to_sizes[id] = length(unique_conic_forms.id_to_variables[id]) end end end diff --git a/src/conic_form.jl b/src/conic_form.jl index 051c6a146..f700241c9 100644 --- a/src/conic_form.jl +++ b/src/conic_form.jl @@ -106,15 +106,18 @@ const UniqueExpMap = OrderedDict{Tuple{Symbol, UInt64}, ConicObj} const UniqueConstrMap = OrderedDict{Tuple{Symbol, UInt64}, Int} # records each ConicConstr created const UniqueConstrList = Vector{ConicConstr} +# map variables' hash to the variable itself +const IdToVariables = OrderedDict{UInt64, Variable} # UniqueConicForms caches all the conic forms of expressions we've parsed so far struct UniqueConicForms exp_map::UniqueExpMap constr_map::UniqueConstrMap constr_list::UniqueConstrList + id_to_variables::IdToVariables end -UniqueConicForms() = UniqueConicForms(UniqueExpMap(), UniqueConstrMap(), ConicConstr[]) +UniqueConicForms() = UniqueConicForms(UniqueExpMap(), UniqueConstrMap(), ConicConstr[], IdToVariables()) function has_conic_form(conic_forms::UniqueConicForms, exp::AbstractExpr) return haskey(conic_forms.exp_map, (exp.head, exp.id_hash)) @@ -145,3 +148,7 @@ function cache_conic_form!(conic_forms::UniqueConicForms, constr::Constraint, ne conic_forms.constr_map[(constr.head, constr.id_hash)] = 0 append!(conic_forms.constr_list, new_conic_forms) end + +function cache_conic_form!(conic_forms::UniqueConicForms, var::Variable) + conic_forms.id_to_variables[var.id_hash] = var +end diff --git a/src/problems.jl b/src/problems.jl index 1cc9d88f6..04bddd303 100644 --- a/src/problems.jl +++ b/src/problems.jl @@ -52,7 +52,7 @@ end # constr_size: m # var_to_ranges a dictionary mapping from variable id to (start_index, end_index) # where start_index and end_index are the start and end indexes of the variable in A -function find_variable_ranges(constraints) +function find_variable_ranges(constraints, id_to_variables) index = 0 constr_size = 0 var_to_ranges = Dict{UInt64, Tuple{Int, Int}}() @@ -127,10 +127,12 @@ function conic_problem(p::Problem) unique_conic_forms = UniqueConicForms() objective, objective_var_id = conic_form!(p, unique_conic_forms) constraints = unique_conic_forms.constr_list + id_to_variables = unique_conic_forms.id_to_variables + # var_to_ranges maps from variable id to the (start_index, stop_index) pairs of the columns of A corresponding to that variable # var_size is the sum of the lengths of all variables in the problem # constr_size is the sum of the lengths of all constraints in the problem - var_size, constr_size, var_to_ranges = find_variable_ranges(constraints) + var_size, constr_size, var_to_ranges = find_variable_ranges(constraints, id_to_variables) c = spzeros(var_size, 1) objective_range = var_to_ranges[objective_var_id] c[objective_range[1]:objective_range[2]] .= 1 @@ -188,7 +190,7 @@ function conic_problem(p::Problem) c = -c end - return c, A, b, cones, var_to_ranges, vartypes, constraints + return c, A, b, cones, var_to_ranges, vartypes, constraints, id_to_variables end Problem(head::Symbol, objective::AbstractExpr, constraints::Constraint...) = diff --git a/src/solution.jl b/src/solution.jl index cb3e27419..a71e44b4a 100644 --- a/src/solution.jl +++ b/src/solution.jl @@ -33,20 +33,20 @@ function solve!(problem::Problem; vex = vexity(problem) end - c, A, b, cones, var_to_ranges, vartypes, conic_constraints = conic_problem(problem) + c, A, b, cones, var_to_ranges, vartypes, conic_constraints, id_to_variables = conic_problem(problem) # load MPB conic problem m = problem.model load_problem!(m, c, A, b, cones, vartypes) if warmstart - set_warmstart!(m, problem, length(c), var_to_ranges) + set_warmstart!(m, problem, length(c), var_to_ranges, id_to_variables) end # optimize MPB conic problem MathProgBase.optimize!(m) # populate the status, the primal (and possibly dual) solution # and the primal (and possibly dual) variables with values - populate_solution!(m, problem, var_to_ranges, conic_constraints) + populate_solution!(m, problem, var_to_ranges, conic_constraints, id_to_variables) if problem.status != :Optimal && verbose @warn "Problem status $(problem.status); solution may be inaccurate." end @@ -55,7 +55,8 @@ end function set_warmstart!(m::MathProgBase.AbstractConicModel, problem::Problem, n::Int, # length of primal (conic) solution - var_to_ranges) + var_to_ranges, + id_to_variables) # use previously cached solution, if any, try primal = problem.solution.primal @@ -73,7 +74,7 @@ function set_warmstart!(m::MathProgBase.AbstractConicModel, end # grab any variables whose values the user may be trying to set - load_primal_solution!(primal, var_to_ranges) + load_primal_solution!(primal, var_to_ranges, id_to_variables) # notify the model that we're trying to warmstart try @@ -105,7 +106,8 @@ end function populate_solution!(m::MathProgBase.AbstractConicModel, problem::Problem, var_to_ranges, - conic_constraints) + conic_constraints, + id_to_variables) dual = try MathProgBase.getdual(m) catch @@ -130,7 +132,7 @@ function populate_solution!(m::MathProgBase.AbstractConicModel, problem.solution = Solution(solution, dual, MathProgBase.status(m), objective) end - populate_variables!(problem, var_to_ranges) + populate_variables!(problem, var_to_ranges, id_to_variables) if problem.solution.has_dual populate_duals!(conic_constraints, problem.solution.dual) @@ -148,7 +150,7 @@ function populate_solution!(m::MathProgBase.AbstractConicModel, problem end -function populate_variables!(problem::Problem, var_to_ranges::Dict{UInt64, Tuple{Int, Int}}) +function populate_variables!(problem::Problem, var_to_ranges::Dict{UInt64, Tuple{Int, Int}}, id_to_variables) x = problem.solution.primal for (id, (start_index, end_index)) in var_to_ranges var = id_to_variables[id] @@ -174,7 +176,7 @@ end # TODO: it would be super cool to grab the other expressions that appear in the primal solution vector, # get their `expression_to_range`, # and populate them too using `evaluate` -function load_primal_solution!(primal::Array{Float64,1}, var_to_ranges::Dict{UInt64, Tuple{Int, Int}}) +function load_primal_solution!(primal::Array{Float64,1}, var_to_ranges::Dict{UInt64, Tuple{Int, Int}}, id_to_variables) for (id, (start_index, end_index)) in var_to_ranges var = id_to_variables[id] if var.value !== nothing diff --git a/src/variable.jl b/src/variable.jl index d9d549dfe..181c9836b 100644 --- a/src/variable.jl +++ b/src/variable.jl @@ -19,7 +19,6 @@ mutable struct Variable <: AbstractExpr function Variable(size::Tuple{Int, Int}, sign::Sign=NoSign(), sets::Symbol...) this = new(:variable, 0, nothing, size, AffineVexity(), sign, Symbol[sets...]) this.id_hash = objectid(this) - id_to_variables[this.id_hash] = this return this end @@ -53,11 +52,6 @@ function HermitianSemidefinite(m::Integer, n::Integer) end end -# global map from unique variable ids to variables. -# the expression tree will only utilize variable ids during construction -# full information of the variables will be needed during stuffing -# and after solving to populate the variables with values -const id_to_variables = Dict{UInt64, Variable}() function vexity(x::Variable) return x.vexity @@ -86,32 +80,6 @@ function imag_conic_form(x::Variable) end end -function conic_form!(x::Variable, unique_conic_forms::UniqueConicForms=UniqueConicForms()) - if !has_conic_form(unique_conic_forms, x) - if vexity(x) == ConstVexity() - # do exactly what we would for a constant - objective = ConicObj() - objective[objectid(:constant)] = (vec([real(x.value);]),vec([imag(x.value);])) - cache_conic_form!(unique_conic_forms, x, objective) - else - objective = ConicObj() - vec_size = length(x) - - objective[x.id_hash] = (real_conic_form(x), imag_conic_form(x)) - objective[objectid(:constant)] = (spzeros(vec_size, 1), spzeros(vec_size, 1)) - # placeholder values in unique constraints prevent infinite recursion depth - cache_conic_form!(unique_conic_forms, x, objective) - if !(x.sign == NoSign() || x.sign == ComplexSign()) - conic_form!(x.sign, x, unique_conic_forms) - end - for set in x.sets - conic_form!(set, x, unique_conic_forms) - end - end - end - return get_conic_form(unique_conic_forms, x) -end - # fix variables to hold them at their current value, and free them afterwards function fix!(x::Variable) x.value === nothing && error("This variable has no value yet; cannot fix value to nothing!") diff --git a/src/variable_conic_form.jl b/src/variable_conic_form.jl new file mode 100644 index 000000000..81948c7b0 --- /dev/null +++ b/src/variable_conic_form.jl @@ -0,0 +1,26 @@ +function conic_form!(x::Variable, unique_conic_forms::UniqueConicForms=UniqueConicForms()) + if !has_conic_form(unique_conic_forms, x) + cache_conic_form!(unique_conic_forms, x) + if vexity(x) == ConstVexity() + # do exactly what we would for a constant + objective = ConicObj() + objective[objectid(:constant)] = (vec([real(x.value);]),vec([imag(x.value);])) + cache_conic_form!(unique_conic_forms, x, objective) + else + objective = ConicObj() + vec_size = length(x) + + objective[x.id_hash] = (real_conic_form(x), imag_conic_form(x)) + objective[objectid(:constant)] = (spzeros(vec_size, 1), spzeros(vec_size, 1)) + # placeholder values in unique constraints prevent infinite recursion depth + cache_conic_form!(unique_conic_forms, x, objective) + if !(x.sign == NoSign() || x.sign == ComplexSign()) + conic_form!(x.sign, x, unique_conic_forms) + end + for set in x.sets + conic_form!(set, x, unique_conic_forms) + end + end + end + return get_conic_form(unique_conic_forms, x) +end \ No newline at end of file diff --git a/test/test_utilities.jl b/test/test_utilities.jl index 8c5a7b75c..dc8830fd1 100644 --- a/test/test_utilities.jl +++ b/test/test_utilities.jl @@ -1,19 +1,17 @@ @testset "Utilities" begin @testset "clearmemory" begin - # solve a problem to populate globals + # solve a problem to populate global x = Variable() p = minimize(-x, [x <= 0]) @test vexity(p) == AffineVexity() solve!(p, solvers[1]) - @test !isempty(Convex.id_to_variables) @test !isempty(Convex.conic_constr_to_constr) Convex.clearmemory() - # check they are cleared - @test isempty(Convex.id_to_variables) + # check it is cleared @test isempty(Convex.conic_constr_to_constr) end From 487c5c9a17cebc967c7e37422daaf12a1776d073 Mon Sep 17 00:00:00 2001 From: Eric <5846501+ericphanson@users.noreply.github.com> Date: Sun, 1 Sep 2019 00:19:23 +0100 Subject: [PATCH 2/5] Use better name for method --- src/conic_form.jl | 2 +- src/variable_conic_form.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conic_form.jl b/src/conic_form.jl index f700241c9..0d01c054e 100644 --- a/src/conic_form.jl +++ b/src/conic_form.jl @@ -149,6 +149,6 @@ function cache_conic_form!(conic_forms::UniqueConicForms, constr::Constraint, ne append!(conic_forms.constr_list, new_conic_forms) end -function cache_conic_form!(conic_forms::UniqueConicForms, var::Variable) +function add_to_id_to_variables!(conic_forms::UniqueConicForms, var::Variable) conic_forms.id_to_variables[var.id_hash] = var end diff --git a/src/variable_conic_form.jl b/src/variable_conic_form.jl index 81948c7b0..e14c7db34 100644 --- a/src/variable_conic_form.jl +++ b/src/variable_conic_form.jl @@ -1,6 +1,6 @@ function conic_form!(x::Variable, unique_conic_forms::UniqueConicForms=UniqueConicForms()) if !has_conic_form(unique_conic_forms, x) - cache_conic_form!(unique_conic_forms, x) + add_to_id_to_variables!(unique_conic_forms, x) if vexity(x) == ConstVexity() # do exactly what we would for a constant objective = ConicObj() From 09e278c1f315c666967c17d855e3a0c7a77aef21 Mon Sep 17 00:00:00 2001 From: Eric <5846501+ericphanson@users.noreply.github.com> Date: Sun, 1 Sep 2019 15:22:56 +0100 Subject: [PATCH 3/5] Remove the other global, `conic_constr_to_constr` --- src/Convex.jl | 5 ++--- src/conic_form.jl | 5 +++-- src/constraints/constraints.jl | 10 +++++----- src/problems.jl | 3 ++- src/solution.jl | 11 ++++++----- test/test_utilities.jl | 13 +------------ 6 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/Convex.jl b/src/Convex.jl index 4d37fe15c..9067d4694 100644 --- a/src/Convex.jl +++ b/src/Convex.jl @@ -86,10 +86,9 @@ include("utilities/show.jl") include("utilities/iteration.jl") include("utilities/broadcast.jl") -#Temporary workaround for memory leak (https://github.com/JuliaOpt/Convex.jl/issues/83) +# Deprecated workaround for memory leak (https://github.com/JuliaOpt/Convex.jl/issues/83) function clearmemory() - global conic_constr_to_constr - empty!(conic_constr_to_constr) + Base.depwarn("Convex.clearmemory() is deprecated, as the memory leak it works around has been closed. See https://github.com/JuliaOpt/Convex.jl/issues/83. Use `GC.gc()` for a literal translation of the remaining functionality.", :clearmemory ) GC.gc() end diff --git a/src/conic_form.jl b/src/conic_form.jl index 0d01c054e..b5ba98dac 100644 --- a/src/conic_form.jl +++ b/src/conic_form.jl @@ -108,16 +108,17 @@ const UniqueConstrMap = OrderedDict{Tuple{Symbol, UInt64}, Int} const UniqueConstrList = Vector{ConicConstr} # map variables' hash to the variable itself const IdToVariables = OrderedDict{UInt64, Variable} - +const ConicConstrToConstr = Dict{ConicConstr, Constraint} # UniqueConicForms caches all the conic forms of expressions we've parsed so far struct UniqueConicForms exp_map::UniqueExpMap constr_map::UniqueConstrMap constr_list::UniqueConstrList id_to_variables::IdToVariables + conic_constr_to_constr::ConicConstrToConstr end -UniqueConicForms() = UniqueConicForms(UniqueExpMap(), UniqueConstrMap(), ConicConstr[], IdToVariables()) +UniqueConicForms() = UniqueConicForms(UniqueExpMap(), UniqueConstrMap(), ConicConstr[], IdToVariables(), ConicConstrToConstr()) function has_conic_form(conic_forms::UniqueConicForms, exp::AbstractExpr) return haskey(conic_forms.exp_map, (exp.head, exp.id_hash)) diff --git a/src/constraints/constraints.jl b/src/constraints/constraints.jl index eab3f90a3..de127119e 100644 --- a/src/constraints/constraints.jl +++ b/src/constraints/constraints.jl @@ -2,7 +2,7 @@ import Base.==, Base.<=, Base.>=, Base.<, Base.> export EqConstraint, LtConstraint, GtConstraint export ==, <=, >= -const conic_constr_to_constr = Dict{ConicConstr, Constraint}() +# const conic_constr_to_constr = Dict{ConicConstr, Constraint}() ### Linear equality constraint mutable struct EqConstraint <: Constraint @@ -42,14 +42,14 @@ function conic_form!(c::EqConstraint, unique_conic_forms::UniqueConicForms=Uniqu expr = c.lhs - c.rhs objective = conic_form!(expr, unique_conic_forms) new_constraint = ConicConstr([objective], :Zero, [c.size[1] * c.size[2]]) - conic_constr_to_constr[new_constraint] = c + unique_conic_forms.conic_constr_to_constr[new_constraint] = c else real_expr = real(c.lhs - c.rhs) imag_expr = imag(c.lhs - c.rhs) real_objective = conic_form!(real_expr, unique_conic_forms) imag_objective = conic_form!(imag_expr, unique_conic_forms) new_constraint = ConicConstr([real_objective, imag_objective], :Zero, [c.size[1] * c.size[2], c.size[1] * c.size[2]]) - conic_constr_to_constr[new_constraint] = c + unique_conic_forms.conic_constr_to_constr[new_constraint] = c end cache_conic_form!(unique_conic_forms, c, new_constraint) end @@ -100,7 +100,7 @@ function conic_form!(c::LtConstraint, unique_conic_forms::UniqueConicForms=Uniqu expr = c.rhs - c.lhs objective = conic_form!(expr, unique_conic_forms) new_constraint = ConicConstr([objective], :NonNeg, [c.size[1] * c.size[2]]) - conic_constr_to_constr[new_constraint] = c + unique_conic_forms.conic_constr_to_constr[new_constraint] = c cache_conic_form!(unique_conic_forms, c, new_constraint) end return get_conic_form(unique_conic_forms, c) @@ -152,7 +152,7 @@ function conic_form!(c::GtConstraint, unique_conic_forms::UniqueConicForms=Uniqu expr = c.lhs - c.rhs objective = conic_form!(expr, unique_conic_forms) new_constraint = ConicConstr([objective], :NonNeg, [c.size[1] * c.size[2]]) - conic_constr_to_constr[new_constraint] = c + unique_conic_forms.conic_constr_to_constr[new_constraint] = c cache_conic_form!(unique_conic_forms, c, new_constraint) end return get_conic_form(unique_conic_forms, c) diff --git a/src/problems.jl b/src/problems.jl index 04bddd303..3e5bf81ec 100644 --- a/src/problems.jl +++ b/src/problems.jl @@ -127,6 +127,7 @@ function conic_problem(p::Problem) unique_conic_forms = UniqueConicForms() objective, objective_var_id = conic_form!(p, unique_conic_forms) constraints = unique_conic_forms.constr_list + conic_constr_to_constr = unique_conic_forms.conic_constr_to_constr id_to_variables = unique_conic_forms.id_to_variables # var_to_ranges maps from variable id to the (start_index, stop_index) pairs of the columns of A corresponding to that variable @@ -190,7 +191,7 @@ function conic_problem(p::Problem) c = -c end - return c, A, b, cones, var_to_ranges, vartypes, constraints, id_to_variables + return c, A, b, cones, var_to_ranges, vartypes, constraints, id_to_variables, conic_constr_to_constr end Problem(head::Symbol, objective::AbstractExpr, constraints::Constraint...) = diff --git a/src/solution.jl b/src/solution.jl index a71e44b4a..30e024688 100644 --- a/src/solution.jl +++ b/src/solution.jl @@ -33,7 +33,7 @@ function solve!(problem::Problem; vex = vexity(problem) end - c, A, b, cones, var_to_ranges, vartypes, conic_constraints, id_to_variables = conic_problem(problem) + c, A, b, cones, var_to_ranges, vartypes, conic_constraints, id_to_variables, conic_constr_to_constr = conic_problem(problem) # load MPB conic problem m = problem.model @@ -46,7 +46,7 @@ function solve!(problem::Problem; # populate the status, the primal (and possibly dual) solution # and the primal (and possibly dual) variables with values - populate_solution!(m, problem, var_to_ranges, conic_constraints, id_to_variables) + populate_solution!(m, problem, var_to_ranges, conic_constraints, id_to_variables, conic_constr_to_constr) if problem.status != :Optimal && verbose @warn "Problem status $(problem.status); solution may be inaccurate." end @@ -107,7 +107,8 @@ function populate_solution!(m::MathProgBase.AbstractConicModel, problem::Problem, var_to_ranges, conic_constraints, - id_to_variables) + id_to_variables, + conic_constr_to_constr) dual = try MathProgBase.getdual(m) catch @@ -135,7 +136,7 @@ function populate_solution!(m::MathProgBase.AbstractConicModel, populate_variables!(problem, var_to_ranges, id_to_variables) if problem.solution.has_dual - populate_duals!(conic_constraints, problem.solution.dual) + populate_duals!(conic_constraints, problem.solution.dual, conic_constr_to_constr) end # minimize -> maximize @@ -190,7 +191,7 @@ function load_primal_solution!(primal::Array{Float64,1}, var_to_ranges::Dict{UIn end end -function populate_duals!(constraints::Array{ConicConstr}, dual::Vector) +function populate_duals!(constraints::Array{ConicConstr}, dual::Vector, conic_constr_to_constr) constr_index = 1 for constraint in constraints # conic_constr_to_constr only has keys for conic constraints with a single objective diff --git a/test/test_utilities.jl b/test/test_utilities.jl index dc8830fd1..9f8a5fb4f 100644 --- a/test/test_utilities.jl +++ b/test/test_utilities.jl @@ -1,18 +1,7 @@ @testset "Utilities" begin @testset "clearmemory" begin - # solve a problem to populate global - x = Variable() - p = minimize(-x, [x <= 0]) - @test vexity(p) == AffineVexity() - solve!(p, solvers[1]) - - @test !isempty(Convex.conic_constr_to_constr) - - Convex.clearmemory() - - # check it is cleared - @test isempty(Convex.conic_constr_to_constr) + @test_deprecated Convex.clearmemory() end @testset "ConicObj" for T = [UInt32, UInt64] From 86f5067625d899e506a1fb2f49efb019c7217a2b Mon Sep 17 00:00:00 2001 From: Eric <5846501+ericphanson@users.noreply.github.com> Date: Sun, 1 Sep 2019 20:45:29 +0100 Subject: [PATCH 4/5] Remove `GC.gc()` from `Convex.clearmemory()` --- src/Convex.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Convex.jl b/src/Convex.jl index 9067d4694..11075776b 100644 --- a/src/Convex.jl +++ b/src/Convex.jl @@ -88,8 +88,7 @@ include("utilities/broadcast.jl") # Deprecated workaround for memory leak (https://github.com/JuliaOpt/Convex.jl/issues/83) function clearmemory() - Base.depwarn("Convex.clearmemory() is deprecated, as the memory leak it works around has been closed. See https://github.com/JuliaOpt/Convex.jl/issues/83. Use `GC.gc()` for a literal translation of the remaining functionality.", :clearmemory ) - GC.gc() + Base.depwarn("Convex.clearmemory() is deprecated, as the memory leak it works around has been closed (in https://github.com/JuliaOpt/Convex.jl/pull/322). This function no longer does anything and will be removed in a future Convex.jl release.", :clearmemory ) end end From 26f73e969127fd3c5f6fda3ba272517f9011e649 Mon Sep 17 00:00:00 2001 From: Eric <5846501+ericphanson@users.noreply.github.com> Date: Sun, 1 Sep 2019 22:08:18 +0100 Subject: [PATCH 5/5] Remove commented line --- src/constraints/constraints.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/constraints/constraints.jl b/src/constraints/constraints.jl index de127119e..304e1fee5 100644 --- a/src/constraints/constraints.jl +++ b/src/constraints/constraints.jl @@ -2,8 +2,6 @@ import Base.==, Base.<=, Base.>=, Base.<, Base.> export EqConstraint, LtConstraint, GtConstraint export ==, <=, >= -# const conic_constr_to_constr = Dict{ConicConstr, Constraint}() - ### Linear equality constraint mutable struct EqConstraint <: Constraint head::Symbol