Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3c01e0c
Temp commit
a-alveyblanc Sep 26, 2022
a5ee582
Updated kernel-level dependency finding mechanisms.
a-alveyblanc Oct 2, 2022
1a939a5
Merge branch 'inducer:main' into dep_finder
a-alveyblanc Oct 2, 2022
e553cce
Kernel now updates `depends_on` in line with the description of
a-alveyblanc Oct 3, 2022
ed6d03b
Merge branch 'dep_finder' of github.com:a-alveyblanc/loopy into dep_f…
a-alveyblanc Oct 3, 2022
a10d3db
New file created for dependencies, added type annotations, documentat…
a-alveyblanc Oct 10, 2022
81b26a0
Adjusted alignment so lines of code were not so far past 80 columns
a-alveyblanc Oct 10, 2022
09899bf
Stub in dep_finder function
a-alveyblanc Oct 10, 2022
464895f
Add documentation, begin fleshing out
a-alveyblanc Oct 15, 2022
d947d6b
Add documentation, begin fleshing out generate_execution_order
a-alveyblanc Oct 15, 2022
fdb5a01
Implemented draft version of generate_execution_order and stub in ver…
a-alveyblanc Oct 15, 2022
29ae7c0
Last commit does not reflect all changes made in that commit
a-alveyblanc Oct 15, 2022
0294761
Rewrote execution order generation function
a-alveyblanc Oct 16, 2022
6ed1cce
Minor changes to draft of generate_execution_order and to the documen…
a-alveyblanc Oct 16, 2022
ccfca54
Removed some things from kernel __init__.py that shouldn't be there
a-alveyblanc Oct 17, 2022
6e47dd0
Updated subtraction of diagonal from found dependency relation.
a-alveyblanc Nov 4, 2022
a0fd274
Replaced dependency union operation with a reduction. Can this be red…
a-alveyblanc Nov 5, 2022
2569006
Added various TODOs to mark changes
a-alveyblanc Nov 5, 2022
d35f11b
Changes in the way dependencies are computed
a-alveyblanc Nov 6, 2022
a3a4c15
Using itertools.product instead of doubly nested for loop in computin…
a-alveyblanc Nov 6, 2022
4d4ebdb
Small changes
a-alveyblanc Nov 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions loopy/kernel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ class _BoundsRecord:
upper_bound_pw_aff: isl.PwAff
size: isl.PwAff

@dataclass(frozen=True)
class RelationInfo:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Add docstrings, specifying what variables are in the map, what the two ends of the map mean, what naming conventions are used.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Add into documentation.

insn_id: str
var_name: str
relation: isl.Map

@dataclass(frozen=True)
class AccessRelation(RelationInfo):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Should access relations be long-lived?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

"has-a happier than is-a"

access_type: str

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Does this want to be an enum?


@dataclass(frozen=True)
class DependencyRelation(RelationInfo):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Something should be named "happens-before"

dependent_id: str

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Make one end of the happens-before implicit by ownership---only one insn ID needs storing.

dependency_type: str

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Wants to be an enum, possibly.


PreambleGenerator = Callable[["PreambleInfo"], Iterator[Tuple[int, str]]]

Expand Down Expand Up @@ -640,6 +654,81 @@ def _remove_inames_for_shared_hw_axes(self, cond_inames):

# {{{ dependency wrangling

def generate_access_relations(self):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Things should be functions (not methods) unless absolutely necessary.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Suggested change
def generate_access_relations(self):
def generate_access_relations(self) -> ...:

from loopy.symbolic import BatchedAccessMapMapper
bmap = BatchedAccessMapMapper(self, self.all_variable_names())
for insn in self.instructions:
bmap(insn.assignee, insn.within_inames)
bmap(insn.expression, insn.within_inames)

def get_map(var, insn):
return bmap.access_maps[var][insn.within_inames]

def read_var_list(insn):
return insn.read_dependency_names() - insn.within_inames

def write_var_list(insn):
return insn.write_dependency_names() - insn.within_inames

read_maps = [AccessRelation(insn.id, var, get_map(var, insn), "read")
for insn in self.instructions
for var in read_var_list(insn)]
write_maps = [AccessRelation(insn.id, var, get_map(var, insn), "write")
for insn in self.instructions
for var in write_var_list(insn)]

return read_maps, write_maps

def generate_dependency_relations(self, read_maps, write_maps):

def get_dependency_relation(x, y):

# TODO deal with self dependencies
#self_dependency = x.relation.apply_range(x.relation.reverse())

dependency_relation = x.relation.apply_range(y.relation.reverse())
#dependency_relation -= self_dependency

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Subtract the diagonal instead: $\{[i,j] \to [i',j']: i=i' \land j=j'\}$


return dependency_relation

write_read = [DependencyRelation(write.insn_id, write.var_name,
get_dependency_relation(write, read),
read.insn_id, "write-read")
for write in write_maps
for read in read_maps
if write.var_name == read.var_name]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Unnecessary quadratic complexity?


read_write = [DependencyRelation(read.insn_id, read.var_name,
get_dependency_relation(read, write),
write.insn_id, "read-write")
for read in read_maps
for write in write_maps
if read.var_name == write.var_name]

write_write = [DependencyRelation(write1.insn_id, write1.var_name,
get_dependency_relation(write1, write2),
write2.insn_id, "write-write")
for write1 in write_maps
for write2 in write_maps
if write1.var_name == write2.var_name]

# update depends_on for each instruction
for insn in self.instructions:
for relation in write_read:
if relation.dependent_id == insn.id:
insn.update_depends_on(relation.insn_id)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Suggested change
insn.update_depends_on(relation.insn_id)
insn = insn.copy(depends_on=...)

for relation in read_write:
if relation.dependent_id == insn.id:
insn.update_depends_on(relation.insn_id)
for relation in write_write:
if relation.dependent_id == insn.id:
insn.update_depends_on(relation.insn_id)

return write_read, read_write, write_write

def dep_finder(self):
pass

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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


@memoize_method
def recursive_insn_dep_map(self):
"""Returns a :class:`dict` mapping an instruction IDs *a*
Expand Down
5 changes: 4 additions & 1 deletion loopy/kernel/instruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ def __init__(self, id, depends_on, depends_on_is_final,

# {{{ abstract interface

def update_depends_on(self, dependee):
update = frozenset({dependee})
self.depends_on = self.depends_on | update

def read_dependency_names(self):
from loopy.symbolic import get_dependencies
result = frozenset()
Expand Down Expand Up @@ -471,7 +475,6 @@ def __setstate__(self, val):

# }}}


def _get_assignee_var_name(expr):
from pymbolic.primitives import Variable, Subscript, Lookup
from loopy.symbolic import LinearSubscript, SubArrayRef
Expand Down