use of com.dat3m.dartagnan.wmm.utils.TupleSet in project Dat3M by hernanponcedeleon.
the class Acyclic method getEncodeTupleSet.
@Override
public TupleSet getEncodeTupleSet() {
logger.info("Computing encodeTupleSet for " + this);
// ====== Construct [Event -> Successor] mapping ======
Map<Event, Collection<Event>> succMap = new HashMap<>();
TupleSet relMaxTuple = rel.getMaxTupleSet();
for (Tuple t : relMaxTuple) {
succMap.computeIfAbsent(t.getFirst(), key -> new ArrayList<>()).add(t.getSecond());
}
// ====== Compute SCCs ======
DependencyGraph<Event> depGraph = DependencyGraph.from(succMap.keySet(), succMap);
TupleSet result = new TupleSet();
for (Set<DependencyGraph<Event>.Node> scc : depGraph.getSCCs()) {
for (DependencyGraph<Event>.Node node1 : scc) {
for (DependencyGraph<Event>.Node node2 : scc) {
Tuple t = new Tuple(node1.getContent(), node2.getContent());
if (relMaxTuple.contains(t)) {
result.add(t);
}
}
}
}
logger.info("encodeTupleSet size " + result.size());
if (GlobalSettings.REDUCE_ACYCLICITY_ENCODE_SETS) {
reduceWithMinSets(result);
logger.info("reduced encodeTupleSet size " + result.size());
}
return result;
}
use of com.dat3m.dartagnan.wmm.utils.TupleSet in project Dat3M by hernanponcedeleon.
the class Acyclic method reduceWithMinSets.
private void reduceWithMinSets(TupleSet encodeSet) {
/*
ASSUMPTION: MinSet is acyclic!
IDEA:
Edges that are (must-)transitively implied do not need to get encoded.
For this, we compute a (must-)transitive closure and a (must-)transitive reduction of must(rel).
The difference "must(rel)+ \ red(must(rel))" does not net to be encoded.
Note that it this is sound if the closure gets underapproximated and/or the reduction
gets over approximated.
COMPUTATION:
(1) We compute an approximate (must-)transitive closure of must(rel)
- must(rel) is likely to be already transitive per thread (due to mostly coming from po)
Hence, we get a reasonable approximation by closing transitively over thread-crossing edges only.
(2) We compute a (must) transitive reduction of the transitively closed must(rel)+.
- Since must(rel)+ is transitive, it suffice to check for each edge (a, c) if there
is an intermediate event b such that (a, b) and (b, c) are in must(rel)+
and b is implied by either a or c.
- It is possible to reduce must(rel) but that may give a less precise result.
*/
ExecutionAnalysis exec = analysisContext.get(ExecutionAnalysis.class);
TupleSet minSet = rel.getMinTupleSet();
// (1) Approximate transitive closure of minSet (only gets computed when crossEdges are available)
List<Tuple> crossEdges = minSet.stream().filter(t -> t.isCrossThread() && !t.getFirst().is(Tag.INIT)).collect(Collectors.toList());
TupleSet transMinSet = crossEdges.isEmpty() ? minSet : new TupleSet(minSet);
for (Tuple crossEdge : crossEdges) {
Event e1 = crossEdge.getFirst();
Event e2 = crossEdge.getSecond();
List<Event> ingoing = new ArrayList<>();
// ingoing events + self
ingoing.add(e1);
minSet.getBySecond(e1).stream().map(Tuple::getFirst).filter(e -> exec.isImplied(e, e1)).forEach(ingoing::add);
List<Event> outgoing = new ArrayList<>();
// outgoing edges + self
outgoing.add(e2);
minSet.getByFirst(e2).stream().map(Tuple::getSecond).filter(e -> exec.isImplied(e, e2)).forEach(outgoing::add);
for (Event in : ingoing) {
for (Event out : outgoing) {
transMinSet.add(new Tuple(in, out));
}
}
}
// (2) Approximate reduction of transitive must-set: red(must(r)+).
// Note: We reduce the transitive closure which may have more edges
// that can be used to perform reduction
TupleSet reduct = TupleSet.approximateTransitiveMustReduction(exec, transMinSet);
// Remove (must(r)+ \ red(must(r)+)
encodeSet.removeIf(t -> transMinSet.contains(t) && !reduct.contains(t));
}
use of com.dat3m.dartagnan.wmm.utils.TupleSet in project Dat3M by hernanponcedeleon.
the class Irreflexive method getEncodeTupleSet.
@Override
public TupleSet getEncodeTupleSet() {
TupleSet set = new TupleSet();
rel.getMaxTupleSet().stream().filter(Tuple::isLoop).forEach(set::add);
return set;
}
use of com.dat3m.dartagnan.wmm.utils.TupleSet in project Dat3M by hernanponcedeleon.
the class Relation method initializeEncoding.
// TODO: The following two methods are provided because currently Relations are treated as three things:
// data objects, static analysers (relation analysis) and encoders of said data objects.
// Once we split these aspects, we might get rid of these methods
// Due to being an encoder
public void initializeEncoding(SolverContext ctx) {
Preconditions.checkState(this.maxTupleSet != null && this.minTupleSet != null, String.format("No available relation data to encode %s. Perform RelationAnalysis before encoding.", this));
this.isEncoded = false;
this.encodeTupleSet = new TupleSet();
}
use of com.dat3m.dartagnan.wmm.utils.TupleSet in project Dat3M by hernanponcedeleon.
the class RelRMW method getMaxTupleSet.
@Override
public TupleSet getMaxTupleSet() {
if (maxTupleSet == null) {
logger.info("Computing maxTupleSet for " + getName());
baseMaxTupleSet = new TupleSet();
// RMWLoad -> RMWStore
FilterAbstract filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), FilterBasic.get(Tag.WRITE));
for (Event store : task.getProgram().getCache().getEvents(filter)) {
if (store instanceof RMWStore) {
baseMaxTupleSet.add(new Tuple(((RMWStore) store).getLoadEvent(), store));
}
}
// Locks: Load -> Assume/CondJump -> Store
FilterAbstract locks = FilterUnion.get(FilterBasic.get(Tag.C11.LOCK), FilterBasic.get(Tag.Linux.LOCK_READ));
filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), locks);
for (Event e : task.getProgram().getCache().getEvents(filter)) {
// Connect Load to Store
baseMaxTupleSet.add(new Tuple(e, e.getSuccessor().getSuccessor()));
}
// Atomics blocks: BeginAtomic -> EndAtomic
filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), FilterBasic.get(SVCOMPATOMIC));
for (Event end : task.getProgram().getCache().getEvents(filter)) {
List<Event> block = ((EndAtomic) end).getBlock().stream().filter(x -> x.is(Tag.VISIBLE)).collect(Collectors.toList());
for (int i = 0; i < block.size(); i++) {
for (int j = i + 1; j < block.size(); j++) {
baseMaxTupleSet.add(new Tuple(block.get(i), block.get(j)));
}
}
}
removeMutuallyExclusiveTuples(baseMaxTupleSet);
maxTupleSet = new TupleSet();
maxTupleSet.addAll(baseMaxTupleSet);
// to find guaranteed pairs (the encoding can then also be improved)
for (Thread thread : task.getProgram().getThreads()) {
for (Event load : thread.getCache().getEvents(loadExclFilter)) {
for (Event store : thread.getCache().getEvents(storeExclFilter)) {
if (load.getCId() < store.getCId()) {
maxTupleSet.add(new Tuple(load, store));
}
}
}
}
removeMutuallyExclusiveTuples(maxTupleSet);
logger.info("maxTupleSet size for " + getName() + ": " + maxTupleSet.size());
}
return maxTupleSet;
}
Aggregations