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

Julia 0.7 #100

Merged
merged 17 commits into from
May 6, 2018
Merged
Show file tree
Hide file tree
Changes from 13 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
9 changes: 6 additions & 3 deletions deps/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ using BinDeps

@BinDeps.setup

blasvendor = Base.BLAS.vendor()
using Libdl
Copy link
Member

Choose a reason for hiding this comment

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

You may need Compat for Libdl, LinearAlgebra, and Sys

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yep, but to be honest I don't know what to do with NamedTuples, as on 0.6 we get

julia> (x=1,)
ERROR: syntax: assignment not allowed inside tuple

using LinearAlgebra.BLAS

blasvendor = BLAS.vendor()

direct = library_dependency("libscsdir", aliases=["libscsdir64"])
indirect = library_dependency("libscsindir", aliases=["libscsindir64"])

# TODO: Provide both libs in the "scs" Homebrew package.
# if is_apple()
# if Sys.isapple()
# using Homebrew
# provides(Homebrew.HB, "scs", [direct, indirect], os = :Darwin)
# end
Expand All @@ -35,7 +38,7 @@ prefix = joinpath(BinDeps.depsdir(direct), "usr")
srcdir = joinpath(BinDeps.depsdir(direct), "src", "scs-$version/")

ldflags = ""
if is_apple()
if Sys.isapple()
ldflags = "$ldflags -undefined suppress -flat_namespace"
end
cflags = "-DCOPYAMATRIX -DDLONG -DUSE_LAPACK -DCTRLC=1"
Expand Down
14 changes: 7 additions & 7 deletions src/MOIWrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ end
mutable struct SCSOptimizer <: MOI.AbstractOptimizer
cone::ConeData
maxsense::Bool
data::Union{Void, ModelData} # only non-Void between MOI.copy! and MOI.optimize!
data::Union{Nothing, ModelData} # only non-Void between MOI.copy! and MOI.optimize!
sol::MOISolution
function SCSOptimizer()
new(ConeData(), false, nothing, MOISolution())
Expand Down Expand Up @@ -169,7 +169,7 @@ function _scalecoef(rows, coef, minus, ::Type{MOI.PositiveSemidefiniteConeTriang
scaling = minus ? -1 : 1
scaling2 = rev ? scaling / √2 : scaling * √2
output = copy(coef)
diagidx = IntSet()
diagidx = BitSet()
for i in 1:d
push!(diagidx, trimap(i, i))
end
Expand Down Expand Up @@ -232,11 +232,11 @@ function MOIU.loadconstraint!(optimizer::SCSOptimizer, ci, f::MOI.VectorAffineFu
offset = constroffset(optimizer, ci)
rows = constrrows(s)
optimizer.cone.nrows[offset] = length(rows)
i = offset + rows
i = offset .+ rows
# The SCS format is b - Ax ∈ cone
# so minus=false for b and minus=true for A
optimizer.data.b[i] = scalecoef(rows, orderval(f.constant, s), false, s)
append!(optimizer.data.I, offset + orderidx(I, s))
append!(optimizer.data.I, offset .+ orderidx(I, s))
append!(optimizer.data.J, J)
append!(optimizer.data.V, scalecoef(I, V, true, s))
end
Expand Down Expand Up @@ -268,7 +268,7 @@ MOIU.canload(::SCSOptimizer, ::MOI.ObjectiveSense) = true
function MOIU.load!(::SCSOptimizer, ::MOI.ObjectiveSense, ::MOI.OptimizationSense) end
MOIU.canload(::SCSOptimizer, ::MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}) = true
function MOIU.load!(optimizer::SCSOptimizer, ::MOI.ObjectiveFunction, f::MOI.ScalarAffineFunction)
c0 = full(sparsevec(_varmap(f), f.coefficients, optimizer.data.n))
c0 = Vector(sparsevec(_varmap(f), f.coefficients, optimizer.data.n))
optimizer.data.objconstant = f.constant
optimizer.data.c = optimizer.maxsense ? -c0 : c0
end
Expand Down Expand Up @@ -352,7 +352,7 @@ end
function MOI.get(optimizer::SCSOptimizer, ::MOI.ConstraintPrimal, ci::CI{<:MOI.AbstractFunction, S}) where S <: MOI.AbstractSet
offset = constroffset(optimizer, ci)
rows = constrrows(optimizer, ci)
_unshift(optimizer, offset, unscalecoef(rows, reorderval(optimizer.sol.slack[offset + rows], S), S, length(rows)), S)
_unshift(optimizer, offset, unscalecoef(rows, reorderval(optimizer.sol.slack[offset .+ rows], S), S, length(rows)), S)
end

MOI.canget(optimizer::SCSOptimizer, ::MOI.DualStatus) = true
Expand All @@ -372,7 +372,7 @@ end
function MOI.get(optimizer::SCSOptimizer, ::MOI.ConstraintDual, ci::CI{<:MOI.AbstractFunction, S}) where S <: MOI.AbstractSet
offset = constroffset(optimizer, ci)
rows = constrrows(optimizer, ci)
unscalecoef(rows, reorderval(optimizer.sol.dual[offset + rows], S), S, length(rows))
unscalecoef(rows, reorderval(optimizer.sol.dual[offset .+ rows], S), S, length(rows))
end

MOI.canget(optimizer::SCSOptimizer, ::MOI.ResultCount) = true
Expand Down
17 changes: 12 additions & 5 deletions src/MPBWrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@
# MathProgBase.jl interface for the SCS.jl solver wrapper
#############################################################################

importall MathProgBase.SolverInterface
using LinearAlgebra: dot
using MathProgBase.SolverInterface

import MathProgBase.SolverInterface: ConicModel, LinearQuadraticModel,
getdual, getobjval, getsolution, getsolvetime, getvardual, loadproblem!,
numconstr, numvar, optimize!, setbvec!, setwarmstart!, status,
supportedcones

import Base.convert

# TODO: don't add to Base.convert!
Expand Down Expand Up @@ -145,14 +152,14 @@ function orderconesforscs(A_in, b_in, c_cones, v_cones)
A_t = spzeros(n,0)
b = zeros(0)
row_map_ind = zeros(Int, length(b_in))
row_map_type = Array{Symbol}(length(b_in))
row_map_type = Array{Symbol}(undef, length(b_in))
col_map_ind = zeros(Int, n)
col_map_type = Array{Symbol}(n)
col_map_type = Array{Symbol}(undef, n)

# First, count the total number of variables
num_vars = 0
for (cone, idxs) in v_cones
col_map_type[idxs] = cone
col_map_type[idxs] .= cone
num_vars += length(idxs)
end
@assert num_vars == n
Expand Down Expand Up @@ -432,7 +439,7 @@ end
# warmstart
# kwargs can be `primal_sol`, `dual_sol`, and `slack`
function setwarmstart!(m::SCSMathProgModel, primal_sol; kwargs...)
push!(m.options, (:warm_start, true))
m.options = pairs(merge(m.options.data, (warm_start=true,)))
m.primal_sol = primal_sol
for (k,v) in kwargs
setfield!(m, k, v)
Expand Down
4 changes: 2 additions & 2 deletions src/SCS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ else
error("SCS not properly installed. Please run Pkg.build(\"SCS\") and restart julia")
end

import Base.Libdl: RTLD_LAZY, RTLD_DEEPBIND, RTLD_GLOBAL, dlopen
using Libdl

function __init__()
vnum = VersionNumber(SCS_version())
# default binaries need access to Julia's lapack symbols
if is_unix()
if Sys.isunix()
dlopen(Base.liblapack_name, RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL)
end
depsdir = realpath(joinpath(dirname(@__FILE__),"..","deps"))
Expand Down
16 changes: 8 additions & 8 deletions src/c_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ macro compat_gc_preserve(args...)
vars = args[1:end-1]
body = args[end]
if VERSION > v"0.7.0-"
return esc(Expr(:macrocall, Expr(:., :Base, Base.Meta.quot(Symbol("@gc_preserve"))), __source__, args...))
return esc(Expr(:macrocall, Expr(:., :GC, Base.Meta.quot(Symbol("@preserve"))), __source__, args...))
else
return esc(body)
end
Expand Down Expand Up @@ -52,7 +52,7 @@ function SCS_solve(T::Union{Type{Direct}, Type{Indirect}},
cone = Ref(SCSCone(f, l, q, s, ep, ed, p))
info = Ref(SCSInfo())

if (:warm_start, true) in options && length(primal_sol) == n && length(dual_sol) == m && length(slack) == m
if (:warm_start=>true) in options && length(primal_sol) == n && length(dual_sol) == m && length(slack) == m
x = primal_sol
y = dual_sol
s = slack
Expand Down Expand Up @@ -82,26 +82,26 @@ for (T, lib) in zip([SCS.Direct, SCS.Indirect], [SCS.direct, SCS.indirect])
@eval begin
function SCS_init(::Type{$T}, data::Ref{SCSData}, cone::Ref{SCSCone}, info::Ref{SCSInfo})

p_work = ccall((:scs_init, $lib), Ptr{Void},
p_work = ccall((:scs_init, $lib), Ptr{Nothing},
(Ptr{SCSData}, Ptr{SCSCone}, Ptr{SCSInfo}),
data, cone, info)

return p_work
end

# solution struct is simple enough, we know it won't be modified by SCS so take by value
function SCS_solve(::Type{$T}, p_work::Ptr{Void}, data::Ref{SCSData}, cone::Ref{SCSCone}, solution::SCSSolution, info::Ref{SCSInfo})
function SCS_solve(::Type{$T}, p_work::Ptr{Nothing}, data::Ref{SCSData}, cone::Ref{SCSCone}, solution::SCSSolution, info::Ref{SCSInfo})

status = ccall((:scs_solve, $lib), Int,
(Ptr{Void}, Ptr{SCSData}, Ptr{SCSCone}, Ref{SCSSolution}, Ptr{SCSInfo}),
(Ptr{Nothing}, Ptr{SCSData}, Ptr{SCSCone}, Ref{SCSSolution}, Ptr{SCSInfo}),
p_work, data, cone, solution, info)

return status
end

function SCS_finish(::Type{$T}, p_work::Ptr{Void})
ccall((:scs_finish, $lib), Void,
(Ptr{Void}, ),
function SCS_finish(::Type{$T}, p_work::Ptr{Nothing})
ccall((:scs_finish, $lib), Nothing,
(Ptr{Nothing}, ),
p_work)
end
end
Expand Down
9 changes: 5 additions & 4 deletions src/types.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export SCSMatrix, SCSData, SCSSettings, SCSSolution, SCSInfo, SCSCone, SCSVecOrMatOrSparse
using SparseArrays

export SCSMatrix, SCSData, SCSSettings, SCSSolution, SCSInfo, SCSCone, SCSVecOrMatOrSparse

SCSVecOrMatOrSparse = Union{VecOrMat, SparseMatrixCSC{Float64,Int}}

Expand Down Expand Up @@ -68,9 +69,9 @@ struct SCSData
end

struct SCSSolution
x::Ptr{Void}
y::Ptr{Void}
s::Ptr{Void}
x::Ptr{Nothing}
y::Ptr{Nothing}
s::Ptr{Nothing}
end


Expand Down
4 changes: 2 additions & 2 deletions test/MPBWrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
include("mpb_linear.jl")
end

import SCS
using Pkg.dir
@testset "MathProgBase" begin
include(joinpath(Pkg.dir("MathProgBase"),"test","conicinterface.jl"))
include(joinpath(dir("MathProgBase"),"test","conicinterface.jl"))
coniclineartest(SCS.SCSSolver(), duals=true, tol=1e-2)
conicSOCtest(SCS.SCSSolver(), duals=true, tol=1e-2)
conicEXPtest(SCS.SCSSolver(), duals=true, tol=1e-2)
Expand Down
3 changes: 0 additions & 3 deletions test/direct.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using SCS
using Base.Test

# Solve a trivial problem
A = reshape([1.0],(1,1))
solution = SCS_solve(SCS.Direct, 1, 1, A, [1.0], [1.0], 1, 0, Int[], Int[], 0, 0, Float64[]);
Expand Down
3 changes: 0 additions & 3 deletions test/indirect.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using SCS
using Base.Test

# Solve a trivial problem
A = reshape([1.0],(1,1))
solution = SCS_solve(SCS.Indirect, 1, 1, A, [1.0], [1.0], 1, 0, Int[], Int[], 0, 0, Float64[]);
Expand Down
4 changes: 2 additions & 2 deletions test/mpb_linear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
# Test the MathProgBase.jl interface for the SCS.jl solver wrapper
#############################################################################

using Base.Test
using MathProgBase
using SCS
using LinearAlgebra
using SparseArrays

solver = SCSSolver()
objtol = 1e-4
Expand Down
8 changes: 2 additions & 6 deletions test/options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
# Tests the ability to pass options
#############################################################################

using Base.Test
using MathProgBase.SolverInterface
using SCS

using MathProgBase

# The normal test
A = [1.0 1.0 0.0 0.0 0.0;
Expand All @@ -33,8 +30,7 @@ MathProgBase.optimize!(m)
@test isapprox(MathProgBase.getobjval(m), -99.0, atol=1e-5)

# With a warmstart from the eps = 1e-8 solution, solution should be extremely accurate even after 1 iteration
push!(m.options, (:warm_start, true))
push!(m.options, (:max_iters, 1))
m.options = pairs(merge(m.options.data, (warm_start=true, max_iters=1)))
MathProgBase.optimize!(m)
@test isapprox(MathProgBase.getobjval(m), -99.0, atol=1e-5)

Expand Down
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Base.Test
using Test
using SCS

tests = ["direct.jl",
"indirect.jl",
Expand Down
639 changes: 612 additions & 27 deletions test/test_problems.jl

Large diffs are not rendered by default.