Conversation
loopy/kernel/dependency.py
Outdated
| variable_name: Optional[str] | ||
| instances_rel: Optional[Map] | ||
|
|
||
| class AccessMapMapper(WalkMapper): |
There was a problem hiding this comment.
Consider making this a CombineMapper? (In that case, you'd need to define combine)
loopy/kernel/dependency.py
Outdated
| self._var_names = var_names | ||
|
|
||
| from collections import defaultdict | ||
| self.access_maps = defaultdict(lambda: |
There was a problem hiding this comment.
Document what the keys/values of these mappings are.
loopy/kernel/dependency.py
Outdated
|
|
||
| super.__init__() | ||
|
|
||
| def map_subscript(self, expr, inames, insn_id): |
loopy/kernel/dependency.py
Outdated
| try: | ||
| access_map = get_access_map(domain, subscript) | ||
| except UnableToDetermineAccessRangeError: | ||
| return |
There was a problem hiding this comment.
Is this the conservative approach?
loopy/kernel/dependency.py
Outdated
| except UnableToDetermineAccessRangeError: | ||
| return | ||
|
|
||
| if self.access_maps[insn_id][arg_name][inames] is None: |
loopy/kernel/dependency.py
Outdated
| } | ||
|
|
||
| new_insns = [] | ||
| for insn in knl.instructions: |
There was a problem hiding this comment.
Think about transitive dependencies
loopy/kernel/dependency.py
Outdated
| # return the kernel with the new instructions | ||
| return knl.copy(instructions=new_insns) | ||
|
|
||
| def add_lexicographic_happens_after(knl: LoopKernel) -> None: |
There was a problem hiding this comment.
Lexicographic happens before is the "coarsest" ordering, and the above would be the refinement of that based on data dependencies.
cededcd to
01d3688
Compare
| assert shared_inames_order_after == shared_inames_order_before | ||
| shared_inames_order = shared_inames_order_after |
There was a problem hiding this comment.
There's a big unresolved question here, in terms of what nesting order we should use for the shared inames. Right now, this uses the axis order in the domains, however we also already do have LoopKernel.loop_priority to indicate nesting order during code generation). If nothing else, this should make sure that the order produced is consistent with that. But there's also the option of using/introducing a different mechanism entirely for this.
@kaushikcfd, got an opinion?
…ng for successive instructions
loopy/kernel/dependency.py
Outdated
| def map_linear_subscript(self, expr, insn): | ||
| self.rec(expr.index, insn) |
loopy/kernel/dependency.py
Outdated
|
|
||
| amf = AccessMapFinder(knl) | ||
| for insn in knl.instructions: | ||
| amf(insn.assignee, insn) |
There was a problem hiding this comment.
CallInstructions) have more than one assignee.
loopy/kernel/dependency.py
Outdated
| def get_map(self, insn_id: str, variable_name: str) -> isl.Map: | ||
| try: | ||
| return self.access_maps[insn_id][variable_name] | ||
| except KeyError: |
loopy/kernel/dependency.py
Outdated
|
|
||
| def __init__(self, knl: LoopKernel) -> None: | ||
| self.kernel = knl | ||
| self.access_maps = defaultdict(lambda: defaultdict(lambda: None)) |
loopy/kernel/dependency.py
Outdated
| domain, subscript, self.kernel.assumptions | ||
| ) | ||
|
|
||
| if self.access_maps[insn.id][arg_name]: |
There was a problem hiding this comment.
| if self.access_maps[insn.id][arg_name]: | |
| if self.access_maps[insn.id][arg_name] is not None: |
loopy/kernel/dependency.py
Outdated
| def map_reduction(self, expr, insn): | ||
| return WalkMapper.map_reduction(self, expr, insn) | ||
|
|
||
| def map_type_cast(self, expr, inames): |
There was a problem hiding this comment.
| def map_type_cast(self, expr, inames): | |
| def map_type_cast(self, expr, insn): |
loopy/kernel/dependency.py
Outdated
| accessed_by = reader_map.get(variable, set()) | \ | ||
| writer_map.get(variable, set()) |
There was a problem hiding this comment.
Are you still avoiding read-after-read?
…fter are both specified
…hic_... and apply_single_writer...
919dc51 to
d361167
Compare
…ndency finding in narrow_dependencies [skip ci]
| happens_after=( | ||
| red_realize_ctx.surrounding_depends_on | ||
| | frozenset([init_id, init_neutral_id])), |
There was a problem hiding this comment.
The new code suggests that happens_after is still a set?
loopy/kernel/dependency.py
Outdated
|
|
||
| @for_each_kernel | ||
| def narrow_dependencies(knl: LoopKernel) -> LoopKernel: | ||
| """Attempt to relax a strict (lexical) ordering between statements in a |
loopy/kernel/dependency.py
Outdated
|
|
||
| @for_each_kernel | ||
| def narrow_dependencies(knl: LoopKernel) -> LoopKernel: | ||
| """Attempt to relax a strict (lexical) ordering between statements in a |
There was a problem hiding this comment.
Probably not safe to assume that the input ordering is lexicographic.
loopy/kernel/dependency.py
Outdated
| statements. | ||
| """ | ||
|
|
||
| assert isinstance(insn.id, str) # stop complaints |
There was a problem hiding this comment.
Turns this into an actual type annotation in InstructionBase.
loopy/transform/dependency.py
Outdated
| t_sort = compute_topological_order(deps_dag) | ||
|
|
||
| for insn_id in t_sort: | ||
| transitive_deps[insn_id] = reduce( |
There was a problem hiding this comment.
transitive_deps can't help but be quadratic in the size of the program.
loopy/transform/dependency.py
Outdated
| lex_map = insn.happens_after[dependency].instances_rel | ||
| else: | ||
| lex_map = dep_map.lex_lt_map(dep_map) |
There was a problem hiding this comment.
We should use the fine-grain/instance-level dependency info that's already in the kernel at this point.
…computing dependencies
New draft PR based on PR 683. Major change is that the HappensAfter data structure used to represent statement-level dependency relations has been implemented into the InstructionBase data structure.