Skip to content

Commit

Permalink
v0.5.0 (#124)
Browse files Browse the repository at this point in the history
* snoop precompile and package load times (#122)

* Pg/sdp rust port (#125)

* Support for PSDTriangleConeT with dimension zero (#126)

* Support BigFloat SDPs (#127)
  • Loading branch information
goulart-paul authored Apr 25, 2023
1 parent 0c34116 commit feafc10
Show file tree
Hide file tree
Showing 26 changed files with 608 additions and 391 deletions.
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
# Changelog

Changes for the Julia version of Clarabel are documented in this file. For the Rust version, see [here](https://github.com/oxfordcontrol/clarabel.rs/CHANGELOG.md).
Changes for the Julia version of Clarabel are documented in this file. For the Rust version, see [here](https://github.com/oxfordcontrol/Clarabel.rs/blob/main/CHANGELOG.md).

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

Version numbering in this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). We aim to keep the core solver functionality and minor releases in sync between the Rust/Python and Julia implementations. Small fixes that affect one implementation only may result in the patch release versions differing.

## [0.5.0] - 2023-25-04
### Changed

This version ports support for PSD cones from the Julia version to Rust, with internal supporting modifications to both versions to keep implementations synchronized.
### Julia specific changes

- Julia package now uses SnoopPrecompile to reduce load times. Load times will be faster in particular when using Julia versions 1.9 onwards, but code remains backwards compatible to older versions. Removed some dependencies in favor of lighter weight ones in support. Fixes [#120](https://github.com/oxfordcontrol/Clarabel.jl/issues/120)

- Solver now allows SDP cone constraints with dimension 0.


## [0.4.1] - 2023-08-03
### Changed

Expand Down Expand Up @@ -53,7 +64,7 @@ Internal modifications to SDP cone implementation to reduce allocations.

- Initial release


[0.5.0]: https://github.com/oxfordcontrol/Clarabel.jl/compare/v0.4.1...v0.5.0
[0.4.1]: https://github.com/oxfordcontrol/Clarabel.jl/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/oxfordcontrol/Clarabel.jl/compare/v0.4.0...v0.3.0
[0.3.0]: https://github.com/oxfordcontrol/Clarabel.jl/compare/v0.3.0...v0.2.0
Expand Down
12 changes: 5 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
name = "Clarabel"
uuid = "61c947e1-3e6d-4ee4-985a-eec8c727bd6e"
authors = ["Paul Goulart <[email protected]>"]
version = "0.4.1"
version = "0.5.0"

[deps]
AMD = "14f7f29c-3bd6-536c-9a0b-7339e30b5a3e"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
GenericLinearAlgebra = "14197337-ba66-59df-a3e3-ca00e7dcff7a"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
QDLDL = "bfc457fd-c171-5ab7-bd9e-d5dbfc242d63"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
SnoopPrecompile = "66db9d55-30c0-4569-8b51-7e840670fc0c"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
SuiteSparse = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"

[compat]
AMD = "0.4, 0.5"
DataFrames = "1"
MathOptInterface = "1.2"
PrettyTables = "1, 2"
QDLDL = "0.4"
Requires = "1"
SnoopPrecompile = "1"
StaticArrays = "1"
TimerOutputs = "0.5"
julia = "1.2"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Interior Point Conic Optimization for Julia
<a href="https://codecov.io/gh/oxfordcontrol/Clarabel.jl"><img src="https://codecov.io/gh/oxfordcontrol/Clarabel.jl/branch/main/graph/badge.svg"></a>
<a href="https://oxfordcontrol.github.io/ClarabelDocs/stable"><img src="https://img.shields.io/badge/Documentation-stable-purple.svg"></a>
<a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a>
<a href="https://github.com/oxfordcontrol/Clarabel.jl/releases"><img src="https://img.shields.io/badge/Release-v0.4.1-blue.svg"></a>
<a href="https://github.com/oxfordcontrol/Clarabel.jl/releases"><img src="https://img.shields.io/badge/Release-v0.5.0-blue.svg"></a>
</p>

<p align="center">
Expand Down
13 changes: 12 additions & 1 deletion src/Clarabel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,16 @@ module Clarabel
end
const Optimizer{T} = Clarabel.MOImodule.Optimizer{T}

end

#precompile minimal MOI / native examples
using SnoopPrecompile
include("./precompile.jl")
redirect_stdout(devnull) do;
SnoopPrecompile.@precompile_all_calls begin
__precompile_native()
__precompile_moi()
end
end
__precompile_printfcns()

end #end module
47 changes: 25 additions & 22 deletions src/MOI_wrapper/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ const MOIU = MOI.Utilities
const SparseTriplet{T} = Tuple{Vector{<:Integer}, Vector{<:Integer}, Vector{T}}

# Cones supported by the solver
#PJG : Support for PSD cones within ClarabelRs is manually
#disabled in the two implementations of supports_constraint below.

const OptimizerSupportedMOICones{T} = Union{
MOI.Zeros,
MOI.Nonnegatives,
Expand Down Expand Up @@ -134,10 +131,14 @@ function MOI.empty!(optimizer::Optimizer{T}) where {T}
optimizer.rowranges = Dict{Int, UnitRange{Int}}()
end

MOI.is_empty(optimizer::Optimizer) = isnothing(optimizer.solver)
MOI.is_empty(optimizer::Optimizer{T}) where {T} = isnothing(optimizer.solver)

function MOI.optimize!(optimizer::Optimizer)
solution = optimizer.solver_module.solve!(optimizer.solver)
function MOI.optimize!(optimizer::Optimizer{T}) where {T}
if(optimizer.solver_module === Clarabel)
solution = Clarabel.solve!(optimizer.solver)
else
solution = optimizer.solver_module.solve!(optimizer.solver)
end
optimizer.solver_solution = solution
optimizer.solver_info = optimizer.solver_module.get_info(optimizer.solver)
nothing
Expand Down Expand Up @@ -304,12 +305,6 @@ function MOI.supports_constraint(
::Type{<:MOI.VectorAffineFunction{T}},
t::Type{<:OptimizerSupportedMOICones{T}}
) where{T}
# PJG: workaround so that the compiled version does not
# report support for PSD constraints. Remove once they
# are supported
if(opt.solver_module != Clarabel && t == MOI.PositiveSemidefiniteConeTriangle)
return false
end
true
end

Expand All @@ -319,12 +314,6 @@ function MOI.supports_constraint(
::Type{<:MOI.VectorOfVariables},
t::Type{<:OptimizerSupportedMOICones{T}}
) where {T}
# PJG: workaround so that the compiled version does not
# report support for PSD constraints. Remove once they
# are supported
if(opt.solver_module != Clarabel && t == MathOptInterface.PositiveSemidefiniteConeTriangle)
return false
end
return true
end

Expand Down Expand Up @@ -558,13 +547,13 @@ end

scalecoef(v,::Type{<:MOI.AbstractVectorSet}) = v #default don't scale
scalecoef(v,idx,::Type{<:MOI.AbstractVectorSet}) = v #default don't scale
scalecoef(v,::Type{<:MOI.AbstractSymmetricMatrixSetTriangle}) = Clarabel._triangle_unscaled_to_svec(v)
scalecoef(v,idx,::Type{<:MOI.AbstractSymmetricMatrixSetTriangle}) = Clarabel._triangle_unscaled_to_svec(v,idx)
scalecoef(v,::Type{<:MOI.AbstractSymmetricMatrixSetTriangle}) = _triangle_unscaled_to_svec(v)
scalecoef(v,idx,::Type{<:MOI.AbstractSymmetricMatrixSetTriangle}) = _triangle_unscaled_to_svec(v,idx)

unscalecoef(v,::Type{<:MOI.AbstractVectorSet}) = v #default don't scale
unscalecoef(v,idx,::Type{<:MOI.AbstractVectorSet}) = v #default don't scale
unscalecoef(v,::Type{<:MOI.AbstractSymmetricMatrixSetTriangle}) = Clarabel._triangle_svec_to_unscaled(v)
unscalecoef(v,idx,::Type{<:MOI.AbstractSymmetricMatrixSetTriangle}) = Clarabel._triangle_svec_to_unscaled(v,idx)
unscalecoef(v,::Type{<:MOI.AbstractSymmetricMatrixSetTriangle}) = _triangle_svec_to_unscaled(v)
unscalecoef(v,idx,::Type{<:MOI.AbstractSymmetricMatrixSetTriangle}) = _triangle_svec_to_unscaled(v,idx)


function push_constraint_constant!(
Expand Down Expand Up @@ -777,3 +766,17 @@ function upper_triangularize!(triplet::SparseTriplet{T}) where {T}
end
end
end


# ---------------------------------
# utility functions for manipulating scaled vectors representing packed
# matrices in the upper triangle, read columnwise
# ---------------------------------

_triangle_svec_scale(v, index, scale) = Clarabel.is_triangular_number(index) ? v : scale*v
_triangle_svec_to_unscaled(v::T,idx::Int) where {T} = _triangle_svec_scale(v, idx, 1/sqrt(T(2)))
_triangle_unscaled_to_svec(v::T,idx::Int) where {T} = _triangle_svec_scale(v, idx, sqrt(T(2)))

#vectorized versions on full triangles
_triangle_svec_to_unscaled(v::AbstractVector) = _triangle_svec_to_unscaled.(v,eachindex(v))
_triangle_unscaled_to_svec(v::AbstractVector) = _triangle_unscaled_to_svec.(v,eachindex(v))
2 changes: 1 addition & 1 deletion src/cones/cone_api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ end
function nvars(cone:: SupportedCone)

if isa(cone, PSDTriangleConeT)
(cone.dim*(cone.dim+1)) >> 1
triangular_number(cone.dim)
elseif isa(cone, ExponentialConeT)
3
elseif isa(cone, PowerConeT)
Expand Down
8 changes: 4 additions & 4 deletions src/cones/cone_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,13 @@ mutable struct PSDConeWork{T}
R = zeros(T,n,n)
Rinv = zeros(T,n,n)
kronRR = zeros(T,n^2,n^2)
B = zeros(T,((n+1)*n)>>1,n^2)
B = zeros(T,triangular_number(n),n^2)
Hs = zeros(T,size(B,1),size(B,1))

workmat1 = zeros(T,n,n)
workmat2 = zeros(T,n,n)
workmat3 = zeros(T,n,n)
workvec = zeros(T,(n*(n+1))>>1)
workvec = zeros(T,triangular_number(n))

return new(cholS,cholZ,SVD,λ,Λisqrt,R,Rinv,
kronRR,B,Hs,workmat1,workmat2,workmat3,workvec)
Expand All @@ -151,8 +151,8 @@ struct PSDTriangleCone{T} <: AbstractCone{T}

function PSDTriangleCone{T}(n) where {T}

n >= 1 || throw(DomainError(dim, "dimension must be positive"))
numel = (n*(n+1))>>1
n >= 0 || throw(DomainError(n, "dimension must be non-negative"))
numel = triangular_number(n)
work = PSDConeWork{T}(n)

return new(n,numel,work)
Expand Down
1 change: 0 additions & 1 deletion src/cones/coneops_compositecone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ macro conedispatch(call)
esc(_conedispatch(:cone, call))
end

dim(::CompositeCone{T}) where {T} = error("dim() not well defined for the CompositeCone");
degree(cones::CompositeCone{T}) where {T} = cones.degree
numel(cones::CompositeCone{T}) where {T} = cones.numel

Expand Down
12 changes: 7 additions & 5 deletions src/cones/coneops_defaults.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Statistics: mean

## -------------------------------------------
# Default implementations for cone operations
# --------------------------------------------
Expand All @@ -10,9 +8,13 @@ import Statistics: mean
# For SDP cone, the matrix is in R^{dim \times dim},
# so numel will be different. The length of (s,z)
# vectors will be \sum_i numel(K_i)
dim(K::AbstractCone{T}) where {T} = K.dim
degree(K::AbstractCone{T}) where {T} = dim(K)
numel(K::AbstractCone{T}) where {T} = dim(K)
function degree(K::AbstractCone{T}) where {T}
error("Incomplete cone operation specification: ",typeof(K))
end

function numel(K::AbstractCone{T}) where {T}
error("Incomplete cone operation specification: ",typeof(K))
end

#All cones default to symmetric unless overridden
is_symmetric(::AbstractCone{T}) where {T} = true
Expand Down
7 changes: 3 additions & 4 deletions src/cones/coneops_expcone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
# ----------------------------------------------------

# degree of the cone. Always 3
dim(K::ExponentialCone{T}) where {T} = 3
degree(K::ExponentialCone{T}) where {T} = dim(K)
numel(K::ExponentialCone{T}) where {T} = dim(K)
degree(K::ExponentialCone{T}) where {T} = 3
numel(K::ExponentialCone{T}) where {T} = 3

is_symmetric(::ExponentialCone{T}) where {T} = false

Expand Down Expand Up @@ -96,7 +95,7 @@ function get_Hs!(
) where {T}

# stores triu(K.Hs) into a vector
_pack_triu(Hsblock,K.Hs)
pack_triu(Hsblock,K.Hs)

end

Expand Down
3 changes: 3 additions & 0 deletions src/cones/coneops_nncone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
# Nonnegative Cone
# -------------------------------------

degree(K::NonnegativeCone{T}) where {T} = K.dim
numel(K::NonnegativeCone{T}) where {T} = K.dim

function rectify_equilibration!(
K::NonnegativeCone{T},
δ::AbstractVector{T},
Expand Down
7 changes: 3 additions & 4 deletions src/cones/coneops_powcone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
# ----------------------------------------------------

# degree of the cone is always 3 for PowerCone
dim(K::PowerCone{T}) where {T} = 3
degree(K::PowerCone{T}) where {T} = dim(K)
numel(K::PowerCone{T}) where {T} = dim(K)
degree(K::PowerCone{T}) where {T} = 3
numel(K::PowerCone{T}) where {T} = 3

is_symmetric(::PowerCone{T}) where {T} = false

Expand Down Expand Up @@ -98,7 +97,7 @@ function get_Hs!(
) where {T}

#Vectorize triu(K.μH)
_pack_triu(Hsblock,K.Hs)
pack_triu(Hsblock,K.Hs)

end

Expand Down
Loading

0 comments on commit feafc10

Please sign in to comment.