Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] compiler: Add new HaloSpot optimization #2475

Closed
wants to merge 4 commits into from
Closed
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
16 changes: 14 additions & 2 deletions devito/ir/iet/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1457,8 +1457,20 @@ def __init__(self, body, halo_scheme):
self._halo_scheme = halo_scheme

def __repr__(self):
functions = "(%s)" % ",".join(i.name for i in self.functions)
return "<%s%s>" % (self.__class__.__name__, functions)
fstrings = []
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we also print the slice for each halospot

i.e. v[t0] instead of just v.

What do you think?

for f in self.functions:
loc_indices = set().union(*[self.halo_scheme.fmapper[f].loc_indices.values()])
loc_indices = list(loc_indices)
if loc_indices:
loc_indices_str = str(loc_indices)
else:
loc_indices_str = ""

fstrings.append(f"{f.name}{loc_indices_str}")

functions = ",".join(fstrings)

return "<%s(%s)>" % (self.__class__.__name__, functions)

@property
def halo_scheme(self):
Expand Down
2 changes: 1 addition & 1 deletion devito/ir/support/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class IndexMode(Tag):
REGULAR = IndexMode('regular')
IRREGULAR = IndexMode('irregular')

# Symbols to create mock data depdendencies
# Symbols to create mock data dependencies
mocksym0 = Symbol(name='__⋈_0__')
mocksym1 = Symbol(name='__⋈_1__')

Expand Down
59 changes: 53 additions & 6 deletions devito/mpi/halo_scheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,39 @@ class HaloLabel(Tag):
STENCIL = HaloLabel('stencil')


HaloSchemeEntry = namedtuple('HaloSchemeEntry', 'loc_indices loc_dirs halos dims')
class HaloSchemeEntry:

def __init__(self, loc_indices, loc_dirs, halos, dims):
self.loc_indices = loc_indices
self.loc_dirs = loc_dirs
self.halos = halos
self.dims = dims

def __repr__(self):
return (f"HaloSchemeEntry(loc_indices={self.loc_indices}, "
f"loc_dirs={self.loc_dirs}, halos={self.halos}, dims={self.dims})")

def __eq__(self, other):
if not isinstance(other, HaloSchemeEntry):
return False
return (self.loc_indices == other.loc_indices and
self.loc_dirs == other.loc_dirs and
self.halos == other.halos and
self.dims == other.dims)

def __hash__(self):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was autocompleted by copilot.
Are people happy to have class instead of namedtuple?

return hash((frozenset(self.loc_indices.items()),
frozenset(self.loc_dirs.items()),
frozenset(self.halos),
frozenset(self.dims)))

def rebuild(self, **kwargs):
loc_indices = kwargs.get('loc_indices', self.loc_indices)
loc_dirs = kwargs.get('loc_dirs', self.loc_dirs)
halos = kwargs.get('halos', self.halos)
dims = kwargs.get('dims', self.dims)
return HaloSchemeEntry(loc_indices, loc_dirs, halos, dims)


Halo = namedtuple('Halo', 'dim side')

Expand Down Expand Up @@ -95,8 +127,20 @@ def __init__(self, exprs, ispace):
self._honored = frozendict(self._honored)

def __repr__(self):
fnames = ",".join(i.name for i in set(self._mapper))
return "HaloScheme<%s>" % fnames
fstrings = []
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same w above

for f in self.fmapper:
loc_indices = set().union(*[self._mapper[f].loc_indices.values()])
loc_indices = list(loc_indices)
if loc_indices:
loc_indices_str = str(loc_indices)
else:
loc_indices_str = ""

fstrings.append(f"{f.name}{loc_indices_str}")

functions = ",".join(fstrings)

return "%s<%s>" % (self.__class__.__name__, functions)

def __eq__(self, other):
return (isinstance(other, HaloScheme) and
Expand Down Expand Up @@ -366,6 +410,10 @@ def distributed_aindices(self):
def loc_indices(self):
return set().union(*[i.loc_indices.keys() for i in self.fmapper.values()])

@cached_property
def loc_values(self):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better way to get the values of loc_indices?
If so happy to drop this

return set().union(*[i.loc_indices.values() for i in self.fmapper.values()])

@cached_property
def arguments(self):
return self.dimensions | set(flatten(self.honored.values()))
Expand Down Expand Up @@ -635,9 +683,8 @@ def _uxreplace_dispatch_haloscheme(hs0, rule):
# Nope, let's try with the next Indexed, if any
continue

hse = HaloSchemeEntry(frozendict(loc_indices),
frozendict(loc_dirs),
hse0.halos, hse0.dims)
hse = hse0.rebuild(loc_indices=frozendict(loc_indices),
loc_dirs=frozendict(loc_dirs))

else:
continue
Expand Down
Loading
Loading