Example #1
0
def to_codegen_result(codegen_state, insn_id, domain, check_inames,
                      required_preds, ast):
    from loopy.codegen.bounds import get_bounds_checks
    from loopy.symbolic import constraint_to_expr

    bounds_checks = get_bounds_checks(domain,
                                      check_inames,
                                      codegen_state.implemented_domain,
                                      overapproximate=False)
    bounds_check_set = isl.Set.universe(domain.get_space()) \
            .add_constraints(bounds_checks)
    bounds_check_set, new_implemented_domain = isl.align_two(
        bounds_check_set, codegen_state.implemented_domain)
    new_implemented_domain = new_implemented_domain & bounds_check_set

    if bounds_check_set.is_empty():
        return None

    condition_exprs = [constraint_to_expr(cns) for cns in bounds_checks]

    condition_exprs.extend(required_preds -
                           codegen_state.implemented_predicates)

    if condition_exprs:
        from pymbolic.primitives import LogicalAnd
        from pymbolic.mapper.stringifier import PREC_NONE
        ast = codegen_state.ast_builder.emit_if(
            codegen_state.expression_to_code_mapper(
                LogicalAnd(tuple(condition_exprs)), PREC_NONE), ast)

    return CodeGenerationResult.new(codegen_state, insn_id, ast,
                                    new_implemented_domain)
Example #2
0
    def realize_conditional(self, node, context_cond=None):
        scope = self.scope_stack[-1]

        cond_name = intern("loopy_cond%d" % self.condition_id_counter)
        self.condition_id_counter += 1
        assert cond_name not in scope.type_map

        scope.type_map[cond_name] = np.int32

        from pymbolic import var
        cond_var = var(cond_name)

        self.add_expression_instruction(cond_var,
                                        self.parse_expr(node, node.expr))

        cond_expr = cond_var
        if context_cond is not None:
            from pymbolic.primitives import LogicalAnd
            cond_expr = LogicalAnd((cond_var, context_cond))

            self.conditions_data.append((context_cond, cond_var))
        else:
            self.conditions_data.append((None, cond_var))

        self.conditions.append(cond_expr)
Example #3
0
def to_codegen_result(codegen_state, insn_id, domain, check_inames,
                      required_preds, ast):
    chk_domain = isl.Set.from_basic_set(domain)
    chk_domain = chk_domain.remove_redundancies()
    chk_domain = codegen_state.kernel.cache_manager.eliminate_except(
        chk_domain, check_inames, (dim_type.set, ))

    chk_domain, new_implemented_domain = _get_new_implemented_domain(
        codegen_state.kernel, chk_domain, codegen_state.implemented_domain)

    if chk_domain.is_empty():
        return None

    condition_exprs = []
    if not chk_domain.plain_is_universe():
        from loopy.symbolic import set_to_cond_expr
        condition_exprs.append(set_to_cond_expr(chk_domain))

    condition_exprs.extend(required_preds -
                           codegen_state.implemented_predicates)

    if condition_exprs:
        from pymbolic.primitives import LogicalAnd
        from pymbolic.mapper.stringifier import PREC_NONE
        ast = codegen_state.ast_builder.emit_if(
            codegen_state.expression_to_code_mapper(
                LogicalAnd(tuple(condition_exprs)), PREC_NONE), ast)

    return CodeGenerationResult.new(codegen_state, insn_id, ast,
                                    new_implemented_domain)
Example #4
0
    def parse_postfix(self, pstate, min_precedence, left_exp):
        from pymbolic.parser import (
                _PREC_CALL, _PREC_COMPARISON, _openpar,
                _PREC_LOGICAL_OR, _PREC_LOGICAL_AND)
        from pymbolic.primitives import (
                Comparison, LogicalAnd, LogicalOr)

        next_tag = pstate.next_tag()
        if next_tag is _openpar and _PREC_CALL > min_precedence:
            raise TranslationError("parenthesis operator only works on names")

        elif next_tag in self.COMP_MAP and _PREC_COMPARISON > min_precedence:
            pstate.advance()
            left_exp = Comparison(
                    left_exp,
                    self.COMP_MAP[next_tag],
                    self.parse_expression(pstate, _PREC_COMPARISON))
            did_something = True
        elif next_tag is _and and _PREC_LOGICAL_AND > min_precedence:
            pstate.advance()
            left_exp = LogicalAnd((left_exp,
                    self.parse_expression(pstate, _PREC_LOGICAL_AND)))
            did_something = True
        elif next_tag is _or and _PREC_LOGICAL_OR > min_precedence:
            pstate.advance()
            left_exp = LogicalOr((left_exp,
                    self.parse_expression(pstate, _PREC_LOGICAL_OR)))
            did_something = True
        else:
            left_exp, did_something = ExpressionParserBase.parse_postfix(
                    self, pstate, min_precedence, left_exp)

        return left_exp, did_something
Example #5
0
def flat_LogicalAnd(*children):  # noqa
    from pymbolic.primitives import LogicalAnd
    result = []
    for child in children:
        if isinstance(child, LogicalAnd):
            result.extend(child.children)
        else:
            result.append(child)
    return LogicalAnd(tuple(result))
Example #6
0
def wrap_in_if(codegen_state, condition_exprs, inner):
    if condition_exprs:
        from pymbolic.primitives import LogicalAnd
        from pymbolic.mapper.stringifier import PREC_NONE
        cur_ast = inner.current_ast(codegen_state)
        return inner.with_new_ast(
            codegen_state,
            codegen_state.ast_builder.emit_if(
                codegen_state.expression_to_code_mapper(
                    LogicalAnd(tuple(condition_exprs)), PREC_NONE), cur_ast))

    return inner
Example #7
0
    def construct_else_condition(self):
        context_cond, prev_cond = self.conditions_data.pop()
        if prev_cond is None:
            raise RuntimeError("else if may not follow else")

        self.conditions.pop()

        from pymbolic.primitives import LogicalNot, LogicalAnd
        else_expr = LogicalNot(prev_cond)
        if context_cond is not None:
            else_expr = LogicalAnd((else_expr, context_cond))

        return else_expr
Example #8
0
    def parse_postfix(self, pstate, min_precedence, left_exp):
        from pymbolic.parser import (_PREC_CALL, _PREC_COMPARISON, _openpar,
                                     _PREC_LOGICAL_OR, _PREC_LOGICAL_AND)
        from pymbolic.primitives import (Comparison, LogicalAnd, LogicalOr)

        next_tag = pstate.next_tag()
        if next_tag is _openpar and _PREC_CALL > min_precedence:
            raise TranslationError("parenthesis operator only works on names")

        elif next_tag in self.COMP_MAP and _PREC_COMPARISON > min_precedence:
            pstate.advance()
            left_exp = Comparison(
                left_exp, self.COMP_MAP[next_tag],
                self.parse_expression(pstate, _PREC_COMPARISON))
            did_something = True
        elif next_tag is _and and _PREC_LOGICAL_AND > min_precedence:
            pstate.advance()
            left_exp = LogicalAnd(
                (left_exp, self.parse_expression(pstate, _PREC_LOGICAL_AND)))
            did_something = True
        elif next_tag is _or and _PREC_LOGICAL_OR > min_precedence:
            pstate.advance()
            left_exp = LogicalOr(
                (left_exp, self.parse_expression(pstate, _PREC_LOGICAL_OR)))
            did_something = True
        else:
            left_exp, did_something = ExpressionParserBase.parse_postfix(
                self, pstate, min_precedence, left_exp)

            if isinstance(left_exp,
                          tuple) and min_precedence < self._PREC_FUNC_ARGS:
                # this must be a complex literal
                if len(left_exp) != 2:
                    raise TranslationError("complex literals must have "
                                           "two entries")

                r, i = left_exp

                dtype = (r.dtype.type(0) + i.dtype.type(0))
                if dtype == np.float32:
                    dtype = np.complex64
                else:
                    dtype = np.complex128

                left_exp = dtype(float(r) + float(i) * 1j)

        return left_exp, did_something
Example #9
0
    def make_spectra_knl(self, is_real, rank_shape):
        from pymbolic import var, parse
        indices = i, j, k = parse("i, j, k")
        momenta = [var("momenta_"+xx) for xx in ("x", "y", "z")]
        ksq = sum((dk_i * mom[ii])**2
                  for mom, dk_i, ii in zip(momenta, self.dk, indices))
        kmag = var("sqrt")(ksq)
        bin_expr = var("round")(kmag / self.bin_width)

        if is_real:
            from pymbolic.primitives import If, Comparison, LogicalAnd
            nyq = self.grid_shape[-1] / 2
            condition = LogicalAnd((Comparison(momenta[2][k], ">", 0),
                                    Comparison(momenta[2][k], "<", nyq)))
            count = If(condition, 2, 1)
        else:
            count = 1

        fk = var("fk")[i, j, k]
        weight_expr = count * kmag**(var("k_power")) * var("abs")(fk)**2

        histograms = {"spectrum": (bin_expr, weight_expr)}

        args = [
            lp.GlobalArg("fk", self.cdtype, shape=("Nx", "Ny", "Nz"),
                         offset=lp.auto),
            lp.GlobalArg("momenta_x", self.rdtype, shape=("Nx",)),
            lp.GlobalArg("momenta_y", self.rdtype, shape=("Ny",)),
            lp.GlobalArg("momenta_z", self.rdtype, shape=("Nz",)),
            lp.ValueArg("k_power", self.rdtype),
            ...
        ]

        from pystella.histogram import Histogrammer
        return Histogrammer(self.decomp, histograms, self.num_bins,
                            self.rdtype, args=args, rank_shape=rank_shape)
Example #10
0
    def parse_postfix(self, pstate, min_precedence, left_exp):
        import pymbolic.primitives as primitives

        did_something = False

        next_tag = pstate.next_tag()

        if next_tag is _openpar and _PREC_CALL > min_precedence:
            pstate.advance()
            args, kwargs = self.parse_arglist(pstate)

            if kwargs:
                left_exp = primitives.CallWithKwargs(left_exp, args, kwargs)
            else:
                left_exp = primitives.Call(left_exp, args)

            did_something = True
        elif next_tag is _openbracket and _PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect_not_end()
            left_exp = primitives.Subscript(left_exp, self.parse_expression(pstate))
            pstate.expect(_closebracket)
            pstate.advance()
            did_something = True
        elif next_tag is _if and _PREC_IF > min_precedence:
            from pymbolic.primitives import If
            then_expr = left_exp
            pstate.advance()
            pstate.expect_not_end()
            condition = self.parse_expression(pstate, _PREC_LOGICAL_OR)
            pstate.expect(_else)
            pstate.advance()
            else_expr = self.parse_expression(pstate)
            left_exp = If(condition, then_expr, else_expr)
            did_something = True
        elif next_tag is _dot and _PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect(_identifier)
            left_exp = primitives.Lookup(left_exp, pstate.next_str())
            pstate.advance()
            did_something = True
        elif next_tag is _plus and _PREC_PLUS > min_precedence:
            pstate.advance()
            right_exp = self.parse_expression(pstate, _PREC_PLUS)
            if isinstance(left_exp, primitives.Sum):
                left_exp = primitives.Sum(left_exp.children + (right_exp,))
            else:
                left_exp = primitives.Sum((left_exp, right_exp))

            did_something = True
        elif next_tag is _minus and _PREC_PLUS > min_precedence:
            pstate.advance()
            right_exp = self.parse_expression(pstate, _PREC_PLUS)
            if isinstance(left_exp, primitives.Sum):
                left_exp = primitives.Sum(left_exp.children + ((-right_exp),))  # noqa pylint:disable=invalid-unary-operand-type
            else:
                left_exp = primitives.Sum((left_exp, -right_exp))  # noqa pylint:disable=invalid-unary-operand-type
            did_something = True
        elif next_tag is _times and _PREC_TIMES > min_precedence:
            pstate.advance()
            right_exp = self.parse_expression(pstate, _PREC_PLUS)
            if isinstance(left_exp, primitives.Product):
                left_exp = primitives.Product(left_exp.children + (right_exp,))
            else:
                left_exp = primitives.Product((left_exp, right_exp))
            did_something = True
        elif next_tag is _floordiv and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp = primitives.FloorDiv(
                    left_exp, self.parse_expression(pstate, _PREC_TIMES))
            did_something = True
        elif next_tag is _over and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp = primitives.Quotient(
                    left_exp, self.parse_expression(pstate, _PREC_TIMES))
            did_something = True
        elif next_tag is _modulo and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp = primitives.Remainder(
                    left_exp, self.parse_expression(pstate, _PREC_TIMES))
            did_something = True
        elif next_tag is _power and _PREC_POWER > min_precedence:
            pstate.advance()
            left_exp = primitives.Power(
                    left_exp, self.parse_expression(pstate, _PREC_TIMES))
            did_something = True
        elif next_tag is _and and _PREC_LOGICAL_AND > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LogicalAnd
            left_exp = LogicalAnd((
                    left_exp,
                    self.parse_expression(pstate, _PREC_LOGICAL_AND)))
            did_something = True
        elif next_tag is _or and _PREC_LOGICAL_OR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LogicalOr
            left_exp = LogicalOr((
                    left_exp,
                    self.parse_expression(pstate, _PREC_LOGICAL_OR)))
            did_something = True
        elif next_tag is _bitwiseor and _PREC_BITWISE_OR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseOr
            left_exp = BitwiseOr((
                    left_exp,
                    self.parse_expression(pstate, _PREC_BITWISE_OR)))
            did_something = True
        elif next_tag is _bitwisexor and _PREC_BITWISE_XOR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseXor
            left_exp = BitwiseXor((
                    left_exp,
                    self.parse_expression(pstate, _PREC_BITWISE_XOR)))
            did_something = True
        elif next_tag is _bitwiseand and _PREC_BITWISE_AND > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseAnd
            left_exp = BitwiseAnd((
                    left_exp,
                    self.parse_expression(pstate, _PREC_BITWISE_AND)))
            did_something = True
        elif next_tag is _rightshift and _PREC_SHIFT > min_precedence:
            pstate.advance()
            from pymbolic.primitives import RightShift
            left_exp = RightShift(
                    left_exp,
                    self.parse_expression(pstate, _PREC_SHIFT))
            did_something = True
        elif next_tag is _leftshift and _PREC_SHIFT > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LeftShift
            left_exp = LeftShift(
                    left_exp,
                    self.parse_expression(pstate, _PREC_SHIFT))
            did_something = True
        elif next_tag in self._COMP_TABLE and _PREC_COMPARISON > min_precedence:
            pstate.advance()
            from pymbolic.primitives import Comparison
            left_exp = Comparison(
                    left_exp,
                    self._COMP_TABLE[next_tag],
                    self.parse_expression(pstate, _PREC_COMPARISON))
            did_something = True
        elif next_tag is _colon and _PREC_SLICE >= min_precedence:
            pstate.advance()
            expr_pstate = pstate.copy()

            assert not isinstance(left_exp, primitives.Slice)

            from pytools.lex import ParseError
            try:
                next_expr = self.parse_expression(expr_pstate, _PREC_SLICE)
            except ParseError:
                # no expression follows, too bad.
                left_exp = primitives.Slice((left_exp, None,))
            else:
                left_exp = _join_to_slice(left_exp, next_expr)
                pstate.assign(expr_pstate)

            did_something = True

        elif next_tag is _comma and _PREC_COMMA > min_precedence:
            # The precedence makes the comma left-associative.

            pstate.advance()
            if pstate.is_at_end() or pstate.next_tag() is _closepar:
                if isinstance(left_exp, (tuple, list)) \
                        and not isinstance(left_exp, FinalizedContainer):
                    # left_expr is a container with trailing commas
                    pass
                else:
                    left_exp = (left_exp,)
            else:
                new_el = self.parse_expression(pstate, _PREC_COMMA)
                if isinstance(left_exp, (tuple, list)) \
                        and not isinstance(left_exp, FinalizedContainer):
                    left_exp = left_exp + (new_el,)
                else:
                    left_exp = (left_exp, new_el)

            did_something = True

        return left_exp, did_something
Example #11
0
    def __init__(self, fft, effective_k, dk, dx):
        self.fft = fft

        if not callable(effective_k):
            if effective_k != 0:
                from pystella.derivs import FirstCenteredDifference
                h = effective_k
                effective_k = FirstCenteredDifference(h).get_eigenvalues
            else:

                def effective_k(k, dx):  # pylint: disable=function-redefined
                    return k

        queue = self.fft.sub_k["momenta_x"].queue
        sub_k = list(x.get().astype("int") for x in self.fft.sub_k.values())
        eff_mom_names = ("eff_mom_x", "eff_mom_y", "eff_mom_z")
        self.eff_mom = {}
        for mu, (name, kk) in enumerate(zip(eff_mom_names, sub_k)):
            eff_k = effective_k(dk[mu] * kk.astype(fft.rdtype), dx[mu])
            eff_k[abs(sub_k[mu]) == fft.grid_shape[mu] // 2] = 0.
            eff_k[sub_k[mu] == 0] = 0.

            import pyopencl.array as cla
            self.eff_mom[name] = cla.to_device(queue, eff_k)

        from pymbolic import var, parse
        from pymbolic.primitives import If, Comparison, LogicalAnd
        from pystella import Field
        indices = parse("i, j, k")
        eff_k = tuple(
            var(array)[mu] for array, mu in zip(eff_mom_names, indices))
        fabs, sqrt, conj = parse("fabs, sqrt, conj")
        kmag = sqrt(sum(kk**2 for kk in eff_k))

        from pystella import ElementWiseMap
        vector = Field("vector", shape=(3, ))
        vector_T = Field("vector_T", shape=(3, ))

        kvec_zero = LogicalAnd(
            tuple(Comparison(fabs(eff_k[mu]), "<", 1e-14) for mu in range(3)))

        # note: write all output via private temporaries to allow for in-place

        div = var("div")
        div_insn = [(div, sum(eff_k[mu] * vector[mu] for mu in range(3)))]
        self.transversify_knl = ElementWiseMap(
            {
                vector_T[mu]: If(kvec_zero, 0,
                                 vector[mu] - eff_k[mu] / kmag**2 * div)
                for mu in range(3)
            },
            tmp_instructions=div_insn,
            lsize=(32, 1, 1),
            rank_shape=fft.shape(True),
        )

        import loopy as lp

        def assign(asignee, expr, **kwargs):
            default = dict(within_inames=frozenset(("i", "j", "k")),
                           no_sync_with=[("*", "any")])
            default.update(kwargs)
            return lp.Assignment(asignee, expr, **default)

        kmag, Kappa = parse("kmag, Kappa")
        eps_insns = [
            assign(kmag, sqrt(sum(kk**2 for kk in eff_k))),
            assign(Kappa, sqrt(sum(kk**2 for kk in eff_k[:2])))
        ]

        zero = fft.cdtype.type(0)
        kx_ky_zero = LogicalAnd(
            tuple(Comparison(fabs(eff_k[mu]), "<", 1e-10) for mu in range(2)))
        kz_nonzero = Comparison(fabs(eff_k[2]), ">", 1e-10)

        eps = var("eps")
        eps_insns.extend([
            assign(
                eps[0],
                If(kx_ky_zero, If(kz_nonzero, fft.cdtype.type(1 / 2**.5),
                                  zero),
                   (eff_k[0] * eff_k[2] / kmag - 1j * eff_k[1]) / Kappa /
                   2**.5)),
            assign(
                eps[1],
                If(kx_ky_zero,
                   If(kz_nonzero, fft.cdtype.type(1j / 2**(1 / 2)),
                      zero), (eff_k[1] * eff_k[2] / kmag + 1j * eff_k[0]) /
                   Kappa / 2**.5)),
            assign(eps[2], If(kx_ky_zero, zero, -Kappa / kmag / 2**.5))
        ])

        plus, minus, lng = Field("plus"), Field("minus"), Field("lng")

        plus_tmp, minus_tmp = parse("plus_tmp, minus_tmp")
        pol_isns = [(plus_tmp,
                     sum(vector[mu] * conj(eps[mu]) for mu in range(3))),
                    (minus_tmp, sum(vector[mu] * eps[mu] for mu in range(3)))]

        args = [
            lp.TemporaryVariable("kmag"),
            lp.TemporaryVariable("Kappa"),
            lp.TemporaryVariable("eps", shape=(3, )), ...
        ]

        self.vec_to_pol_knl = ElementWiseMap(
            {
                plus: plus_tmp,
                minus: minus_tmp
            },
            tmp_instructions=eps_insns + pol_isns,
            args=args,
            lsize=(32, 1, 1),
            rank_shape=fft.shape(True),
        )

        vector_tmp = var("vector_tmp")
        vec_insns = [(vector_tmp[mu], plus * eps[mu] + minus * conj(eps[mu]))
                     for mu in range(3)]

        self.pol_to_vec_knl = ElementWiseMap(
            {vector[mu]: vector_tmp[mu]
             for mu in range(3)},
            tmp_instructions=eps_insns + vec_insns,
            args=args,
            lsize=(32, 1, 1),
            rank_shape=fft.shape(True),
        )

        ksq = sum(kk**2 for kk in eff_k)
        lng_rhs = If(kvec_zero, 0, -div / ksq * 1j)
        self.vec_decomp_knl = ElementWiseMap(
            {
                plus: plus_tmp,
                minus: minus_tmp,
                lng: lng_rhs
            },
            tmp_instructions=eps_insns + pol_isns + div_insn,
            args=args,
            lsize=(32, 1, 1),
            rank_shape=fft.shape(True),
        )
        lng_rhs = If(kvec_zero, 0, -div / ksq**.5 * 1j)
        self.vec_decomp_knl_times_abs_k = ElementWiseMap(
            {
                plus: plus_tmp,
                minus: minus_tmp,
                lng: lng_rhs
            },
            tmp_instructions=eps_insns + pol_isns + div_insn,
            args=args,
            lsize=(32, 1, 1),
            rank_shape=fft.shape(True),
        )

        from pystella.sectors import tensor_index as tid

        eff_k_hat = tuple(kk / sqrt(sum(kk**2 for kk in eff_k))
                          for kk in eff_k)
        hij = Field("hij", shape=(6, ))
        hij_TT = Field("hij_TT", shape=(6, ))

        Pab = var("P")
        Pab_insns = [(Pab[tid(a, b)], (If(Comparison(a, "==", b), 1, 0) -
                                       eff_k_hat[a - 1] * eff_k_hat[b - 1]))
                     for a in range(1, 4) for b in range(a, 4)]

        hij_TT_tmp = var("hij_TT_tmp")
        TT_insns = [(hij_TT_tmp[tid(a, b)],
                     sum((Pab[tid(a, c)] * Pab[tid(d, b)] -
                          Pab[tid(a, b)] * Pab[tid(c, d)] / 2) * hij[tid(c, d)]
                         for c in range(1, 4) for d in range(1, 4)))
                    for a in range(1, 4) for b in range(a, 4)]
        # note: where conditionals (branch divergence) go can matter:
        # this kernel is twice as fast when putting the branching in the global
        # write, rather than when setting hij_TT_tmp
        write_insns = [(hij_TT[tid(a,
                                   b)], If(kvec_zero, 0, hij_TT_tmp[tid(a,
                                                                        b)]))
                       for a in range(1, 4) for b in range(a, 4)]
        self.tt_knl = ElementWiseMap(
            write_insns,
            tmp_instructions=Pab_insns + TT_insns,
            lsize=(32, 1, 1),
            rank_shape=fft.shape(True),
        )

        tensor_to_pol_insns = {
            plus:
            sum(hij[tid(c, d)] * conj(eps[c - 1]) * conj(eps[d - 1])
                for c in range(1, 4) for d in range(1, 4)),
            minus:
            sum(hij[tid(c, d)] * eps[c - 1] * eps[d - 1] for c in range(1, 4)
                for d in range(1, 4))
        }
        self.tensor_to_pol_knl = ElementWiseMap(
            tensor_to_pol_insns,
            tmp_instructions=eps_insns,
            args=args,
            lsize=(32, 1, 1),
            rank_shape=fft.shape(True),
        )

        pol_to_tensor_insns = {
            hij[tid(a, b)]: (plus * eps[a - 1] * eps[b - 1] +
                             minus * conj(eps[a - 1]) * conj(eps[b - 1]))
            for a in range(1, 4) for b in range(a, 4)
        }
        self.pol_to_tensor_knl = ElementWiseMap(
            pol_to_tensor_insns,
            tmp_instructions=eps_insns,
            args=args,
            lsize=(32, 1, 1),
            rank_shape=fft.shape(True),
        )
Example #12
0
    def _add_statement(self, stmt):
        stmt_id = self.next_statement_id()

        read_variables = set(stmt.get_read_variables())
        written_variables = set(stmt.get_written_variables())

        # Add the global execution state as an implicitly read variable.
        read_variables.add(self._EXECUTION_STATE)

        # Build the condition attribute.
        if not self._conditional_expression_stack:
            condition = True
        elif len(self._conditional_expression_stack) == 1:
            condition = self._conditional_expression_stack[0]
        else:
            from pymbolic.primitives import LogicalAnd
            condition = LogicalAnd(tuple(self._conditional_expression_stack))

        from dagrt.utils import get_variables
        read_variables |= get_variables(condition)

        is_non_assignment = (not isinstance(
            stmt, (Assign, AssignImplicit, AssignFunctionCall)))

        # We regard all non-assignments as having potential external side
        # effects (i.e., writing to EXECUTION_STATE).  To keep the global
        # variables in a well-defined state, ensure that all updates to global
        # variables have happened before a non-assignment.
        if is_non_assignment:
            from dagrt.utils import is_state_variable
            read_variables |= {
                var
                for var in self._seen_var_names if is_state_variable(var)
            }
            written_variables.add(self._EXECUTION_STATE)

        depends_on = set()

        # Ensure this statement happens after the last write of all the
        # variables it reads or writes.
        for var in read_variables | written_variables:
            writer = self._writer_map.get(var, None)
            if writer is not None:
                depends_on.add(writer)

        # Ensure this statement happens after the last read(s) of the variables
        # it writes to.
        for var in written_variables:
            readers = self._reader_map.get(var, set())
            depends_on |= readers
            # Keep the graph sparse by clearing the readers set.
            readers.clear()

        for var in written_variables:
            self._writer_map[var] = stmt_id

        for var in read_variables:
            # reader_map should ignore reads that happen before writes, so
            # ignore if this statement also reads *var*.
            if var in written_variables:
                continue
            self._reader_map.setdefault(var, set()).add(stmt_id)

        stmt = stmt.copy(id=stmt_id,
                         condition=condition,
                         depends_on=frozenset(depends_on))
        self.statements.append(stmt)
        self._seen_var_names |= read_variables | written_variables
Example #13
0
    def parse_postfix(self, pstate, min_precedence, left_exp):
        import pymbolic.primitives as primitives

        did_something = False

        next_tag = pstate.next_tag()

        if next_tag is _openpar and _PREC_CALL > min_precedence:
            pstate.advance()
            args, kwargs = self.parse_arglist(pstate)

            if kwargs:
                left_exp = primitives.CallWithKwargs(left_exp, args, kwargs)
            else:
                left_exp = primitives.Call(left_exp, args)

            did_something = True
        elif next_tag is _openbracket and _PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect_not_end()
            left_exp = primitives.Subscript(left_exp,
                                            self.parse_expression(pstate))
            pstate.expect(_closebracket)
            pstate.advance()
            did_something = True
        elif next_tag is _dot and _PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect(_identifier)
            left_exp = primitives.Lookup(left_exp, pstate.next_str())
            pstate.advance()
            did_something = True
        elif next_tag is _plus and _PREC_PLUS > min_precedence:
            pstate.advance()
            left_exp += self.parse_expression(pstate, _PREC_PLUS)
            did_something = True
        elif next_tag is _minus and _PREC_PLUS > min_precedence:
            pstate.advance()
            left_exp -= self.parse_expression(pstate, _PREC_PLUS)
            did_something = True
        elif next_tag is _times and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp *= self.parse_expression(pstate, _PREC_TIMES)
            did_something = True
        elif next_tag is _floordiv and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp //= self.parse_expression(pstate, _PREC_TIMES)
            did_something = True
        elif next_tag is _over and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp /= self.parse_expression(pstate, _PREC_TIMES)
            did_something = True
        elif next_tag is _modulo and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp %= self.parse_expression(pstate, _PREC_TIMES)
            did_something = True
        elif next_tag is _power and _PREC_POWER > min_precedence:
            pstate.advance()
            left_exp **= self.parse_expression(pstate, _PREC_POWER)
            did_something = True
        elif next_tag is _and and _PREC_LOGICAL_AND > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LogicalAnd
            left_exp = LogicalAnd(
                (left_exp, self.parse_expression(pstate, _PREC_LOGICAL_AND)))
            did_something = True
        elif next_tag is _or and _PREC_LOGICAL_OR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LogicalOr
            left_exp = LogicalOr(
                (left_exp, self.parse_expression(pstate, _PREC_LOGICAL_OR)))
            did_something = True
        elif next_tag is _bitwiseor and _PREC_BITWISE_OR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseOr
            left_exp = BitwiseOr(
                (left_exp, self.parse_expression(pstate, _PREC_BITWISE_OR)))
            did_something = True
        elif next_tag is _bitwisexor and _PREC_BITWISE_XOR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseXor
            left_exp = BitwiseXor(
                (left_exp, self.parse_expression(pstate, _PREC_BITWISE_XOR)))
            did_something = True
        elif next_tag is _bitwiseand and _PREC_BITWISE_AND > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseAnd
            left_exp = BitwiseAnd(
                (left_exp, self.parse_expression(pstate, _PREC_BITWISE_AND)))
            did_something = True
        elif next_tag is _rightshift and _PREC_SHIFT > min_precedence:
            pstate.advance()
            from pymbolic.primitives import RightShift
            left_exp = RightShift(left_exp,
                                  self.parse_expression(pstate, _PREC_SHIFT))
            did_something = True
        elif next_tag is _leftshift and _PREC_SHIFT > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LeftShift
            left_exp = LeftShift(left_exp,
                                 self.parse_expression(pstate, _PREC_SHIFT))
            did_something = True
        elif next_tag in self._COMP_TABLE and _PREC_COMPARISON > min_precedence:
            pstate.advance()
            from pymbolic.primitives import Comparison
            left_exp = Comparison(
                left_exp, self._COMP_TABLE[next_tag],
                self.parse_expression(pstate, _PREC_COMPARISON))
            did_something = True
        elif next_tag is _colon and _PREC_SLICE >= min_precedence:
            pstate.advance()
            expr_pstate = pstate.copy()

            assert not isinstance(left_exp, primitives.Slice)

            from pytools.lex import ParseError
            try:
                next_expr = self.parse_expression(expr_pstate, _PREC_SLICE)
            except ParseError:
                # no expression follows, too bad.
                left_exp = primitives.Slice((
                    left_exp,
                    None,
                ))
            else:
                left_exp = _join_to_slice(left_exp, next_expr)
                pstate.assign(expr_pstate)

        elif next_tag is _comma and _PREC_COMMA > min_precedence:
            # The precedence makes the comma left-associative.

            pstate.advance()
            if pstate.is_at_end() or pstate.next_tag() is _closepar:
                left_exp = (left_exp, )
            else:
                new_el = self.parse_expression(pstate, _PREC_COMMA)
                if isinstance(left_exp, tuple) \
                        and not isinstance(left_exp, FinalizedTuple):
                    left_exp = left_exp + (new_el, )
                else:
                    left_exp = (left_exp, new_el)

            did_something = True

        return left_exp, did_something
Example #14
0
 def __call__(self, dtype, operand1, operand2, callables_table, target):
     from pymbolic.primitives import LogicalAnd
     return LogicalAnd((operand1, operand2)), callables_table