math_opt: export from google3

This commit is contained in:
Corentin Le Molgat
2024-02-23 10:20:28 +01:00
parent 874ad953eb
commit dae0ec2219
17 changed files with 280 additions and 16 deletions

View File

@@ -370,6 +370,7 @@ if(BUILD_MATH_OPT)
ortools/math_opt/python/result.py
ortools/math_opt/python/solution.py
ortools/math_opt/python/solve.py
ortools/math_opt/python/solver_resources.py
ortools/math_opt/python/sparse_containers.py
ortools/math_opt/python/statistics.py
DESTINATION ${PYTHON_PROJECT_DIR}/math_opt/python)

View File

@@ -508,3 +508,16 @@ cc_library(
"//ortools/math_opt/core:solve_interrupter",
],
)
cc_library(
name = "solver_resources",
srcs = ["solver_resources.cc"],
hdrs = ["solver_resources.h"],
deps = [
"//ortools/math_opt:rpc_cc_proto",
"//ortools/port:proto_utils",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:string_view",
],
)

View File

@@ -345,7 +345,7 @@ bool AbslParseFlag(absl::string_view text, SolveParameters* solve_parameters,
}
std::string AbslUnparseFlag(SolveParameters solve_parameters) {
return ProtobufTextFormatPrintToString(solve_parameters.Proto());
return ProtobufTextFormatPrintToStringForFlag(solve_parameters.Proto());
}
} // namespace math_opt

View File

@@ -0,0 +1,66 @@
// Copyright 2010-2024 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "ortools/math_opt/cpp/solver_resources.h"
#include <string>
#include <utility>
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "ortools/port/proto_utils.h"
namespace operations_research::math_opt {
SolverResourcesProto SolverResources::Proto() const {
SolverResourcesProto ret;
if (cpu.has_value()) {
ret.set_cpu(cpu.value());
}
return ret;
}
absl::StatusOr<SolverResources> SolverResources::FromProto(
const SolverResourcesProto& proto) {
SolverResources ret;
if (proto.has_cpu()) {
ret.cpu = proto.cpu();
}
return ret;
}
bool AbslParseFlag(const absl::string_view text,
SolverResources* const solver_resources,
std::string* const error) {
SolverResourcesProto proto;
if (!ProtobufParseTextProtoForFlag(text, &proto, error)) {
return false;
}
absl::StatusOr<SolverResources> resources = SolverResources::FromProto(proto);
if (!resources.ok()) {
*error = absl::StrCat(
"SolverResourcesProto was invalid and could not convert to "
"SolverResources: ",
resources.status().ToString());
return false;
}
*solver_resources = *std::move(resources);
return true;
}
std::string AbslUnparseFlag(const SolverResources& solver_resources) {
return ProtobufTextFormatPrintToStringForFlag(solver_resources.Proto());
}
} // namespace operations_research::math_opt

View File

@@ -0,0 +1,73 @@
// Copyright 2010-2024 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef OR_TOOLS_MATH_OPT_CPP_SOLVER_RESOURCES_H_
#define OR_TOOLS_MATH_OPT_CPP_SOLVER_RESOURCES_H_
#include <optional>
#include <string>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "ortools/math_opt/rpc.pb.h"
namespace operations_research::math_opt {
// The hints on the resources a remote solve is expected to use. These
// parameters are hints and may be ignored by the remote server (in particular
// in case of solve in a local subprocess, for example).
//
// When using RemoteSolve() and RemoteComputeInfeasibleSubsystem(), these hints
// are mostly optional as some defaults will be computed based on the other
// parameters.
//
// When using RemoteStreamingSolve() these hints are used to dimension the
// resources available during the execution of every action; thus it is
// recommended to set them.
//
struct SolverResources {
// The number of solver threads that are expected to actually execute in
// parallel. Must be finite and >0.0.
//
// For example a value of 3.0 means that if the solver has 5 threads that can
// execute we expect at least 3 of these threads to be scheduled in parallel
// for any given time slice of the operating system scheduler.
//
// A fractional value indicates that we don't expect the operating system to
// constantly schedule the solver's work. For example with 0.5 we would expect
// the solver's threads to be scheduled half the time.
//
// This parameter is usually used in conjunction with
// SolveParameters.threads. For some solvers like Gurobi it makes sense to use
// SolverResources.cpu = SolveParameters.threads. For other solvers like
// CP-SAT, it may makes sense to use a value lower than the number of threads
// as not all threads may be ready to be scheduled at the same time. It is
// better to consult each solver documentation to set this parameter.
//
// Note that if the SolveParameters.threads is not set then this parameter
// should also be left unset.
std::optional<double> cpu;
SolverResourcesProto Proto() const;
static absl::StatusOr<SolverResources> FromProto(
const SolverResourcesProto& proto);
};
bool AbslParseFlag(absl::string_view text, SolverResources* solver_resources,
std::string* error);
std::string AbslUnparseFlag(const SolverResources& solver_resources);
} // namespace operations_research::math_opt
#endif // OR_TOOLS_MATH_OPT_CPP_SOLVER_RESOURCES_H_

View File

@@ -35,6 +35,7 @@ py_library(
":result",
":solution",
":solve",
":solver_resources",
":sparse_containers",
],
)
@@ -194,3 +195,9 @@ py_library(
":model",
],
)
py_library(
name = "solver_resources",
srcs = ["solver_resources.py"],
deps = ["//ortools/math_opt:rpc_py_pb2"],
)

View File

@@ -158,6 +158,7 @@ from ortools.math_opt.python.solve import compute_infeasible_subsystem
from ortools.math_opt.python.solve import IncrementalSolver
from ortools.math_opt.python.solve import solve
from ortools.math_opt.python.solve import SolveCallback
from ortools.math_opt.python.solver_resources import SolverResources
from ortools.math_opt.python.sparse_containers import LinearConstraintFilter
from ortools.math_opt.python.sparse_containers import parse_linear_constraint_map
from ortools.math_opt.python.sparse_containers import parse_variable_map

View File

@@ -31,6 +31,7 @@ from ortools.math_opt.python import parameters
from ortools.math_opt.python import result
from ortools.math_opt.python import solution
from ortools.math_opt.python import solve
from ortools.math_opt.python import solver_resources
from ortools.math_opt.python import sparse_containers
# This list does not contain some modules intentionally:
@@ -56,6 +57,7 @@ _MODULES_TO_CHECK: List[types.ModuleType] = [
sparse_containers,
solution,
solve,
solver_resources,
]
# Some symbols are not meant to be exported; we exclude them here.

View File

@@ -0,0 +1,66 @@
# Copyright 2010-2024 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
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Configures solver resources."""
import dataclasses
from typing import Optional
from ortools.math_opt import rpc_pb2
@dataclasses.dataclass
class SolverResources:
"""The hints on the resources a remote solve is expected to use.
These parameters are hints and may be ignored by the remote server (in
particular in case of solve in a local subprocess, for example).
When using remote_solve() and remote_compute_infeasible_subsystem(), these
hints are mostly optional as some defaults will be computed based on the other
parameters.
When using remote_streaming_solve() these hints are used to dimension the
resources available during the execution of every action; thus it is
recommended to set them.
MOE:begin_intracomment_strip
The go/uoss server will use these parameters to do a bin-packing of all
requests. They are generally used as soft-limits though instead of
hard-limits and a solve may be able to consume more resources than requested.
MOE:end_intracomment_strip
Attributes:
cpu: The number of solver threads that are expected to actually execute in
parallel. Must be finite and >0.0. For example a value of 3.0 means that
if the solver has 5 threads that can execute we expect at least 3 of these
threads to be scheduled in parallel for any given time slice of the
operating system scheduler. A fractional value indicates that we don't
expect the operating system to constantly schedule the solver's work. For
example with 0.5 we would expect the solver's threads to be scheduled half
the time. This parameter is usually used in conjunction with
SolveParameters.threads. For some solvers like Gurobi it makes sense to
use SolverResources.cpu = SolveParameters.threads. For other solvers like
CP-SAT, it may makes sense to use a value lower than the number of threads
as not all threads may be ready to be scheduled at the same time. It is
better to consult each solver documentation to set this parameter. Note
that if the SolveParameters.threads is not set then this parameter should
also be left unset.
"""
cpu: Optional[float] = None
def to_proto(self) -> rpc_pb2.SolverResourcesProto:
return rpc_pb2.SolverResourcesProto(cpu=self.cpu)

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python3
# Copyright 2010-2024 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
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unit tests for solver_resources."""
from absl.testing import absltest
from ortools.math_opt import rpc_pb2
from ortools.math_opt.python import solver_resources
from ortools.math_opt.python.testing import compare_proto
class SolverResourcesTest(compare_proto.MathOptProtoAssertions, absltest.TestCase):
def test_to_proto_empty(self):
self.assert_protos_equiv(
solver_resources.SolverResources().to_proto(),
rpc_pb2.SolverResourcesProto(),
)
def test_to_proto_with_cpu(self):
self.assert_protos_equiv(
solver_resources.SolverResources(cpu=3.5).to_proto(),
rpc_pb2.SolverResourcesProto(cpu=3.5),
)
if __name__ == "__main__":
absltest.main()

View File

@@ -28,7 +28,7 @@ option java_multiple_files = true;
// This message is used to specify some hints on the resources a remote solve is
// expected to use. These parameters are hints and may be ignored by the remote
// server (in particular in case of solve in a local subprocess for example).
// server (in particular in case of solve in a local subprocess, for example).
//
// When using SolveService.Solve and SolveService.ComputeInfeasibleSubsystem,
// these hints are mostly optional as some defaults will be computed based on
@@ -43,10 +43,10 @@ message SolverResourcesProto {
// parallel. Must be finite and >0.0.
//
// For example a value of 3.0 means that if the solver has 5 threads that can
// execute we expect at least 3 of these threads to be schedule in parallel
// execute we expect at least 3 of these threads to be scheduled in parallel
// for any given time slice of the operating system scheduler.
//
// A fractional value indicate that we don't expect the operating system to
// A fractional value indicates that we don't expect the operating system to
// constantly schedule the solver's work. For example with 0.5 we would expect
// the solver's threads to be scheduled half the time.
//

View File

@@ -247,7 +247,7 @@ math_opt::BoundedLinearExpression CutsetConstraint(
// Solves the TSP by returning the ordering of the cities that minimizes travel
// distance.
absl::StatusOr<Cycle> SolveTsp(
const std::vector<std::pair<double, double>>& cities,
absl::Span<const std::pair<double, double>> cities,
const math_opt::SolverType solver) {
const int n = static_cast<int>(cities.size());
const std::vector<std::vector<double>> distance_matrix =

View File

@@ -96,10 +96,9 @@ struct EnumFormatter {
absl::StatusOr<std::unique_ptr<Model>> LoadMiplibInstance(
const absl::string_view name) {
ASSIGN_OR_RETURN(const ModelProto model_proto,
ReadMpsFile(devtools_build::GetDataDependencyFilepath(
absl::StrCat("operations_research_data/"
ReadMpsFile(absl::StrCat("operations_research_data/"
"MIP_MIPLIB/miplib2017/",
name, ".mps.gz"))));
name, ".mps.gz")));
return Model::FromModelProto(model_proto);
}

View File

@@ -1025,10 +1025,9 @@ namespace {
absl::StatusOr<std::unique_ptr<Model>> LoadMiplibInstance(
absl::string_view name) {
ASSIGN_OR_RETURN(const ModelProto model_proto,
ReadMpsFile(devtools_build::GetDataDependencyFilepath(
absl::StrCat("operations_research_data/"
ReadMpsFile(absl::StrCat("operations_research_data/"
"MIP_MIPLIB/miplib2017/",
name, ".mps.gz"))));
name, ".mps.gz")));
return Model::FromModelProto(model_proto);
}

View File

@@ -64,10 +64,9 @@ namespace {
absl::StatusOr<std::unique_ptr<Model>> LoadMiplibInstance(
absl::string_view name) {
ASSIGN_OR_RETURN(const ModelProto model_proto,
ReadMpsFile(devtools_build::GetDataDependencyFilepath(
absl::StrCat("operations_research_data/"
ReadMpsFile(absl::StrCat("operations_research_data/"
"MIP_MIPLIB/miplib2017/",
name, ".mps.gz"))));
name, ".mps.gz")));
return Model::FromModelProto(model_proto);
}

View File

@@ -157,7 +157,7 @@ std::optional<ObjectiveUpdatesProto> ObjectiveStorage::ObjectiveData::Update(
std::pair<ObjectiveUpdatesProto, AuxiliaryObjectivesUpdatesProto>
ObjectiveStorage::Update(
const Diff& diff, const absl::flat_hash_set<VariableId>& deleted_variables,
const std::vector<VariableId>& new_variables) const {
absl::Span<const VariableId> new_variables) const {
AuxiliaryObjectivesUpdatesProto auxiliary_result;
for (const AuxiliaryObjectiveId id : diff.deleted) {

View File

@@ -192,7 +192,7 @@ class ObjectiveStorage {
std::pair<ObjectiveUpdatesProto, AuxiliaryObjectivesUpdatesProto> Update(
const Diff& diff,
const absl::flat_hash_set<VariableId>& deleted_variables,
const std::vector<VariableId>& new_variables) const;
absl::Span<const VariableId> new_variables) const;
// Updates the checkpoint and clears all stored changes in diff.
void AdvanceCheckpointInDiff(VariableId variable_checkpoint,