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
Generalize DSE as compiler passes #1030
Conversation
bd374bb
to
2971618
Compare
Codecov Report
@@ Coverage Diff @@
## master #1030 +/- ##
=========================================
+ Coverage 90.63% 90.7% +0.07%
=========================================
Files 164 167 +3
Lines 23161 23234 +73
Branches 3324 3337 +13
=========================================
+ Hits 20991 21075 +84
+ Misses 1761 1745 -16
- Partials 409 414 +5
Continue to review full report at Codecov.
|
devito/ir/support/space.py
Outdated
def _normalize(func): | ||
""" | ||
A simple decorator to normalize the input of operator methods that | ||
expect an IntervalGroup as operand. |
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.
'... as an operand.'
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.
fixed
devito/passes/clusters/aliases.py
Outdated
|
||
# Optimization: no need to retain a SpaceDimension if it does not | ||
# induce a flow/anti dependence (below, `i.offsets` captures this, by | ||
# telling how much halo will be needed to honour such dependences) |
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 again: '... determining how much halo will be required ...'.
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. I thought they were pretty much interchangeable here. Could you elaborate?
devito/passes/clusters/aliases.py
Outdated
index = writeto.index(dep_inducing[0]) | ||
writeto = IntervalGroup(writeto[index:]) | ||
except IndexError: | ||
perf_adv("Couldn't optimize some of the detected redundancies") |
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.
Super pedantic I know, but "Could not optimize ..." reads better in such situations.
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, you're totally right. Fixing.
devito/passes/clusters/cse.py
Outdated
# - it sometimes "captures too much", losing factorization opportunities; | ||
# - very slow | ||
# TODO: a second "sympy" mode will be provided, relying on SymPy's CSE() but | ||
# also ensuring some sort of post-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.
... some form of post-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.
fixing
pass | ||
elif not i.function.is_DiscreteFunction: | ||
# It didn't come from the outside and it's not in `mapper`, so | ||
# cannot determine if time-invariant; assume time-varying then |
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.
Could you give example of an object for which we can't determine whether it's time-variant or not? Not sure at the moment why we wouldn't be able to determine this.
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.
not off top of my head, but I'm sure I needed this elif
.
However, I have plans to drop this whole routine (I want to generalize it to any "Dimension-invariant" -- there's no reason to restrict ourselves to time-invariant).
tests/test_dse.py
Outdated
f = Function(name='f', grid=grid) | ||
f.data_with_halo[:] = 1. | ||
u = TimeFunction(name='u', grid=grid, space_order=3) | ||
u.data_with_halo[:] = 0. |
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 this not/will be 0.
by default?
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.
yeah. Just cut-pasting from test_dle
. I will drop it.
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.
actually, replaced with 0.5 . I don't like computing on zeros.
3256145
to
cf9efd4
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.
Pushed updates + yask patch
devito/ir/support/space.py
Outdated
def _normalize(func): | ||
""" | ||
A simple decorator to normalize the input of operator methods that | ||
expect an IntervalGroup as operand. |
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.
fixed
devito/passes/clusters/aliases.py
Outdated
|
||
# Optimization: no need to retain a SpaceDimension if it does not | ||
# induce a flow/anti dependence (below, `i.offsets` captures this, by | ||
# telling how much halo will be needed to honour such dependences) |
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. I thought they were pretty much interchangeable here. Could you elaborate?
devito/passes/clusters/aliases.py
Outdated
index = writeto.index(dep_inducing[0]) | ||
writeto = IntervalGroup(writeto[index:]) | ||
except IndexError: | ||
perf_adv("Couldn't optimize some of the detected redundancies") |
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, you're totally right. Fixing.
pass | ||
elif not i.function.is_DiscreteFunction: | ||
# It didn't come from the outside and it's not in `mapper`, so | ||
# cannot determine if time-invariant; assume time-varying then |
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.
not off top of my head, but I'm sure I needed this elif
.
However, I have plans to drop this whole routine (I want to generalize it to any "Dimension-invariant" -- there's no reason to restrict ourselves to time-invariant).
tests/test_dse.py
Outdated
f = Function(name='f', grid=grid) | ||
f.data_with_halo[:] = 1. | ||
u = TimeFunction(name='u', grid=grid, space_order=3) | ||
u.data_with_halo[:] = 0. |
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.
yeah. Just cut-pasting from test_dle
. I will drop it.
tests/test_dse.py
Outdated
f = Function(name='f', grid=grid) | ||
f.data_with_halo[:] = 1. | ||
u = TimeFunction(name='u', grid=grid, space_order=3) | ||
u.data_with_halo[:] = 0. |
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.
actually, replaced with 0.5 . I don't like computing on zeros.
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.
Small comments (mostly reminders for myself)
devito/operator/operator.py
Outdated
perf("- [Hotspot] %s: %.2f s (%.1f %%)" % (i.lstrip('_'), v, perc)) | ||
threshold = 20. | ||
|
||
def pprint(timings, indent=''): |
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: pprint
is a sympy function, with the amount of sympy we use I'd prefer another name
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'll change it to _emit_timings
-- no ambiguities then
__all__ = ['cire'] | ||
|
||
|
||
MIN_COST_ALIAS = 10 |
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.
Still can't be user modified easily right?
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, but we can easily turn it into a dict, or better, provide an API. For another PR, I'd say
except AttributeError: | ||
assert w_pows == 0 | ||
|
||
# Collect common temporaries (r0, r1, ...) |
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.
Note to myself, need test for that part if Iremeber correctly
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.
yes.
Also , we can think of optimizations for factorize
. There's ample scope for improvement and testing
return v | ||
|
||
|
||
def eval_taylor_cos(expr): |
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.
note to myself
Even in sigle precision , still callin cos instead of cosf (and sinf/...)
devito/operator/operator.py
Outdated
perf("- [Hotspot] %s: %.2f s (%.1f %%)" % (i.lstrip('_'), v, perc)) | ||
threshold = 20. | ||
|
||
def pprint(timings, indent=''): |
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'll change it to _emit_timings
-- no ambiguities then
__all__ = ['cire'] | ||
|
||
|
||
MIN_COST_ALIAS = 10 |
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, but we can easily turn it into a dict, or better, provide an API. For another PR, I'd say
__all__ = ['factorize'] | ||
|
||
|
||
MIN_COST_FACTORIZE = 100 |
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.
@mloubout same story here.
In the (near) future, I'll add devito/passes/config.py
-- a centralised place for all these parameters
except AttributeError: | ||
assert w_pows == 0 | ||
|
||
# Collect common temporaries (r0, r1, ...) |
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.
yes.
Also , we can think of optimizations for factorize
. There's ample scope for improvement and testing
cf9efd4
to
5dbf7c5
Compare
This is the last of the restructuring PRs, to go in after #1026 #1027 #1028