From 8e7db4fbda12933ea3fd37b193dc21c885ffddec Mon Sep 17 00:00:00 2001 From: Laurent Perron Date: Wed, 4 Jul 2018 13:31:00 +0200 Subject: [PATCH] use std::atomic in external boolean for time limit --- examples/cpp/sat_runner.cc | 3 ++- ortools/flatzinc/cp_model_fz_solver.cc | 3 ++- ortools/linear_solver/bop_interface.cc | 3 ++- ortools/linear_solver/glop_interface.cc | 3 ++- ortools/sat/cp_model_solver.cc | 15 +++++---------- ortools/util/time_limit.h | 13 +++++++++---- 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/examples/cpp/sat_runner.cc b/examples/cpp/sat_runner.cc index b9ed5e2cae..0254297ac0 100644 --- a/examples/cpp/sat_runner.cc +++ b/examples/cpp/sat_runner.cc @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -219,7 +220,7 @@ int Run() { // completely replaced by the more general CpModelProto. if (!cp_model.variables().empty()) { problem.Clear(); // We no longer need it, release memory. - bool stopped = false; + std::atomic stopped(false); Model model; model.Add(NewSatParameters(parameters)); model.GetOrCreate()->RegisterExternalBooleanAsLimit(&stopped); diff --git a/ortools/flatzinc/cp_model_fz_solver.cc b/ortools/flatzinc/cp_model_fz_solver.cc index 0f340850b9..80a098fc1f 100644 --- a/ortools/flatzinc/cp_model_fz_solver.cc +++ b/ortools/flatzinc/cp_model_fz_solver.cc @@ -13,6 +13,7 @@ #include "ortools/flatzinc/cp_model_fz_solver.h" +#include #include #include #include @@ -923,7 +924,7 @@ void SolveFzWithCpModelProto(const fz::Model& fz_model, << sat_params; m.parameters.MergeFrom(flag_parameters); - bool stopped = false; + std::atomic stopped(false); SigintHandler handler; handler.Register([&stopped]() { stopped = true; }); diff --git a/ortools/linear_solver/bop_interface.cc b/ortools/linear_solver/bop_interface.cc index 576d84998c..5851ae63e5 100644 --- a/ortools/linear_solver/bop_interface.cc +++ b/ortools/linear_solver/bop_interface.cc @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -115,7 +116,7 @@ class BopInterface : public MPSolverInterface { std::vector row_status_; bop::BopParameters parameters_; double best_objective_bound_; - bool interrupt_solver_; + std::atomic interrupt_solver_; }; BopInterface::BopInterface(MPSolver* const solver) diff --git a/ortools/linear_solver/glop_interface.cc b/ortools/linear_solver/glop_interface.cc index aca0759975..7103ab71d5 100644 --- a/ortools/linear_solver/glop_interface.cc +++ b/ortools/linear_solver/glop_interface.cc @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -102,7 +103,7 @@ class GLOPInterface : public MPSolverInterface { std::vector column_status_; std::vector row_status_; glop::GlopParameters parameters_; - bool interrupt_solver_; + std::atomic interrupt_solver_; }; GLOPInterface::GLOPInterface(MPSolver* const solver) diff --git a/ortools/sat/cp_model_solver.cc b/ortools/sat/cp_model_solver.cc index ac6db975d3..8aaed6fb42 100644 --- a/ortools/sat/cp_model_solver.cc +++ b/ortools/sat/cp_model_solver.cc @@ -3019,10 +3019,10 @@ CpSolverResponse SolveCpModelParallel( const SatParameters& params = *model->GetOrCreate(); CHECK(!params.enumerate_all_solutions()); - // This is a bit hacky. If the provided TimeLimit as a "stopped" Boolean, we + // This is a bit hacky. If the provided TimeLimit as a "`" Boolean, we // use this one instead. - bool stopped_boolean = false; - bool* stopped = &stopped_boolean; + std::atomic stopped_boolean(false); + std::atomic* stopped = &stopped_boolean; if (model->GetOrCreate()->ExternalBooleanAsLimit() != nullptr) { stopped = model->GetOrCreate()->ExternalBooleanAsLimit(); } @@ -3045,11 +3045,10 @@ CpSolverResponse SolveCpModelParallel( auto fix_walltime = ::operations_research::util::MakeCleanup( [&timer, &best_response]() { best_response.set_wall_time(timer.Get()); }); - // In the LNS threads, we wait for this notification before starting work. - absl::Notification first_solution_found_or_search_finished; - absl::Mutex mutex; const int num_search_workers = params.num_search_workers(); + // In the LNS threads, we wait for this notification before starting work. + absl::Notification first_solution_found_or_search_finished; VLOG(1) << "Starting parallel search with " << num_search_workers << " workers."; ThreadPool pool("Parallel_search", num_search_workers); @@ -3294,10 +3293,6 @@ CpSolverResponse SolveCpModel(const CpModelProto& model_proto, Model* model) { } }; -#if defined(__PORTABLE_PLATFORM__) - model->GetOrCreate()->set_num_search_workers(1); -#endif // __PORTABLE_PLATFORM__ - CpSolverResponse response; if (params.num_search_workers() > 1) { #if !defined(__PORTABLE_PLATFORM__) diff --git a/ortools/util/time_limit.h b/ortools/util/time_limit.h index 5a2e449b73..8fa06f9388 100644 --- a/ortools/util/time_limit.h +++ b/ortools/util/time_limit.h @@ -15,6 +15,7 @@ #define OR_TOOLS_UTIL_TIME_LIMIT_H_ #include +#include #include #include #include @@ -240,12 +241,15 @@ class TimeLimit { // the check of the limit. // // Note that ResetLimitFromParameters() will set this Boolean to false. - void RegisterExternalBooleanAsLimit(bool* external_boolean_as_limit) { + void RegisterExternalBooleanAsLimit( + std::atomic* external_boolean_as_limit) { external_boolean_as_limit_ = external_boolean_as_limit; } // Returns the current external Boolean limit. - bool* ExternalBooleanAsLimit() const { return external_boolean_as_limit_; } + std::atomic* ExternalBooleanAsLimit() const { + return external_boolean_as_limit_; + } // Sets new time limits. Note that this do not reset the running max nor // any registered external boolean or calls to RegisterSigintHandler(). @@ -277,7 +281,7 @@ class TimeLimit { double deterministic_limit_; double elapsed_deterministic_time_; - bool* external_boolean_as_limit_; + std::atomic* external_boolean_as_limit_; #ifdef HAS_PERF_SUBSYSTEM // PMU counter to help count the instructions. @@ -412,7 +416,8 @@ inline double TimeLimit::ReadInstructionCounter() { } inline bool TimeLimit::LimitReached() { - if (external_boolean_as_limit_ != nullptr && *external_boolean_as_limit_) { + if (external_boolean_as_limit_ != nullptr && + external_boolean_as_limit_->load()) { return true; }