Skip to content

Commit fee1a48

Browse files
committed
Merge github.com:nvidia/cuopt into add_nightly_container_support
2 parents 28096a9 + 4824781 commit fee1a48

31 files changed

+312
-83
lines changed

cpp/include/cuopt/linear_programming/cuopt_c.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,22 @@ int8_t cuOptGetFloatSize();
9393
*/
9494
int8_t cuOptGetIntSize();
9595

96+
/**
97+
* @brief Get the version of the library.
98+
*
99+
* @param[out] version_major - A pointer to a cuopt_int_t that will contain the major version
100+
* number.
101+
* @param[out] version_minor - A pointer to a cuopt_int_t that will contain the minor version
102+
* number.
103+
* @param[out] version_patch - A pointer to a cuopt_int_t that will contain the patch version
104+
* number.
105+
*
106+
* @return A status code indicating success or failure.
107+
*/
108+
cuopt_int_t cuOptGetVersion(cuopt_int_t* version_major,
109+
cuopt_int_t* version_minor,
110+
cuopt_int_t* version_patch);
111+
96112
/**
97113
* @brief Read an optimization problem from an MPS file.
98114
*
@@ -656,6 +672,18 @@ cuopt_int_t cuOptGetSolutionBound(cuOptSolution solution, cuopt_float_t* solutio
656672
*/
657673
cuopt_int_t cuOptGetDualSolution(cuOptSolution solution, cuopt_float_t* dual_solution_ptr);
658674

675+
/** @brief Get the dual objective value of an optimization problem.
676+
*
677+
* @param[in] solution - The solution object.
678+
*
679+
* @param[in, out] dual_objective_value_ptr - A pointer to a cuopt_float_t that will contain the
680+
* dual objective value.
681+
*
682+
* @return A status code indicating success or failure.
683+
*/
684+
cuopt_int_t cuOptGetDualObjectiveValue(cuOptSolution solution,
685+
cuopt_float_t* dual_objective_value_ptr);
686+
659687
/** @brief Get the reduced costs of an optimization problem.
660688
*
661689
* @param[in] solution - The solution object.

cpp/include/cuopt/linear_programming/pdlp/solver_solution.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ class optimization_problem_solution_t : public base_solution_t {
214214
*/
215215
f_t get_objective_value() const;
216216

217+
/**
218+
* @brief Returns the dual objective value of the solution as a `f_t`.
219+
* @return objective value of the dual problem
220+
*/
221+
f_t get_dual_objective_value() const;
222+
217223
/**
218224
* @brief Returns the solution for the values of the primal variables as a vector of `f_t`.
219225
*

cpp/src/dual_simplex/solve.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@ template <typename i_t, typename f_t>
9696
f_t compute_user_objective(const lp_problem_t<i_t, f_t>& lp, const std::vector<f_t>& x)
9797
{
9898
const f_t obj = compute_objective(lp, x);
99-
const f_t user_obj = obj * lp.obj_scale + lp.obj_constant;
99+
const f_t user_obj = compute_user_objective(lp, obj);
100100
return user_obj;
101101
}
102102

103103
template <typename i_t, typename f_t>
104104
f_t compute_user_objective(const lp_problem_t<i_t, f_t>& lp, f_t obj)
105105
{
106-
const f_t user_obj = obj * lp.obj_scale + lp.obj_constant;
106+
const f_t user_obj = lp.obj_scale * (obj + lp.obj_constant);
107107
return user_obj;
108108
}
109109

cpp/src/linear_programming/cuopt_c.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
#include <mps_parser/parser.hpp>
2626

27+
#include <cuopt/version_config.hpp>
28+
2729
#include <memory>
2830
#include <string>
2931

@@ -59,6 +61,19 @@ int8_t cuOptGetFloatSize() { return sizeof(cuopt_float_t); }
5961

6062
int8_t cuOptGetIntSize() { return sizeof(cuopt_int_t); }
6163

64+
cuopt_int_t cuOptGetVersion(cuopt_int_t* version_major,
65+
cuopt_int_t* version_minor,
66+
cuopt_int_t* version_patch)
67+
{
68+
if (version_major == nullptr || version_minor == nullptr || version_patch == nullptr) {
69+
return CUOPT_INVALID_ARGUMENT;
70+
}
71+
*version_major = CUOPT_VERSION_MAJOR;
72+
*version_minor = CUOPT_VERSION_MINOR;
73+
*version_patch = CUOPT_VERSION_PATCH;
74+
return CUOPT_SUCCESS;
75+
}
76+
6277
cuopt_int_t cuOptReadProblem(const char* filename, cuOptOptimizationProblem* problem_ptr)
6378
{
6479
problem_and_stream_view_t* problem_and_stream = new problem_and_stream_view_t();
@@ -825,6 +840,24 @@ cuopt_int_t cuOptGetDualSolution(cuOptSolution solution, cuopt_float_t* dual_sol
825840
}
826841
}
827842

843+
cuopt_int_t cuOptGetDualObjectiveValue(cuOptSolution solution,
844+
cuopt_float_t* dual_objective_value_ptr)
845+
{
846+
if (solution == nullptr) { return CUOPT_INVALID_ARGUMENT; }
847+
if (dual_objective_value_ptr == nullptr) { return CUOPT_INVALID_ARGUMENT; }
848+
solution_and_stream_view_t* solution_and_stream_view =
849+
static_cast<solution_and_stream_view_t*>(solution);
850+
if (solution_and_stream_view->is_mip) {
851+
return CUOPT_INVALID_ARGUMENT;
852+
} else {
853+
optimization_problem_solution_t<cuopt_int_t, cuopt_float_t>* optimization_problem_solution =
854+
static_cast<optimization_problem_solution_t<cuopt_int_t, cuopt_float_t>*>(
855+
solution_and_stream_view->lp_solution_ptr);
856+
*dual_objective_value_ptr = optimization_problem_solution->get_dual_objective_value();
857+
return CUOPT_SUCCESS;
858+
}
859+
}
860+
828861
cuopt_int_t cuOptGetReducedCosts(cuOptSolution solution, cuopt_float_t* reduced_cost_ptr)
829862
{
830863
if (solution == nullptr) { return CUOPT_INVALID_ARGUMENT; }

cpp/src/linear_programming/solver_solution.cu

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,12 @@ f_t optimization_problem_solution_t<i_t, f_t>::get_objective_value() const
309309
return termination_stats_.primal_objective;
310310
}
311311

312+
template <typename i_t, typename f_t>
313+
f_t optimization_problem_solution_t<i_t, f_t>::get_dual_objective_value() const
314+
{
315+
return termination_stats_.dual_objective;
316+
}
317+
312318
template <typename i_t, typename f_t>
313319
rmm::device_uvector<f_t>& optimization_problem_solution_t<i_t, f_t>::get_primal_solution()
314320
{

cpp/src/linear_programming/termination_strategy/convergence_information.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ __global__ void apply_objective_scaling_and_offset(f_t* objective,
254254
{
255255
if (threadIdx.x + blockIdx.x * blockDim.x > 0) { return; }
256256

257-
*objective = (objective_scaling_factor * *objective) + objective_offset;
257+
*objective = objective_scaling_factor * (*objective + objective_offset);
258258
}
259259

260260
template <typename i_t, typename f_t>

cpp/src/math_optimization/solver_settings.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ solver_settings_t<i_t, f_t>::solver_settings_t() : pdlp_settings(), mip_settings
7979
{CUOPT_MIP_ABSOLUTE_TOLERANCE, &mip_settings.tolerances.absolute_tolerance, 0.0, 1e-1, 1e-4},
8080
{CUOPT_MIP_RELATIVE_TOLERANCE, &mip_settings.tolerances.relative_tolerance, 0.0, 1e-1, 1e-4},
8181
{CUOPT_MIP_INTEGRALITY_TOLERANCE, &mip_settings.tolerances.integrality_tolerance, 0.0, 1e-1, 1e-5},
82-
{CUOPT_MIP_ABSOLUTE_GAP, &mip_settings.tolerances.absolute_mip_gap, 0.0, 1e-1, 1e-10},
82+
{CUOPT_MIP_ABSOLUTE_GAP, &mip_settings.tolerances.absolute_mip_gap, 0.0, CUOPT_INFINITY, 1e-10},
8383
{CUOPT_MIP_RELATIVE_GAP, &mip_settings.tolerances.relative_mip_gap, 0.0, 1e-1, 1e-4},
8484
{CUOPT_PRIMAL_INFEASIBLE_TOLERANCE, &pdlp_settings.tolerances.primal_infeasible_tolerance, 0.0, 1e-1, 1e-8},
8585
{CUOPT_DUAL_INFEASIBLE_TOLERANCE, &pdlp_settings.tolerances.dual_infeasible_tolerance, 0.0, 1e-1, 1e-8}

cpp/src/mip/presolve/trivial_presolve.cuh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ void update_from_csr(problem_t<i_t, f_t>& pb)
234234

235235
// update objective_offset
236236
pb.presolve_data.objective_offset +=
237-
pb.presolve_data.objective_scaling_factor *
238237
thrust::transform_reduce(handle_ptr->get_thrust_policy(),
239238
thrust::counting_iterator<i_t>(0),
240239
thrust::counting_iterator<i_t>(pb.n_variables),

cpp/src/mip/problem/problem.cu

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,26 @@ void problem_t<i_t, f_t>::op_problem_cstr_body(const optimization_problem_t<i_t,
6767

6868
// Set variables bounds to default if not set and constraints bounds if user has set a row type
6969
set_bounds_if_not_set(*this);
70+
71+
const bool is_mip = original_problem_ptr->get_problem_category() != problem_category_t::LP;
72+
if (is_mip) {
73+
variable_types =
74+
rmm::device_uvector<var_t>(problem_.get_variable_types(), handle_ptr->get_stream());
75+
// round bounds to integer for integer variables, note: do this before checking sanity
76+
round_bounds(*this);
77+
}
78+
7079
// check bounds sanity before, so that we can throw exceptions before going into asserts
7180
check_bounds_sanity(*this);
81+
7282
// Check before any modifications
7383
check_problem_representation(false, false);
7484
// If maximization problem, convert the problem
7585
if (maximize) convert_to_maximization_problem(*this);
7686

77-
const bool is_mip = original_problem_ptr->get_problem_category() != problem_category_t::LP;
7887
if (is_mip) {
7988
// Resize what is needed for MIP
8089
raft::common::nvtx::range scope("trivial_presolve");
81-
variable_types =
82-
rmm::device_uvector<var_t>(problem_.get_variable_types(), handle_ptr->get_stream());
8390
integer_indices.resize(n_variables, handle_ptr->get_stream());
8491
is_binary_variable.resize(n_variables, handle_ptr->get_stream());
8592
compute_n_integer_vars();
@@ -93,7 +100,9 @@ void problem_t<i_t, f_t>::op_problem_cstr_body(const optimization_problem_t<i_t,
93100
}
94101

95102
template <typename i_t, typename f_t>
96-
problem_t<i_t, f_t>::problem_t(const optimization_problem_t<i_t, f_t>& problem_)
103+
problem_t<i_t, f_t>::problem_t(
104+
const optimization_problem_t<i_t, f_t>& problem_,
105+
const typename mip_solver_settings_t<i_t, f_t>::tolerances_t tolerances_)
97106
: original_problem_ptr(&problem_),
98107
handle_ptr(problem_.get_handle_ptr()),
99108
n_variables(problem_.get_n_variables()),
@@ -129,7 +138,8 @@ problem_t<i_t, f_t>::problem_t(const optimization_problem_t<i_t, f_t>& problem_)
129138
related_variables_offsets(n_variables, problem_.get_handle_ptr()->get_stream()),
130139
var_names(problem_.get_variable_names()),
131140
row_names(problem_.get_row_names()),
132-
objective_name(problem_.get_objective_name())
141+
objective_name(problem_.get_objective_name()),
142+
tolerances(tolerances_)
133143
{
134144
op_problem_cstr_body(problem_);
135145
branch_and_bound_callback = nullptr;
@@ -1430,7 +1440,7 @@ void problem_t<i_t, f_t>::get_host_user_problem(
14301440
template <typename i_t, typename f_t>
14311441
f_t problem_t<i_t, f_t>::get_user_obj_from_solver_obj(f_t solver_obj)
14321442
{
1433-
return solver_obj * presolve_data.objective_scaling_factor + presolve_data.objective_offset;
1443+
return presolve_data.objective_scaling_factor * (solver_obj + presolve_data.objective_offset);
14341444
}
14351445
14361446
#if MIP_INSTANTIATE_FLOAT

cpp/src/mip/problem/problem.cuh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ constexpr bool USE_REL_TOLERANCE = true;
5454
template <typename i_t, typename f_t>
5555
class problem_t {
5656
public:
57-
problem_t(const optimization_problem_t<i_t, f_t>& problem);
57+
problem_t(const optimization_problem_t<i_t, f_t>& problem,
58+
const typename mip_solver_settings_t<i_t, f_t>::tolerances_t tolerances_ = {});
5859
problem_t() = delete;
5960
// copy constructor
6061
problem_t(const problem_t<i_t, f_t>& problem);

0 commit comments

Comments
 (0)