Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
75a19a5
batch_* API & dumb VectorBatchNLPModel
klamike Nov 17, 2025
1416856
add missing SimpleNLPModel methods
klamike Nov 17, 2025
9f7752e
counters
klamike Nov 17, 2025
d34272b
cleanup
klamike Nov 18, 2025
4c3531c
update
klamike Nov 20, 2025
90b332a
stubs
klamike Nov 20, 2025
66c2c9d
rm comment
klamike Nov 20, 2025
79f86ea
inplace
klamike Nov 20, 2025
5c83737
reduce lambdas
klamike Nov 20, 2025
2f708ec
no inplace ops, test with parametric simple model
klamike Nov 20, 2025
dd57069
Vararg{Any} -> Vararg{T}
klamike Nov 20, 2025
f8a510d
simplify inplace syntax
klamike Nov 20, 2025
6838778
add todo
klamike Nov 24, 2025
bf3df92
1.12 gi
klamike Dec 5, 2025
446cd4c
revert
klamike Dec 5, 2025
706f99d
try `@eval`
klamike Dec 6, 2025
7ecaaf2
simplify inputs/outputs
klamike Dec 10, 2025
e07a4fd
back to old API
klamike Dec 10, 2025
786b01e
Polish the batch API
amontoison Feb 3, 2026
539ee4f
Add BatchNLPModelMeta
amontoison Feb 3, 2026
d9c6ac9
Update batch_api.jl
amontoison Feb 4, 2026
ee763e9
Trim a little bit the content of the PR
amontoison Feb 4, 2026
49b4269
Update batch_meta.jl
amontoison Feb 4, 2026
487d53a
Apply suggestion from @amontoison
amontoison Feb 4, 2026
e2364f6
rm new simplenlpmodel methods
klamike Feb 5, 2026
c97d64c
nits
klamike Feb 5, 2026
8ba159a
typos
klamike Feb 5, 2026
ed1bdc2
bugs
klamike Feb 5, 2026
b35d114
simple batch model
klamike Feb 5, 2026
31d9cd8
tests
klamike Feb 5, 2026
d8009b3
VI -> Vector{Int}
amontoison Feb 5, 2026
9d55284
Fix the tests
amontoison Feb 5, 2026
d4c5cae
Support dense API
amontoison Feb 14, 2026
19c24f3
Support dense API
amontoison Feb 14, 2026
b67f04e
Remove the prefix batch_ and rely on multiple dispatch
amontoison Feb 18, 2026
570618e
Remove a few things in the batch meta
amontoison Feb 18, 2026
0b6e25b
Update src/nlp/batch_meta.jl
amontoison Feb 24, 2026
edcec16
Update the API
amontoison Feb 24, 2026
3694eff
[documentation] Add a page about batch API
amontoison Feb 25, 2026
a2fe4eb
Finalize the documentation
amontoison Feb 25, 2026
474a78d
Finalize the documentation
amontoison Feb 25, 2026
634dbc0
Fix the tests
amontoison Feb 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
*.jl.mem
docs/build
docs/site
Manifest.toml
Manifest*.toml
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ makedocs(
"Guidelines" => "guidelines.md",
"Tools" => "tools.md",
"API" => "api.md",
"Batch API" => "batch_api.md",
"Internals" => "internals.md",
"Reference" => "reference.md",
],
Expand Down
103 changes: 103 additions & 0 deletions docs/src/batch_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Batch API

This section documents the batch API of `NLPModels.jl`.
The batch API reuses the same symbols as the standard (non-batch) API.
The only new in-place function is `obj!`, which returns a vector of all objectives.

---

## Abstract types

- [`AbstractBatchNLPModel`](@ref)
- [`AbstractBatchNLPModelMeta`](@ref)

---

## Batch metadata

- [`BatchNLPModelMeta`](@ref)

---

## Objectives

| Function | Signature |
|:--------:|:---------:|
| `obj` | `obj(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix)` |
| `obj!` | `obj!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bf::AbstractVector)` |

---

## Gradients

| Function | Signature |
|:--------:|:---------:|
| `grad` | `grad(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix)` |
| `grad!` | `grad!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bg::AbstractMatrix)` |

---

## Constraints

| Function | Signature |
|:--------:|:---------:|
| `cons` | `cons(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix)` |
| `cons!` | `cons!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bc::AbstractMatrix)` |

---

## Sparse jacobians

| Function | Signature |
|:--------:|:---------:|
| `jac_structure` | `(jrows, jcols) = jac_structure(bnlp::AbstractBatchNLPModel)` |
| `jac_structure!` | `(jrows, jcols) = jac_structure!(bnlp::AbstractBatchNLPModel, jrows::AbstractVector, jcols::AbstractVector)` |
| `jac_coord` | `bjvals = jac_coord(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix)` |
| `jac_coord!` | `bjvals = jac_coord!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bjvals::AbstractMatrix)` |

---

## Dense Jacobians

| Function | Signature |
|:--------:|:---------:|
| `jac_dense!` | `bJx = jac_dense!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bJx::AbstractArray)` |

---

## Jacobian-vector products

| Function | Signature |
|:--------:|:---------:|
| `jprod` | `bJv = jprod(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bv::AbstractMatrix)` |
| `jprod!` | `bJv = jprod!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bv::AbstractMatrix, bJv::AbstractMatrix)` |
| `jtprod` | `bJtv = jtprod(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bv::AbstractMatrix)` |
| `jtprod!` | `bJtv = jtprod!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, bv::AbstractMatrix, bJtv::AbstractMatrix)` |

---

## Sparse Hessians of the Lagrangian

| Function | Signature |
|:--------:|:---------:|
| `hess_structure` | `(hrows, hcols) = hess_structure(bnlp::AbstractBatchNLPModel)` |
| `hess_structure!` | `(hrows, hcols) = hess_structure!(bnlp::AbstractBatchNLPModel, hrows::AbstractVector, hcols::AbstractVector)` |
| `hess_coord` | `bhvals = hess_coord(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, by::AbstractMatrix, bobj_weight::AbstractVector)` |
| `hess_coord!` | `bhvals = hess_coord!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, by::AbstractMatrix, bobj_weight::AbstractVector, bhvals::AbstractMatrix)` |

---

## Dense Hessians of the Lagrangian

| Function | Signature |
|:--------:|:---------:|
| `hess_dense!` | `bHx = hess_dense!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, by::AbstractMatrix, bobj_weight::AbstractVector, bHx::AbstractArray)` |

---

## Hessian-vector products

| Function | Signature |
|:--------:|:---------:|
| `hprod` | `bHv = hprod(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, by::AbstractMatrix, bv::AbstractMatrix, bobj_weight::AbstractVector)` |
| `hprod!` | `bHv = hprod!(bnlp::AbstractBatchNLPModel, bx::AbstractMatrix, by::AbstractMatrix, bv::AbstractMatrix, bobj_weight::AbstractVector, bHv::AbstractMatrix)` |
12 changes: 6 additions & 6 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Reference

## Contents

```@contents
Pages = ["reference.md"]
```

## Index

```@index
Pages = ["reference.md"]
```

```@autodocs
Modules = [NLPModels]
```
```
2 changes: 2 additions & 0 deletions src/NLPModels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,7 @@ for f in ["utils", "api", "counters", "meta", "show", "tools"]
include("nlp/$f.jl")
include("nls/$f.jl")
end
include("nlp/batch_api.jl")
include("nlp/batch_meta.jl")

end # module
90 changes: 90 additions & 0 deletions src/nlp/batch_api.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
export AbstractBatchNLPModel
export obj!

"""
AbstractBatchNLPModel

Abstract base type for batched nonlinear optimization models.

Each model in the batch has the same number of variables and constraints,
and the sparsity patterns of the Jacobian and the Hessian of the Lagrangian are identical across the batch.
"""
abstract type AbstractBatchNLPModel{T, S} end

function obj(bnlp::AbstractBatchNLPModel{T, S}, bx::AbstractMatrix) where {T, S}
bf = S(undef, 1, bnlp.meta.nbatch) |> vec
obj!(bnlp, bx, bf)
return bf
end

"""
bf = obj!(bnlp, bx)
"""
function obj! end

function grad(bnlp::AbstractBatchNLPModel{T, S}, bx::AbstractMatrix) where {T, S}
bg = S(undef, bnlp.meta.nvar, bnlp.meta.nbatch)
grad!(bnlp, bx, bg)
return bg
end

function cons(bnlp::AbstractBatchNLPModel{T, S}, bx::AbstractMatrix) where {T, S}
bc = S(undef, bnlp.meta.ncon, bnlp.meta.nbatch)
cons!(bnlp, bx, bc)
return bc
end

function jac_structure(bnlp::AbstractBatchNLPModel)
jrows = Vector{Int}(undef, bnlp.meta.nnzj)
jcols = Vector{Int}(undef, bnlp.meta.nnzj)
jac_structure!(bnlp, jrows, jcols)
return (jrows, jcols)
end

function jac_coord(bnlp::AbstractBatchNLPModel{T, S}, bx::AbstractMatrix) where {T, S}
bjvals = S(undef, bnlp.meta.nnzj, bnlp.meta.nbatch)
jac_coord!(bnlp, bx, bjvals)
return bjvals
end

function jprod(bnlp::AbstractBatchNLPModel{T, S}, bx::AbstractMatrix, bv::AbstractMatrix) where {T, S}
bJv = S(undef, bnlp.meta.ncon, bnlp.meta.nbatch)
jprod!(bnlp, bx, bv, bJv)
return bJv
end

function jtprod(bnlp::AbstractBatchNLPModel{T, S}, bx::AbstractMatrix, bv::AbstractMatrix) where {T, S}
bJtv = S(undef, bnlp.meta.nvar, bnlp.meta.nbatch)
jtprod!(bnlp, bx, bv, bJtv)
return bJtv
end

function hess_structure(bnlp::AbstractBatchNLPModel)
hrows = Vector{Int}(undef, bnlp.meta.nnzh)
hcols = Vector{Int}(undef, bnlp.meta.nnzh)
hess_structure!(bnlp, hrows, hcols)
return hrows, hcols
end

function hess_coord(
bnlp::AbstractBatchNLPModel{T, S},
bx::AbstractMatrix,
by::AbstractMatrix,
bobj_weight::AbstractVector,
) where {T, S}
bhvals = S(undef, bnlp.meta.nnzh, bnlp.meta.nbatch)
hess_coord!(bnlp, bx, by, bobj_weight, bhvals)
return bhvals
end

function hprod(
bnlp::AbstractBatchNLPModel{T, S},
bx::AbstractMatrix,
by::AbstractMatrix,
bv::AbstractMatrix,
bobj_weight::AbstractVector,
) where {T, S}
bHv = S(undef, bnlp.meta.nvar, bnlp.meta.nbatch)
hprod!(bnlp, bx, by, bv, bobj_weight, bHv)
return bHv
end
145 changes: 145 additions & 0 deletions src/nlp/batch_meta.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
export AbstractBatchNLPModelMeta, BatchNLPModelMeta

"""
AbstractBatchNLPModelMeta

Abstract base type for metadata related to batched nonlinear optimization models.
"""
abstract type AbstractBatchNLPModelMeta{T, S} end

"""
BatchNLPModelMeta <: AbstractBatchNLPModelMeta

A composite type that represents the main features of a batch of
nonlinear optimization problems sharing the same structure.

Each batch contains `nbatch` independent NLP models of the form:

optimize objᵢ(x)
subject to lvarᵢ ≤ x ≤ uvarᵢ
lconᵢ ≤ consᵢ(x) ≤ uconᵢ

for i = 1, ..., nbatch.

Each model variable vector `x` has dimension `nvar`, and constraint vector
`consᵢ(x)` has dimension `ncon`.

All batch data are stored in matrices of size:

- `(nvar, nbatch)` for variables and bounds (`x0`, `lvar`, `uvar`)
- `(ncon, nbatch)` for constraints and multipliers (`y0`, `lcon`, `ucon`)

---

BatchNLPModelMeta(nbatch::Int, nvar::Int; kwargs...)

Create a `BatchNLPModelMeta` with `nbatch` models, each having `nvar` variables.
The following keyword arguments are accepted:
- `x0`: initial guess
- `lvar`: matrix of lower bounds
- `uvar`: matrix of upper bounds
- `ncon`: number of general constraints
- `y0`: initial Lagrange multipliers
- `lcon`: matrix of constraint lower bounds
- `ucon`: matrix of constraint upper bounds
- `nnzj`: number of elements needed to store the nonzeros in the sparse Jacobian
- `nnzh`: number of elements needed to store the nonzeros in the sparse Hessian
- `minimize`: true if optimize == minimize
- `islp`: true if the problems are linear programs
- `name`: problem name for the batch
- `sparse_jacobian`: indicates whether the Jacobian of the constraints is sparse
- `sparse_hessian`: indicates whether the Hessian of the Lagrangian is sparse
- `grad_available`: indicates whether the gradient of the objective is available
- `jac_available`: indicates whether the Jacobian of the constraints is available
- `hess_available`: indicates whether the Hessian of the Lagrangian is available
- `jprod_available`: indicates whether the Jacobian-vector product `J * v` is available
- `jtprod_available`: indicates whether the transpose Jacobian-vector product `J' * v` is available
- `hprod_available`: indicates whether the Hessian-vector product of the Lagrangian `H * v` is available
"""
struct BatchNLPModelMeta{T, S} <: AbstractBatchNLPModelMeta{T, S}
nbatch::Int
nvar::Int
x0::S
lvar::S
uvar::S
ncon::Int
y0::S
lcon::S
ucon::S
nnzj::Int
nnzh::Int
minimize::Bool
islp::Bool
name::String
sparse_jacobian::Bool
sparse_hessian::Bool
grad_available::Bool
jac_available::Bool
hess_available::Bool
jprod_available::Bool
jtprod_available::Bool
hprod_available::Bool
end

for field in fieldnames(BatchNLPModelMeta)
meth = Symbol("get_", field)
@eval begin
$meth(meta::AbstractBatchNLPModelMeta) = getproperty(meta, $(QuoteNode(field)))
end
@eval $meth(bnlp::AbstractBatchNLPModel) = $meth(bnlp.meta)
@eval export $meth
end

function BatchNLPModelMeta{T, S}(
nbatch::Int,
nvar::Int;
x0::S = fill!(S(undef, nvar, nbatch), zero(T)),
lvar::S = fill!(S(undef, nvar, nbatch), T(-Inf)),
uvar::S = fill!(S(undef, nvar, nbatch), T(Inf)),
ncon::Int = 0,
y0::S = fill!(S(undef, ncon, nbatch), zero(T)),
lcon::S = fill!(S(undef, ncon, nbatch), T(-Inf)),
ucon::S = fill!(S(undef, ncon, nbatch), T(Inf)),
nnzj::Int = nvar * ncon,
nnzh::Int = nvar * (nvar + 1) ÷ 2,
minimize::Bool = true,
islp::Bool = false,
name::String = "Batch NLP",
sparse_jacobian::Bool = true,
sparse_hessian::Bool = true,
grad_available::Bool = true,
jac_available::Bool = (ncon > 0),
hess_available::Bool = true,
jprod_available::Bool = (ncon > 0),
jtprod_available::Bool = (ncon > 0),
hprod_available::Bool = true,
) where {T, S}
if (nbatch < 1) || (nvar < 1) || (ncon < 0) || (nnzj < 0) || (nnzh < 0)
error("Nonsensical dimensions")
end

BatchNLPModelMeta{T, S}(
nbatch,
nvar,
x0,
lvar,
uvar,
ncon,
y0,
lcon,
ucon,
nnzj,
nnzh,
minimize,
islp,
name,
sparse_jacobian,
sparse_hessian,
grad_available,
jac_available,
hess_available,
jprod_available,
jtprod_available,
hprod_available,
)
end
Loading
Loading