Thanks to visit codestin.com
Credit goes to github.com

Skip to content

yinxd15/cuPDLP-C

 
 

Repository files navigation

cuPDLP-C

Code for solving LP on GPU using first-order methods.

This is the C implementation of the Julia version cuPDLP.jl.

Compile

We use CMAKE to build CUPDLP. The current version is built on the Coin-OR CLP project. Please install the dependencies therein.

Once you setup CLP and CUDA, set the following environment variables.

export CLP_HOME=/path-to-clp
export COIN_HOME=/path-to-coinutils
export CUDA_HOME=/path-to-cuda

You can build the project with CUDA by setting -DBUILD_CUDA=ON (by default OFF, i.e., the CPU version):

  • in the debug mode:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_CUDA=ON ..
cmake --build . --target plc

then you can find the binary plc in the folder build/bin/.

To build the python extension culpy:

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_CUDA=ON ..
cmake --build . --target culpy

then you can find the dynamic library culpy.so/culpy.pyd in the folder build/lib/.

When using the release mode, we suggest the following options,

cmake -DBUILD_CUDA=ON \
-DCMAKE_C_FLAGS_RELEASE="-O2 -DNDEBUG" \
-DCMAKE_CXX_FLAGS_RELEASE="-O2 -DNDEBUG" \
-DCMAKE_CUDA_FLAGS_RELEASE="-O2 -DNDEBUG" ..

Usage

Executable Binary

Usage example: set nIterLim to 5000 and solve.

./bin/plc -fname <mpsfile> -nIterLim 5000
Param Type Range Default Description
fname str .mps or .mps.gz file of the LP instance
fout str ./solution.json .json file to save result
savesol bool true, false false whether to write solution to .json output
ifScaling bool true, false true Whether to use scaling
ifRuizScaling bool true, false true Whether to use Ruiz scaling (10 times)
ifL2Scaling bool true, false false Whether to use L2 scaling
ifPcScaling bool true, false true Whether to use Pock-Chambolle scaling
nIterLim int >=0 10000000 Maximum iteration number
eLineSearchMethod int 0-2 2 Choose line search: 0-fixed, 1-Malitsky, 2-Adaptive
dPrimalTol double >=0 1e-4 Primal feasibility tolerance for termination
dDualTol double >=0 1e-4 Dual feasibility tolerance for termination
dGapTol double >=0 1e-4 Duality gap tolerance for termination
dFeasTol double >=0 1e-8 Not used yet, maybe infeasibility tolerance
dTimeLim double >0 3600 Time limit (in seconds)
eRestartMethod int 0-1 1 Choose restart: 0-none, 1-GPU

Python Extension

Copy the lib culpy.so/culpy.pyd to (somewhere python can find). Then you can import culpy in Python. Currently there is only one function, solve, in culpy, whose signature is given by

def solve(
    nRows: int, nCols: int, nnz: int, nEqs: int,
    colMatBeg: np.ndarray, colMatIdx: np.ndarray, colMatElem: np.ndarray,
    b: np.ndarray, c: np.ndarray, params: dict[str, float | int],
) -> Dict[str, Any]: ...

A nRows x nCols sparse matrix (A) with nnz nonzero elements is given by colMatBeg, colMatIdx, colMatElem in CSC format. b should have length nRows and c should have length nCols. The first nEqs rows of A and b give the equation constraints, while the following (nRows - nEqs) rows give the inequality constraints. All parameters (except fname and fout) in the previous section could be overwrite in the params dict.

The result dictionary has the following items:

  • status
  • primal_vars: Numpy array format.
  • dual_vars: Numpy array format.
  • pcost
  • solve_time
  • setup_time
  • num_iters

A simple example of calling culpy could be found in py/culpy_test.py.

We recommend utilize the culpy package via cvxpy rather than call solve directly.

The PDLP Algorithm

Consider the generic linear programming problem:

$$ \begin{aligned} \min\ & c^\top x \\ \text{s.t.}\ & A x = b \\ & Gx \geq h \\ & l \leq x \leq u \end{aligned} $$

Equivalently, we solve the following saddle-point problem,

$$ \max_{y_1,\text{free}, y_2\geq 0}\min_{l\leq x\leq u}c^\top x - y^\top Kx + q^\top y $$

where dual variables $y^\top=(y_1^\top, y_2^\top)$, $K^\top = (A^\top, G^\top)$, $q^\top=(b^\top, h^\top)$.

Primal-Dual Hybrid Gradient (PDHG) algorithm takes the step as follows,

$$ \begin{aligned} x^{k+1} &= \Pi_{l\leq x\leq u} (x^k - \tau (c - K^\top y^k)) \\ y^{k+1} &= \Pi_{y_2\geq 0} (y^k + \sigma (q - K(2x^{k+1} - x^k))) \end{aligned} $$

The termination criteria contain the primal feasibility, dual feasibility, and duality gap.

$$ \begin{aligned} \left\| \begin{matrix} Ax-b \\ (h - Gx)^+ \end{matrix} \right\| &\leq \epsilon (1 + \|q\|) \\ \|c - K^\top y - \lambda\|&\leq \epsilon(1 + \|c\|) \\ |q^\top y + l^\top \lambda^+ - u^\top \lambda^- - c^\top x| &\leq \epsilon(1 + |c^\top x| + |q^\top y + l^\top \lambda^+ - u^\top \lambda^-|) \end{aligned} $$

where $\lambda = \Pi_\Lambda(c - K^\top y)$

$$ \lambda_i \begin{cases} = 0 & l_i=-\infty, u_i=+\infty\\ \leq 0 & l_i=-\infty, u_i<+\infty\\ \geq 0 & l_i<-\infty, u_i=+\infty\\ \text{free} & l_i>-\infty, u_i<+\infty \end{cases}.$$

$\|\cdot\|$ is 2-norm, and $|\cdot|$ is absolute value.

Authors

Dongdong Ge, Haodong Hu, Qi Huangfu, Jinsong Liu, Tianhao Liu, Haihao Lu, Jinwen Yang, Yinyu Ye, Chuwen Zhang

Contact

  • Jinsong Liu <github.com/JinsongLiu6>
  • Tianhao Liu <github.com/SkyLiu0>
  • Chuwen Zhang <github.com/bzhangcw>

About

Code for solving LP on GPU using first-order methods

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 80.6%
  • Cuda 8.9%
  • C++ 6.5%
  • CMake 3.5%
  • Python 0.5%