-
Notifications
You must be signed in to change notification settings - Fork 248
compiler: Turn aliases' choose() into an instance method #2839
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -111,6 +111,7 @@ class CireTransformer: | |
| def __init__(self, sregistry, options, platform): | ||
| self.sregistry = sregistry | ||
| self.platform = platform | ||
|
|
||
| self.opt_minstorage = options['min-storage'] | ||
| self.opt_rotate = options['cire-rotate'] | ||
| self.opt_ftemps = options['cire-ftemps'] | ||
|
|
@@ -125,7 +126,7 @@ def _aliases_from_clusters(self, cgroup, exclude, meta): | |
| for mapper in self._generate(cgroup, exclude): | ||
| # Clusters -> AliasList | ||
| found = collect(mapper.extracted, meta.ispace, self.opt_minstorage) | ||
| exprs, aliases = choose(found, cgroup, mapper, self.opt_mingain) | ||
| exprs, aliases = self._choose(found, cgroup, mapper) | ||
|
|
||
| # AliasList -> Schedule | ||
| schedule = lower_aliases(aliases, meta, self.opt_maxpar) | ||
|
|
@@ -189,6 +190,52 @@ def _lookup_key(self, c): | |
| """ | ||
| raise NotImplementedError | ||
|
|
||
| def _choose(self, aliases, cgroup, mapper): | ||
| """ | ||
| Analyze the detected aliases and, after applying a cost model to rule | ||
| out the aliases with a bad memory/flops trade-off, inject them into the | ||
| original expressions. | ||
| """ | ||
| exprs = cgroup.exprs | ||
|
|
||
| aliases = AliasList(aliases) | ||
| if not aliases: | ||
| return exprs, aliases | ||
|
|
||
| # `score < m` => discarded | ||
| # `score > M` => optimized | ||
| # `m <= score <= M` => maybe optimized, depends on heuristics | ||
| m = self.opt_mingain | ||
| M = self.opt_mingain*3 | ||
|
|
||
| # Filter off the aliases with low score | ||
| key = lambda a: a.score >= m | ||
| aliases.filter(key) | ||
|
|
||
| # Project the candidate aliases into `exprs` to derive the final | ||
| # working set | ||
| mapper = {k: v for k, v in mapper.items() | ||
| if v.free_symbols & set(aliases.aliaseds)} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| templated = [uxreplace(e, mapper) for e in exprs] | ||
| owset = wset(templated) | ||
|
|
||
| # Filter off the aliases with a weak flop-reduction / working-set tradeoff | ||
| key = lambda a: \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this wants to be an actual function rather than a lambda - it's pretty unreadable
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, just saw that all this is just lifted from elsewhere. I think the point still stands even if it's not so pressing |
||
| a.score > M or \ | ||
| m <= a.score <= M and (max(len(wset(a.pivot)), 1) > | ||
| len(wset(a.pivot) & owset)) | ||
| aliases.filter(key) | ||
|
|
||
| if not aliases: | ||
| return exprs, aliases | ||
|
|
||
| # Substitute the chosen aliasing sub-expressions | ||
| mapper = {k: v for k, v in mapper.items() | ||
| if v.free_symbols & set(aliases.aliaseds)} | ||
| exprs = [uxreplace(e, mapper) for e in exprs] | ||
|
|
||
| return exprs, aliases | ||
|
|
||
| def _select(self, variants): | ||
| """ | ||
| Select the best variant out of a set of `variants`, weighing flops and | ||
|
|
@@ -611,49 +658,6 @@ def collect(extracted, ispace, minstorage): | |
| return aliases | ||
|
|
||
|
|
||
| def choose(aliases, cgroup, mapper, mingain): | ||
| """ | ||
| Analyze the detected aliases and, after applying a cost model to rule out | ||
| the aliases with a bad memory/flops trade-off, inject them into the original | ||
| expressions. | ||
| """ | ||
| exprs = cgroup.exprs | ||
|
|
||
| aliases = AliasList(aliases) | ||
| if not aliases: | ||
| return exprs, aliases | ||
|
|
||
| # `score < m` => discarded | ||
| # `score > M` => optimized | ||
| # `m <= score <= M` => maybe discarded, maybe optimized; depends on heuristics | ||
| m = mingain | ||
| M = mingain*3 | ||
|
|
||
| # Filter off the aliases with low score | ||
| key = lambda a: a.score >= m | ||
| aliases.filter(key) | ||
|
|
||
| # Project the candidate aliases into `exprs` to derive the final working set | ||
| mapper = {k: v for k, v in mapper.items() if v.free_symbols & set(aliases.aliaseds)} | ||
| templated = [uxreplace(e, mapper) for e in exprs] | ||
| owset = wset(templated) | ||
|
|
||
| # Filter off the aliases with a weak flop-reduction / working-set tradeoff | ||
| key = lambda a: \ | ||
| a.score > M or \ | ||
| m <= a.score <= M and max(len(wset(a.pivot)), 1) > len(wset(a.pivot) & owset) | ||
| aliases.filter(key) | ||
|
|
||
| if not aliases: | ||
| return exprs, aliases | ||
|
|
||
| # Substitute the chosen aliasing sub-expressions | ||
| mapper = {k: v for k, v in mapper.items() if v.free_symbols & set(aliases.aliaseds)} | ||
| exprs = [uxreplace(e, mapper) for e in exprs] | ||
|
|
||
| return exprs, aliases | ||
|
|
||
|
|
||
| def lower_aliases(aliases, meta, maxpar): | ||
| """ | ||
| Create a Schedule from an AliasList. | ||
|
|
||
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 3? Is it just a magic number?