generate_loop_schedule_v2 - #350
Conversation
Uh oh!
There was an error while loading. Please reload this page.
inducer
left a comment
There was a problem hiding this comment.
Some thoughts from a quick look here.
Uh oh!
There was an error while loading. Please reload this page.
| tree = get_loop_nest_tree(kernel) | ||
| iname_to_insns = kernel.iname_to_insns() | ||
| loop_nest_around_map = defaultdict(frozenset) |
There was a problem hiding this comment.
In my view, the loop_nest_around_map should go. The loop nest tree is a strictly more informative data structure, and it is not of size O(n^2). I think we should get rid of it. I looked through the uses, and it shouldn't be hard to replace, and it'll fix another bottleneck in linearization.
There was a problem hiding this comment.
In the new version, I didn't touch the old implementation (v1-scheduler) to keep things simpler in this PR. So, for such cases
There was a problem hiding this comment.
I can handle it as a separate PR.
| Updates *tree* to make *inames_to_pull_out* a loop nesting level in | ||
| *loop_nests* | ||
| :returns: a :class:`tuple` ``(outer_loop_nest, inner_loop_nest)``, where |
| Updates *tree* to make *inames_to_pull_out* a loop nesting level in | ||
| *loop_nests* |
There was a problem hiding this comment.
Describe which is nested "inside" and which is "outside".
96856f8 to
0203d09Compareinducer
commented
May 26, 2021
Does #372 supersede this? |
kaushikcfd
commented
May 26, 2021
e14a03d to
2d526dcComparee8b03c8 to
72334e8Compare6945d16 to
d74da04Compared74da04 to
1aef04fCompare1aef04f to
581e82eComparee20c6ca to
931c6e9Compare931c6e9 to
36a1a2fComparef10f24c to
c1f8e0dComparec1f8e0d to
8c42d10Compare8c42d10 to
15cea20Compare15cea20 to
5b55bcdCompare5b55bcd to
f8dc959Comparef8dc959 to
80425bdCompareinducer
commented
Jun 9, 2022
I was just rebasing this. You beat me to it! :) |
inducer
left a comment
There was a problem hiding this comment.
Here's a first look. I haven't really gotten very far into the core algorithm, because I'm not sure I understood _pull_out_loop_nest_tree, which seems like it's a core operation.
| return wrapper | ||
| # {{{ tree data structure |
There was a problem hiding this comment.
This is big enough to be its own file.
There was a problem hiding this comment.
#694 puts the Tree class into its own file (loopy/schedule/tree.py).
| return wrapper | ||
| # {{{ tree data structure |
There was a problem hiding this comment.
Given that this has type annotations, mypy should like them (and there should be CI saying as much).
There was a problem hiding this comment.
As far as I can see, mypy checks and passes the annotations.
| @dataclass(frozen=True) | ||
| class Tree(Generic[T]): | ||
| """ | ||
| An immutable tree implementation. |
There was a problem hiding this comment.
Describe the role of the type variable T. Specifically describe that there's one Tree object, but many nodes T. Maybe rename T to NodeT?
There was a problem hiding this comment.
c53a9af hopefully clarifies this (and renames T to NodeT).
| @dataclass(frozen=True) | ||
| class Tree(Generic[T]): |
There was a problem hiding this comment.
Is this mature enough to be in pytools?
| _parent_to_children: "PMap[T, FrozenSet[T]]" | ||
| _child_to_parent: "PMap[T, Optional[T]]" |
There was a problem hiding this comment.
In terms of data structure, this is a forest (i.e. it allows multiple trees). It wouldn't take much to allow that fully... YAGNI though.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| loop_nests = sorted(loop_nests, key=lambda nest: tree.depth(nest)) | ||
| for outer, inner in zip(loop_nests[:-1], loop_nests[1:]): |
There was a problem hiding this comment.
It seems that all you'd need to pass here is the innermost node in the loop nest tree, and tree.ancestors (at least the proposed changed version) would cheaply give you this without the need to enforce these invariants.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
inducer
left a comment
There was a problem hiding this comment.
Thanks! Finally made it all the way through. There's a bit to digest here, but as far as I remember, it's mostly superficial. I didn't find any flaws in the thinking. Nice job!
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| if outer_loop == "": | ||
| continue | ||
| for child in loop_nest_tree.children(outer_loop): |
There was a problem hiding this comment.
Add a comment that this only works because loop_nest_tree contains a total order of loops. Otherwise it might windup with mismatched enter/leaves.
Uh oh!
There was an error while loading. Please reload this page.
inducer
commented
Jun 10, 2022
Unsubscribing... @-mention or request review once it's ready for a look or needs attention. But I'm eager to get this in soon! |
65a6b62 to
c21c092Comparec21c092 to
fadb652Compareinducer
commented
Aug 24, 2024
Most review comments from here are addressed in #864. |
Implementation for finding loop nest around map in O(N.k), 'N' being the number of inames and 'k' being the max. loop depth.
For comparison, let's consider the kernel in #288: on
mainthis map in computed in 5 minutes and this branch takes300.4 seconds.