Skip to content

Commit 9c6fef2

Browse files
committed
Update
1 parent 98e70b1 commit 9c6fef2

File tree

2 files changed

+37
-23
lines changed

2 files changed

+37
-23
lines changed

src/DSDP.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ module DSDP
77

88
using CEnum: @cenum
99
using DSDP_jll: libdsdp
10-
11-
using LinearAlgebra
10+
import LinearAlgebra
11+
import MathOptInterface as MOI
1212

1313
include("libdsdp.jl")
1414

15+
# This one is named poorly in the upstream C API
1516
const DSDPSetReuseMatrix = DSDPReuseMatrix
1617

1718
include("MOI_wrapper.jl")

src/MOI_wrapper.jl

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@
33
# Use of this source code is governed by an MIT-style license that can be found
44
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
55

6-
import MathOptInterface as MOI
6+
macro check(expr)
7+
@assert expr.head == :call
8+
msg = "Error calling $(expr.args[1])"
9+
return quote
10+
if (ret = $(esc(expr))) != 0
11+
error($msg)
12+
end
13+
end
14+
end
715

816
mutable struct Optimizer <: MOI.AbstractOptimizer
917
dsdp::Ptr{Cvoid}
@@ -63,6 +71,8 @@ end
6371

6472
varmap(optimizer::Optimizer, vi::MOI.VariableIndex) = optimizer.varmap[vi.value]
6573

74+
# MOI.Silent
75+
6676
MOI.supports(::Optimizer, ::MOI.Silent) = true
6777

6878
function MOI.set(optimizer::Optimizer, ::MOI.Silent, value::Bool)
@@ -72,6 +82,8 @@ end
7282

7383
MOI.get(optimizer::Optimizer, ::MOI.Silent) = optimizer.silent
7484

85+
# MOI.SolverName
86+
7587
MOI.get(::Optimizer, ::MOI.SolverName) = "DSDP"
7688

7789
function MOI.empty!(optimizer::Optimizer)
@@ -182,13 +194,13 @@ for (param, default) in gettable_options
182194
struct $param <: GettableOption end
183195
function _call_get(dsdp, ::$param)
184196
ret = Ref{$T}()
185-
$getter(dsdp, ret)
197+
@check $getter(dsdp, ret)
186198
return ret[]
187199
end
188200
options_setters[$sym] = $setter
189201
_dict_set!(options, ::$param, val) = options[$sym] = val
190202
_dict_get(options, ::$param) = get(options, $sym, $default)
191-
_call_set!(dsdp, ::$param, val) = $setter(dsdp, val)
203+
_call_set!(dsdp, ::$param, val) = @check $setter(dsdp, val)
192204
end
193205
end
194206

@@ -200,7 +212,7 @@ for (param, default) in options
200212
options_setters[$sym] = $setter
201213
_dict_set!(options, ::$param, val) = options[$sym] = val
202214
_dict_get(options, ::$param) = get(options, $sym, $default)
203-
_call_set!(dsdp, ::$param, val) = $setter(dsdp, val)
215+
_call_set!(dsdp, ::$param, val) = @check $setter(dsdp, val)
204216
end
205217
end
206218

@@ -421,14 +433,14 @@ function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
421433
dest.lpdrows = Int[]
422434
dest.lpcoefs = Cdouble[]
423435
p = Ref{Ptr{Cvoid}}()
424-
DSDPCreate(length(dest.b), p)
436+
@check DSDPCreate(length(dest.b), p)
425437
dest.dsdp = p[]
426438
for (option, value) in dest.options
427439
options_setters[option](dest.dsdp, value)
428440
end
429441
if !iszero(num_sdp)
430442
sdpcone = Ref{Ptr{Cvoid}}()
431-
DSDPCreateSDPCone(dest.dsdp, num_sdp, sdpcone)
443+
@check DSDPCreateSDPCone(dest.dsdp, num_sdp, sdpcone)
432444
dest.sdpcone = sdpcone[]
433445
for i in eachindex(dest.blockdims)
434446
if dest.blockdims[i] < 0
@@ -444,7 +456,7 @@ function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
444456
for constr in eachindex(dest.b)
445457
# TODO in examples/readsdpa.c line 162,
446458
# -0.0 is used instead of 0.0 if the dual obj is <= 0., check if it has impact
447-
DSDPSetY0(dest.dsdp, constr, 0.0)
459+
@check DSDPSetY0(dest.dsdp, constr, 0.0)
448460
end
449461
# TODO ComputeY0 as in examples/readsdpa.c
450462
empty!(dest.y)
@@ -462,7 +474,7 @@ function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
462474
),
463475
)
464476
end
465-
DSDPSetDualObjective(dest.dsdp, k, MOI.constant(set))
477+
@check DSDPSetDualObjective(dest.dsdp, k, MOI.constant(set))
466478
_new_A_matrix(dest)
467479
for t in func.terms
468480
if !iszero(t.coefficient)
@@ -521,7 +533,7 @@ function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
521533
# Pass info to `dest.dsdp`
522534
if !isempty(dest.lpdvars)
523535
lpcone = Ref{Ptr{Cvoid}}()
524-
DSDPCreateLPCone(dest.dsdp, lpcone)
536+
@check DSDPCreateLPCone(dest.dsdp, lpcone)
525537
dest.lpcone = lpcone[]
526538
nnzin, row, aval = _buildlp(
527539
length(dest.b) + 1,
@@ -531,7 +543,7 @@ function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
531543
)
532544
LPConeSetData(dest.lpcone, dest.nlpdrows, nnzin, row, aval)
533545
end
534-
DSDPSetup(dest.dsdp)
546+
@check DSDPSetup(dest.dsdp)
535547
return index_map
536548
end
537549

@@ -559,12 +571,13 @@ function _buildlp(nvars, lpdvars, lpdrows, lpcoefs)
559571
end
560572

561573
function MOI.optimize!(m::Optimizer)
562-
DSDPSolve(m.dsdp)
574+
@check DSDPSetStandardMonitor(m.dsdp, !m.silent ? 1 : 0)
575+
@check DSDPSolve(m.dsdp)
563576
# Calling `ComputeX` not right after `Solve` seems to sometime cause segfaults or weird Heisenbug's
564577
# let's call it directly what `DSDP/examples/readsdpa.c` does
565-
DSDPComputeX(m.dsdp)
578+
@check DSDPComputeX(m.dsdp)
566579
m.y = zeros(Cdouble, length(m.b))
567-
DSDPGetY(m.dsdp, m.y, length(m.y))
580+
@check DSDPGetY(m.dsdp, m.y, length(m.y))
568581
map!(-, m.y, m.y) # The primal objective is Max in SDOI but Min in DSDP
569582
return
570583
end
@@ -574,7 +587,7 @@ function MOI.get(m::Optimizer, ::MOI.RawStatusString)
574587
return "`optimize!` not called"
575588
end
576589
stop = Ref{DSDPTerminationReason}()
577-
DSDPStopReason(m.dsdp, stop)
590+
@check DSDPStopReason(m.dsdp, stop)
578591
status = stop[]
579592
if status == DSDP_CONVERGED
580593
return "Converged"
@@ -603,11 +616,11 @@ function MOI.get(m::Optimizer, ::MOI.TerminationStatus)
603616
return MOI.OPTIMIZE_NOT_CALLED
604617
end
605618
stop = Ref{DSDPTerminationReason}()
606-
DSDPStopReason(m.dsdp, stop)
619+
@check DSDPStopReason(m.dsdp, stop)
607620
status = stop[]
608621
if status == DSDP_CONVERGED
609622
sol = Ref{DSDPSolutionType}()
610-
DSDPGetSolutionType(m.dsdp, sol)
623+
@check DSDPGetSolutionType(m.dsdp, sol)
611624
sol_status = sol[]
612625
if sol_status == DSDP_PDFEASIBLE
613626
return MOI.OPTIMAL
@@ -645,7 +658,7 @@ function MOI.get(m::Optimizer, attr::MOI.PrimalStatus)
645658
return MOI.NO_SOLUTION
646659
end
647660
sol = Ref{DSDPSolutionType}()
648-
DSDPGetSolutionType(m.dsdp, sol)
661+
@check DSDPGetSolutionType(m.dsdp, sol)
649662
status = sol[]
650663
if status == DSDP_PDUNKNOWN
651664
return MOI.UNKNOWN_RESULT_STATUS
@@ -664,7 +677,7 @@ function MOI.get(m::Optimizer, attr::MOI.DualStatus)
664677
return MOI.NO_SOLUTION
665678
end
666679
sol = Ref{DSDPSolutionType}()
667-
DSDPGetSolutionType(m.dsdp, sol)
680+
@check DSDPGetSolutionType(m.dsdp, sol)
668681
status = sol[]
669682
if status == DSDP_PDUNKNOWN
670683
return MOI.UNKNOWN_RESULT_STATUS
@@ -684,14 +697,14 @@ MOI.get(m::Optimizer, ::MOI.ResultCount) = m.dsdp == C_NULL ? 0 : 1
684697
function MOI.get(m::Optimizer, attr::MOI.ObjectiveValue)
685698
MOI.check_result_index_bounds(m, attr)
686699
ret = Ref{Cdouble}()
687-
DSDPGetPPObjective(m.dsdp, ret)
700+
@check DSDPGetPPObjective(m.dsdp, ret)
688701
return m.objective_sign * ret[] + m.objective_constant
689702
end
690703

691704
function MOI.get(m::Optimizer, attr::MOI.DualObjectiveValue)
692705
MOI.check_result_index_bounds(m, attr)
693706
ret = Ref{Cdouble}()
694-
DSDPGetDDObjective(m.dsdp, ret)
707+
@check DSDPGetDDObjective(m.dsdp, ret)
695708
return m.objective_sign * ret[] + m.objective_constant
696709
end
697710

@@ -826,7 +839,7 @@ function block(
826839
end
827840

828841
function vectorize_block(M, blk::Integer, ::Type{MOI.Nonnegatives})
829-
return diag(block(M, blk))
842+
return LinearAlgebra.diag(block(M, blk))
830843
end
831844

832845
function vectorize_block(

0 commit comments

Comments
 (0)