Skip to content

Commit 015e36e

Browse files
committed
Reduce allocations.
1 parent 9218073 commit 015e36e

File tree

1 file changed

+42
-16
lines changed

1 file changed

+42
-16
lines changed

src/MathOptChordalDecomposition.jl

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import MathOptInterface as MOI
1111
struct Decomposition
1212
neqns::Int
1313
values::Vector{Int}
14-
cliques::Vector{Vector{Int}}
14+
cliques::SparseMatrixCSC{Bool, Int}
1515
end
1616

1717
mutable struct Optimizer{A <: EliminationAlgorithm} <: MOI.AbstractOptimizer
@@ -206,7 +206,7 @@ function MOI.add_constraint(
206206
s::MOI.PositiveSemidefiniteConeTriangle,
207207
) where {T}
208208
# construct sparse matrices
209-
V, A, b = decode(f, s)
209+
V, A, b = decode(f, s); n = size(b, 2)
210210

211211
# compute aggregate sparsity pattern
212212
pattern = sum(sparsitypattern, A; init = sparsitypattern(b))
@@ -215,16 +215,22 @@ function MOI.add_constraint(
215215
label, tree = cliquetree(pattern; alg = model.alg)
216216

217217
# compute cliques
218-
cliques = map(tree) do clique
219-
return sort!(label[clique])
220-
end
218+
cliques = spzeros(Bool, n, length(tree))
219+
220+
for (b, bag) in enumerate(tree)
221+
append!(cliques.rowval, bag)
222+
cliques.colptr[b + 1] = cliques.colptr[b] + length(bag)
223+
end
224+
225+
resize!(cliques.nzval, length(cliques.rowval))
226+
permute!(cliques, invperm(label), axes(cliques, 2))
221227

222228
# terms
223229
indices = Int[]
224230
terms = MOI.VectorAffineTerm{T}[]
225231

226-
for clique in cliques
227-
m = length(clique)
232+
for b in axes(cliques, 2)
233+
clique = view(cliques.rowval, nzrange(cliques, b)); m = length(clique)
228234
U = MOI.add_variables(model, m * (m + 1) ÷ 2)
229235

230236
for j in oneto(m), i in oneto(j)
@@ -246,7 +252,6 @@ function MOI.add_constraint(
246252
end
247253

248254
# constants
249-
n = size(b, 2)
250255
constants = zeros(T, n * (n + 1) ÷ 2)
251256

252257
for j in axes(b, 2)
@@ -294,11 +299,22 @@ function MOI.get(
294299
F <: MOI.VectorAffineFunction{Float64},
295300
S <: MOI.PositiveSemidefiniteConeTriangle,
296301
}
297-
decomposition = model.outer_to_inner[index.value]
298-
result = zeros(Float64, decomposition.neqns * (decomposition.neqns + 1) ÷ 2)
299302

300-
for (value, clique) in zip(decomposition.values, decomposition.cliques)
301-
part = MOI.get(model.inner, attribute, MOI.ConstraintIndex{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle}(value))
303+
decomposition = model.outer_to_inner[index.value]
304+
neqns = decomposition.neqns
305+
values = decomposition.values
306+
cliques = decomposition.cliques
307+
result = zeros(Float64, neqns * (neqns + 1) ÷ 2)
308+
309+
for b in axes(cliques, 2)
310+
clique = view(cliques.rowval, nzrange(cliques, b))
311+
value = values[b]
312+
313+
part = MOI.get(
314+
model.inner,
315+
attribute,
316+
MOI.ConstraintIndex{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle}(value),
317+
)
302318

303319
for (j, w) in enumerate(clique)
304320
for (i, v) in enumerate(clique)
@@ -320,10 +336,20 @@ function MOI.get(
320336
S <: MOI.PositiveSemidefiniteConeTriangle,
321337
}
322338
decomposition = model.outer_to_inner[index.value]
323-
result = zeros(Float64, decomposition.neqns * (decomposition.neqns + 1) ÷ 2)
324-
325-
for (value, clique) in zip(decomposition.values, decomposition.cliques)
326-
part = MOI.get(model.inner, attribute, MOI.ConstraintIndex{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle}(value))
339+
neqns = decomposition.neqns
340+
values = decomposition.values
341+
cliques = decomposition.cliques
342+
result = zeros(Float64, neqns * (neqns + 1) ÷ 2)
343+
344+
for b in axes(cliques, 2)
345+
clique = view(cliques.rowval, nzrange(cliques, b))
346+
value = values[b]
347+
348+
part = MOI.get(
349+
model.inner,
350+
attribute,
351+
MOI.ConstraintIndex{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle}(value),
352+
)
327353

328354
for (j, w) in enumerate(clique)
329355
for (i, v) in enumerate(clique)

0 commit comments

Comments
 (0)