24#include "absl/log/check.h"
25#include "absl/status/status.h"
26#include "absl/status/statusor.h"
30#include "ortools/math_opt/model.pb.h"
31#include "ortools/math_opt/parameters.pb.h"
32#include "ortools/math_opt/result.pb.h"
44absl::StatusOr<std::pair<void*, size_t>> SolveImpl(
45 const void* model_bytes,
const size_t model_size,
const int solver_type,
47 if (model_bytes ==
nullptr && model_size != 0) {
48 return absl::InvalidArgumentError(
49 "model cannot be null unless model_size is zero");
51 if (model_size > std::numeric_limits<int>::max()) {
53 <<
"model_size must be at most max int, was: " << model_size;
57 if (!
model.ParseFromArray(model_bytes,
static_cast<int>(model_size))) {
58 return absl::InvalidArgumentError(
"bad model proto");
62 Solver::SolveArgs solve_args;
63 if (interrupter !=
nullptr) {
68 model,
static_cast<SolverTypeProto
>(solver_type),
69 init_args, solve_args));
70 const size_t result_size_bytes = result.ByteSizeLong();
71 if (result_size_bytes > std::numeric_limits<int>::max()) {
73 <<
"cannot serialize a SolveResultProto with more than INT_MAX = "
74 << std::numeric_limits<int>::max() <<
"(0x" << std::hex
75 << std::numeric_limits<int>::max() << std::dec
76 <<
") bytes, but solve result proto needed " << result_size_bytes
77 <<
" bytes in binary format";
79 void* result_bin =
nullptr;
81 result_bin =
malloc(result_size_bytes);
84 const bool serialize_ok = result.SerializeToArray(
85 result_bin,
static_cast<int>(result_size_bytes));
88 return absl::InternalError(
"fail to serialize SolveResultProto");
91 return std::make_pair(result_bin, result_size_bytes);
104 CHECK(interrupter !=
nullptr);
108 CHECK(interrupter !=
nullptr);
114 void** solve_result,
size_t* solve_result_size,
116 const absl::StatusOr<std::pair<void*, size_t>> result =
117 operations_research::math_opt::SolveImpl(
118 model, model_size, solver_type, interrupter,
119 solve_result !=
nullptr);
121 if (solve_result_size !=
nullptr) {
122 *solve_result_size = result->second;
124 if (solve_result !=
nullptr) {
125 *solve_result = result->first;
127 if (status_msg !=
nullptr) {
128 *status_msg =
nullptr;
133 if (status_msg !=
nullptr) {
134 const size_t num_bytes = result.status().message().size() + 1;
135 *status_msg =
static_cast<char*
>(
malloc(num_bytes));
136 std::memcpy(*status_msg, result.status().message().data(), num_bytes);
138 if (solve_result !=
nullptr) {
139 *solve_result =
nullptr;
141 if (solve_result_size !=
nullptr) {
142 *solve_result_size = 0;
144 return result.status().raw_code();
#define ASSIGN_OR_RETURN(lhs, rexpr)
void MathOptFree(void *ptr)
int MathOptIsInterrupted(const MathOptInterrupter *interrupter)
void MathOptInterrupt(MathOptInterrupter *interrupter)
int MathOptSolve(const void *model, const size_t model_size, const int solver_type, MathOptInterrupter *const interrupter, void **solve_result, size_t *solve_result_size, char **status_msg)
MathOptInterrupter * MathOptNewInterrupter()
void MathOptFreeInterrupter(MathOptInterrupter *interrupter)
Frees interrupter, has no effect when interrupter is NULL.
bool IsInterrupted() const
static absl::StatusOr< SolveResultProto > NonIncrementalSolve(const ModelProto &model, SolverTypeProto solver_type, const InitArgs &init_args, const SolveArgs &solve_args)
A shortcut for calling Solver::New() and then Solver::Solve().
SolverInterface::InitArgs InitArgs
An object oriented wrapper for quadratic constraints in ModelStorage.
StatusBuilder InvalidArgumentErrorBuilder()
operations_research::SolveInterrupter cpp_interrupter