-
Notifications
You must be signed in to change notification settings - Fork 228
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
misc: various Dimension internal fixes #2205
Conversation
6ad85cf
to
03c25b7
Compare
d09401b
to
1519665
Compare
Codecov Report
@@ Coverage Diff @@
## master #2205 +/- ##
=======================================
Coverage 87.08% 87.08%
=======================================
Files 228 228
Lines 40611 40700 +89
Branches 7429 7454 +25
=======================================
+ Hits 35367 35445 +78
- Misses 4644 4652 +8
- Partials 600 603 +3
|
2dd25ba
to
8ae1f5f
Compare
610eeb2
to
7d2abb3
Compare
devito/core/autotuning.py
Outdated
@@ -209,8 +209,11 @@ def init_time_bounds(stepper, at_args, args): | |||
else: | |||
at_args[dim.max_name] = at_args[dim.min_name] + options['squeezer'] | |||
if dim.size_name in args: | |||
# May need to shrink to avoid OOB accesses | |||
at_args[dim.max_name] = min(at_args[dim.max_name], args[dim.max_name]) | |||
if isinstance(args[dim.size_name], range): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not isinstance(...):
# May need to shrink to avoid OOB accesses
at_args[dim.max_name] = min(at_args[dim.max_name], args[dim.max_name])
devito/operations/interpolators.py
Outdated
@@ -380,5 +394,6 @@ def interpolation_coeffs(self): | |||
@property | |||
def _weights(self): | |||
ddim, cdim = self.interpolation_coeffs.dimensions[1:] | |||
return Mul(*[self.interpolation_coeffs.subs({ddim: ri, cdim: rd-rd.symbolic_min}) | |||
return Mul(*[self.interpolation_coeffs.subs({ddim: ri, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpicking
for better readability, can we introduce mapper = {ddim: ....}
on the line above?
devito/operator/operator.py
Outdated
@@ -584,6 +590,9 @@ def _prepare_arguments(self, autotune=None, **kwargs): | |||
if configuration['mpi']: | |||
raise ValueError("Multiple Grids found") | |||
try: | |||
# Take biggest grid, i.e discard grids with subdimensions | |||
grids = {g for g in grids if not any(d.is_Sub for d in g.dimensions)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to be better abstracted in my opinion
I wonder whether we could have a SubGrid object (returned via __new__
) to capture subsampled grids. And dramatically simplify our lives here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main though is that this needs to be part of the Function on subdomain
overall, this is a temporary fix for arg processing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if we drop this line and modify the one above as
discretizations = {g for g in discretizations
if not any(d.is_Sub for d in g.dimensions)}
This should be enough to filter away the Subdomain grids?
Also: can we not at least add a property to Grid such as g.is_subdomain
or g.is_domain
or I don't know what name would be better. I feel having properties as opposed to peeking at the individual dimensions would be neater
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be enough to filter away the Subdomain grids?
No this will create issue for example if there is only one "sub-grid" this would end up empty and leads to missing arguments.
But looks like it's a duplicate from above now might be able to remove that one.
@@ -94,7 +94,7 @@ def __init_finalize__(self, *args, function=None, **kwargs): | |||
# a reference to the user-provided buffer | |||
self._initializer = None | |||
if len(initializer) > 0: | |||
self.data_with_halo[:] = initializer | |||
self.data_with_halo[:] = initializer[:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting, what's the difference here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No difference, just debug leftover, the issue was calling __init_finalize__
before setting newobj.function
above, needed for first touch init. Slightly safer in case of shape differences though for weird (1, n)/(n, 1)
shape where someone might give and (n,)
vector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just being paranoid here... are we completely sure both the performance and the semantics of this assignment are exactly the same as master, except for that corner case u mention above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I worry the new one might be slightly slower
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[:]
is just a view it has no performance impact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well the view gets created, so it's not really 0 impact.... but yeah, I agree it's gonna be 0.0000001 in practice 😬
7d2abb3
to
6f9beba
Compare
6f9beba
to
fa1a9b7
Compare
6ed3785
to
87d8d0e
Compare
227730a
to
47f6154
Compare
963ec1b
to
fa1a7ac
Compare
fa1a7ac
to
441de0f
Compare
devito/ir/stree/algorithms.py
Outdated
@@ -147,6 +147,12 @@ def preprocess(clusters, options=None, **kwargs): | |||
found = [] | |||
for c1 in list(queue): | |||
distributed_aindices = c1.halo_scheme.distributed_aindices | |||
h_indices = set().union(*[(d, d.root) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For homogeneity with the rest of the code below, I would rather write:
distributed_aindices = c1.halo_scheme.distributed_aindices
loc_indices = c1.halo_scheme.loc_indices
all_loc_indices = set().union(*[d._defines for d in ...])
...
Note: I'm using _defines
above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
d_defines ?
devito/operator/operator.py
Outdated
@@ -584,6 +590,9 @@ def _prepare_arguments(self, autotune=None, **kwargs): | |||
if configuration['mpi']: | |||
raise ValueError("Multiple Grids found") | |||
try: | |||
# Take biggest grid, i.e discard grids with subdimensions | |||
grids = {g for g in grids if not any(d.is_Sub for d in g.dimensions)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if we drop this line and modify the one above as
discretizations = {g for g in discretizations
if not any(d.is_Sub for d in g.dimensions)}
This should be enough to filter away the Subdomain grids?
Also: can we not at least add a property to Grid such as g.is_subdomain
or g.is_domain
or I don't know what name would be better. I feel having properties as opposed to peeking at the individual dimensions would be neater
devito/passes/iet/langbase.py
Outdated
@@ -336,7 +345,8 @@ def _is_offloadable(self, iet): | |||
functions = FindSymbols().visit(iet) | |||
buffers = [f for f in functions if f.is_Array and f._mem_mapped] | |||
hostfuncs = [f for f in functions if not is_on_device(f, self.gpu_fit)] | |||
return not (buffers and hostfuncs) | |||
|
|||
return not (hostfuncs and buffers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leftover change?
devito/passes/iet/parpragma.py
Outdated
@@ -377,6 +375,12 @@ def _make_partree(self, candidates, nthreads=None): | |||
ncollapsed=ncollapsed, nthreads=nthreads, | |||
**root.args) | |||
prefix = [] | |||
elif all(i.is_ParallelRelaxed for i in candidates) and nthreads is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about just
elif nthreads is not None:
actually, to mirror what we have in the first if
, I might prefer:
else:
if nthreads is None:
nthreads = self.nthreads_nonaffine
chunk_size = ...
...
else:
body = self.HostIteration(schedule='static', ...)
prefix = []
@@ -94,7 +94,7 @@ def __init_finalize__(self, *args, function=None, **kwargs): | |||
# a reference to the user-provided buffer | |||
self._initializer = None | |||
if len(initializer) > 0: | |||
self.data_with_halo[:] = initializer | |||
self.data_with_halo[:] = initializer[:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just being paranoid here... are we completely sure both the performance and the semantics of this assignment are exactly the same as master, except for that corner case u mention above?
@@ -94,7 +94,7 @@ def __init_finalize__(self, *args, function=None, **kwargs): | |||
# a reference to the user-provided buffer | |||
self._initializer = None | |||
if len(initializer) > 0: | |||
self.data_with_halo[:] = initializer | |||
self.data_with_halo[:] = initializer[:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I worry the new one might be slightly slower
@@ -286,7 +284,7 @@ def test_cache_blocking_structure_optrelax_prec_inject(): | |||
'openmp': True, | |||
'par-collapse-ncores': 1})) | |||
|
|||
assert_structure(op, ['t', 't,p_s0_blk0,p_s,rsx,rsy'], | |||
assert_structure(op, ['t,p_s0_blk0,p_s', 't,p_s0_blk0,p_s,rsx,rsy'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmhh, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CHange of parent hierachy in interp with rx...
always being conditional
devito/types/dimension.py
Outdated
@@ -1446,7 +1452,7 @@ def symbolic_max(self): | |||
def _arg_names(self): | |||
return (self.min_name, self.max_name, self.name) + self.parent._arg_names | |||
|
|||
def _arg_defaults(self, _min=None, **kwargs): | |||
def _arg_defaults(self, _min=None, size=None, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
devito/types/dimension.py
Outdated
@@ -977,7 +983,7 @@ def symbolic_incr(self): | |||
def bound_symbols(self): | |||
return set(self.parent.bound_symbols) | |||
|
|||
def _arg_defaults(self, **kwargs): | |||
def _arg_defaults(self, alias=None, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useless change
@@ -1515,7 +1515,7 @@ def test_issue_1927(self, factor): | |||
|
|||
op = Operator(Eq(f, 1)) | |||
|
|||
assert op.arguments()['time_M'] == 4*(save-1) # == min legal endpoint | |||
assert op.arguments()['time_M'] == 4*save-1 # == min legal endpoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a comment here which appearly I forgot to fire up...
anyway: was my old comment (min legal endpoint) wrong? or is the new one to be updated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment is correct, the value wasn't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
devito/ir/stree/algorithms.py
Outdated
h_indices = set().union(*[(d, d.root) | ||
for d in c1.halo_scheme.loc_indices]) | ||
|
||
# Skip if the Halo echange would end up outside its need iteration space |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couple of typos here
a9263b4
to
6613990
Compare
6613990
to
ab160dd
Compare
args = kwargs['args'] = args.reduce_all() | ||
|
||
# DiscreteFunctions may be created from CartesianDiscretizations, which in | ||
# turn could be Grids or SubDomains. Both may provide arguments | ||
discretizations = {getattr(kwargs[p.name], 'grid', None) for p in overrides} | ||
discretizations.update({getattr(p, 'grid', None) for p in defaults}) | ||
discretizations.discard(None) | ||
# Remove subgrids if multiple grids | ||
if len(discretizations) > 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to coin a term for any CartesianDiscretization that is not the main Grid
Also, we need to distinguish I think between SubDomain and SubGrid. The latter being a coarser representation of the (main) Grid
I don't exactly what names to use, but I feel an increasing need for a set of CartesianDiscretization attributes -- suitably overridden in the various subclasses -- along the lines of
is_root (is_main? is_domain?)
is_subdomain
is_subgrid
etc
and then here just g.is_domain
for eaxmple
@@ -1515,7 +1515,7 @@ def test_issue_1927(self, factor): | |||
|
|||
op = Operator(Eq(f, 1)) | |||
|
|||
assert op.arguments()['time_M'] == 4*(save-1) # == min legal endpoint | |||
assert op.arguments()['time_M'] == 4*save-1 # == min legal endpoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
94b5c07
to
97f1cc8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GTG , thanks
Fixes #2204
Fixes #2132
Fixes #2206
Fixes issue with ConditionalDimension range from @ccuetom