@@ -953,27 +953,31 @@ void RegisterClausesExport(int id, SharedClausesManager* shared_clauses_manager,
953953 if (!model->GetOrCreate <SatParameters>()->share_glue_clauses ()) {
954954 return ;
955955 }
956- auto * clause_stream = shared_clauses_manager->GetClauseStream (id);
957- const int max_lbd =
958- model->GetOrCreate <SatParameters>()->clause_cleanup_lbd_bound ();
959- // Note that this callback takes no global locks, everything operates on this
960- // worker's own clause stream, whose lock is only used by this worker, and
961- // briefly when generating a batch in SharedClausesManager::Synchronize().
962- auto share_clause = [mapping, clause_stream, max_lbd,
963- clause = std::vector<int >()](
956+ const double share_interval =
957+ model->GetOrCreate <SatParameters>()->share_glue_clauses_dtime ();
958+ auto * clause_stream = model->GetOrCreate <UniqueClauseStream>();
959+ auto * time_limit = model->GetOrCreate <TimeLimit>();
960+ auto share_clause = [mapping, clause_stream, time_limit, id,
961+ shared_clauses_manager, share_interval,
962+ next_batch_dtime = -1.0 , clause = std::vector<int >()](
964963 int lbd, absl::Span<const Literal> literals) mutable {
965- if (lbd <= 0 || lbd > max_lbd ||
966- !clause_stream->CanAccept (literals.size (), lbd)) {
967- return ;
964+ if (literals.size () >= UniqueClauseStream::kMinClauseSize &&
965+ literals.size () <= UniqueClauseStream::kMaxClauseSize ) {
966+ clause.clear ();
967+ for (const Literal& lit : literals) {
968+ const int var =
969+ mapping->GetProtoVariableFromBooleanVariable (lit.Variable ());
970+ if (var == -1 ) return ;
971+ clause.push_back (lit.IsPositive () ? var : NegatedRef (var));
972+ }
973+ clause_stream->Add (clause, lbd);
968974 }
969- clause.clear ();
970- for (const Literal& lit : literals) {
971- const int var =
972- mapping->GetProtoVariableFromBooleanVariable (lit.Variable ());
973- if (var == -1 ) return ;
974- clause.push_back (lit.IsPositive () ? var : NegatedRef (var));
975+ const double elapsed_dtime = time_limit->GetElapsedDeterministicTime ();
976+ if (next_batch_dtime < 0 ) next_batch_dtime = elapsed_dtime + share_interval;
977+ if (elapsed_dtime >= next_batch_dtime) {
978+ shared_clauses_manager->AddBatch (id, clause_stream->NextBatch ());
979+ next_batch_dtime = elapsed_dtime + share_interval;
975980 }
976- clause_stream->Add (clause);
977981 };
978982 model->GetOrCreate <ClauseManager>()->SetAddClauseCallback (
979983 std::move (share_clause));
@@ -994,16 +998,16 @@ int RegisterClausesLevelZeroImport(int id,
994998 auto * implications = model->GetOrCreate <BinaryImplicationGraph>();
995999 const bool share_glue_clauses =
9961000 model->GetOrCreate <SatParameters>()->share_glue_clauses ();
1001+ auto * clause_stream =
1002+ share_glue_clauses ? model->GetOrCreate <UniqueClauseStream>() : nullptr ;
9971003 const bool minimize_shared_clauses =
9981004 model->GetOrCreate <SatParameters>()->minimize_shared_clauses ();
999- auto * clause_stream = share_glue_clauses
1000- ? shared_clauses_manager->GetClauseStream (id)
1001- : nullptr ;
10021005 auto * clause_manager = model->GetOrCreate <ClauseManager>();
10031006 const auto & import_level_zero_clauses = [shared_clauses_manager, id, mapping,
10041007 sat_solver, implications,
1005- clause_stream, clause_manager,
1006- minimize_shared_clauses]() {
1008+ minimize_shared_clauses,
1009+ clause_stream,
1010+ clause_manager]() mutable {
10071011 std::vector<std::pair<int , int >> new_binary_clauses;
10081012 shared_clauses_manager->GetUnseenBinaryClauses (id, &new_binary_clauses);
10091013 implications->EnableSharing (false );
@@ -1020,28 +1024,27 @@ int RegisterClausesLevelZeroImport(int id,
10201024 int new_clauses = 0 ;
10211025 std::array<Literal, UniqueClauseStream::kMaxClauseSize > local_clause;
10221026 sat_solver->EnsureNewClauseIndexInitialized ();
1023- // Temporarily disable clause sharing so we don't immediately re-export the
1024- // clauses we just imported.
1027+ // Temporarily disable clause sharing.
10251028 auto callback = clause_manager->TakeAddClauseCallback ();
1026- for (const absl::Span<const int > shared_clause :
1027- shared_clauses_manager->GetUnseenClauses (id)) {
1028- // Check this clause was not already learned by this worker.
1029- // We can delete the fingerprint because we should not learn an identical
1030- // clause, and the global stream will not emit the same clause while any
1031- // worker hasn't consumed this clause (and thus also shouldn't relearn the
1032- // clause).
1033- if (clause_stream->Delete (shared_clause)) continue ;
1034- for (int i = 0 ; i < shared_clause.size (); ++i) {
1035- local_clause[i] = mapping->Literal (shared_clause[i]);
1036- }
1037- if (!sat_solver->AddProblemClause (
1038- absl::MakeSpan (local_clause).subspan (0 , shared_clause.size ()))) {
1039- return false ;
1029+ while (true ) {
1030+ auto batch = shared_clauses_manager->GetUnseenClauses (id);
1031+ if (batch.empty ()) break ;
1032+ for (int clause_index = 0 ; clause_index < batch.size (); ++clause_index) {
1033+ const absl::Span<const int >& shared_clause = batch[clause_index];
1034+ // Check this clause was not already learned by this worker.
1035+ if (!clause_stream->BlockClause (shared_clause)) continue ;
1036+ ++new_clauses;
1037+ for (int i = 0 ; i < shared_clause.size (); ++i) {
1038+ local_clause[i] = mapping->Literal (shared_clause[i]);
1039+ }
1040+ if (!sat_solver->AddProblemClause (
1041+ absl::MakeSpan (local_clause)
1042+ .subspan (0 , shared_clause.size ()))) {
1043+ return false ;
1044+ }
10401045 }
1041- ++new_clauses;
10421046 }
10431047 clause_manager->SetAddClauseCallback (std::move (callback));
1044- clause_stream->RemoveWorstClauses ();
10451048 if (minimize_shared_clauses && new_clauses > 0 ) {
10461049 // The new clauses may be subsumed, so try to minimize them to reduce
10471050 // overhead of sharing.
@@ -2110,8 +2113,7 @@ SharedClasses::SharedClasses(const CpModelProto* proto, Model* global_model)
21102113 !params.interleave_search () || params.num_workers () <= 1 ;
21112114 response->SetSynchronizationMode (always_synchronize);
21122115 if (params.share_binary_clauses () && params.num_workers () > 1 ) {
2113- clauses = std::make_unique<SharedClausesManager>(always_synchronize,
2114- absl::Seconds (1 ));
2116+ clauses = std::make_unique<SharedClausesManager>(always_synchronize);
21152117 }
21162118}
21172119
0 commit comments