Skip to content

Commit

Permalink
Added FindSingleUseData Pass (#1906)
Browse files Browse the repository at this point in the history
Added `FindSingleUseData` analysis pass

This new pass scans the SDFG and computes the data that is only used in
one single place.
Essentially, this boils down to the check how often a data descriptor is
accessed
A data descriptor is classified if the following statements are true:
- There is exactly one AccessNode referring to the data descriptor.
- The data descriptor is not referred to on an interstate edge, nor in
the condition parts of `ConditionBlock`s or `LoopRegion`s.

This pass will be needed to speed up fusion passes.
  • Loading branch information
philip-paul-mueller authored Jan 28, 2025
1 parent 7771baf commit e1886a0
Show file tree
Hide file tree
Showing 2 changed files with 507 additions and 0 deletions.
73 changes: 73 additions & 0 deletions dace/transformation/passes/analysis/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,79 @@ def apply_pass(self, top_sdfg: SDFG, _) -> Dict[int, Dict[str, Set[SDFGState]]]:
return top_result


@properties.make_properties
@transformation.explicit_cf_compatible
class FindSingleUseData(ppl.Pass):
"""
For each SDFG find all data descriptors that are referenced in exactly one location.
In addition to the requirement that there exists exactly one AccessNode that
refers to a data descriptor the following conditions have to be meet as well:
- The data is not read on an interstate edge.
- The data is not accessed in the branch condition, loop condition, etc. of
control flow regions.
- There must be at least one AccessNode that refers to the data. I.e. if it exists
inside `SDFG.arrays` but there is no AccessNode, then it is _not_ included.
It is also important to note that the degree of the AccessNodes are ignored.
"""

CATEGORY: str = 'Analysis'

def modifies(self) -> ppl.Modifies:
return ppl.Modifies.Nothing

def should_reapply(self, modified: ppl.Modifies) -> bool:
# If anything was modified, reapply
return modified & ppl.Modifies.AccessNodes & ppl.Modifies.CFG

def apply_pass(self, sdfg: SDFG, _) -> Dict[SDFG, Set[str]]:
"""
:return: A dictionary mapping SDFGs to a `set` of strings containing the name
of the data descriptors that are only used once.
"""
# TODO(pschaad): Should we index on cfg or the SDFG itself.
exclusive_data: Dict[SDFG, Set[str]] = {}
for nsdfg in sdfg.all_sdfgs_recursive():
exclusive_data[nsdfg] = self._find_single_use_data_in_sdfg(nsdfg)
return exclusive_data

def _find_single_use_data_in_sdfg(self, sdfg: SDFG) -> Set[str]:
"""Scans an SDFG and computes the data that is only used once in the SDFG.
The rules used to classify data descriptors are outlined above. The function
will not scan nested SDFGs.
:return: The set of data descriptors that are used once in the SDFG.
"""
# If we encounter a data descriptor for the first time we immediately
# classify it as single use. We will undo this decision as soon as
# learn that it is used somewhere else.
single_use_data: Set[str] = set()
previously_seen: Set[str] = set()

for state in sdfg.states():
for dnode in state.data_nodes():
data_name: str = dnode.data
if data_name in single_use_data:
single_use_data.discard(data_name) # Classified too early -> Undo
elif data_name not in previously_seen:
single_use_data.add(data_name) # Never seen -> Assume single use
previously_seen.add(data_name)

# By definition, data that is referenced by interstate edges is not single
# use data, also remove it.
for edge in sdfg.all_interstate_edges():
single_use_data.difference_update(edge.data.free_symbols)

# By definition, data that is referenced by the conditions (branching condition,
# loop condition, ...) is not single use data, also remove that.
for cfr in sdfg.all_control_flow_regions():
single_use_data.difference_update(cfr.used_symbols(all_symbols=True, with_contents=False))

return single_use_data


@properties.make_properties
@transformation.explicit_cf_compatible
class FindAccessNodes(ppl.Pass):
Expand Down
Loading

0 comments on commit e1886a0

Please sign in to comment.