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

Generalize DSE as compiler passes #1030

Merged
merged 29 commits into from Jan 27, 2020
Merged

Generalize DSE as compiler passes #1030

merged 29 commits into from Jan 27, 2020

Conversation

FabioLuporini
Copy link
Contributor

This is the last of the restructuring PRs, to go in after #1026 #1027 #1028

@codecov
Copy link

codecov bot commented Jan 17, 2020

Codecov Report

Merging #1030 into master will increase coverage by 0.07%.
The diff coverage is 95.28%.

Impacted file tree graph

@@            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
Impacted Files Coverage Δ
devito/logger.py 83.05% <ø> (-2.03%) ⬇️
devito/exceptions.py 100% <ø> (ø) ⬆️
devito/passes/__init__.py 100% <100%> (ø) ⬆️
devito/ir/clusters/__init__.py 100% <100%> (ø) ⬆️
tests/test_dle.py 97.27% <100%> (-0.29%) ⬇️
devito/symbolics/extended_sympy.py 92.78% <100%> (+6.43%) ⬆️
devito/ir/support/space.py 88.23% <100%> (+0.37%) ⬆️
devito/ir/clusters/cluster.py 98.51% <100%> (+0.8%) ⬆️
devito/yask/operator.py 87.06% <100%> (+1.11%) ⬆️
devito/ir/stree/algorithms.py 100% <100%> (ø) ⬆️
... and 34 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 95ab69c...5dbf7c5. Read the comment docs.

def _normalize(func):
"""
A simple decorator to normalize the input of operator methods that
expect an IntervalGroup as operand.
Copy link
Contributor

Choose a reason for hiding this comment

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

'... as an operand.'

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed


# 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)
Copy link
Contributor

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 ...'.

Copy link
Contributor Author

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?

index = writeto.index(dep_inducing[0])
writeto = IntervalGroup(writeto[index:])
except IndexError:
perf_adv("Couldn't optimize some of the detected redundancies")
Copy link
Contributor

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.

Copy link
Contributor Author

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.

# - 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
Copy link
Contributor

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.

Copy link
Contributor Author

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
Copy link
Contributor

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.

Copy link
Contributor Author

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).

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.
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

@FabioLuporini FabioLuporini left a 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/stree/algorithms.py Show resolved Hide resolved
def _normalize(func):
"""
A simple decorator to normalize the input of operator methods that
expect an IntervalGroup as operand.
Copy link
Contributor Author

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 Show resolved Hide resolved

# 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)
Copy link
Contributor Author

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?

index = writeto.index(dep_inducing[0])
writeto = IntervalGroup(writeto[index:])
except IndexError:
perf_adv("Couldn't optimize some of the detected redundancies")
Copy link
Contributor Author

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/rewriters.py Show resolved Hide resolved
devito/passes/clusters/utils.py Show resolved Hide resolved
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
Copy link
Contributor Author

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).

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.
Copy link
Contributor Author

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.

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.
Copy link
Contributor Author

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.

Copy link
Contributor

@mloubout mloubout left a 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)

perf("- [Hotspot] %s: %.2f s (%.1f %%)" % (i.lstrip('_'), v, perc))
threshold = 20.

def pprint(timings, indent=''):
Copy link
Contributor

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

Copy link
Contributor Author

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
Copy link
Contributor

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?

Copy link
Contributor Author

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

devito/passes/clusters/aliases.py Show resolved Hide resolved
except AttributeError:
assert w_pows == 0

# Collect common temporaries (r0, r1, ...)
Copy link
Contributor

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

Copy link
Contributor Author

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):
Copy link
Contributor

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/...)

perf("- [Hotspot] %s: %.2f s (%.1f %%)" % (i.lstrip('_'), v, perc))
threshold = 20.

def pprint(timings, indent=''):
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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, ...)
Copy link
Contributor Author

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

@mloubout mloubout merged commit d022ffa into master Jan 27, 2020
@mloubout mloubout deleted the move-clustering-algos branch January 27, 2020 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants