Skip to content

Commit 129a792

Browse files
Merge pull request #103 from conp-solutions/parallel-proofs
Parallel proofs
2 parents bd16219 + bf248a1 commit 129a792

File tree

17 files changed

+680
-126
lines changed

17 files changed

+680
-126
lines changed

.github/workflows/build-and-test-parallel.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ jobs:
2828
RUNOPENWBO: 0
2929
RUNFUZZ: 0
3030
RUNDIVERSIFY: 0
31+
RUNPARALLELPROOF: 1
3132
run: ./tools/ci.sh
3233

3334
- name: mergesat re-build
@@ -42,10 +43,6 @@ jobs:
4243
run: |
4344
./tools/check-determinism.sh "build/release/bin/mergesat -cores=3" "build/release/bin/mergesat -cores=3 -no-diversify" "build/release/bin/mergesat -cores=2 -no-pre" "build/debug/bin/mergesat -cores=3" "build/debug/bin/mergesat -cores=3 -no-diversify" "build/debug/bin/mergesat -cores=2 -no-pre"
4445
45-
- name: check cadical interface
46-
run: |
47-
./tools/cadical-interface/compare-cadical-mergesat.sh
48-
4946
5047
MacOS:
5148

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [unreleased]
99

10+
* parallel: support proof generation
1011
* testing: use modgen generator during fuzzing runs
1112
* fix FPU control to compile on ARM
1213

Makefile

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,15 @@ MINISAT_LDFLAGS = -Wall $(LD_EXTRA_FLAGS)
7474
ifeq ($(BUILD_TYPE),)
7575
BUILD_TYPE=simp
7676
else
77-
MINISAT_LDFLAGS += -lpthread
77+
ifeq (Darwin,$(findstring Darwin,$(shell uname)))
78+
MINISAT_LDFLAGS += -lpthread
79+
else
80+
# Static linking with conditional variables with glibc and libstdc++
81+
# fails, in case we do not include whole archives. Just adding lpthread
82+
# is not good enough.
83+
# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58909
84+
MINISAT_LDFLAGS += -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
85+
endif
7886
endif
7987

8088
ifeq (Darwin,$(findstring Darwin,$(shell uname)))
@@ -186,12 +194,12 @@ $(BUILD_DIR)/release/bin/$(MINISAT) $(BUILD_DIR)/debug/bin/$(MINISAT) $(BUILD_DI
186194
$(BUILD_DIR)/debug/tests/%:
187195
$(ECHO) Linking Binary: $@
188196
$(VERB) mkdir -p $(dir $@)
189-
$(VERB) $(CXX) $^ $(MINISAT_LDFLAGS) $(LDFLAGS) -o $@
197+
$(VERB) $(CXX) $^ $(MINISAT_LDFLAGS) $(MINISAT_CXXFLAGS) $(LDFLAGS) -o $@
190198

191199
$(BUILD_DIR)/release/tests/%:
192200
$(ECHO) Linking Binary: $@
193201
$(VERB) mkdir -p $(dir $@)
194-
$(VERB) $(CXX) $^ $(MINISAT_LDFLAGS) $(LDFLAGS) -o $@
202+
$(VERB) $(CXX) $^ $(MINISAT_LDFLAGS) $(MINISAT_CXXFLAGS) $(LDFLAGS) -o $@
195203

196204
## Static Library rule
197205
%/lib/$(MINISAT_SLIB):

minisat/core/LockGuard.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*************************************************************************************[LockGuard.h]
2+
Copyright (c) 2022, Norbert Manthey
3+
**************************************************************************************************/
4+
5+
#ifndef LockGuard_h
6+
#define LockGuard_h
7+
8+
#include "mtl/XAlloc.h"
9+
#include <mutex>
10+
11+
namespace MERGESAT_NSPACE
12+
{
13+
14+
/** Allow to easily grab a lock for the life time of a function or code block.*/
15+
class LockGuard
16+
{
17+
std::mutex &lock;
18+
bool doUnlock;
19+
20+
public:
21+
LockGuard(std::mutex &externLock, bool doLock) : lock(externLock), doUnlock(doLock)
22+
{
23+
if (doLock) lock.lock();
24+
}
25+
~LockGuard()
26+
{
27+
if (doUnlock) lock.unlock();
28+
}
29+
};
30+
31+
} // namespace MERGESAT_NSPACE
32+
33+
#endif

minisat/core/OnlineProofChecker.h

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Copyright (c) 2020, Norbert Manthey
66
#define OnlineProofChecker_h
77

88
#include "core/Constants.h"
9+
#include "core/LockGuard.h"
910
#include "core/SolverTypes.h"
1011
#include "mtl/Alg.h"
1112
#include "mtl/Heap.h"
@@ -68,38 +69,40 @@ class OnlineProofChecker
6869
vec<Lit> tmpLits; // for temporary addidion
6970
int verbose;
7071

72+
std::mutex checker_mutex; // mutex to log the checker
73+
7174
public:
7275
/** setup a proof checker with the given format */
7376
OnlineProofChecker(ProofStyle proofStyle);
7477

7578
/** add a clause of the initial formula */
76-
void addParsedclause(const vec<Lit> &cls);
79+
void addParsedclause(const vec<Lit> &cls, bool dolock);
7780

7881
/** add a clause during search
7982
* Note: for DRAT clauses only the very first literal will be used for checking RAT!
8083
* @return true, if the addition of this clause is valid wrt. the current proof format
8184
*/
82-
bool addClause(const std::vector<int> &clause);
83-
template <class T> bool addClause(const T &clause, const Lit &remLit, bool checkOnly = false);
84-
bool addClause(const vec<Lit> &cls, bool checkOnly = false);
85-
bool addClause(const Lit &l);
86-
template <class T> bool addStrengthenedClause(const T &clause, const Lit toDropLit, bool checkOnly = false);
85+
bool addClause(const std::vector<int> &clause, bool dolock);
86+
template <class T> bool addClause(const T &clause, const Lit &remLit, bool checkOnly, bool dolock);
87+
bool addClause(const vec<Lit> &cls, bool checkOnly, bool dolock);
88+
bool addClause(const Lit &l, bool dolock);
89+
template <class T> bool addStrengthenedClause(const T &clause, const Lit toDropLit, bool checkOnly, bool dolock);
8790

8891
/** remove a clause during search */
89-
bool removeClause(const std::vector<int> &clause);
90-
bool removeClause(const Lit &l);
91-
template <class T> bool removeClause(const T &cls);
92-
template <class T> bool removeClause(const T &cls, const Lit &rmLit);
92+
bool removeClause(const std::vector<int> &clause, bool dolock);
93+
bool removeClause(const Lit &l, bool dolock);
94+
template <class T> bool removeClause(const T &cls, bool dolock);
95+
template <class T> bool removeClause(const T &cls, const Lit &rmLit, bool dolock);
9396

9497
/** check whether the given clause exists in the current proof (useful for debugging) */
95-
template <class T> bool hasClause(const T &cls);
96-
bool hasClause(const Lit &cls);
98+
template <class T> bool hasClause(const T &cls, bool dolock);
99+
bool hasClause(const Lit &cls, bool dolock);
97100

98101
/// plot the current unit clauses and the current formula
99102
void printState();
100103

101104
/// check whether all clauses in the online checker are correctly in the data structures!
102-
void fullCheck();
105+
void fullCheck(bool doLock);
103106

104107
/// set verbosity of the checker
105108
void setVerbosity(int newVerbosity);
@@ -265,27 +268,30 @@ inline bool OnlineProofChecker::propagate()
265268
return (confl != CRef_Undef); // return true, if something was found!
266269
}
267270

268-
inline bool OnlineProofChecker::removeClause(const std::vector<int> &clause)
271+
inline bool OnlineProofChecker::removeClause(const std::vector<int> &clause, bool doLock)
269272
{
273+
LockGuard guard(checker_mutex, doLock);
270274
tmpLits.clear();
271275
for (size_t i = 0; i < clause.size(); ++i) {
272276
tmpLits.push(clause[i] < 0 ? mkLit(-clause[i] - 1, true) : mkLit(clause[i] - 1, false));
273277
}
274278
// remove this clause in the usual way
275-
return removeClause(tmpLits);
279+
return removeClause(tmpLits, false);
276280
}
277281

278-
inline bool OnlineProofChecker::removeClause(const Lit &l)
282+
inline bool OnlineProofChecker::removeClause(const Lit &l, bool doLock)
279283
{
284+
LockGuard guard(checker_mutex, doLock);
280285
// create a clause with l
281286
tmpLits.clear();
282287
tmpLits.push(l);
283288
// add this clause in the usual way
284-
return removeClause(tmpLits);
289+
return removeClause(tmpLits, false);
285290
}
286291

287-
template <class T> inline bool OnlineProofChecker::removeClause(const T &cls, const Lit &remLit)
292+
template <class T> inline bool OnlineProofChecker::removeClause(const T &cls, const Lit &remLit, bool doLock)
288293
{
294+
LockGuard guard(checker_mutex, doLock);
289295
tmpLits.clear();
290296
if (remLit != lit_Undef) {
291297
tmpLits.push(remLit);
@@ -296,18 +302,20 @@ template <class T> inline bool OnlineProofChecker::removeClause(const T &cls, co
296302
}
297303
}
298304
// remove this clause in the usual way
299-
return removeClause(tmpLits);
305+
return removeClause(tmpLits, false);
300306
}
301307

302-
inline bool OnlineProofChecker::hasClause(const Lit &cls)
308+
inline bool OnlineProofChecker::hasClause(const Lit &cls, bool doLock)
303309
{
310+
LockGuard guard(checker_mutex, doLock);
304311
vec<Lit> l;
305312
l.push(cls);
306-
return hasClause(l);
313+
return hasClause(l, false);
307314
}
308315

309-
template <class T> inline bool OnlineProofChecker::hasClause(const T &cls)
316+
template <class T> inline bool OnlineProofChecker::hasClause(const T &cls, bool doLock)
310317
{
318+
LockGuard guard(checker_mutex, doLock);
311319
if (verbose > 3) {
312320
std::cerr << "c [DRAT-OTFC] check for clause " << cls << std::endl;
313321
}
@@ -380,8 +388,9 @@ template <class T> inline bool OnlineProofChecker::hasClause(const T &cls)
380388
}
381389

382390

383-
template <class T> inline bool OnlineProofChecker::removeClause(const T &cls)
391+
template <class T> inline bool OnlineProofChecker::removeClause(const T &cls, bool doLock)
384392
{
393+
LockGuard guard(checker_mutex, doLock);
385394
if (verbose > 3) {
386395
std::cerr << "c [DRAT-OTFC] remove clause " << cls << std::endl;
387396
printState();
@@ -503,8 +512,9 @@ template <class T> inline bool OnlineProofChecker::removeClause(const T &cls)
503512
return true;
504513
}
505514

506-
inline void OnlineProofChecker::addParsedclause(const vec<Lit> &cls)
515+
inline void OnlineProofChecker::addParsedclause(const vec<Lit> &cls, bool doLock)
507516
{
517+
LockGuard guard(checker_mutex, doLock);
508518
if (cls.size() == 0) {
509519
ok = false;
510520
return;
@@ -534,19 +544,22 @@ inline void OnlineProofChecker::addParsedclause(const vec<Lit> &cls)
534544
// here, do not check whether the clause is entailed, because its still input!
535545
}
536546

537-
inline bool OnlineProofChecker::addClause(const std::vector<int> &clause)
547+
inline bool OnlineProofChecker::addClause(const std::vector<int> &clause, bool lock)
538548
{
549+
LockGuard guard(checker_mutex, lock);
539550
// create a clause where remLit is the first literal
540551
tmpLits.clear();
541552
for (size_t i = 0; i < clause.size(); ++i) {
542553
tmpLits.push(clause[i] < 0 ? mkLit(-clause[i] - 1, true) : mkLit(clause[i] - 1, false));
543554
}
544555
// add this clause in the usual way
545-
return addClause(tmpLits);
556+
return addClause(tmpLits, false, false);
546557
}
547558

548-
template <class T> inline bool OnlineProofChecker::addClause(const T &clause, const Lit &remLit, bool checkOnly)
559+
template <class T>
560+
inline bool OnlineProofChecker::addClause(const T &clause, const Lit &remLit, bool checkOnly, bool lock)
549561
{
562+
LockGuard guard(checker_mutex, lock);
550563
// create a clause where remLit is the first literal
551564
tmpLits.clear();
552565
if (remLit != lit_Undef) {
@@ -558,12 +571,13 @@ template <class T> inline bool OnlineProofChecker::addClause(const T &clause, co
558571
}
559572
}
560573
// add this clause in the usual way
561-
return addClause(tmpLits, checkOnly);
574+
return addClause(tmpLits, checkOnly, false);
562575
}
563576

564577
template <class T>
565-
inline bool OnlineProofChecker::addStrengthenedClause(const T &clause, const Lit toDropLit, bool checkOnly)
578+
inline bool OnlineProofChecker::addStrengthenedClause(const T &clause, const Lit toDropLit, bool checkOnly, bool lock)
566579
{
580+
LockGuard guard(checker_mutex, lock);
567581
// create a clause without literal remLit
568582
tmpLits.clear();
569583
for (int i = 0; i < clause.size(); ++i) {
@@ -572,27 +586,29 @@ inline bool OnlineProofChecker::addStrengthenedClause(const T &clause, const Lit
572586
}
573587
}
574588
// add this clause in the usual way
575-
return addClause(tmpLits, checkOnly);
589+
return addClause(tmpLits, checkOnly, false);
576590
}
577591

578-
inline bool OnlineProofChecker::addClause(const Lit &l)
592+
inline bool OnlineProofChecker::addClause(const Lit &l, bool lock)
579593
{
594+
LockGuard guard(checker_mutex, lock);
580595
// create a clause with l
581596
tmpLits.clear();
582597
if (l != lit_Undef) {
583598
tmpLits.push(l);
584599
}
585600
// add this clause in the usual way
586-
return addClause(tmpLits);
601+
return addClause(tmpLits, false, false);
587602
}
588603

589-
inline bool OnlineProofChecker::addClause(const vec<Lit> &cls, bool checkOnly)
604+
inline bool OnlineProofChecker::addClause(const vec<Lit> &cls, bool checkOnly, bool lock)
590605
{
591606
if (!ok) {
592607
return true;
593608
} // trivially true, we reached the empty clause already!
594609
bool conflict = false;
595610

611+
LockGuard guard(checker_mutex, lock);
596612
const int initialVars = nVars();
597613

598614
// have enough variables present
@@ -771,7 +787,7 @@ inline void OnlineProofChecker::printState()
771787
return;
772788
}
773789

774-
fullCheck();
790+
fullCheck(false);
775791

776792
std::cerr << "c [DRAT-OTFC] STATE:" << std::endl;
777793
for (int i = 0; i < unitClauses.size(); ++i) {
@@ -789,8 +805,9 @@ inline void OnlineProofChecker::printState()
789805
}
790806
}
791807

792-
inline void OnlineProofChecker::fullCheck()
808+
inline void OnlineProofChecker::fullCheck(bool doLock)
793809
{
810+
LockGuard guard(checker_mutex, doLock);
794811
for (int i = 0; i < clauses.size(); ++i) {
795812
const CRef cr = clauses[i];
796813
const Clause &c = ca[cr];

0 commit comments

Comments
 (0)