use std::atomic<bool> in external boolean for time limit

This commit is contained in:
Laurent Perron
2018-07-04 13:31:00 +02:00
parent 8dde7ff690
commit 8e7db4fbda
6 changed files with 22 additions and 18 deletions

View File

@@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <atomic>
#include <cstdio>
#include <cstdlib>
#include <memory>
@@ -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<bool> stopped(false);
Model model;
model.Add(NewSatParameters(parameters));
model.GetOrCreate<TimeLimit>()->RegisterExternalBooleanAsLimit(&stopped);

View File

@@ -13,6 +13,7 @@
#include "ortools/flatzinc/cp_model_fz_solver.h"
#include <atomic>
#include <cmath>
#include <limits>
#include <unordered_map>
@@ -923,7 +924,7 @@ void SolveFzWithCpModelProto(const fz::Model& fz_model,
<< sat_params;
m.parameters.MergeFrom(flag_parameters);
bool stopped = false;
std::atomic<bool> stopped(false);
SigintHandler handler;
handler.Register([&stopped]() { stopped = true; });

View File

@@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <atomic>
#include <fstream>
#include <string>
#include <vector>
@@ -115,7 +116,7 @@ class BopInterface : public MPSolverInterface {
std::vector<MPSolver::BasisStatus> row_status_;
bop::BopParameters parameters_;
double best_objective_bound_;
bool interrupt_solver_;
std::atomic<bool> interrupt_solver_;
};
BopInterface::BopInterface(MPSolver* const solver)

View File

@@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <atomic>
#include <fstream>
#include <string>
#include <unordered_map>
@@ -102,7 +103,7 @@ class GLOPInterface : public MPSolverInterface {
std::vector<MPSolver::BasisStatus> column_status_;
std::vector<MPSolver::BasisStatus> row_status_;
glop::GlopParameters parameters_;
bool interrupt_solver_;
std::atomic<bool> interrupt_solver_;
};
GLOPInterface::GLOPInterface(MPSolver* const solver)

View File

@@ -3019,10 +3019,10 @@ CpSolverResponse SolveCpModelParallel(
const SatParameters& params = *model->GetOrCreate<SatParameters>();
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<bool> stopped_boolean(false);
std::atomic<bool>* stopped = &stopped_boolean;
if (model->GetOrCreate<TimeLimit>()->ExternalBooleanAsLimit() != nullptr) {
stopped = model->GetOrCreate<TimeLimit>()->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<SatParameters>()->set_num_search_workers(1);
#endif // __PORTABLE_PLATFORM__
CpSolverResponse response;
if (params.num_search_workers() > 1) {
#if !defined(__PORTABLE_PLATFORM__)

View File

@@ -15,6 +15,7 @@
#define OR_TOOLS_UTIL_TIME_LIMIT_H_
#include <algorithm>
#include <atomic>
#include <cstdlib>
#include <limits>
#include <memory>
@@ -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<bool>* 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<bool>* 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<bool>* 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;
}