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
16 changes: 13 additions & 3 deletions devito/ir/support/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from devito.ir.support.utils import AccessMode, extrema
from devito.ir.support.vector import LabeledVector, Vector
from devito.symbolics import (
compare_ops, q_affine, q_comp_acc, q_constant, retrieve_indexed
compare_ops, q_affine, q_comp_acc, q_constant, retrieve_indexed, search
)
from devito.tools import (
CacheInstances, Tag, as_mapper, as_tuple, cached_hash, filter_sorted, flatten,
Expand All @@ -20,6 +20,7 @@
ComponentAccess, CriticalRegion, Dimension, DimensionTuple, Fence, Function, Symbol,
TBArray, Temp, TempArray
)
from devito.types.dimension import Thickness

__all__ = ['ExprGeometry', 'IterationInstance', 'Scope', 'TimedAccess']

Expand Down Expand Up @@ -515,8 +516,17 @@ def touched_halo(self, findex):
# If `m + (self[d] - d) < self.function._size_nodomain[d].left`, then `self`
# will definitely touch the left-halo, at least when `d=0`
size_nodomain_left = self.function._size_nodomain[findex].left

# Symbolic thicknesses may appear in indices for Functions defined on SubDomains
# These are used to offset the loop index values to correctly index into the
# reduced array allocated on the SubDomain. As such, they do not represent a
# shift of index on the physical grid and can (and should) be zeroed for the
# purpose of determining if the halo is touched.
tkns_subs = {tkn: 0 for tkn in search(self[findex], Thickness)}
findex_wo_thickness = self[findex].subs(tkns_subs)

try:
touch_halo_left = bool(m + (self[findex] - d) < size_nodomain_left)
touch_halo_left = bool(m + (findex_wo_thickness - d) < size_nodomain_left)
except TypeError:
# Two reasons we might end up here:
# * `d` is a constant integer
Expand All @@ -529,7 +539,7 @@ def touched_halo(self, findex):
# If `M + (self[d] - d) > self.function._size_nodomain[d].left`, then
# `self` will definitely touch the right-halo, at least when `d=d_M`
try:
touch_halo_right = bool(M + (self[findex] - d) > size_nodomain_left)
touch_halo_right = bool(M + (findex_wo_thickness - d) > size_nodomain_left)
except TypeError:
# See comments in the except block above
touch_halo_right = True
Expand Down
22 changes: 22 additions & 0 deletions tests/test_mpi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2323,6 +2323,28 @@ def test_merge_subset_comms_w_overlap(self, mode):
halo_update1 = body[1].body[0]
assert isinstance(halo_update1, HaloUpdateList)

@pytest.mark.parallel(mode=1)
def test_function_on_subdomain_no_exchange(self, mode):

class Boundary(SubDomain):
name = 'boundary'

def define(self, dimensions):
x, y, z = dimensions
return {x: ('left', 1), y: ('middle', 1, 1), z: ('right', 1)}

grid = Grid(shape=(6, 6, 6))
boundary = Boundary(grid=grid)

f = TimeFunction(name='f', grid=boundary, space_order=2)

op = Operator(Eq(f.forward, f))
_ = op.cfunction

# Halo should not be considered touched, despite symbolic offsets in indices due
# to Function on SubDomain
check_halo_exchanges(op, 0, 0)


class TestOperatorAdvanced:

Expand Down
Loading