Allow module to be precompiled

master
Alinson S. Xavier 4 years ago
parent 062ccf8b39
commit 529e6289ec

@ -2,12 +2,21 @@
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
__precompile__(false)
module MIPLearn
using PyCall
global miplearn = pyimport("miplearn")
global traceback = pyimport("traceback")
global DynamicLazyConstraintsComponent = PyNULL()
global JuMPSolver = PyNULL()
global MinPrecisionThreshold = PyNULL()
global miplearn = PyNULL()
global ObjectiveValueComponent = PyNULL()
global PrimalSolutionComponent = PyNULL()
global PyFileInstance = PyNULL()
global PyJuMPInstance = PyNULL()
global StaticLazyConstraintsComponent = PyNULL()
global traceback = PyNULL()
global UserCutsComponent = PyNULL()
include("utils/log.jl")
include("utils/exceptions.jl")
@ -19,12 +28,19 @@ include("solvers/learning.jl")
include("solvers/macros.jl")
include("utils/benchmark.jl")
DynamicLazyConstraintsComponent = miplearn.DynamicLazyConstraintsComponent
UserCutsComponent = miplearn.UserCutsComponent
ObjectiveValueComponent = miplearn.ObjectiveValueComponent
PrimalSolutionComponent = miplearn.PrimalSolutionComponent
StaticLazyConstraintsComponent = miplearn.StaticLazyConstraintsComponent
MinPrecisionThreshold = miplearn.MinPrecisionThreshold
function __init__()
copy!(miplearn, pyimport("miplearn"))
copy!(traceback, pyimport("traceback"))
copy!(DynamicLazyConstraintsComponent, miplearn.DynamicLazyConstraintsComponent)
copy!(UserCutsComponent, miplearn.UserCutsComponent)
copy!(ObjectiveValueComponent, miplearn.ObjectiveValueComponent)
copy!(PrimalSolutionComponent, miplearn.PrimalSolutionComponent)
copy!(StaticLazyConstraintsComponent, miplearn.StaticLazyConstraintsComponent)
copy!(MinPrecisionThreshold, miplearn.MinPrecisionThreshold)
__init_PyFileInstance__()
__init_PyJuMPInstance__()
__init_JuMPSolver__()
end
export DynamicLazyConstraintsComponent,
UserCutsComponent,

@ -3,56 +3,58 @@
# Released under the modified BSD license. See COPYING.md for more details.
@pydef mutable struct PyFileInstance <: miplearn.Instance
function __init__(self, filename)
self.filename = filename
self.loaded = nothing
self.samples = nothing
end
function __init_PyFileInstance__()
@pydef mutable struct Class <: miplearn.Instance
function __init__(self, filename)
self.filename = filename
self.loaded = nothing
self.samples = nothing
end
function to_model(self)
return self.loaded.py.to_model()
end
function to_model(self)
return self.loaded.py.to_model()
end
function get_instance_features(self)
return self.loaded.py.get_instance_features()
end
function get_instance_features(self)
return self.loaded.py.get_instance_features()
end
function get_variable_features(self, var_name)
return self.loaded.py.get_variable_features(var_name)
end
function get_variable_features(self, var_name)
return self.loaded.py.get_variable_features(var_name)
end
function get_variable_category(self, var_name)
return self.loaded.py.get_variable_category(var_name)
end
function get_variable_category(self, var_name)
return self.loaded.py.get_variable_category(var_name)
end
function get_constraint_features(self, cname)
return self.loaded.py.get_constraint_features(cname)
end
function get_constraint_features(self, cname)
return self.loaded.py.get_constraint_features(cname)
end
function get_constraint_category(self, cname)
return self.loaded.py.get_constraint_category(cname)
end
function get_constraint_category(self, cname)
return self.loaded.py.get_constraint_category(cname)
end
function load(self)
if self.loaded === nothing
self.loaded = load_instance(self.filename)
self.samples = self.loaded.py.samples
function load(self)
if self.loaded === nothing
self.loaded = load_instance(self.filename)
self.samples = self.loaded.py.samples
end
end
end
function free(self)
self.loaded = nothing
self.samples = nothing
end
function free(self)
self.loaded = nothing
self.samples = nothing
end
function flush(self)
self.loaded.py.samples = self.samples
save(self.filename, self.loaded)
function flush(self)
self.loaded.py.samples = self.samples
save(self.filename, self.loaded)
end
end
copy!(PyFileInstance, Class)
end
struct FileInstance <: Instance
py::PyCall.PyObject
filename::AbstractString

@ -5,45 +5,47 @@
using JuMP
using JLD2
function __init_PyJuMPInstance__()
@pydef mutable struct Class <: miplearn.Instance
function __init__(self, model)
init_miplearn_ext(model)
self.model = model
self.samples = []
end
@pydef mutable struct PyJuMPInstance <: miplearn.Instance
function __init__(self, model)
init_miplearn_ext(model)
self.model = model
self.samples = []
end
function to_model(self)
return self.model
end
function to_model(self)
return self.model
end
function get_instance_features(self)
return self.model.ext[:miplearn][:instance_features]
end
function get_instance_features(self)
return self.model.ext[:miplearn][:instance_features]
end
function get_variable_features(self, var_name)
model = self.model
v = variable_by_name(model, var_name)
return get(model.ext[:miplearn][:variable_features], v, nothing)
end
function get_variable_features(self, var_name)
model = self.model
v = variable_by_name(model, var_name)
return get(model.ext[:miplearn][:variable_features], v, nothing)
end
function get_variable_category(self, var_name)
model = self.model
v = variable_by_name(model, var_name)
return get(model.ext[:miplearn][:variable_categories], v, nothing)
end
function get_variable_category(self, var_name)
model = self.model
v = variable_by_name(model, var_name)
return get(model.ext[:miplearn][:variable_categories], v, nothing)
end
function get_constraint_features(self, cname)
model = self.model
c = constraint_by_name(model, cname)
return get(model.ext[:miplearn][:constraint_features], c, nothing)
end
function get_constraint_features(self, cname)
model = self.model
c = constraint_by_name(model, cname)
return get(model.ext[:miplearn][:constraint_features], c, nothing)
end
function get_constraint_category(self, cname)
model = self.model
c = constraint_by_name(model, cname)
return get(model.ext[:miplearn][:constraint_categories], c, nothing)
function get_constraint_category(self, cname)
model = self.model
c = constraint_by_name(model, cname)
return get(model.ext[:miplearn][:constraint_categories], c, nothing)
end
end
copy!(PyJuMPInstance, Class)
end

@ -467,144 +467,147 @@ function get_constraints(
end
@pydef mutable struct JuMPSolver <: miplearn.solvers.internal.InternalSolver
function __init__(self, optimizer_factory)
self.data = JuMPSolverData(
optimizer_factory,
Dict(), # varname_to_var
Dict(), # cname_to_constr
nothing, # instance
nothing, # model
[], # bin_vars
Dict(), # solution
[], # reduced_costs
Dict(), # dual_values
)
end
function __init_JuMPSolver__()
@pydef mutable struct Class <: miplearn.solvers.internal.InternalSolver
function __init__(self, optimizer_factory)
self.data = JuMPSolverData(
optimizer_factory,
Dict(), # varname_to_var
Dict(), # cname_to_constr
nothing, # instance
nothing, # model
[], # bin_vars
Dict(), # solution
[], # reduced_costs
Dict(), # dual_values
)
end
function add_constraints(self, cf)
lhs = cf.lhs
if lhs isa Matrix
# Undo incorrect automatic conversion performed by PyCall
lhs = [col[:] for col in eachcol(lhs)]
function add_constraints(self, cf)
lhs = cf.lhs
if lhs isa Matrix
# Undo incorrect automatic conversion performed by PyCall
lhs = [col[:] for col in eachcol(lhs)]
end
add_constraints(
self.data,
lhs=lhs,
rhs=cf.rhs,
senses=cf.senses,
names=cf.names,
)
end
add_constraints(
self.data,
lhs=lhs,
rhs=cf.rhs,
senses=cf.senses,
names=cf.names,
)
end
function are_constraints_satisfied(self, cf; tol=1e-5)
lhs = cf.lhs
if lhs isa Matrix
# Undo incorrect automatic conversion performed by PyCall
lhs = [col[:] for col in eachcol(lhs)]
function are_constraints_satisfied(self, cf; tol=1e-5)
lhs = cf.lhs
if lhs isa Matrix
# Undo incorrect automatic conversion performed by PyCall
lhs = [col[:] for col in eachcol(lhs)]
end
return are_constraints_satisfied(
self.data,
lhs=lhs,
rhs=cf.rhs,
senses=cf.senses,
tol=tol,
)
end
return are_constraints_satisfied(
self.data,
lhs=lhs,
rhs=cf.rhs,
senses=cf.senses,
tol=tol,
)
end
build_test_instance_infeasible(self) =
build_test_instance_infeasible()
build_test_instance_infeasible(self) =
build_test_instance_infeasible()
build_test_instance_knapsack(self) =
build_test_instance_knapsack()
build_test_instance_knapsack(self) =
build_test_instance_knapsack()
clone(self) = JuMPSolver(self.data.optimizer_factory)
clone(self) = JuMPSolver(self.data.optimizer_factory)
fix(self, solution) =
fix!(self.data, solution)
fix(self, solution) =
fix!(self.data, solution)
get_solution(self) =
isempty(self.data.solution) ? nothing : self.data.solution
get_solution(self) =
isempty(self.data.solution) ? nothing : self.data.solution
get_constraints(
self;
with_static=true,
with_sa=true,
with_lhs=true,
) = get_constraints(
self.data,
with_static=with_static,
)
get_constraints(
self;
with_static=true,
with_sa=true,
with_lhs=true,
) = get_constraints(
self.data,
with_static=with_static,
)
get_constraint_attrs(self) = [
# "basis_status",
"categories",
"dual_values",
"lazy",
"lhs",
"names",
"rhs",
# "sa_rhs_down",
# "sa_rhs_up",
"senses",
# "slacks",
"user_features",
]
get_constraint_attrs(self) = [
# "basis_status",
"categories",
"dual_values",
"lazy",
"lhs",
"names",
"rhs",
# "sa_rhs_down",
# "sa_rhs_up",
"senses",
# "slacks",
"user_features",
]
get_variables(
self;
with_static=true,
with_sa=true,
) = get_variables(self.data; with_static=with_static)
get_variable_attrs(self) = [
"names",
# "basis_status",
"categories",
"lower_bounds",
"obj_coeffs",
"reduced_costs",
# "sa_lb_down",
# "sa_lb_up",
# "sa_obj_down",
# "sa_obj_up",
# "sa_ub_down",
# "sa_ub_up",
"types",
"upper_bounds",
"user_features",
"values",
]
get_variables(
self;
with_static=true,
with_sa=true,
) = get_variables(self.data; with_static=with_static)
get_variable_attrs(self) = [
"names",
# "basis_status",
"categories",
"lower_bounds",
"obj_coeffs",
"reduced_costs",
# "sa_lb_down",
# "sa_lb_up",
# "sa_obj_down",
# "sa_obj_up",
# "sa_ub_down",
# "sa_ub_up",
"types",
"upper_bounds",
"user_features",
"values",
]
is_infeasible(self) =
is_infeasible(self.data)
is_infeasible(self) =
is_infeasible(self.data)
remove_constraints(self, names) =
remove_constraints(
remove_constraints(self, names) =
remove_constraints(
self.data,
[n for n in names],
)
set_instance(self, instance, model=nothing) =
set_instance!(self.data, instance, model=model)
set_warm_start(self, solution) =
set_warm_start!(self.data, solution)
solve(
self;
tee=false,
iteration_cb=nothing,
lazy_cb=nothing,
user_cut_cb=nothing,
) = solve(
self.data,
[n for n in names],
tee=tee,
iteration_cb=iteration_cb,
)
set_instance(self, instance, model=nothing) =
set_instance!(self.data, instance, model=model)
set_warm_start(self, solution) =
set_warm_start!(self.data, solution)
solve(
self;
tee=false,
iteration_cb=nothing,
lazy_cb=nothing,
user_cut_cb=nothing,
) = solve(
self.data,
tee=tee,
iteration_cb=iteration_cb,
)
solve_lp(self; tee=false) =
solve_lp(self.data, tee=tee)
solve_lp(self; tee=false) =
solve_lp(self.data, tee=tee)
end
copy!(JuMPSolver, Class)
end

Loading…
Cancel
Save