Skip to main content

Python bindings for cuPDLPx (GPU-accelerated first-order LP solver)

Project description

cuPDLPx: A GPU-Accelerated First-Order LP Solver

License GitHub release PyPI version arXiv arXiv

cuPDLPx is a GPU-accelerated linear programming solver based on a restarted Halpern PDHG method specifically tailored for GPU architectures. It incorporates a Halpern update scheme, an adaptive restart scheme, and a PID-controlled primal weight, resulting in substantial empirical improvements over its predecessor, cuPDLP, on standard LP benchmark suites.

Our work is presented in two papers:

Getting started

Follow these steps to build the solver and verify its installation.

Requirements

  • An NVIDIA GPU with CUDA support (≥12.4 required).
  • A C toolchain (gcc) and the NVIDIA CUDA Compiler (nvcc).

Build from Source

Clone the repository and compile the project using make.

make clean
make build

This will create the solver binary at ./build/cupdlpx.

Verifying the Installation

Run a small test problem to confirm that the solver was built correctly.

# 1. Download a test instance from the MIPLIB library
wget -P test/ https://miplib.zib.de/WebData/instances/2club200v15p5scn.mps.gz

# 2. Solve the problem and write output to the current directory (.)
./build/cupdlpx test/2club200v15p5scn.mps.gz test/

If the solver runs and creates output files, your installation is successful.

Usage Guide

Command-Line Interface

The solver is invoked with the following syntax, specifying an input file and an output directory.

./build/cupdlpx [OPTIONS] <mps_file> <output_directory>

Arguments

  • <mps_file>: The path to the input linear programming problem. Both plain (.mps) and gzipped (.mps.gz) files are supported.
  • <output_directory>: The directory where the output files will be saved.

Solver Options

Option Type Description Default
-h, --help flag Display the help message. N/A
-v, --verbose flag Enable verbose logging. false
--time_limit double Time limit in seconds. 3600.0
--iter_limit int Iteration limit. 2147483647
--eps_opt double Relative optimality tolerance. 1e-4
--eps_feas double Relative feasibility tolerance. 1e-4
--eps_infeas_detect double Infeasibility detection tolerance. 1e-10

Output Files

The solver generates three text files in the specified <output_directory>. The filenames are derived from the input file's basename. For an input INSTANCE.mps.gz, the output will be:

  • INSTANCE_summary.txt: Contains solver statistics, timings, and termination information.
  • INSTANCE_primal_solution.txt: The primal solution vector.
  • INSTANCE_dual_solution.txt: The dual solution vector.

Python Interface

In addition to the command-line and C APIs, cuPDLPx provides a Python interface (cupdlpx)
for building and solving LPs directly with NumPy and SciPy.

  • High-level, Pythonic API similar to commercial solvers.
  • Supports dense and sparse matrices.
  • Provides easy parameter management and solution attributes.

Install from PyPI:

pip install cupdlpx

Or build from source:

git clone https://github.com/MIT-Lu-Lab/cuPDLPx.git
cd cuPDLPx
pip install .

See the cupdlpx guide for full usage instructions, examples, and API details.

C Interface

Besides the command-line interface, cuPDLPx also provides a C API (interface.c) for directly solving LPs in memory. This is useful when integrating cuPDLPx into other C/C++ projects or when generating problems programmatically.

Functions and Parameters

The C API involves two main functions:

lp_problem_t* create_lp_problem(
    const double* c,                   // objective vector (length n)
    const matrix_desc_t* A,            // constraint matrix (m×n)
    const double* con_lb,              // constraint lower bounds (length m)
    const double* con_ub,              // constraint upper bounds (length m)
    const double* var_lb,              // variable lower bounds (length n)
    const double* var_ub,              // variable upper bounds (length n)
    const double* c0                   // scalar objective offset
);

cupdlpx_result_t* solve_lp_problem(
    const lp_problem_t* prob,
    const pdhg_parameters_t* params    // NULL → use default parameters
);

create_lp_problem parameters:

  • objective_c: Objective vector. If NULL, defaults to all zeros.
  • A_desc: Matrix descriptor. Supports matrix_dense, matrix_csr, matrix_csc, matrix_coo.
  • con_lb: Constraint lower bounds. If NULL, defaults to all -INFINITY.
  • con_ub: Constraint upper bounds. If NULL, defaults to all +INFINITY.
  • var_lb: Variable lower bounds. If NULL, defaults to all 0.0.
  • var_ub: Variable upper bounds. If NULL, defaults to all +INFINITY.
  • objective_constant: Scalar constant term added to the objective value. If NULL, defaults to 0.0.

solve_lp_problem parameters:

  • prob: An LP problem built with create_LP_problem.
  • params: Solver parameters. If NULL, the solver will use default parameters.

Example: Solving a Small LP

#include "cupdlpx/interface.h"
#include <math.h>
#include <stdio.h>

int main() {
    int m = 3; // number of constraints
    int n = 2; // number of variables

    // Dense matrix A
    double A[3][2] = {
        {1.0, 2.0},
        {0.0, 1.0},
        {3.0, 2.0}
    };

    // Describe A
    matrix_desc_t A_desc;
    A_desc.m = m; A_desc.n = n;
    A_desc.fmt = matrix_dense;
    A_desc.zero_tolerance = 0.0;
    A_desc.data.dense.A = &A[0][0];

    // Objective coefficients
    double c[2] = {1.0, 1.0};

    // Constraint bounds: l <= A x <= u
    double l[3] = {5.0, -INFINITY, -INFINITY};
    double u[3] = {5.0, 2.0, 8.0};

    // Build the problem
    lp_problem_t* prob = create_lp_problem(
        &A_desc, c, NULL, NULL, NULL, l, u);

    // Solve (NULL → use default parameters)
    cupdlpx_result_t* res = solve_lp_problem(prob, NULL);

    printf("Termination reason: %d\n", res->termination_reason);
    printf("Primal objective: %.6f\n", res->primal_objective_value);
    printf("Dual objective:   %.6f\n", res->dual_objective_value);
    for (int j = 0; j < res->num_variables; ++j) {
        printf("x[%d] = %.6f\n", j, res->primal_solution[j]);
    }

    lp_problem_free(prob);
    cupdlpx_result_free(res);

    return 0;
}

Reference

If you use cuPDLPx or the ideas in your work, please cite the source below.

@article{lu2025cupdlpx,
  title={cuPDLPx: A Further Enhanced GPU-Based First-Order Solver for Linear Programming},
  author={Lu, Haihao and Peng, Zedong and Yang, Jinwen},
  journal={arXiv preprint arXiv:2507.14051},
  year={2025}
}

@article{lu2024restarted,
  title={Restarted Halpern PDHG for linear programming},
  author={Lu, Haihao and Yang, Jinwen},
  journal={arXiv preprint arXiv:2407.16144},
  year={2024}
}

License

cuPDLPx is licensed under the Apache 2.0 License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cupdlpx-0.1.2.tar.gz (109.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cupdlpx-0.1.2-cp312-cp312-win_amd64.whl (250.9 kB view details)

Uploaded CPython 3.12Windows x86-64

File details

Details for the file cupdlpx-0.1.2.tar.gz.

File metadata

  • Download URL: cupdlpx-0.1.2.tar.gz
  • Upload date:
  • Size: 109.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for cupdlpx-0.1.2.tar.gz
Algorithm Hash digest
SHA256 7dae95c88038723dc0cf9b6a8ace324a3f769428388c731b1b8ca4050960c6fc
MD5 ed2ea6bbe7ad8cd9bb75d68ef15c0bdd
BLAKE2b-256 91d4af02965ae489168dbbb88a733e35312fb66ea05fe40d3e856ee3117c14b0

See more details on using hashes here.

File details

Details for the file cupdlpx-0.1.2-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: cupdlpx-0.1.2-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 250.9 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for cupdlpx-0.1.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 47e6a375a60759ff293513404e7444ff9da5b3d3f221bb8d6f1d8320803ede45
MD5 ab8a1d25b51fb0b40fa17828120c0759
BLAKE2b-256 3258cb53fe3f7de900597c391b3c0982c12728bbae6e2e1c04b6c692e221f354

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page