def apply(self, sdfg: dace.SDFG): before_state = sdfg.node(self.subgraph[self._before_state]) loop_state = sdfg.node(self.subgraph[self._loop_state]) guard_state = sdfg.node(self.subgraph[self._guard_state]) loop_var = next(iter(sdfg.in_edges(guard_state)[0].data.assignments)) loop_axis = self._get_loop_axis(loop_state, loop_var) buffer_size = self._get_buffer_size(loop_state, loop_var, loop_axis) self._replace_indices(sdfg.states(), loop_var, loop_axis, buffer_size) array = sdfg.arrays[self.array] # TODO: generalize if array.shape[loop_axis] == array.total_size: array.shape = tuple(buffer_size if i == loop_axis else s for i, s in enumerate(array.shape)) array.total_size = buffer_size
def apply(self, graph: dace.SDFGState, sdfg: dace.SDFG): guard = self.loop_guard edge = sdfg.in_edges(guard)[0] loopindex = next(iter(edge.data.assignments.keys())) guard._LOOPINDEX = loopindex
def apply(self, sdfg: dace.SDFG): guard = sdfg.node(self.subgraph[ld.DetectLoop._loop_guard]) edge = sdfg.in_edges(guard)[0] loopindex = next(iter(edge.data.assignments.keys())) guard._LOOPINDEX = loopindex
def collect_constants( self, sdfg: SDFG, initial_symbols: Optional[Dict[str, Any]] = None ) -> Dict[SDFGState, Dict[str, Any]]: """ Finds all constants and constant-assigned symbols in the SDFG for each state. :param sdfg: The SDFG to traverse. :param initial_symbols: If not None, sets values of initial symbols. :return: A dictionary mapping an SDFG state to a mapping of constants and their corresponding values. """ arrays: Set[str] = set(sdfg.arrays.keys() | sdfg.constants_prop.keys()) result: Dict[SDFGState, Dict[str, Any]] = {} # Process: # * Collect constants in topologically ordered states # * If unvisited state has one incoming edge - propagate symbols forward and edge assignments # * If unvisited state has more than one incoming edge, consider all paths (use reverse DFS on unvisited paths) # * If value is ambiguous (not the same), set value to UNKNOWN start_state = sdfg.start_state if initial_symbols: result[start_state] = {} result[start_state].update(initial_symbols) # Traverse SDFG topologically for state in sdfg.topological_sort(start_state): if state in result: continue result[state] = {} # Get predecessors in_edges = sdfg.in_edges(state) if len(in_edges) == 1: # Special case, propagate as-is # First the prior state self._propagate(result[state], result[in_edges[0].src]) # Then assignments on the incoming edge self._propagate( result[state], self._data_independent_assignments(in_edges[0].data, arrays)) continue # More than one incoming edge: may require reversed traversal assignments = {} for edge in in_edges: # If source was already visited, use its propagated constants constants: Dict[str, Any] = {} if edge.src in result: constants.update(result[edge.src]) else: # Otherwise, reverse DFS to find constants until a visited state constants = self._constants_from_unvisited_state( sdfg, edge.src, arrays, result) # Update constants with incoming edge self._propagate( constants, self._data_independent_assignments(edge.data, arrays)) for aname, aval in constants.items(): # If something was assigned more than once (to a different value), it's not a constant if aname in assignments and aval != assignments[aname]: assignments[aname] = _UnknownValue else: assignments[aname] = aval self._propagate(result[state], assignments) return result