Esempio n. 1
0
def parse_memlet_subset(array: data.Data, node: Union[ast.Name, ast.Subscript],
                        das: Dict[str, Any],
                        parsed_slice: Any = None) -> Tuple[subsets.Range, List[int]]:
    """ 
    Parses an AST subset and returns access range, as well as new dimensions to
    add.
    :param array: Accessed data descriptor (used for filling in missing data, 
                  e.g., negative indices or empty shapes).
    :param node: AST node representing whole array or subset thereof.
    :param das: Dictionary of defined arrays and symbols mapped to their values.
    :return: A 2-tuple of (subset, list of new axis indices).
    """
    # Get memlet range
    ndslice = [(0, s - 1, 1) for s in array.shape]
    extra_dims = []
    arrdims: Dict[int, str] = {}
    if isinstance(node, ast.Subscript):
        # Parse and evaluate ND slice(s) (possibly nested)
        if parsed_slice:
            cnode = copy.deepcopy(node)
            cnode.slice = parsed_slice
        else:
            cnode = node
        ast_ndslices = astutils.subscript_to_ast_slice_recursive(cnode)
        offsets = list(range(len(array.shape)))

        # Loop over nd-slices (A[i][j][k]...)
        subset_array = []
        for idx, ast_ndslice in enumerate(ast_ndslices):
            # Cut out dimensions that were indexed in the previous slice
            narray = copy.deepcopy(array)
            narray.shape = [
                s for i, s in enumerate(array.shape) if i in offsets
            ]

            # Loop over the N dimensions
            ndslice, offsets, new_extra_dims, arrdims = _fill_missing_slices(
                das, ast_ndslice, narray, offsets)
            if new_extra_dims and idx != (len(ast_ndslices) - 1):
                raise NotImplementedError('New axes only implemented for last '
                                          'slice')
            if arrdims and len(ast_ndslices) != 1:
                raise NotImplementedError('Array dimensions not implemented '
                                          'for consecutive subscripts')
            extra_dims = new_extra_dims
            subset_array.append(_ndslice_to_subset(ndslice))

        subset = subset_array[0]

        # Compose nested indices, e.g., of the form "A[i,:,j,:][k,l]"
        for i in range(1, len(subset_array)):
            subset = subset.compose(subset_array[i])

    else:  # Use entire range
        subset = _ndslice_to_subset(ndslice)

    if isinstance(subset, subsets.Indices):
        subset = subsets.Range([(i, i, 1) for i in subset])
    return subset, extra_dims, arrdims
Esempio n. 2
0
def parse_memlet_subset(array: data.Data, node: Union[ast.Name, ast.Subscript],
                        das: Dict[str, Any]):
    array_dependencies = {}

    # Get memlet range
    ndslice = [(0, s - 1, 1) for s in array.shape]
    if isinstance(node, ast.Subscript):
        # Parse and evaluate ND slice(s) (possibly nested)
        ast_ndslices = astutils.subscript_to_ast_slice_recursive(node)
        offsets = list(range(len(array.shape)))

        # Loop over nd-slices (A[i][j][k]...)
        subset_array = []
        for ast_ndslice in ast_ndslices:
            # Cut out dimensions that were indexed in the previous slice
            narray = copy.deepcopy(array)
            narray.shape = [
                s for i, s in enumerate(array.shape) if i in offsets
            ]

            # Loop over the N dimensions
            ndslice, offsets = _fill_missing_slices(das, ast_ndslice, narray,
                                                    offsets)
            subset_array.append(_ndslice_to_subset(ndslice))

        subset = subset_array[0]

        # Compose nested indices, e.g., of the form "A[i,:,j,:][k,l]"
        for i in range(1, len(subset_array)):
            subset = subset.compose(subset_array[i])

        # Compute additional array dependencies (as a result of
        # indirection)
        # for dim in subset:
        #     if not isinstance(dim, tuple): dim = [dim]
        #     for r in dim:
        #         for expr in symbolic.swalk(r):
        #             if symbolic.is_sympy_userfunction(expr):
        #                 arr = expr.func.__name__
        #                 array_dependencies[arr] = self.curnode.globals[arr]

    else:  # Use entire range
        subset = _ndslice_to_subset(ndslice)

    if isinstance(subset, subsets.Indices):
        subset = subsets.Range([(i, i, 1) for i in subset])
    return subset