LP C API Examples#

Example With Data#

This example demonstrates how to use the LP solver in C. More details on the API can be found in C API.

The example code is available at examples/cuopt-c/lp/simple_lp_example.c (download):

  1/*
  2 * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  3 * SPDX-License-Identifier: Apache-2.0
  4 */
  5/*
  6 * Simple LP C API Example
  7 *
  8 * This example demonstrates how to use the cuOpt C API for linear programming.
  9 *
 10 * Problem:
 11 *   Minimize: -0.2*x1 + 0.1*x2
 12 *   Subject to:
 13 *     3.0*x1 + 4.0*x2 <= 5.4
 14 *     2.7*x1 + 10.1*x2 <= 4.9
 15 *     x1, x2 >= 0
 16 *
 17 * Expected Output:
 18 *   Termination status: Optimal (1)
 19 *   Solve time: 0.000013 seconds
 20 *   Objective value: -0.360000
 21 *   x1 = 1.800000
 22 *   x2 = 0.000000
 23 *
 24 * Build:
 25 *   gcc -I $INCLUDE_PATH -L $LIBCUOPT_LIBRARY_PATH -o simple_lp_example simple_lp_example.c -lcuopt
 26 *
 27 * Run:
 28 *   ./simple_lp_example
 29 */
 30
 31// Include the cuOpt linear programming solver header
 32#include <cuopt/linear_programming/cuopt_c.h>
 33#include <stdio.h>
 34#include <stdlib.h>
 35
 36// Convert termination status to string
 37const char* termination_status_to_string(cuopt_int_t termination_status)
 38{
 39  switch (termination_status) {
 40    case CUOPT_TERIMINATION_STATUS_OPTIMAL:
 41      return "Optimal";
 42    case CUOPT_TERIMINATION_STATUS_INFEASIBLE:
 43      return "Infeasible";
 44    case CUOPT_TERIMINATION_STATUS_UNBOUNDED:
 45      return "Unbounded";
 46    case CUOPT_TERIMINATION_STATUS_ITERATION_LIMIT:
 47      return "Iteration limit";
 48    case CUOPT_TERIMINATION_STATUS_TIME_LIMIT:
 49      return "Time limit";
 50    case CUOPT_TERIMINATION_STATUS_NUMERICAL_ERROR:
 51      return "Numerical error";
 52    case CUOPT_TERIMINATION_STATUS_PRIMAL_FEASIBLE:
 53      return "Primal feasible";
 54    case CUOPT_TERIMINATION_STATUS_FEASIBLE_FOUND:
 55      return "Feasible found";
 56    default:
 57      return "Unknown";
 58  }
 59}
 60
 61// Test simple LP problem
 62cuopt_int_t test_simple_lp()
 63{
 64  cuOptOptimizationProblem problem = NULL;
 65  cuOptSolverSettings settings = NULL;
 66  cuOptSolution solution = NULL;
 67
 68  /* Solve the following LP:
 69     minimize -0.2*x1 + 0.1*x2
 70     subject to:
 71     3.0*x1 + 4.0*x2 <= 5.4
 72     2.7*x1 + 10.1*x2 <= 4.9
 73     x1, x2 >= 0
 74  */
 75
 76  cuopt_int_t num_variables = 2;
 77  cuopt_int_t num_constraints = 2;
 78  cuopt_int_t nnz = 4;
 79
 80  // CSR format constraint matrix
 81  // https://docs.nvidia.com/nvpl/latest/sparse/storage_format/sparse_matrix.html#compressed-sparse-row-csr
 82  // From the constraints:
 83  // 3.0*x1 + 4.0*x2 <= 5.4
 84  // 2.7*x1 + 10.1*x2 <= 4.9
 85  cuopt_int_t row_offsets[] = {0, 2, 4};
 86  cuopt_int_t column_indices[] = {0, 1, 0, 1};
 87  cuopt_float_t values[] = {3.0, 4.0, 2.7, 10.1};
 88
 89  // Objective coefficients
 90  // From the objective function: minimize -0.2*x1 + 0.1*x2
 91  // -0.2 is the coefficient of x1
 92  // 0.1 is the coefficient of x2
 93  cuopt_float_t objective_coefficients[] = {-0.2, 0.1};
 94
 95  // Constraint bounds
 96  // From the constraints:
 97  // 3.0*x1 + 4.0*x2 <= 5.4
 98  // 2.7*x1 + 10.1*x2 <= 4.9
 99  cuopt_float_t constraint_upper_bounds[] = {5.4, 4.9};
100  cuopt_float_t constraint_lower_bounds[] = {-CUOPT_INFINITY, -CUOPT_INFINITY};
101
102  // Variable bounds
103  // From the constraints:
104  // x1, x2 >= 0
105  cuopt_float_t var_lower_bounds[] = {0.0, 0.0};
106  cuopt_float_t var_upper_bounds[] = {CUOPT_INFINITY, CUOPT_INFINITY};
107
108  // Variable types (continuous)
109  // From the constraints:
110  // x1, x2 >= 0
111  char variable_types[] = {CUOPT_CONTINUOUS, CUOPT_CONTINUOUS};
112
113  cuopt_int_t status;
114  cuopt_float_t time;
115  cuopt_int_t termination_status;
116  cuopt_float_t objective_value;
117
118  printf("Creating and solving simple LP problem...\n");
119
120  // Create the problem
121  status = cuOptCreateRangedProblem(num_constraints,
122                                   num_variables,
123                                   CUOPT_MINIMIZE,
124                                   0.0,            // objective offset
125                                   objective_coefficients,
126                                   row_offsets,
127                                   column_indices,
128                                   values,
129                                   constraint_lower_bounds,
130                                   constraint_upper_bounds,
131                                   var_lower_bounds,
132                                   var_upper_bounds,
133                                   variable_types,
134                                   &problem);
135  if (status != CUOPT_SUCCESS) {
136    printf("Error creating problem: %d\n", status);
137    goto DONE;
138  }
139
140  // Create solver settings
141  status = cuOptCreateSolverSettings(&settings);
142  if (status != CUOPT_SUCCESS) {
143    printf("Error creating solver settings: %d\n", status);
144    goto DONE;
145  }
146
147  // Set solver parameters
148  status = cuOptSetFloatParameter(settings, CUOPT_ABSOLUTE_PRIMAL_TOLERANCE, 0.0001);
149  if (status != CUOPT_SUCCESS) {
150    printf("Error setting optimality tolerance: %d\n", status);
151    goto DONE;
152  }
153
154  // Solve the problem
155  status = cuOptSolve(problem, settings, &solution);
156  if (status != CUOPT_SUCCESS) {
157    printf("Error solving problem: %d\n", status);
158    goto DONE;
159  }
160
161  // Get solution information
162  status = cuOptGetSolveTime(solution, &time);
163  if (status != CUOPT_SUCCESS) {
164    printf("Error getting solve time: %d\n", status);
165    goto DONE;
166  }
167
168  status = cuOptGetTerminationStatus(solution, &termination_status);
169  if (status != CUOPT_SUCCESS) {
170    printf("Error getting termination status: %d\n", status);
171    goto DONE;
172  }
173
174  status = cuOptGetObjectiveValue(solution, &objective_value);
175  if (status != CUOPT_SUCCESS) {
176    printf("Error getting objective value: %d\n", status);
177    goto DONE;
178  }
179
180  // Print results
181  printf("\nResults:\n");
182  printf("--------\n");
183  printf("Termination status: %s (%d)\n", termination_status_to_string(termination_status), termination_status);
184  printf("Solve time: %f seconds\n", time);
185  printf("Objective value: %f\n", objective_value);
186
187  // Get and print solution variables
188  cuopt_float_t* solution_values = (cuopt_float_t*)malloc(num_variables * sizeof(cuopt_float_t));
189  if (solution_values == NULL) {
190    printf("Error allocating solution values\n");
191    goto DONE;
192  }
193  status = cuOptGetPrimalSolution(solution, solution_values);
194  if (status != CUOPT_SUCCESS) {
195    printf("Error getting solution values: %d\n", status);
196    free(solution_values);
197    goto DONE;
198  }
199
200  printf("\nPrimal Solution: Solution variables \n");
201  for (cuopt_int_t i = 0; i < num_variables; i++) {
202    printf("x%d = %f\n", i + 1, solution_values[i]);
203  }
204  free(solution_values);
205
206DONE:
207  cuOptDestroyProblem(&problem);
208  cuOptDestroySolverSettings(&settings);
209  cuOptDestroySolution(&solution);
210
211  return status;
212}
213
214int main() {
215  // Run the test
216  cuopt_int_t status = test_simple_lp();
217
218  if (status == CUOPT_SUCCESS) {
219    printf("\nTest completed successfully!\n");
220    return 0;
221  } else {
222    printf("\nTest failed with status: %d\n", status);
223    return 1;
224  }
225}

It is necessary to have the path for include and library dirs ready, if you know the paths, please add them to the path variables directly. Otherwise, run the following commands to find the path and assign it to the path variables. The following commands are for Linux and might fail in cases where the cuopt library is not installed or there are multiple cuopt libraries in the system.

If you have built it locally, libcuopt.so will be in the build directory cpp/build and include directoy would be cpp/include.

# Find the cuopt header file and assign to INCLUDE_PATH
INCLUDE_PATH=$(find / -name "cuopt_c.h" -path "*/linear_programming/*" -printf "%h\n" | sed 's/\/linear_programming//' 2>/dev/null)
# Find the libcuopt library and assign to LIBCUOPT_LIBRARY_PATH
LIBCUOPT_LIBRARY_PATH=$(find / -name "libcuopt.so" 2>/dev/null)

Build and run the example

# Build and run the example
gcc -I $INCLUDE_PATH -L $LIBCUOPT_LIBRARY_PATH -o simple_lp_example simple_lp_example.c -lcuopt
./simple_lp_example

You should see the following output:

Output#
Creating and solving simple LP problem...
Solving a problem with 2 constraints 2 variables (0 integers) and 4 nonzeros
Objective offset 0.000000 scaling_factor 1.000000
Running concurrent

Dual simplex finished in 0.00 seconds
   Iter    Primal Obj.      Dual Obj.    Gap        Primal Res.  Dual Res.   Time
      0 +0.00000000e+00 +0.00000000e+00  0.00e+00   0.00e+00     2.00e-01   0.011s
PDLP finished
Concurrent time:  0.013s
Solved with dual simplex
Status: Optimal   Objective: -3.60000000e-01  Iterations: 1  Time: 0.013s

Results:
--------
Termination status: Optimal (1)
Solve time: 0.000013 seconds
Objective value: -0.360000

Primal Solution: Solution variables
x1 = 1.800000
x2 = 0.000000

Test completed successfully!

Example With MPS File#

This example demonstrates how to use the cuOpt linear programming solver in C to solve an MPS file.

The example code is available at examples/cuopt-c/lp/mps_file_example.c (download):

  1/*
  2 * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  3 * SPDX-License-Identifier: Apache-2.0
  4 */
  5/*
  6 * LP MPS File C API Example
  7 *
  8 * This example demonstrates how to solve LP problems from MPS files using the cuOpt C API.
  9 *
 10 * Problem (from MPS file):
 11 *   Minimize: -0.2*VAR1 + 0.1*VAR2
 12 *   Subject to:
 13 *     3*VAR1 + 4*VAR2 <= 5.4
 14 *     2.7*VAR1 + 10.1*VAR2 <= 4.9
 15 *     VAR1, VAR2 >= 0
 16 *
 17 * Expected Output:
 18 *   Number of variables: 2
 19 *   Termination status: Optimal (1)
 20 *   Solve time: 0.000014 seconds
 21 *   Objective value: -0.360000
 22 *   x1 = 1.800000
 23 *   x2 = 0.000000
 24 *
 25 * Build:
 26 *   gcc -I $INCLUDE_PATH -L $LIBCUOPT_LIBRARY_PATH -o lp_example_mps lp_example_mps.c -lcuopt
 27 *
 28 * Run:
 29 *   ./lp_example_mps sample.mps
 30 */
 31
 32#include <cuopt/linear_programming/cuopt_c.h>
 33#include <stdio.h>
 34#include <stdlib.h>
 35
 36const char* termination_status_to_string(cuopt_int_t termination_status)
 37{
 38  switch (termination_status) {
 39    case CUOPT_TERIMINATION_STATUS_OPTIMAL:
 40      return "Optimal";
 41    case CUOPT_TERIMINATION_STATUS_INFEASIBLE:
 42      return "Infeasible";
 43    case CUOPT_TERIMINATION_STATUS_UNBOUNDED:
 44      return "Unbounded";
 45    case CUOPT_TERIMINATION_STATUS_ITERATION_LIMIT:
 46      return "Iteration limit";
 47    case CUOPT_TERIMINATION_STATUS_TIME_LIMIT:
 48      return "Time limit";
 49    case CUOPT_TERIMINATION_STATUS_NUMERICAL_ERROR:
 50      return "Numerical error";
 51    case CUOPT_TERIMINATION_STATUS_PRIMAL_FEASIBLE:
 52      return "Primal feasible";
 53    case CUOPT_TERIMINATION_STATUS_FEASIBLE_FOUND:
 54      return "Feasible found";
 55    default:
 56      return "Unknown";
 57  }
 58}
 59
 60cuopt_int_t solve_mps_file(const char* filename)
 61{
 62  cuOptOptimizationProblem problem = NULL;
 63  cuOptSolverSettings settings = NULL;
 64  cuOptSolution solution = NULL;
 65  cuopt_int_t status;
 66  cuopt_float_t time;
 67  cuopt_int_t termination_status;
 68  cuopt_float_t objective_value;
 69  cuopt_int_t num_variables;
 70  cuopt_float_t* solution_values = NULL;
 71
 72  printf("Reading and solving MPS file: %s\n", filename);
 73
 74  // Create the problem from MPS file
 75  status = cuOptReadProblem(filename, &problem);
 76  if (status != CUOPT_SUCCESS) {
 77    printf("Error creating problem from MPS file: %d\n", status);
 78    goto DONE;
 79  }
 80
 81  // Get problem size
 82  status = cuOptGetNumVariables(problem, &num_variables);
 83  if (status != CUOPT_SUCCESS) {
 84    printf("Error getting number of variables: %d\n", status);
 85    goto DONE;
 86  }
 87
 88  // Create solver settings
 89  status = cuOptCreateSolverSettings(&settings);
 90  if (status != CUOPT_SUCCESS) {
 91    printf("Error creating solver settings: %d\n", status);
 92    goto DONE;
 93  }
 94
 95  // Set solver parameters
 96  status = cuOptSetFloatParameter(settings, CUOPT_ABSOLUTE_PRIMAL_TOLERANCE, 0.0001);
 97  if (status != CUOPT_SUCCESS) {
 98    printf("Error setting optimality tolerance: %d\n", status);
 99    goto DONE;
100  }
101
102  // Solve the problem
103  status = cuOptSolve(problem, settings, &solution);
104  if (status != CUOPT_SUCCESS) {
105    printf("Error solving problem: %d\n", status);
106    goto DONE;
107  }
108
109  // Get solution information
110  status = cuOptGetSolveTime(solution, &time);
111  if (status != CUOPT_SUCCESS) {
112    printf("Error getting solve time: %d\n", status);
113    goto DONE;
114  }
115
116  status = cuOptGetTerminationStatus(solution, &termination_status);
117  if (status != CUOPT_SUCCESS) {
118    printf("Error getting termination status: %d\n", status);
119    goto DONE;
120  }
121
122  status = cuOptGetObjectiveValue(solution, &objective_value);
123  if (status != CUOPT_SUCCESS) {
124    printf("Error getting objective value: %d\n", status);
125    goto DONE;
126  }
127
128  // Print results
129  printf("\nResults:\n");
130  printf("--------\n");
131  printf("Number of variables: %d\n", num_variables);
132  printf("Termination status: %s (%d)\n", termination_status_to_string(termination_status), termination_status);
133  printf("Solve time: %f seconds\n", time);
134  printf("Objective value: %f\n", objective_value);
135
136  // Get and print solution variables
137  solution_values = (cuopt_float_t*)malloc(num_variables * sizeof(cuopt_float_t));
138  status = cuOptGetPrimalSolution(solution, solution_values);
139  if (status != CUOPT_SUCCESS) {
140    printf("Error getting solution values: %d\n", status);
141    goto DONE;
142  }
143
144  printf("\nPrimal Solution: First 10 solution variables (or fewer if less exist):\n");
145  for (cuopt_int_t i = 0; i < (num_variables < 10 ? num_variables : 10); i++) {
146    printf("x%d = %f\n", i + 1, solution_values[i]);
147  }
148  if (num_variables > 10) {
149    printf("... (showing only first 10 of %d variables)\n", num_variables);
150  }
151
152DONE:
153  free(solution_values);
154  cuOptDestroyProblem(&problem);
155  cuOptDestroySolverSettings(&settings);
156  cuOptDestroySolution(&solution);
157
158  return status;
159}
160
161int main(int argc, char* argv[]) {
162  if (argc != 2) {
163    printf("Usage: %s <mps_file_path>\n", argv[0]);
164    return 1;
165  }
166
167  // Run the solver
168  cuopt_int_t status = solve_mps_file(argv[1]);
169
170  if (status == CUOPT_SUCCESS) {
171    printf("\nSolver completed successfully!\n");
172    return 0;
173  } else {
174    printf("\nSolver failed with status: %d\n", status);
175    return 1;
176  }
177}

It is necessary to have the path for include and library dirs ready, if you know the paths, please add them to the path variables directly. Otherwise, run the following commands to find the path and assign it to the path variables. The following commands are for Linux and might fail in cases where the cuopt library is not installed or there are multiple cuopt libraries in the system.

If you have built it locally, libcuopt.so will be in the build directory cpp/build and include directoy would be cpp/include.

# Find the cuopt header file and assign to INCLUDE_PATH
INCLUDE_PATH=$(find / -name "cuopt_c.h" -path "*/linear_programming/*" -printf "%h\n" | sed 's/\/linear_programming//' 2>/dev/null)
# Find the libcuopt library and assign to LIBCUOPT_LIBRARY_PATH
LIBCUOPT_LIBRARY_PATH=$(find / -name "libcuopt.so" 2>/dev/null)

A sample MPS file (download sample.mps):

 1NAME   good-1
 2ROWS
 3 N  COST
 4 L  ROW1
 5 L  ROW2
 6COLUMNS
 7   VAR1      COST      -0.2
 8   VAR1      ROW1      3              ROW2      2.7
 9   VAR2      COST      0.1
10   VAR2      ROW1      4              ROW2      10.1
11RHS
12   RHS1      ROW1      5.4            ROW2      4.9
13ENDATA

Build and run the example

# Build and run the example
gcc -I $INCLUDE_PATH -L $LIBCUOPT_LIBRARY_PATH -o mps_file_example mps_file_example.c -lcuopt
./mps_file_example sample.mps

You should see the following output:

Output#
Reading and solving MPS file: sample.mps
Solving a problem with 2 constraints 2 variables (0 integers) and 4 nonzeros
Objective offset 0.000000 scaling_factor 1.000000
Running concurrent

Dual simplex finished in 0.00 seconds
   Iter    Primal Obj.      Dual Obj.    Gap        Primal Res.  Dual Res.   Time
      0 +0.00000000e+00 +0.00000000e+00  0.00e+00   0.00e+00     2.00e-01   0.012s
PDLP finished
Concurrent time:  0.014s
Solved with dual simplex
Status: Optimal   Objective: -3.60000000e-01  Iterations: 1  Time: 0.014s

Results:
--------
Number of variables: 2
Termination status: Optimal (1)
Solve time: 0.000014 seconds
Objective value: -0.360000

Primal Solution: First 10 solution variables (or fewer if less exist):
x1 = 1.800000
x2 = 0.000000

Solver completed successfully!

Simple Quadratic Programming Example#

Note

The QP solver is currently in beta.

This example demonstrates how to use the cuOpt C API for quadratic programming.

The example code is available at examples/cuopt-c/lp/simple_qp_example.c (download):

  1/*
  2 * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  3 * SPDX-License-Identifier: Apache-2.0
  4 */
  5/*
  6 * Simple QP C API Example
  7 *
  8 * This example demonstrates how to use the cuOpt C API for quadratic programming.
  9 *
 10 * Problem:
 11 *   Minimize: x^2 + y^2
 12 *   Subject to:
 13 *     x + y >= 1
 14 *     x, y >= 0
 15 *
 16 *
 17 * Build:
 18 *   gcc -I $INCLUDE_PATH -L $LIBCUOPT_LIBRARY_PATH -o simple_qp_example simple_qp_example.c -lcuopt
 19 *
 20 * Run:
 21 *   ./simple_qp_example
 22 */
 23
 24// Include the cuOpt linear programming solver header
 25#include <cuopt/linear_programming/cuopt_c.h>
 26#include <stdio.h>
 27#include <stdlib.h>
 28
 29// Convert termination status to string
 30const char* termination_status_to_string(cuopt_int_t termination_status)
 31{
 32  switch (termination_status) {
 33    case CUOPT_TERIMINATION_STATUS_OPTIMAL:
 34      return "Optimal";
 35    case CUOPT_TERIMINATION_STATUS_INFEASIBLE:
 36      return "Infeasible";
 37    case CUOPT_TERIMINATION_STATUS_UNBOUNDED:
 38      return "Unbounded";
 39    case CUOPT_TERIMINATION_STATUS_ITERATION_LIMIT:
 40      return "Iteration limit";
 41    case CUOPT_TERIMINATION_STATUS_TIME_LIMIT:
 42      return "Time limit";
 43    case CUOPT_TERIMINATION_STATUS_NUMERICAL_ERROR:
 44      return "Numerical error";
 45    case CUOPT_TERIMINATION_STATUS_PRIMAL_FEASIBLE:
 46      return "Primal feasible";
 47    case CUOPT_TERIMINATION_STATUS_FEASIBLE_FOUND:
 48      return "Feasible found";
 49    default:
 50      return "Unknown";
 51  }
 52}
 53
 54// Test simple QP problem
 55cuopt_int_t test_simple_qp()
 56{
 57  cuOptOptimizationProblem problem = NULL;
 58  cuOptSolverSettings settings = NULL;
 59  cuOptSolution solution = NULL;
 60
 61  /* Solve the following QP:
 62     minimize x^2 + y^2
 63     subject to:
 64     x + y >= 1
 65     x, y >= 0
 66  */
 67
 68  cuopt_int_t num_variables = 2;
 69  cuopt_int_t num_constraints = 1;
 70  cuopt_int_t nnz = 2;
 71
 72  // CSR format constraint matrix
 73  // https://docs.nvidia.com/nvpl/latest/sparse/storage_format/sparse_matrix.html#compressed-sparse-row-csr
 74  cuopt_int_t row_offsets[] = {0, 2};
 75  cuopt_int_t column_indices[] = {0, 1};
 76  cuopt_float_t values[] = {1.0, 1.0};
 77
 78  // Objective coefficients
 79  // From the objective function: minimize x^2 + y^2
 80  // 0 is the coefficient of the linear term on x
 81  // 0 is the coefficient of the linear term on y
 82  cuopt_float_t linear_objective_coefficients[] = {0.0, 0.0};
 83
 84  // Quadratic objective matrix
 85  // From the objective function: minimize x^2 + y^2
 86  // 1 is the coefficient of the quadratic term on x^2
 87  // 1 is the coefficient of the quadratic term on y^2
 88  cuopt_float_t quadratic_objective_matrix_values[] = {1.0, 1.0};
 89  cuopt_int_t quadratic_objective_matrix_row_offsets[] = {0, 1, 2};
 90  cuopt_int_t quadratic_objective_matrix_column_indices[] = {0, 1};
 91
 92  // Constraint bounds
 93  // From the constraints:
 94  // x + y >= 1
 95  cuopt_float_t constraint_rhs[] = {1.0};
 96  char constraint_sense[] = { CUOPT_GREATER_THAN };
 97
 98
 99  // Variable bounds
100  // From the constraints:
101  // x1, x2 >= 0
102  cuopt_float_t var_lower_bounds[] = {0.0, 0.0};
103  cuopt_float_t var_upper_bounds[] = {CUOPT_INFINITY, CUOPT_INFINITY};
104
105  // Variable types (continuous)
106  // From the constraints:
107  // x1, x2 >= 0
108  char variable_types[] = {CUOPT_CONTINUOUS, CUOPT_CONTINUOUS};
109
110  cuopt_int_t status;
111  cuopt_float_t time;
112  cuopt_int_t termination_status;
113  cuopt_float_t objective_value;
114
115  printf("Creating and solving simple QP problem...\n");
116
117  // Create the problem
118  status = cuOptCreateQuadraticProblem(num_constraints,
119                                       num_variables,
120                                       CUOPT_MINIMIZE,
121                                       0.0,  // objective offset
122                                       linear_objective_coefficients,
123                                       quadratic_objective_matrix_row_offsets,
124                                       quadratic_objective_matrix_column_indices,
125                                       quadratic_objective_matrix_values,
126                                       row_offsets,
127                                       column_indices,
128                                       values,
129                                       constraint_sense,
130                                       constraint_rhs,
131                                       var_lower_bounds,
132                                       var_upper_bounds,
133                                       variable_types,
134                                       &problem);
135  if (status != CUOPT_SUCCESS) {
136    printf("Error creating problem: %d\n", status);
137    goto DONE;
138  }
139
140  // Create solver settings
141  status = cuOptCreateSolverSettings(&settings);
142  if (status != CUOPT_SUCCESS) {
143    printf("Error creating solver settings: %d\n", status);
144    goto DONE;
145  }
146
147  // Solve the problem
148  status = cuOptSolve(problem, settings, &solution);
149  if (status != CUOPT_SUCCESS) {
150    printf("Error solving problem: %d\n", status);
151    goto DONE;
152  }
153
154  // Get solution information
155  status = cuOptGetSolveTime(solution, &time);
156  if (status != CUOPT_SUCCESS) {
157    printf("Error getting solve time: %d\n", status);
158    goto DONE;
159  }
160
161  status = cuOptGetTerminationStatus(solution, &termination_status);
162  if (status != CUOPT_SUCCESS) {
163    printf("Error getting termination status: %d\n", status);
164    goto DONE;
165  }
166
167  status = cuOptGetObjectiveValue(solution, &objective_value);
168  if (status != CUOPT_SUCCESS) {
169    printf("Error getting objective value: %d\n", status);
170    goto DONE;
171  }
172
173  // Print results
174  printf("\nResults:\n");
175  printf("--------\n");
176  printf("Termination status: %s (%d)\n", termination_status_to_string(termination_status), termination_status);
177  printf("Solve time: %f seconds\n", time);
178  printf("Objective value: %f\n", objective_value);
179
180  // Get and print solution variables
181  cuopt_float_t* solution_values = (cuopt_float_t*)malloc(num_variables * sizeof(cuopt_float_t));
182  if (solution_values == NULL) {
183    printf("Error allocating solution values\n");
184    goto DONE;
185  }
186  status = cuOptGetPrimalSolution(solution, solution_values);
187  if (status != CUOPT_SUCCESS) {
188    printf("Error getting solution values: %d\n", status);
189    free(solution_values);
190    goto DONE;
191  }
192
193  printf("\nPrimal Solution: Solution variables \n");
194  for (cuopt_int_t i = 0; i < num_variables; i++) {
195    printf("x%d = %f\n", i + 1, solution_values[i]);
196  }
197  free(solution_values);
198
199DONE:
200  cuOptDestroyProblem(&problem);
201  cuOptDestroySolverSettings(&settings);
202  cuOptDestroySolution(&solution);
203
204  return status;
205}
206
207int main() {
208  // Run the test
209  cuopt_int_t status = test_simple_qp();
210
211  if (status == CUOPT_SUCCESS) {
212    printf("\nTest completed successfully!\n");
213    return 0;
214  } else {
215    printf("\nTest failed with status: %d\n", status);
216    return 1;
217  }
218}

Build and run the example

# Build and run the example
gcc -I $INCLUDE_PATH -L $LIBCUOPT_LIBRARY_PATH -o simple_qp_example simple_qp_example.c -lcuopt
./simple_qp_example

You should see the following output:

Output#
Creating and solving simple QP problem...
Status: Optimal
Objective value: 0.500000
x = 0.500000
y = 0.500000
Test completed successfully!