Skip to content

[FEA] PDLP warm start through presolve (today: warm start works only without presolve and loses 3x net) + silent-NaN failure modes #1860

Description

@scepeda78

Is your feature request related to a problem?

We repeatedly solve the same large LP (7.2M rows × 2.27M cols, 14.3M nnz)
where only variable bounds change between solves (a subset of variables is
fixed via lo = hi, and the fixed values move slightly from one solve to the
next). Consecutive optimal solutions are nearly identical, so warm starting
should save most of the work. This is a standard pattern in iterative /
decomposition-style workflows.

With cuOpt 26.04 (nvidia/cuopt:latest-cuda12.9-py3.13, method=1 PDLP,
RTX 3060 12 GB, CUDA 12.9) we measured the whole option space:

  1. DataModel.set_initial_primal_solution / set_initial_dual_solution:
    accepted without error, but the solve returns termination status 0 with
    nan primal/dual objectives after ~4 s — no warning, no diagnostic.
  2. SolverSettings.set_pdlp_warm_start_data from a prior solve of a
    same-shape LP, default solver mode: termination status 0 with nan
    objectives after ~1.3 s — again silent.
  3. Same, but with pdlp_solver_mode = Stable2 (per the docs, warm start is
    supported in Stable2/Fast1) and presolve=0 on both solves so the spaces
    match: warm start works — 1,683 s vs 2,375 s cold in the same
    configuration (~1.4× saving). However:
    • cold with presolve solves the same LP in 547 s: presolve is
      worth ~11× on this instance, and warm-start data is incompatible with it
      (with presolve on: Invalid PDLPWarmStart data ... same amount of variables, since the presolved spaces differ). Net effect:
      warm+no-presolve loses ~3× against cold+presolve, so the feature cannot
      pay for itself today;
    • the warm-started solve reports optimal but its objective lands 0.34 %
      above
      the cold reference for the same LP (759,027 vs 756,484 at
      1e-4 relative tolerance) — far outside tolerance, suggesting the
      warm-started run terminates at a materially different point.
  4. Minor: set_parameter("presolve", False) raises
    ValueError: ... not an integer, and
    set_parameter("pdlp_solver_mode", "Stable2") is accepted at set time but
    fails inside Solve with ValueError: ... not an integer — both want
    ints despite doc examples.

Describe the solution you'd like

In order of usefulness:

  1. Warm start mapped through presolve on the solver side — accept
    warm-start data (or plain primal/dual seed vectors) for a problem with the
    same structure and modified bounds, and translate it into the presolved
    space. That is the version of this feature that can actually win, given
    presolve's ~11× value.
  2. When warm-start input is rejected or unusable (wrong mode, wrong space),
    fail loudly with a clear status/exception instead of returning
    termination status 0 with nan objectives.
  3. Either wire set_initial_primal_solution / set_initial_dual_solution as
    a true initial-iterate seed for LP, or document them as unsupported for LP
    and warn when they are set.

Additional context

All timings are from the same machine and instance and are reproducible; happy
to share exact call sequences and logs. Possibly related: the 0.34 % objective
deviation of the warm-started Stable2 run may deserve its own look.

(Same environment as #1859.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

awaiting responseThis expects a response from maintainer or contributor depending on who requested in last comment.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions