Skip to content

Commit 6725299

Browse files
authored
Rename the product functions of QPBlockData to add_...
The products accumulate into their output vector, so that the contributions of several blocks (the QP block, oracle constraints, and an MOI.AbstractNLPEvaluator) can be composed into the same output. This is incompatible with the contract of MOI.eval_constraint_jacobian_product and friends, which store the result, so the functions are renamed add_constraint_jacobian_product, add_constraint_jacobian_transpose_product, and add_hessian_lagrangian_product instead of overloading the MOI generic functions: QPBlockData is not an MOI.AbstractNLPEvaluator, so it does not have to define the same interface as evaluators. The private helpers are renamed _eval_... to _add_... accordingly.
1 parent d939dd4 commit 6725299

2 files changed

Lines changed: 76 additions & 17 deletions

File tree

‎docs/src/submodules/Nonlinear/reference.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ Nonlinear.ExprGraphOnly
7373
Nonlinear.SparseReverseMode
7474
Nonlinear.SymbolicMode
7575
Nonlinear.QPBlockData
76+
Nonlinear.add_constraint_jacobian_product
77+
Nonlinear.add_constraint_jacobian_transpose_product
78+
Nonlinear.add_hessian_lagrangian_product
7679
7780
```
7881

‎src/Nonlinear/qp_block_data.jl‎

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -575,11 +575,15 @@ function MOI.eval_hessian_lagrangian(
575575
return
576576
end
577577

578-
# The product evaluators below ACCUMULATE into their output vector, so that
579-
# they compose with the products of the other layers. Zero the output before
580-
# the first call.
581-
582-
function _eval_Jv_product(
578+
# The product functions below ACCUMULATE into their output vector, so that
579+
# the contributions of several blocks (for example, the QP block, the
580+
# vector-nonlinear-oracle constraints, and an `MOI.AbstractNLPEvaluator`) can
581+
# be composed into the same output. This is why they are not methods of the
582+
# corresponding `MOI.eval_...` functions, whose contract is to store the
583+
# result: `QPBlockData` is not an `MOI.AbstractNLPEvaluator`, so it does not
584+
# have to define the same interface as evaluators.
585+
586+
function _add_Jv_product(
583587
f::MOI.ScalarAffineFunction{T},
584588
y::AbstractVector{T},
585589
x::AbstractVector{T},
@@ -595,7 +599,7 @@ function _eval_Jv_product(
595599
return
596600
end
597601

598-
function _eval_Jv_product(
602+
function _add_Jv_product(
599603
f::MOI.ScalarQuadraticFunction{T},
600604
y::AbstractVector{T},
601605
x::AbstractVector{T},
@@ -622,7 +626,7 @@ function _eval_Jv_product(
622626
return
623627
end
624628

625-
function _eval_Jtv_product(
629+
function _add_Jtv_product(
626630
f::MOI.ScalarAffineFunction{T},
627631
y::AbstractVector{T},
628632
x::AbstractVector{T},
@@ -638,7 +642,7 @@ function _eval_Jtv_product(
638642
return
639643
end
640644

641-
function _eval_Jtv_product(
645+
function _add_Jtv_product(
642646
f::MOI.ScalarQuadraticFunction{T},
643647
y::AbstractVector{T},
644648
x::AbstractVector{T},
@@ -665,7 +669,7 @@ function _eval_Jtv_product(
665669
return
666670
end
667671

668-
function _eval_Hv_product(
672+
function _add_Hv_product(
669673
f::MOI.ScalarQuadraticFunction{T},
670674
H::AbstractVector{T},
671675
x::AbstractVector{T},
@@ -687,7 +691,7 @@ function _eval_Hv_product(
687691
return
688692
end
689693

690-
function _eval_Hv_product(
694+
function _add_Hv_product(
691695
::MOI.ScalarAffineFunction{T},
692696
H::AbstractVector{T},
693697
x::AbstractVector{T},
@@ -698,41 +702,93 @@ function _eval_Hv_product(
698702
return nothing
699703
end
700704

701-
function MOI.eval_constraint_jacobian_product(
705+
# These are used to add the QP contribution on top of the NL contribution.
706+
707+
"""
708+
add_constraint_jacobian_product(
709+
block::QPBlockData{T},
710+
y::AbstractVector{T},
711+
x::AbstractVector{T},
712+
w::AbstractVector{T},
713+
)::Nothing where {T}
714+
715+
Add to `y` the product of the Jacobian of the constraints of `block` at `x`
716+
with `w`.
717+
718+
Unlike [`MOI.eval_constraint_jacobian_product`](@ref), this function
719+
accumulates into `y` instead of storing the result, so that the contributions
720+
of several blocks can be composed: the caller is responsible for zeroing `y`
721+
before the first contribution.
722+
"""
723+
function add_constraint_jacobian_product(
702724
block::QPBlockData{T},
703725
y::AbstractVector{T},
704726
x::AbstractVector{T},
705727
w::AbstractVector{T},
706728
) where {T}
707729
for (i, constraint) in enumerate(block.constraints)
708-
_eval_Jv_product(constraint, y, x, w, block.parameters, i)
730+
_add_Jv_product(constraint, y, x, w, block.parameters, i)
709731
end
710732
return
711733
end
712734

713-
function MOI.eval_constraint_jacobian_transpose_product(
735+
"""
736+
add_constraint_jacobian_transpose_product(
737+
block::QPBlockData{T},
738+
y::AbstractVector{T},
739+
x::AbstractVector{T},
740+
w::AbstractVector{T},
741+
)::Nothing where {T}
742+
743+
Add to `y` the product of the transpose of the Jacobian of the constraints of
744+
`block` at `x` with `w`.
745+
746+
Unlike [`MOI.eval_constraint_jacobian_transpose_product`](@ref), this
747+
function accumulates into `y` instead of storing the result, so that the
748+
contributions of several blocks can be composed: the caller is responsible
749+
for zeroing `y` before the first contribution.
750+
"""
751+
function add_constraint_jacobian_transpose_product(
714752
block::QPBlockData{T},
715753
y::AbstractVector{T},
716754
x::AbstractVector{T},
717755
w::AbstractVector{T},
718756
) where {T}
719757
for (i, constraint) in enumerate(block.constraints)
720-
_eval_Jtv_product(constraint, y, x, w, block.parameters, i)
758+
_add_Jtv_product(constraint, y, x, w, block.parameters, i)
721759
end
722760
return
723761
end
724762

725-
function MOI.eval_hessian_lagrangian_product(
763+
"""
764+
add_hessian_lagrangian_product(
765+
block::QPBlockData{T},
766+
H::AbstractVector{T},
767+
x::AbstractVector{T},
768+
v::AbstractVector{T},
769+
σ::T,
770+
μ::AbstractVector{T},
771+
)::Nothing where {T}
772+
773+
Add to `H` the product of the Hessian of the Lagrangian of `block` at `x`,
774+
with objective weight `σ` and constraint weights `μ`, with `v`.
775+
776+
Unlike [`MOI.eval_hessian_lagrangian_product`](@ref), this function
777+
accumulates into `H` instead of storing the result, so that the contributions
778+
of several blocks can be composed: the caller is responsible for zeroing `H`
779+
before the first contribution.
780+
"""
781+
function add_hessian_lagrangian_product(
726782
block::QPBlockData{T},
727783
H::AbstractVector{T},
728784
x::AbstractVector{T},
729785
v::AbstractVector{T},
730786
σ::T,
731787
μ::AbstractVector{T},
732788
) where {T}
733-
_eval_Hv_product(block.objective, H, x, v, σ, block.parameters)
789+
_add_Hv_product(block.objective, H, x, v, σ, block.parameters)
734790
for (i, constraint) in enumerate(block.constraints)
735-
_eval_Hv_product(constraint, H, x, v, μ[i], block.parameters)
791+
_add_Hv_product(constraint, H, x, v, μ[i], block.parameters)
736792
end
737793
return
738794
end

0 commit comments

Comments
 (0)