Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1eb8dd4
math_opt/third_party_solvers: add CPLEX dynamic library loader
sschnug Apr 3, 2026
a455674
math_opt: add CPLEX solver backend and RAII wrapper
sschnug Apr 3, 2026
4d213d1
math_opt: wire CPLEX into solver registry, parameters and python
sschnug Apr 3, 2026
eed5ba1
math_opt: fix test-suite bugs used across solvers -> use-after-free +…
sschnug Apr 3, 2026
8387b4a
math_opt: add CPLEX test-suite and adapt shared test-infrastructure
sschnug Apr 3, 2026
c892ae8
math-opt: rewrite message callback impl in CPLEX solver
sschnug Apr 4, 2026
0a0b52d
copyright headers update relatex to math-opt CPLEX work
sschnug Apr 4, 2026
f9dd5a5
math-opt: fix undefined behaviour bug in cplex impl due to unhandled …
sschnug Apr 4, 2026
a6f1c46
math-opt: add missing include of <functional> in CPLEX dynamic loadin…
sschnug Apr 4, 2026
93ff76e
math-opt: fix param leaking in CPLEX impl -> reset params in-between …
sschnug Apr 4, 2026
b91313e
math-opt: fix wrong solution status mapping case 110 -> it's no proof…
sschnug Apr 4, 2026
d904985
math-opt: fix "dead" branch in CPLEX impl due to -> don't ask for LP …
sschnug Apr 4, 2026
15d4481
math-opt: cosmetic improvements for CPLEX impl
sschnug Apr 4, 2026
98b2340
math-opt: use SafeCplexDouble also in incremental code-paths (forgot…
sschnug Apr 5, 2026
d6ab3c4
math-opt: CPLEX -> do NOT use unsigned parameter-types in proto schem…
sschnug Apr 5, 2026
2f7607a
math-opt: enforce early (enough) CPLEX output suppression and callbac…
sschnug Apr 5, 2026
0624ec0
Merge remote-tracking branch 'origin/main' into math_opt_add_cplex_su…
sschnug Apr 5, 2026
e6cb38f
formatting / hygiene -> in math-opt CPLEX impl
sschnug Apr 5, 2026
dd01961
math-opt: make cplex dynamic loading quiet (like gurobi) -> INFO -> V…
sschnug Apr 5, 2026
94960d2
math-opt: add missing CPLX specific parameter support in Python wrapper
sschnug Apr 5, 2026
6cb9b83
math-opt: use int/long (like CPLEX C API does) for CPLEX params in Py…
sschnug Apr 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ortools/math_opt/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2010-2025 Google LLC
# Copyright 2010-2026 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand Down Expand Up @@ -127,6 +127,7 @@ proto_library(
srcs = ["parameters.proto"],
deps = [
"//ortools/glop:parameters_proto",
"//ortools/math_opt/solvers:cplex_proto",
"//ortools/math_opt/solvers:glpk_proto",
"//ortools/math_opt/solvers:gurobi_proto",
"//ortools/math_opt/solvers:highs_proto",
Expand Down
61 changes: 59 additions & 2 deletions ortools/math_opt/cpp/parameters.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2010-2025 Google LLC
// Copyright 2010-2026 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand Down Expand Up @@ -88,6 +88,8 @@ std::optional<absl::string_view> Enum<SolverType>::ToOptString(
return "santorini";
case SolverType::kXpress:
return "xpress";
case SolverType::kCplex:
return "cplex";
}
return std::nullopt;
}
Expand All @@ -97,7 +99,7 @@ absl::Span<const SolverType> Enum<SolverType>::AllValues() {
SolverType::kGscip, SolverType::kGurobi, SolverType::kGlop,
SolverType::kCpSat, SolverType::kPdlp, SolverType::kGlpk,
SolverType::kEcos, SolverType::kScs, SolverType::kHighs,
SolverType::kSantorini, SolverType::kXpress,
SolverType::kSantorini, SolverType::kXpress, SolverType::kCplex,
};
return absl::MakeConstSpan(kSolverTypeValues);
}
Expand Down Expand Up @@ -234,6 +236,59 @@ XpressParameters XpressParameters::FromProto(
return result;
}

CplexParametersProto CplexParameters::Proto() const {
CplexParametersProto result;
for (const auto& [key, val] : param_double_values) {
auto* p = result.add_parameters()->mutable_parameter_double();
p->set_name(key);
p->set_value(val);
}
for (const auto& [key, val] : param_bool_values) {
auto* p = result.add_parameters()->mutable_parameter_bool();
p->set_name(key);
p->set_value(val);
}
for (const auto& [key, val] : param_int32_values) {
auto* p = result.add_parameters()->mutable_parameter_int32();
p->set_name(key);
p->set_value(val);
}
for (const auto& [key, val] : param_int64_values) {
auto* p = result.add_parameters()->mutable_parameter_int64();
p->set_name(key);
p->set_value(val);
}
for (const auto& [key, val] : param_string_values) {
auto* p = result.add_parameters()->mutable_parameter_string();
p->set_name(key);
p->set_value(val);
}
return result;
}

CplexParameters CplexParameters::FromProto(const CplexParametersProto& proto) {
CplexParameters result;
for (const CplexParametersProto::Parameter& p : proto.parameters()) {
if (p.has_parameter_double()) {
result.param_double_values[p.parameter_double().name()] =
p.parameter_double().value();
} else if (p.has_parameter_bool()) {
result.param_bool_values[p.parameter_bool().name()] =
p.parameter_bool().value();
} else if (p.has_parameter_int32()) {
result.param_int32_values[p.parameter_int32().name()] =
p.parameter_int32().value();
} else if (p.has_parameter_int64()) {
result.param_int64_values[p.parameter_int64().name()] =
p.parameter_int64().value();
} else if (p.has_parameter_string()) {
result.param_string_values[p.parameter_string().name()] =
p.parameter_string().value();
}
}
return result;
}

SolveParametersProto SolveParameters::Proto() const {
SolveParametersProto result;
result.set_enable_output(enable_output);
Expand Down Expand Up @@ -287,6 +342,7 @@ SolveParametersProto SolveParameters::Proto() const {
*result.mutable_glpk() = glpk.Proto();
*result.mutable_highs() = highs;
*result.mutable_xpress() = xpress.Proto();
*result.mutable_cplex() = cplex.Proto();
return result;
}

Expand Down Expand Up @@ -347,6 +403,7 @@ absl::StatusOr<SolveParameters> SolveParameters::FromProto(
result.glpk = GlpkParameters::FromProto(proto.glpk());
result.highs = proto.highs();
result.xpress = XpressParameters::FromProto(proto.xpress());
result.cplex = CplexParameters::FromProto(proto.cplex());
return result;
}

Expand Down
27 changes: 26 additions & 1 deletion ortools/math_opt/cpp/parameters.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2010-2025 Google LLC
// Copyright 2010-2026 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand Down Expand Up @@ -28,6 +28,7 @@
#include "ortools/glop/parameters.pb.h" // IWYU pragma: export
#include "ortools/math_opt/cpp/enums.h" // IWYU pragma: export
#include "ortools/math_opt/parameters.pb.h"
#include "ortools/math_opt/solvers/cplex.pb.h" // IWYU pragma: export
#include "ortools/math_opt/solvers/gscip/gscip.pb.h" // IWYU pragma: export
#include "ortools/math_opt/solvers/gurobi.pb.h" // IWYU pragma: export
#include "ortools/math_opt/solvers/highs.pb.h" // IWYU pragma: export
Expand Down Expand Up @@ -114,6 +115,12 @@ enum class SolverType {
// Supports LP, MIP, and nonconvex integer quadratic problems.
// A fast option, but has special licensing.
kXpress = SOLVER_TYPE_XPRESS,

// IBM ILOG CPLEX solver (third party).
//
// Supports LP, MIP problems (other types are unimplemented).
// A fast option, but has special licensing.
kCplex = SOLVER_TYPE_CPLEX,
};

MATH_OPT_DEFINE_ENUM(SolverType, SOLVER_TYPE_UNSPECIFIED);
Expand Down Expand Up @@ -292,6 +299,23 @@ struct XpressParameters {
bool empty() const { return param_values.empty(); }
};

struct CplexParameters {
absl::linked_hash_map<std::string, double> param_double_values;
absl::linked_hash_map<std::string, bool> param_bool_values;
absl::linked_hash_map<std::string, int32_t> param_int32_values;
absl::linked_hash_map<std::string, int64_t> param_int64_values;
absl::linked_hash_map<std::string, std::string> param_string_values;

CplexParametersProto Proto() const;
static CplexParameters FromProto(const CplexParametersProto& proto);

bool empty() const {
return param_double_values.empty() && param_bool_values.empty() &&
param_int32_values.empty() && param_int64_values.empty() &&
param_string_values.empty();
}
};

// Parameters to control a single solve.
//
// Contains both parameters common to all solvers, e.g. time_limit, and
Expand Down Expand Up @@ -466,6 +490,7 @@ struct SolveParameters {
GlpkParameters glpk;
HighsOptionsProto highs;
XpressParameters xpress;
CplexParameters cplex;

SolveParametersProto Proto() const;
static absl::StatusOr<SolveParameters> FromProto(
Expand Down
12 changes: 11 additions & 1 deletion ortools/math_opt/parameters.proto
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2010-2025 Google LLC
// Copyright 2010-2026 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand All @@ -19,6 +19,7 @@ package operations_research.math_opt;
import "google/protobuf/duration.proto";
import "ortools/pdlp/solvers.proto";
import "ortools/glop/parameters.proto";
import "ortools/math_opt/solvers/cplex.proto";
import "ortools/math_opt/solvers/glpk.proto";
import "ortools/math_opt/solvers/gscip/gscip.proto";
import "ortools/math_opt/solvers/gurobi.proto";
Expand Down Expand Up @@ -115,6 +116,12 @@ enum SolverTypeProto {
// Supports LP, MIP, and nonconvex integer quadratic problems.
// A fast option, but has special licensing.
SOLVER_TYPE_XPRESS = 13;

// IBM ILOG CPLEX solver (third party).
//
// Supports LP, MIP. (other problem-types are unimplemented)
// A fast option, but has special licensing.
SOLVER_TYPE_CPLEX = 14;
}

// Selects an algorithm for solving linear programs.
Expand Down Expand Up @@ -179,6 +186,7 @@ message SolverInitializerProto {
GurobiInitializerProto gurobi = 1;
reserved 2;
XpressInitializerProto xpress = 3;
CplexInitializerProto cplex = 4;
}

// Parameters to control a single solve.
Expand Down Expand Up @@ -381,5 +389,7 @@ message SolveParametersProto {

XpressParametersProto xpress = 28;

CplexParametersProto cplex = 29;

reserved 11; // Deleted
}
9 changes: 8 additions & 1 deletion ortools/math_opt/python/init_arguments.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Copyright 2010-2025 Google LLC
# Copyright 2010-2026 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand Down Expand Up @@ -129,6 +129,11 @@ class StreamableHighsInitArguments:
"""Streamable Highs specific parameters for solver instantiation."""


@dataclasses.dataclass
class StreamableCplexInitArguments:
"""Streamable Cplex specific parameters for solver instantiation."""


@dataclasses.dataclass
class StreamableSantoriniInitArguments:
"""Streamable Santorini specific parameters for solver instantiation."""
Expand All @@ -150,6 +155,7 @@ class StreamableSolverInitArguments:
scs: Initialization parameters specific to SCS.
highs: Initialization parameters specific to HiGHS.
santorini: Initialization parameters specific to Santorini.
cplex: Initialization parameters specific to Cplex.
"""

gscip: Optional[StreamableGScipInitArguments] = None
Expand All @@ -163,6 +169,7 @@ class StreamableSolverInitArguments:
scs: Optional[StreamableScsInitArguments] = None
highs: Optional[StreamableHighsInitArguments] = None
santorini: Optional[StreamableSantoriniInitArguments] = None
cplex: Optional[StreamableCplexInitArguments] = None

def to_proto(self) -> parameters_pb2.SolverInitializerProto:
"""Returns a protocol buffer equivalent of this."""
Expand Down
3 changes: 2 additions & 1 deletion ortools/math_opt/python/mathopt.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,15 @@
parse_objective_parameters, parse_solution_hint)
from ortools.math_opt.python.objectives import AuxiliaryObjective, Objective
from ortools.math_opt.python.parameters import (Emphasis, GlpkParameters,
GurobiParameters, LPAlgorithm,
GurobiParameters, CplexParameters, LPAlgorithm,
SolveParameters, SolverType,
emphasis_from_proto,
emphasis_to_proto,
lp_algorithm_from_proto,
lp_algorithm_to_proto,
parse_glpk_parameters,
parse_gurobi_parameters,
parse_cplex_parameters,
parse_solve_parameters,
solver_type_from_proto,
solver_type_to_proto)
Expand Down
Loading
Loading