Skip to content

Commit

Permalink
compiler: Fix toposort to account for fences
Browse files Browse the repository at this point in the history
  • Loading branch information
FabioLuporini committed Sep 26, 2024
1 parent 602c448 commit b28aafd
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 15 deletions.
26 changes: 15 additions & 11 deletions devito/ir/clusters/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from devito.mpi.reduction_scheme import DistReduce
from devito.symbolics import estimate_cost
from devito.tools import as_tuple, flatten, infer_dtype
from devito.types import WeakFence, CriticalRegion
from devito.types import Fence, WeakFence, CriticalRegion

__all__ = ["Cluster", "ClusterGroup"]

Expand Down Expand Up @@ -239,42 +239,46 @@ def is_sparse(self):
"""
return any(a.is_irregular for a in self.scope.accesses)

@property
@cached_property
def is_wild(self):
"""
True if encoding a non-mathematical operation, False otherwise.
"""
return self.is_halo_touch or self.is_dist_reduce or self.is_fence
return (self.is_halo_touch or
self.is_dist_reduce or
self.is_weak_fence or
self.is_critical_region)

@property
@cached_property
def is_halo_touch(self):
return self.exprs and all(isinstance(e.rhs, HaloTouch) for e in self.exprs)

@property
@cached_property
def is_dist_reduce(self):
return self.exprs and all(isinstance(e.rhs, DistReduce) for e in self.exprs)

@property
@cached_property
def is_fence(self):
return self.is_weak_fence or self.is_critical_region
return (self.exprs and all(isinstance(e.rhs, Fence) for e in self.exprs) or
self.is_critical_region)

@property
@cached_property
def is_weak_fence(self):
return self.exprs and all(isinstance(e.rhs, WeakFence) for e in self.exprs)

@property
@cached_property
def is_critical_region(self):
return self.exprs and all(isinstance(e.rhs, CriticalRegion) for e in self.exprs)

@property
@cached_property
def is_async(self):
"""
True if an asynchronous Cluster, False otherwise.
"""
return any(isinstance(s, (WithLock, PrefetchUpdate))
for s in flatten(self.syncs.values()))

@property
@cached_property
def is_wait(self):
"""
True if a Cluster waiting on a lock (that is a special synchronization
Expand Down
12 changes: 8 additions & 4 deletions devito/passes/clusters/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ def is_cross(source, sink):
return t0 < v <= t1 or t1 < v <= t0

for cg1 in cgroups[n+1:]:
n1 = cgroups.index(cg1)

# A Scope to compute all cross-ClusterGroup anti-dependences
scope = Scope(exprs=cg0.exprs + cg1.exprs, rules=is_cross)

Expand All @@ -355,14 +357,16 @@ def is_cross(source, sink):
break

# Any anti- and iaw-dependences impose that `cg1` follows `cg0`
# and forbid any sort of fusion
elif any(scope.d_anti_gen()) or\
any(i.is_iaw for i in scope.d_output_gen()):
# and forbid any sort of fusion. Fences have the same effect
elif (any(scope.d_anti_gen()) or
any(i.is_iaw for i in scope.d_output_gen()) or
any(c.is_fence for c in flatten(cgroups[n:n1+1]))):
dag.add_edge(cg0, cg1)

# Any flow-dependences along an inner Dimension (i.e., a Dimension
# that doesn't appear in `prefix`) impose that `cg1` follows `cg0`
elif any(not (i.cause and i.cause & prefix) for i in scope.d_flow_gen()):
elif any(not (i.cause and i.cause & prefix)
for i in scope.d_flow_gen()):
dag.add_edge(cg0, cg1)

# Clearly, output dependences must be honored
Expand Down

0 comments on commit b28aafd

Please sign in to comment.