Add QPBlockData - #3048
Conversation
|
|
||
| # The product evaluators below ACCUMULATE into their output vector, so that | ||
| # they compose with the products of the other layers. Zero the output before | ||
| # the first call. |
There was a problem hiding this comment.
This needs to be something other than a comment.
| w::AbstractVector{T}, | ||
| ) where {T} | ||
| for (i, constraint) in enumerate(block.constraints) | ||
| _eval_Jv_product(constraint, y, x, w, block.parameters, i) |
There was a problem hiding this comment.
For example, we don't zero y before this first call.
| x::AbstractVector{T}, | ||
| w::AbstractVector{T}, | ||
| ) where {T} | ||
| for (i, constraint) in enumerate(block.constraints) |
There was a problem hiding this comment.
Yes, this is the source of bugs like madsuite-org/MadNLP.jl#641
There was a problem hiding this comment.
I'll just rename them to add_.... These eval_... need to not zero out so that we can combine the NL part with the quadratic part so I'll just create new add functions here. We could make them internal functions if we just used this QPBlockData internally and only expose the EvaluatorWithQuad. But if we want to first release an QPBlockData used by wrappers, we have to expose these new add_... functions. That's probably an argument toward EvaluatorWithQuad 😇
| σ::T, | ||
| μ::AbstractVector{T}, | ||
| ) where {T} | ||
| _eval_Hv_product(block.objective, H, x, v, σ, block.parameters) |
The generic functions MOI.eval_constraint_jacobian and MOI.eval_hessian_lagrangian are documented to return nothing: the caller constructs the sparsity pattern, so it knows how many entries are written. Returning the count invited callers to rely on a return value that no other evaluator provides.
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.
This is essentially a copy-paste from @odow 's implementation in Ipopt : https://github.com/jump-dev/Ipopt.jl/blob/b5b0e62b11aff4ae4bf0c5f0bc852c55b8953b4f/ext/IpoptMathOptInterfaceExt/utils.jl#L62 with these 3 functions added by @frapac in MadNLP https://github.com/madsuite-org/MadNLP.jl/blob/9947ee116559e9a2ab684a2006d37951f0bb9a6f/ext/MadNLPMOI/MOI_utils.jl#L654-L691
The changes I made on top of it were: adding
_in front of a few functions likeeval_function->_eval_function.The returned value of
eval_constraint_jacobian/eval_hessian_lagrangianwas returningnnz + 1, not it returnsnnz._is_parameter(x) = x.value >= 0x00f0000000000000is replaced withhaskey(block.parameters, x.value)which means the parameters need to be registered before being used.Downstream PRs: