Precompiling packages... 1150.7 ms ✓ QuartoNotebookWorkerJSONExt (serial) 1 dependency successfully precompiled in 1 seconds
true
2026-08-13
A bakery can produce croissants (1.2€) or pains au chocolat (1.5€):
| Butter | Sugar | Flour | ||
|---|---|---|---|---|
| Croissant | 35g | 20g | 15g | |
| Pain au chocolat | 25g | 30g | 20g |
The ingredients have unit costs and supply limits:
| Butter | Sugar | Flour | |
|---|---|---|---|
| Unit cost | 2€/kg | 1€/kg | 0.5€/kg |
| Max supply | 19kg | 14kg | 12kg |
How much of each should they bake to maximize profits?
\[ \begin{align*} \max_{c, p, b, s, f} \quad & +(1.2c + 1.5p) \\ \phantom{\max_{c, p, b, s, f}} & - (2b + 1s + 0.5f) \\ \text{s.t.} \quad & 0 \leq c, p \\ & 0 \leq b \leq 19 \\ & 0 \leq s \leq 14 \\ \phantom{\max_{c, p, b, s, f}} & 0 \leq f \leq 12 \\ & 35c + 25p = 1000b \\ & 20c + 30p = 1000s \\ & 15c + 20p = 1000f \end{align*} \]
Optimize a linear objective subject to affine constraints:
\[\text{minimize} \quad c^\top x \quad \text{subject to} \quad A x \leq b\]
More useful than it seems:
Why parallelize?
Why not parallelize?
Visualization with lpviz.net by (Grand and Klamkin 2026).
GPUs are best leveraged with first-order methods (Lu and Yang 2025a):
| Package | Hardware | Type-generic | Batchable |
|---|---|---|---|
cuPDLPx |
NVIDIA, AMD | No | No |
HPR-LP-C |
NVIDIA | No | No |
HiGHS |
NVIDIA | No | No |
cuopt |
NVIDIA | No | Yes |
MPAX |
agnostic (via JAX) |
No | Yes |
BatchPDLP.jl |
NVIDIA | No | Yes |
CoolPDLP.jl |
Any | Yes | Yes |
GPUArrays.jl and KernelAbstractions.jl.cuSPARSEFloat32Float64Solves a bunch of problems in lockstep:
\[\text{minimize} \quad [c_1, ..., c_B]^\top x \quad \text{subject to} \quad A x \leq [b_1, ..., b_B]\]
The core primitive becomes sparse matrix-matrix product (SpMM).
Useful imports
Precompiling packages... 1150.7 ms ✓ QuartoNotebookWorkerJSONExt (serial) 1 dependency successfully precompiled in 1 seconds
true
GPU environment setup
Downloading artifact: netliblp
MILP instance 25fv47 from dataset Netlib:
- types:
- values Float64
- vectors Vector{Float64}
- matrices SparseArrays.SparseMatrixCSC{Float64, Int64}
- variables: 1571
- 1571 continuous
- 0 integer
- constraints: 821
- 305 inequalities
- 516 equalities
- nonzeros: 10400
Convergence stats with termination status OPTIMAL:
- KKT relative errors: primal 2.036e-02, dual 4.446e-02, gap 3.684e-02
- time elapsed: 0.006 seconds
- KKT passes: 100
Convergence stats with termination status OPTIMAL:
- KKT relative errors: primal 2.036e-02, dual 4.446e-02, gap 3.684e-02
- time elapsed: 0.454 seconds
- KKT passes: 100
model = JuMP.read_from_file(path; format=MOI.FileFormats.FORMAT_MPS)
JuMP.relax_integrality(model)
JuMP.set_optimizer(model, CoolPDLP.Optimizer)
JuMP.set_silent(model)
JuMP.set_attribute(model, "float_type", Float32)
JuMP.set_attribute(model, "int_type", Int32)
JuMP.set_attribute(model, "matrix_type", GPUSparseMatrixCOO)
JuMP.set_attribute(model, "backend", backend)
JuMP.set_attribute(model, "termination_reltol", 1.0e-1)
JuMP.set_attribute(model, "time_limit", 30.0)
JuMP.optimize!(model)
JuMP.is_solved_and_feasible(model)┌ Warning: Got mismatched float type: solving in Float32 but returning the solution in Float64. └ @ CoolPDLP ~/.julia/packages/CoolPDLP/fN3I2/src/MOI_wrapper.jl:225
true
Reactant.jl