Ejemplo n.º 1
0
    def _do_generate(self, exprs, exclude, cbk_search, cbk_compose=None):
        """
        Carry out the bulk of the work of ``_generate``.
        """
        counter = generator()
        make = lambda: Symbol(name='dummy%d' % counter())

        if cbk_compose is None:
            cbk_compose = lambda *args: None

        mapper = Uxmapper()
        for e in exprs:
            for i in cbk_search(e):
                if not i.is_commutative:
                    continue

                terms = cbk_compose(i)

                # Make sure we won't break any data dependencies
                if terms:
                    free_symbols = set().union(
                        *[i.free_symbols for i in terms])
                else:
                    free_symbols = i.free_symbols
                if {a.function for a in free_symbols} & exclude:
                    continue

                mapper.add(i, make, terms)

        return mapper
Ejemplo n.º 2
0
    def _extract(self, exprs, context, n):
        # Forbid CIRE involving Dimension-independent dependencies, e.g.:
        # r0 = ...
        # u[x, y] = ... r0*a[x, y] ...
        # NOTE: if one uses the DSL in a conventional way and sticks to the default
        # compilation pipelines where CSE always happens after CIRE, then `exclude`
        # will always be empty
        exclude = {i.source.indexed for i in context[None].scope.d_flow.independent()}

        mapper = Uxmapper()
        for e in exprs:
            for i in search_potential_deriv(e, n):
                if i.free_symbols & exclude:
                    continue

                key = lambda a: a.is_Add
                terms, others = split(i.args, key)

                if self._opt_maxalias:
                    # Treat `e` as an FD expression and pull out the derivative
                    # coefficient from `i`
                    # Note: typically derivative coefficients are numbers, but
                    # sometimes they could be provided in symbolic form through an
                    # arbitrary Function.  In the latter case, we rely on the
                    # heuristic that such Function's basically never span the whole
                    # grid, but rather a single Grid dimension (e.g., `c[z, n]` for a
                    # stencil of diameter `n` along `z`)
                    if e.grid is not None and terms:
                        key = partial(maybe_coeff_key, e.grid)
                        others, more_terms = split(others, key)
                        terms += more_terms

                mapper.add(i, self._make_symbol, terms)

        return mapper
Ejemplo n.º 3
0
    def _extract(self, exprs, context, n):
        mapper = Uxmapper()
        for prefix, clusters in context.items():
            if not prefix:
                continue

            exclude = set().union(*[c.scope.writes for c in clusters])
            exclude.add(prefix[-1].dim)

            for e in exprs:
                for i in search(e, self._rule, 'all', 'bfs_first_hit'):
                    if {a.function for a in i.free_symbols} & exclude:
                        continue
                    mapper.add(i, self._make_symbol)

        return mapper
Ejemplo n.º 4
0
    def _extract(self, exprs, context, n):
        extracted = super()._extract(exprs, context, n).extracted

        rule = lambda e: any(a in extracted for a in e.args)

        mapper = Uxmapper()
        for e in exprs:
            for i in search(e, rule, 'all', 'dfs'):
                if not i.is_commutative:
                    continue

                key = lambda a: a in extracted
                terms, others = split(i.args, key)

                mapper.add(i, self._make_symbol, terms)

        return mapper