C interface¶
The C API solves LPs from arrays in host memory. Functions are declared in
include/cupdlpx.h,
with public structures and enums in include/cupdlpx_types.h.
Installation¶
The C library and command-line executable are built from the same source tree. See hardware requirements for supported GPUs and required CUDA or ROCm versions.
Follow the native installation instructions to build the library.
Create a problem¶
lp_problem_t *create_lp_problem(
const double *objective_c,
const matrix_desc_t *A_desc,
const double *con_lb,
const double *con_ub,
const double *var_lb,
const double *var_ub,
const double *objective_constant,
const objective_sense_t *objective_sense
);
create_lp_problem copies the input arrays into a new lp_problem_t.
The caller retains ownership of the inputs. Free the problem with
lp_problem_free and the result of solve_lp_problem with
cupdlpx_result_free.
Only A_desc is required. Passing NULL for another argument selects its
default:
| Argument | Length | NULL default |
|---|---|---|
objective_c |
\(n\) | all zeros |
con_lb |
\(m\) | all \(-\infty\) |
con_ub |
\(m\) | all \(+\infty\) |
var_lb |
\(n\) | all \(-\infty\) |
var_ub |
\(n\) | all \(+\infty\) |
objective_constant |
1 | 0.0 |
objective_sense |
1 | OBJECTIVE_SENSE_MINIMIZE |
Matrix descriptors¶
matrix_desc_t accepts four host-memory layouts:
| Format | Enum | Required arrays |
|---|---|---|
| Row-major dense | matrix_dense |
A with \(m n\) values |
| CSR | matrix_csr |
row_ptr, col_ind, vals, nnz |
| CSC | matrix_csc |
col_ptr, row_ind, vals, nnz |
| COO | matrix_coo |
row_ind, col_ind, vals, nnz |
Indices are zero-based int values and numeric data uses double.
See the cuSPARSE matrix formats documentation.
Solve a small LP¶
#include "cupdlpx.h"
#include <math.h>
#include <stdio.h>
int main(void) {
double A[3][2] = {
{1.0, 2.0},
{0.0, 1.0},
{3.0, 2.0}
};
double c[2] = {1.0, 1.0};
double l[3] = {5.0, -INFINITY, -INFINITY};
double u[3] = {5.0, 2.0, 8.0};
matrix_desc_t matrix = {
.m = 3,
.n = 2,
.fmt = matrix_dense,
.data.dense = {.A = &A[0][0]},
};
lp_problem_t *problem = create_lp_problem(
c, &matrix, l, u, NULL, NULL, NULL, NULL);
if (problem == NULL) {
return 1;
}
pdhg_parameters_t params;
set_default_parameters(¶ms);
params.verbose = false;
params.termination_criteria.eps_optimal_relative = 1e-6;
params.termination_criteria.eps_feasible_relative = 1e-6;
cupdlpx_result_t *result = solve_lp_problem(problem, ¶ms);
if (result == NULL) {
lp_problem_free(problem);
return 1;
}
printf("termination reason: %d\n", result->termination_reason);
printf("objective: %.6f\n", result->primal_objective_value);
for (int j = 0; j < result->num_variables; ++j) {
printf("x[%d] = %.6f\n", j, result->primal_solution[j]);
}
cupdlpx_result_free(result);
lp_problem_free(problem);
return 0;
}
Warm starts¶
To warm-start the solver, disable presolve and provide a primal vector, a dual vector, or both:
double x0[2] = {1.0, 2.0};
double y0[3] = {1.0, -1.0, 0.0};
params.presolve = false;
set_start_values(problem, x0, y0);
The function copies the supplied arrays. Passing NULL clears the
corresponding starting vector.
Default parameters¶
Call set_default_parameters before changing fields:
pdhg_parameters_t params;
set_default_parameters(¶ms);
params.termination_criteria.time_sec_limit = 300.0;
params.feasibility_polishing = true;
Passing NULL as the second argument of solve_lp_problem also selects all
defaults:
See the parameter reference for the main fields and defaults.
Result fields¶
solve_lp_problem returns a cupdlpx_result_t *. Its main fields are:
| Result | cupdlpx_result_t field |
|---|---|
| Termination status | termination_reason |
| Original dimensions | num_variables, num_constraints, num_nonzeros |
| Reduced dimensions | num_reduced_variables, num_reduced_constraints, num_reduced_nonzeros |
| Primal solution, dual solution, dual slacks | primal_solution, dual_solution, reduced_cost |
| Objectives | primal_objective_value, dual_objective_value |
| Gaps | objective_gap, relative_objective_gap |
| Primal residuals | absolute_primal_residual, relative_primal_residual |
| Dual residuals | absolute_dual_residual, relative_dual_residual |
| Iterations | total_count, feasibility_iteration |
| Timings | cumulative_time_sec, rescaling_time_sec, presolve_time, feasibility_polishing_time |
| Ray measures | max_primal_ray_infeasibility, max_dual_ray_infeasibility, primal_ray_linear_objective, dual_ray_objective |
The arrays remain valid until cupdlpx_result_free(result) is called.
Compare termination_reason with symbolic members of termination_reason_t
rather than their integer values. See results and
status for interpretation.
Error handling¶
Creation and solve functions return NULL on failure. Check each returned
pointer before dereferencing it and release any objects already created on the
error path.