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
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
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
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