Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions devito/ir/clusters/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,12 @@ def __hash__(self):
def concatenate(cls, *cgroups):
return list(chain(*cgroups))

def rebuild(self, **kwargs):
clusters = kwargs.get('clusters', self)
ispace = kwargs.get('ispace', self.ispace)

return self.__class__(clusters, ispace=ispace)

@cached_property
def exprs(self):
return flatten(c.exprs for c in self)
Expand All @@ -663,6 +669,10 @@ def exprs(self):
def scope(self):
return Scope(exprs=self.exprs)

@cached_property
def functions(self):
return self.scope.functions

@cached_property
def ispace(self):
return self._ispace
Expand Down
22 changes: 1 addition & 21 deletions devito/passes/clusters/aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
maximum, minimum, normalize_properties, relax_properties, unbounded, vmax, vmin
)
from devito.passes.clusters.cse import _cse
from devito.passes.clusters.utils import expose_tuning_knobs
from devito.symbolics import (
Uxmapper, estimate_cost, retrieve_functions, reuse_if_untouched, search, sympy_dtype,
uxreplace
Expand Down Expand Up @@ -1080,27 +1081,6 @@ def optimize_clusters_msds(clusters):
return processed


def expose_tuning_knobs(clusters, sregistry):
"""
Replace all pre-existing BlockDimensions with fresh ones, to enable
separate tuning for the CIRE-generated temporaries.
"""
# Create the new BlockDimensions
callback = lambda i: sregistry.make_name(prefix=i)

mapper = {}
for d in set().union(*[c.used_dimensions for c in clusters]):
if d.is_Block:
mapper.update(d._rebuild_hierarchy(callback))

if not mapper:
return clusters

processed = [c.subs(mapper) for c in clusters]

return processed


def pick_best(variants):
"""
Return the variant with the best theoretical performance.
Expand Down
23 changes: 9 additions & 14 deletions devito/passes/clusters/misc.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from itertools import groupby, product

from devito.ir.clusters import Queue, cluster_pass
from devito.ir.support import SEPARABLE, SEQUENTIAL, Scope
from devito.ir.support import SEPARABLE, Scope
from devito.passes.clusters.utils import in_critical_region
from devito.symbolics import pow_to_mul
from devito.tools import Stamp, flatten, frozendict, timed_pass
from devito.tools import Stamp, flatten, timed_pass
from devito.types import Hyperplane

__all__ = ['Lift', 'fission', 'optimize_hyperplanes', 'optimize_pows']
Expand Down Expand Up @@ -123,7 +123,7 @@ def callback(self, clusters, prefix):
d = prefix[-1].dim

# Do not waste time if definitely illegal
if any(SEQUENTIAL in c.properties[d] for c in clusters):
if any(c.properties.is_sequential(d) for c in clusters):
return clusters

# Do not waste time if definitely nothing to do
Expand All @@ -136,17 +136,16 @@ def callback(self, clusters, prefix):
return clusters

processed = []
for (it, guards), g in groupby(clusters, key=lambda c: self._key(c, prefix)):
for it, g in groupby(clusters, key=lambda c: self._key(c, prefix)):
group = list(g)

try:
test0 = any(SEQUENTIAL in c.properties[it.dim] for c in group)
test0 = any(c.properties.is_sequential(it.dim) for c in group)
except AttributeError:
# `it` is None because `c`'s IterationSpace has no `d` Dimension,
# hence `key = (it, guards) = (None, guards)`
# `it` is None because `c`'s IterationSpace has no `d` Dimension
test0 = True

if test0 or guards:
if test0:
# Heuristic: no gain from fissioning if unable to ultimately
# increase the number of collapsible iteration spaces, hence give up
processed.extend(group)
Expand All @@ -161,14 +160,10 @@ def callback(self, clusters, prefix):
def _key(self, c, prefix):
try:
index = len(prefix)
dims = tuple(i.dim for i in prefix)

it = c.ispace[index]
guards = frozendict({d: v for d, v in c.guards.items() if d in dims})

return (it, guards)
return it
except IndexError:
return (None, c.guards)
return None


@timed_pass()
Expand Down
24 changes: 23 additions & 1 deletion devito/passes/clusters/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from devito.tools import as_tuple
from devito.types import CriticalRegion, Eq, Symbol

__all__ = ['in_critical_region', 'is_memcpy', 'make_critical_sequence']
__all__ = ['expose_tuning_knobs', 'in_critical_region', 'is_memcpy',
'make_critical_sequence']


def is_memcpy(expr):
Expand Down Expand Up @@ -50,3 +51,24 @@ def in_critical_region(cluster, clusters):
elif c.is_critical_region:
maybe_found = c
return None


def expose_tuning_knobs(clusters, sregistry):
"""
Replace all pre-existing BlockDimensions with fresh ones, to enable
separate tuning for the CIRE-generated temporaries.
"""
# Create the new BlockDimensions
callback = lambda i: sregistry.make_name(prefix=i)

mapper = {}
for d in set().union(*[c.used_dimensions for c in clusters]):
if d.is_Block:
mapper.update(d._rebuild_hierarchy(callback))

if not mapper:
return clusters

processed = [c.subs(mapper) for c in clusters]

return processed
Loading