Skip to content

Commit 322a466

Browse files
committed
More sophisticated cache
1 parent b926ec9 commit 322a466

File tree

2 files changed

+104
-10
lines changed

2 files changed

+104
-10
lines changed

src/oracle/oracle.cpp

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ void Oracle::AddSolToCache() {
6767
}
6868
sol_cache.swap(new_cache);
6969
assert(sol_cache.size()%mult == 0);
70+
rebuild_cache_lookup();
7071
}
7172

7273
sol_cache.push_back(255); // 0th variable, nonsense
@@ -75,29 +76,115 @@ void Oracle::AddSolToCache() {
7576
sol_cache.push_back(vs[i].phase);
7677
}
7778
assert(sol_cache.size()%mult == 0);
79+
80+
// add to lookup
81+
if (cache_lookup_var != 0) {
82+
auto val = vs[cache_lookup_var].phase;
83+
cache_lookup[val].push_back(sol_cache.size()/mult - 1);
84+
assert(cache_lookup[0].size() + cache_lookup[1].size() == sol_cache.size()/mult);
85+
}
7886
stats.cache_added++;
7987
}
8088

89+
void Oracle::rebuild_cache_lookup() {
90+
const uint32_t mult = vars+1;
91+
cache_lookup[0].clear();
92+
cache_lookup[1].clear();
93+
if (cache_lookup_var != 0) {
94+
assert(cache_lookup_var < vars+1);
95+
for (size_t i = 0; i < sol_cache.size()/mult; i++) {
96+
auto val = sol_cache[i*mult + cache_lookup_var];
97+
cache_lookup[val].push_back(i);
98+
}
99+
assert(cache_lookup[0].size() + cache_lookup[1].size() == sol_cache.size()/mult);
100+
}
101+
}
102+
81103
void Oracle::ClearSolCache() {
82104
sol_cache.clear();
105+
cache_lookup_var = 0;
106+
rebuild_cache_lookup();
107+
cache_lookup_frequencies.clear();
83108
}
84109

85110
bool Oracle::SatByCache(const vector<Lit>& assumps) {
86-
// Try all cache lines
87-
uint64_t checks = 0;
88111
const uint32_t mult = vars+1;
89112
assert(sol_cache.size()%mult == 0);
90-
const uint64_t sz = sol_cache.size();
91-
for (uint64_t i = 0; i < sz; i+=mult) {
92-
bool ok = true;
93-
// all our assumptions must be in the solution
94-
for (const Lit& l : assumps) {
95-
checks++;
96-
if (sol_cache[i + VarOf(l)] == !IsPos(l)) { ok = false; break; }
113+
114+
if (cache_lookup_frequencies.empty()) {
115+
cache_lookup_frequencies.resize(vars+1, 0);
116+
}
117+
for (const Lit& l : assumps) cache_lookup_frequencies[VarOf(l)]++;
118+
if ((stats.sat_by_cache_calls % 1000 == 999)) {
119+
vector<uint32_t> occs_int(mult, 0);
120+
const uint64_t sz = sol_cache.size();
121+
for (uint64_t i = 0; i < sz; i+=mult) {
122+
for(uint64_t i2 = 1; i2 < mult; i2++) {
123+
occs_int[i2] += sol_cache[i + i2];
124+
}
97125
}
98-
if (ok) return true;
126+
vector<double> occs(mult, 0.0);
127+
for(uint64_t i = 1; i < mult; i++) {
128+
auto& o = occs[i];
129+
o = (double)occs_int[i]/((double)sz/mult);
130+
o = (o < 0.5) ? o : (1.0 - o);
131+
}
132+
vector<int> v;
133+
for(int i = 1; i <= vars; i++) v.push_back(i);
134+
std::sort(v.begin(), v.end(), [&](int a, int b){
135+
uint64_t fa = (double)cache_lookup_frequencies[a]*occs[a];
136+
uint64_t fb = (double)cache_lookup_frequencies[b]*occs[b];
137+
return fa > fb;
138+
});
139+
cache_lookup_var = v[0];
140+
rebuild_cache_lookup();
99141
}
142+
143+
144+
// Check if cache var is assumps
145+
bool found = false;
146+
bool val;
147+
if (cache_lookup_var != 0) {
148+
for(const auto& l: assumps) {
149+
if (VarOf(l) == cache_lookup_var) {
150+
found = true;
151+
val = IsPos(l);
152+
break;
153+
}
154+
}
155+
}
156+
157+
uint64_t checks = 0;
158+
if (found) {
159+
for(const auto& idx : cache_lookup[val]) {
160+
bool ok = true;
161+
// all our assumptions must be in the solution
162+
for (const Lit& l : assumps) {
163+
checks++;
164+
if (sol_cache[idx*mult + VarOf(l)] == !IsPos(l)) { ok = false; break; }
165+
}
166+
if (ok) return true;
167+
}
168+
} else {
169+
const uint64_t sz = sol_cache.size();
170+
for (uint64_t i = 0; i < sz; i+=mult) {
171+
bool ok = true;
172+
// all our assumptions must be in the solution
173+
for (const Lit& l : assumps) {
174+
checks++;
175+
if (sol_cache[i + VarOf(l)] == !IsPos(l)) { ok = false; break; }
176+
}
177+
if (ok) return true;
178+
}
179+
}
180+
stats.sat_by_cache_calls++;
100181
stats.mems += checks/20;
182+
if (stats.sat_by_cache_calls % 100 == 99) {
183+
cout << "found: " << found << " cache var: " << cache_lookup_var
184+
<< "orig sz: " << sol_cache.size()/mult
185+
<< " cache size: " << cache_lookup[0].size() << " -- " << cache_lookup[1].size()
186+
<< endl;
187+
}
101188

102189
// Not in the cache
103190
return false;

src/oracle/oracle.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#define oclv2(x) do {} while(0)
3535
#endif
3636

37+
using std::array;
38+
3739
namespace sspp {
3840
namespace oracle {
3941

@@ -77,6 +79,7 @@ struct Stats {
7779
int64_t restarts = 0;
7880
int64_t cache_useful = 0;
7981
int64_t cache_added = 0;
82+
int64_t sat_by_cache_calls = 0;
8083
void Print() const;
8184
};
8285

@@ -187,7 +190,11 @@ class Oracle {
187190
vector<Lit> LearnUip(size_t conflict_clause);
188191
int CDCLBT(size_t confl_clause, int min_level=0);
189192

193+
void rebuild_cache_lookup();
190194
vector<uint8_t> sol_cache; // Caches found FULL solutions
195+
array<vector<uint32_t>, 2> cache_lookup; //0/1 for literal cache_lookup_lit
196+
int cache_lookup_var = 0; // 0 = unset
197+
vector<uint64_t> cache_lookup_frequencies;
191198
void AddSolToCache();
192199
bool SatByCache(const vector<Lit>& assumps);
193200
void ClearSolCache();

0 commit comments

Comments
 (0)