Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
380e20c
refactor: rename cuopt::linear_programming -> cuopt::math_optimization
mlubin Jun 20, 2026
dae7dba
refactor: move PDLP solver into cuopt::math_optimization::pdlp
mlubin Jun 20, 2026
fedf6ad
refactor: move barrier solver into cuopt::math_optimization::barrier
mlubin Jun 20, 2026
0012042
chore: remove solver-output files accidentally committed in the rename
mlubin Jun 20, 2026
7e85ff2
refactor: consolidate MIP into cuopt::math_optimization::mip
mlubin Jun 20, 2026
92bd0d9
refactor: fold stray primal/dual/phase2 namespaces into dual_simplex
mlubin Jun 21, 2026
f6b11d1
refactor: eliminate the detail namespace under math_optimization
mlubin Jun 21, 2026
57a51ee
compat: forward <cuopt/linear_programming/cuopt_c.h> to new path
mlubin Jun 21, 2026
59336da
refactor: rename dual_simplex namespace to simplex
mlubin Jun 22, 2026
d5726ae
refactor: remove using-namespace directives from headers
mlubin Jun 22, 2026
801d31c
docs: fix stale dual_simplex namespace references in comments
mlubin Jun 22, 2026
58dc479
refactor: rename cuopt::math_optimization -> cuopt::mathematical_opti…
mlubin Jun 22, 2026
342ec39
refactor: drop dead simplex::branch_and_bound_t forward-decl
mlubin Jun 24, 2026
c57bd23
refactor: use targeted using-declarations for shared simplex names
mlubin Jun 25, 2026
5db73a9
refactor: replace remaining file-scope using-namespace with targeted …
mlubin Jun 25, 2026
c57b2e9
Merge remote-tracking branch 'origin/main' into refactor/math-optimiz…
mlubin Jun 25, 2026
e5fe2a0
refactor: restore the phase2 namespace in phase2.cpp
mlubin Jun 25, 2026
ab50cfe
refactor: add targeted using-declarations per PR review
mlubin Jun 25, 2026
2a531c3
Merge remote-tracking branch 'origin/main' into refactor/math-optimiz…
mlubin Jun 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .coderabbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ reviews:
- Suggest documenting thread-safety, GPU requirements, numerical behavior
- For breaking changes, recommend migration notes

- path: "cpp/include/cuopt/linear_programming/cuopt_c.h"
- path: "cpp/include/cuopt/mathematical_optimization/cuopt_c.h"
instructions: |
This is the C ABI surface. Flag ANY change to struct layout, function
signatures, enum values, or typedef shape as potentially ABI-breaking.
Expand Down
6 changes: 3 additions & 3 deletions .github/.coderabbit_review_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ from the actual code and from `.clang-format`.
- Private/protected member variables: trailing underscore (e.g. `error_type_`)
- Project macros: `SCREAMING_SNAKE_CASE` with `CUOPT_` prefix (e.g. `CUOPT_EXPECTS`)
- **File extensions**: `.hpp`/`.cpp` for C++ host code; `.cuh`/`.cu` for CUDA;
`.h` reserved for the C ABI surface (`cpp/include/cuopt/linear_programming/cuopt_c.h`).
`.h` reserved for the C ABI surface (`cpp/include/cuopt/mathematical_optimization/cuopt_c.h`).
- **Column limit**: 100 (set in `.clang-format`).
- **Error handling**: `throw` + `cuopt_expects(...)` / `CUOPT_EXPECTS(...)`
macros from `cpp/include/cuopt/error.hpp`, which throw `cuopt::logic_error`.
Expand Down Expand Up @@ -113,7 +113,7 @@ CodeRabbit should focus on what they do *not* cover:

### C API

The C API surface is intentionally narrow — `cpp/include/cuopt/linear_programming/cuopt_c.h`.
The C API surface is intentionally narrow — `cpp/include/cuopt/mathematical_optimization/cuopt_c.h`.

- **Any change to `cuopt_c.h` should be flagged for maintainer awareness** (ABI-sensitive). There is no formal ABI-versioning macro today, so phrase it as "this changes the C ABI surface — confirm this is intentional and documented."

Expand Down Expand Up @@ -149,7 +149,7 @@ Bug Patterns" section to avoid duplication.
- Missing RAII in exception paths (cuOpt uses exceptions)

**API surface**
- Any change to `cpp/include/cuopt/linear_programming/cuopt_c.h` — flag as ABI-sensitive
- Any change to `cpp/include/cuopt/mathematical_optimization/cuopt_c.h` — flag as ABI-sensitive
- Python API changes without `DeprecationWarning`
- Server API endpoint changes without deprecation path

Expand Down
29 changes: 15 additions & 14 deletions benchmarks/linear_programming/cuopt/benchmark_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

#pragma once

#include <cuopt/linear_programming/io/parser.hpp>
#include <cuopt/linear_programming/optimization_problem_interface.hpp>
#include <cuopt/linear_programming/pdlp/pdlp_hyper_params.cuh>
#include <cuopt/linear_programming/pdlp/solver_solution.hpp>
#include <cuopt/linear_programming/solve.hpp>
#include <cuopt/mathematical_optimization/io/parser.hpp>
#include <cuopt/mathematical_optimization/optimization_problem_interface.hpp>
#include <cuopt/mathematical_optimization/pdlp/pdlp_hyper_params.cuh>
#include <cuopt/mathematical_optimization/pdlp/solver_solution.hpp>
#include <cuopt/mathematical_optimization/solve.hpp>

#include <raft/sparse/detail/cusparse_wrappers.h>
#include <raft/core/cusparse_macros.hpp>
Expand Down Expand Up @@ -57,9 +57,8 @@ void parse_value(std::istringstream& iss, bool& value)
iss >> std::boolalpha >> value;
}

void fill_pdlp_hyper_params(
const std::string& pdlp_hyper_params_path,
cuopt::linear_programming::pdlp_hyper_params::pdlp_hyper_params_t& params)
void fill_pdlp_hyper_params(const std::string& pdlp_hyper_params_path,
cuopt::mathematical_optimization::pdlp::pdlp_hyper_params_t& params)
{
if (!std::filesystem::exists(pdlp_hyper_params_path)) {
std::cerr << "PDLP config file path is not a valid: " << pdlp_hyper_params_path << std::endl;
Expand Down Expand Up @@ -205,8 +204,9 @@ std::vector<T> read_vector_from_file(const std::string& filename)
}

template <typename i_t, typename f_t>
void write_problem_info(const cuopt::linear_programming::io::mps_data_model_t<i_t, f_t>& op_problem,
const std::string& filename)
void write_problem_info(
const cuopt::mathematical_optimization::io::mps_data_model_t<i_t, f_t>& op_problem,
const std::string& filename)
{
std::ofstream file(filename);
if (!file) {
Expand All @@ -222,8 +222,9 @@ void write_problem_info(const cuopt::linear_programming::io::mps_data_model_t<i_
}

template <typename i_t, typename f_t>
void read_problem_info(cuopt::linear_programming::optimization_problem_t<i_t, f_t>& op_problem,
const std::string& filename)
void read_problem_info(
cuopt::mathematical_optimization::optimization_problem_t<i_t, f_t>& op_problem,
const std::string& filename)
{
std::ifstream file(filename);
if (!file) {
Expand Down Expand Up @@ -274,8 +275,8 @@ void mps_file_to_binary(const std::filesystem::path& filename)

std::string p = std::string(filename);

cuopt::linear_programming::io::mps_data_model_t<int, double> op_problem =
cuopt::linear_programming::io::read_mps<int, double>(p);
cuopt::mathematical_optimization::io::mps_data_model_t<int, double> op_problem =
cuopt::mathematical_optimization::io::read_mps<int, double>(p);

auto filename_string = filename.filename().string();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct violation {
};

bool test_constraint_and_variable_sanity(
const cuopt::linear_programming::io::mps_data_model_t<int, double>& op_problem,
const cuopt::mathematical_optimization::io::mps_data_model_t<int, double>& op_problem,
const std::vector<double>& primal_vars,
double abs_tol,
double rel_tol,
Expand Down
36 changes: 18 additions & 18 deletions benchmarks/linear_programming/cuopt/run_mip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
#include "miplib2017_bks.hpp"

#include <cstdio>
#include <cuopt/linear_programming/io/parser.hpp>
#include <cuopt/linear_programming/mip/solver_settings.hpp>
#include <cuopt/linear_programming/mip/solver_solution.hpp>
#include <cuopt/linear_programming/optimization_problem_interface.hpp>
#include <cuopt/linear_programming/solve.hpp>
#include <cuopt/mathematical_optimization/io/parser.hpp>
#include <cuopt/mathematical_optimization/mip/solver_settings.hpp>
#include <cuopt/mathematical_optimization/mip/solver_solution.hpp>
#include <cuopt/mathematical_optimization/optimization_problem_interface.hpp>
#include <cuopt/mathematical_optimization/solve.hpp>
#include <utilities/logger.hpp>

#include <raft/core/handle.hpp>
Expand Down Expand Up @@ -152,7 +152,7 @@ int run_single_file(std::string file_path,
bool deterministic)
{
const raft::handle_t handle_{};
cuopt::linear_programming::mip_solver_settings_t<int, double> settings;
cuopt::mathematical_optimization::mip_solver_settings_t<int, double> settings;
std::string base_filename = file_path.substr(file_path.find_last_of("/\\") + 1);
// if output directory is given, set the log file
if (write_log_file) {
Expand All @@ -167,13 +167,13 @@ int run_single_file(std::string file_path,
}

constexpr bool input_mps_strict = false;
cuopt::linear_programming::io::mps_data_model_t<int, double> mps_data_model;
cuopt::mathematical_optimization::io::mps_data_model_t<int, double> mps_data_model;
bool parsing_failed = false;
{
CUOPT_LOG_INFO("running file %s on gpu : %d", base_filename.c_str(), device);
try {
mps_data_model =
cuopt::linear_programming::io::read_mps<int, double>(file_path, input_mps_strict);
cuopt::mathematical_optimization::io::read_mps<int, double>(file_path, input_mps_strict);
} catch (const std::logic_error& e) {
CUOPT_LOG_ERROR("MPS parser execption: %s", e.what());
parsing_failed = true;
Expand Down Expand Up @@ -211,14 +211,14 @@ int run_single_file(std::string file_path,
settings.determinism_mode = deterministic ? CUOPT_MODE_DETERMINISTIC : CUOPT_MODE_OPPORTUNISTIC;
settings.tolerances.relative_tolerance = 1e-12;
settings.tolerances.absolute_tolerance = 1e-6;
settings.presolver = cuopt::linear_programming::presolver_t::Default;
settings.presolver = cuopt::mathematical_optimization::presolver_t::Default;
settings.reliability_branching = reliability_branching;
settings.clique_cuts = -1;
settings.seed = 42;
cuopt::linear_programming::benchmark_info_t benchmark_info;
cuopt::mathematical_optimization::benchmark_info_t benchmark_info;
settings.benchmark_info_ptr = &benchmark_info;
auto start_run_solver = std::chrono::high_resolution_clock::now();
auto solution = cuopt::linear_programming::solve_mip(&handle_, mps_data_model, settings);
auto solution = cuopt::mathematical_optimization::solve_mip(&handle_, mps_data_model, settings);
CUOPT_LOG_INFO(
"first obj: %f last improvement of best feasible: %f last improvement after recombination: %f",
benchmark_info.objective_of_initial_population,
Expand All @@ -231,9 +231,9 @@ int run_single_file(std::string file_path,
CUOPT_LOG_INFO("run_solver %d", duration.count());
handle_.sync_stream();
int sol_found = int(solution.get_termination_status() ==
cuopt::linear_programming::mip_termination_status_t::FeasibleFound ||
cuopt::mathematical_optimization::mip_termination_status_t::FeasibleFound ||
solution.get_termination_status() ==
cuopt::linear_programming::mip_termination_status_t::Optimal);
cuopt::mathematical_optimization::mip_termination_status_t::Optimal);
double obj_val = sol_found ? solution.get_objective_value() : std::numeric_limits<double>::max();
if (sol_found) {
CUOPT_LOG_INFO("%s: solution found, obj: %f", base_filename.c_str(), obj_val);
Expand All @@ -254,16 +254,16 @@ int run_single_file(std::string file_path,
1000.0;
std::string _status_str;
switch (solution.get_termination_status()) {
case cuopt::linear_programming::mip_termination_status_t::Optimal:
case cuopt::mathematical_optimization::mip_termination_status_t::Optimal:
_status_str = "Optimal";
break;
case cuopt::linear_programming::mip_termination_status_t::FeasibleFound:
case cuopt::mathematical_optimization::mip_termination_status_t::FeasibleFound:
_status_str = "FeasibleFound";
break;
case cuopt::linear_programming::mip_termination_status_t::TimeLimit:
case cuopt::mathematical_optimization::mip_termination_status_t::TimeLimit:
_status_str = "TimeLimit";
break;
case cuopt::linear_programming::mip_termination_status_t::Infeasible:
case cuopt::mathematical_optimization::mip_termination_status_t::Infeasible:
_status_str = "Infeasible";
break;
default: _status_str = "Other"; break;
Expand All @@ -281,7 +281,7 @@ int run_single_file(std::string file_path,
int decimal_places = 2;
double mip_gap = solution.get_mip_gap();
int is_optimal = solution.get_termination_status() ==
cuopt::linear_programming::mip_termination_status_t::Optimal
cuopt::mathematical_optimization::mip_termination_status_t::Optimal
? 1
: 0;
ss << std::fixed << std::setprecision(decimal_places) << base_filename << "," << sol_found << ","
Expand Down
65 changes: 35 additions & 30 deletions benchmarks/linear_programming/cuopt/run_pdlp.cu
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
*/
/* clang-format on */

#include <cuopt/linear_programming/io/parser.hpp>
#include <cuopt/linear_programming/optimization_problem_interface.hpp>
#include <cuopt/linear_programming/pdlp/solver_solution.hpp>
#include <cuopt/linear_programming/solve.hpp>
#include <cuopt/linear_programming/solver_settings.hpp>
#include <cuopt/mathematical_optimization/io/parser.hpp>
#include <cuopt/mathematical_optimization/optimization_problem_interface.hpp>
#include <cuopt/mathematical_optimization/pdlp/solver_solution.hpp>
#include <cuopt/mathematical_optimization/solve.hpp>
#include <cuopt/mathematical_optimization/solver_settings.hpp>

#include <raft/sparse/detail/cusparse_wrappers.h>
#include <raft/core/cusparse_macros.hpp>
Expand Down Expand Up @@ -85,50 +85,55 @@ static void parse_arguments(argparse::ArgumentParser& program)
.choices("default", "single", "double", "mixed");
}

static cuopt::linear_programming::presolver_t string_to_presolver(const std::string& presolver)
static cuopt::mathematical_optimization::presolver_t string_to_presolver(
const std::string& presolver)
{
if (presolver == "None") return cuopt::linear_programming::presolver_t::None;
if (presolver == "Papilo") return cuopt::linear_programming::presolver_t::Papilo;
if (presolver == "PSLP") return cuopt::linear_programming::presolver_t::PSLP;
if (presolver == "Default") return cuopt::linear_programming::presolver_t::Default;
return cuopt::linear_programming::presolver_t::Default;
if (presolver == "None") return cuopt::mathematical_optimization::presolver_t::None;
if (presolver == "Papilo") return cuopt::mathematical_optimization::presolver_t::Papilo;
if (presolver == "PSLP") return cuopt::mathematical_optimization::presolver_t::PSLP;
if (presolver == "Default") return cuopt::mathematical_optimization::presolver_t::Default;
return cuopt::mathematical_optimization::presolver_t::Default;
}

static cuopt::linear_programming::pdlp_precision_t string_to_pdlp_precision(
static cuopt::mathematical_optimization::pdlp_precision_t string_to_pdlp_precision(
const std::string& precision)
{
if (precision == "single") return cuopt::linear_programming::pdlp_precision_t::SinglePrecision;
if (precision == "double") return cuopt::linear_programming::pdlp_precision_t::DoublePrecision;
if (precision == "mixed") return cuopt::linear_programming::pdlp_precision_t::MixedPrecision;
return cuopt::linear_programming::pdlp_precision_t::DefaultPrecision;
if (precision == "single")
return cuopt::mathematical_optimization::pdlp_precision_t::SinglePrecision;
if (precision == "double")
return cuopt::mathematical_optimization::pdlp_precision_t::DoublePrecision;
if (precision == "mixed")
return cuopt::mathematical_optimization::pdlp_precision_t::MixedPrecision;
return cuopt::mathematical_optimization::pdlp_precision_t::DefaultPrecision;
}

static cuopt::linear_programming::pdlp_solver_mode_t string_to_pdlp_solver_mode(
static cuopt::mathematical_optimization::pdlp_solver_mode_t string_to_pdlp_solver_mode(
const std::string& mode)
{
if (mode == "Stable1") return cuopt::linear_programming::pdlp_solver_mode_t::Stable1;
if (mode == "Stable1") return cuopt::mathematical_optimization::pdlp_solver_mode_t::Stable1;
if (mode == "Stable2")
return cuopt::linear_programming::pdlp_solver_mode_t::Stable2;
return cuopt::mathematical_optimization::pdlp_solver_mode_t::Stable2;
else if (mode == "Methodical1")
return cuopt::linear_programming::pdlp_solver_mode_t::Methodical1;
return cuopt::mathematical_optimization::pdlp_solver_mode_t::Methodical1;
else if (mode == "Fast1")
return cuopt::linear_programming::pdlp_solver_mode_t::Fast1;
return cuopt::mathematical_optimization::pdlp_solver_mode_t::Fast1;
else if (mode == "Stable3")
return cuopt::linear_programming::pdlp_solver_mode_t::Stable3;
return cuopt::linear_programming::pdlp_solver_mode_t::Stable3;
return cuopt::mathematical_optimization::pdlp_solver_mode_t::Stable3;
return cuopt::mathematical_optimization::pdlp_solver_mode_t::Stable3;
}

static cuopt::linear_programming::pdlp_solver_settings_t<int, double> create_solver_settings(
static cuopt::mathematical_optimization::pdlp_solver_settings_t<int, double> create_solver_settings(
const argparse::ArgumentParser& program)
{
cuopt::linear_programming::pdlp_solver_settings_t<int, double> settings{};
cuopt::mathematical_optimization::pdlp_solver_settings_t<int, double> settings{};

settings.time_limit = program.get<double>("--time-limit");
settings.iteration_limit = program.get<int>("--iteration-limit");
settings.set_optimality_tolerance(program.get<double>("--optimality-tolerance"));
settings.pdlp_solver_mode =
string_to_pdlp_solver_mode(program.get<std::string>("--pdlp-solver-mode"));
settings.method = static_cast<cuopt::linear_programming::method_t>(program.get<int>("--method"));
settings.method =
static_cast<cuopt::mathematical_optimization::method_t>(program.get<int>("--method"));
settings.crossover = program.get<int>("--crossover");
settings.presolver = string_to_presolver(program.get<std::string>("--presolver"));
settings.pdlp_precision = string_to_pdlp_precision(program.get<std::string>("--pdlp-precision"));
Expand All @@ -148,13 +153,13 @@ static int run_solver(const argparse::ArgumentParser& program, const raft::handl
}

// Parse MPS file
cuopt::linear_programming::io::mps_data_model_t<int, double> op_problem =
cuopt::linear_programming::io::read_mps<int, double>(program.get<std::string>("--path"));
cuopt::mathematical_optimization::io::mps_data_model_t<int, double> op_problem =
cuopt::mathematical_optimization::io::read_mps<int, double>(program.get<std::string>("--path"));

// Solve LP problem
bool problem_checking = true;
cuopt::linear_programming::optimization_problem_solution_t<int, double> solution =
cuopt::linear_programming::solve_lp(
cuopt::mathematical_optimization::optimization_problem_solution_t<int, double> solution =
cuopt::mathematical_optimization::solve_lp(
&handle_, op_problem, settings, problem_checking, use_pdlp_solver_mode);

// Write solution to file if requested
Expand Down
8 changes: 4 additions & 4 deletions ci/test_doc_examples.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Bash strict mode
Expand Down Expand Up @@ -470,16 +470,16 @@ find_cuopt_libraries() {
if [ -z "${include_path}" ]; then
# Search for cuopt_c.h
local found_header
found_header=$(find "${search_dir}" -name "cuopt_c.h" -path "*/linear_programming/*" 2>/dev/null | head -1)
found_header=$(find "${search_dir}" -name "cuopt_c.h" -path "*/mathematical_optimization/*" 2>/dev/null | head -1)

if [ -n "${found_header}" ]; then
# Check if this is a Python package installation (contains libcuopt/include)
if echo "${found_header}" | grep -q "/libcuopt/include/"; then
# Python package structure: /path/to/libcuopt/include/cuopt/linear_programming/cuopt_c.h
# Python package structure: /path/to/libcuopt/include/cuopt/mathematical_optimization/cuopt_c.h
# Extract the include directory by going up 3 directories from the header file
include_path=$(dirname "$(dirname "$(dirname "${found_header}")")")
else
# Standard installation: /path/to/include/cuopt/linear_programming/cuopt_c.h
# Standard installation: /path/to/include/cuopt/mathematical_optimization/cuopt_c.h
# Extract the include directory by going up 2 directories
include_path=$(dirname "$(dirname "${found_header}")")
fi
Expand Down
Loading
Loading