def facet_integral_predicates(self, mesh, integral_type, kinfo):
        self.bag.needs_cell_facets = True
        # Number of recerence cell facets
        if mesh.cell_set._extruded:
            self.num_facets = mesh._base_mesh.ufl_cell().num_facets()
        else:
            self.num_facets = mesh.ufl_cell().num_facets()

        # Index for loop over cell faces of reference cell
        fidx = self.bag.index_creator((self.num_facets,))

        # Cell is interior or exterior
        select = 1 if integral_type.startswith("interior_facet") else 0

        i = self.bag.index_creator((1,))
        predicates = [pym.Comparison(pym.Subscript(pym.Variable(self.cell_facets_arg), (fidx[0], 0)), "==", select)]

        # TODO subdomain boundary integrals, this does the wrong thing for integrals like f*ds + g*ds(1)
        # "otherwise" is treated incorrectly as "everywhere"
        # However, this replicates an existing slate bug.
        if kinfo.subdomain_id != "otherwise":
            predicates.append(pym.Comparison(pym.Subscript(pym.Variable(self.cell_facets_arg), (fidx[0], 1)), "==", kinfo.subdomain_id))

        # Additional facet array argument to be fed into tsfc loopy kernel
        subscript = pym.Subscript(pym.Variable(self.local_facet_array_arg),
                                  (pym.Sum((i[0], fidx[0]))))
        facet_arg = SubArrayRef(i, subscript)

        return predicates, fidx, facet_arg
Example #2
0
def make_random_expression(var_values, size):
    from random import randrange
    import pymbolic.primitives as p
    v = randrange(1500)
    size[0] += 1
    if v < 500 and size[0] < 40:
        term_count = randrange(2, 5)
        if randrange(2) < 1:
            cls = p.Sum
        else:
            cls = p.Product
        return cls(
            tuple(
                make_random_expression(var_values, size)
                for i in range(term_count)))
    elif v < 750:
        return make_random_value()
    elif v < 1000:
        var_name = "var_%d" % len(var_values)
        assert var_name not in var_values
        var_values[var_name] = make_random_value()
        return p.Variable(var_name)
    elif v < 1250:
        # Cannot use '-' because that destroys numpy constants.
        return p.Sum((make_random_expression(var_values, size),
                      -make_random_expression(var_values, size)))
    elif v < 1500:
        # Cannot use '/' because that destroys numpy constants.
        return p.Quotient(make_random_expression(var_values, size),
                          make_random_expression(var_values, size))
Example #3
0
def expression_indexed(expr, parameters):
    aggregate, multiindex = (expression(c, parameters) for c in expr.children)
    return pym.Subscript(aggregate, multiindex)
    extents = [int(numpy.prod(expr.aggregate.shape[i+1:])) for i in range(len(multiindex))]
    make_sum = lambda x, y: pym.Sum((x, y))
    index = reduce(make_sum, [pym.Product((e, m)) for e, m in zip(extents, multiindex)])
    return pym.Subscript(aggregate, (index,))
Example #4
0
    def initialise_terminals(self, var2terminal, coefficients):
        """ Initilisation of the variables in which coefficients
            and the Tensors coming from TSFC are saved.

            :arg var2terminal: dictionary that maps Slate Tensors to gem Variables
        """

        tensor2temp = OrderedDict()
        inits = []
        for gem_tensor, slate_tensor in var2terminal.items():
            assert slate_tensor.terminal, "Only terminal tensors need to be initialised in Slate kernels."
            (_, dtype), = assign_dtypes([gem_tensor],
                                        self.tsfc_parameters["scalar_type"])
            loopy_tensor = loopy.TemporaryVariable(
                gem_tensor.name,
                dtype=dtype,
                shape=gem_tensor.shape,
                address_space=loopy.AddressSpace.LOCAL)
            tensor2temp[slate_tensor] = loopy_tensor

            if not slate_tensor.assembled:
                indices = self.bag.index_creator(self.shape(slate_tensor))
                inames = {var.name for var in indices}
                var = pym.Subscript(pym.Variable(loopy_tensor.name), indices)
                inits.append(
                    loopy.Assignment(var,
                                     "0.",
                                     id="init%d" % len(inits),
                                     within_inames=frozenset(inames)))

            else:
                f = slate_tensor.form if isinstance(
                    slate_tensor.form, tuple) else (slate_tensor.form, )
                coeff = tuple(coefficients[c] for c in f)
                offset = 0
                ismixed = tuple(
                    (type(c.ufl_element()) == MixedElement) for c in f)
                names = []
                for (im, c) in zip(ismixed, coeff):
                    names += [name
                              for (name, ext) in c.values()] if im else [c[0]]

                # Mixed coefficients come as seperate parameter (one per space)
                for i, shp in enumerate(*slate_tensor.shapes.values()):
                    indices = self.bag.index_creator((shp, ))
                    inames = {var.name for var in indices}
                    offset_index = (pym.Sum((offset, indices[0])), )
                    name = names[i] if ismixed else names
                    var = pym.Subscript(pym.Variable(loopy_tensor.name),
                                        offset_index)
                    c = pym.Subscript(pym.Variable(name), indices)
                    inits.append(
                        loopy.Assignment(var,
                                         c,
                                         id="init%d" % len(inits),
                                         within_inames=frozenset(inames)))
                    offset += shp

        return inits, tensor2temp
Example #5
0
def make_random_int_expression(prefix, var_values, size, nonneg):
    from random import randrange
    import pymbolic.primitives as p
    if size[0] < 10:
        v = randrange(800)
    else:
        v = randrange(1000)

    size[0] += 1

    if v < 10:
        var_name = "var_%s_%d" % (prefix, len(var_values))
        assert var_name not in var_values
        var_values[var_name] = make_random_int_value(nonneg)
        return p.Variable(var_name)
    elif v < 200 and size[0] < 40:
        term_count = randrange(2, 5)
        if randrange(2) < 1:
            cls = p.Sum
        else:
            cls = p.Product
        return cls(
            tuple(
                make_random_int_expression(
                    prefix, var_values, size, nonneg=nonneg)
                for i in range(term_count)))
    elif v < 400 and size[0] < 40:
        return p.FloorDiv(
            make_random_int_expression(prefix, var_values, size,
                                       nonneg=nonneg),
            make_nonzero_random_int_expression(prefix,
                                               var_values,
                                               size,
                                               nonneg=nonneg))
    elif v < 600 and size[0] < 40:
        return p.Remainder(
            make_random_int_expression(prefix, var_values, size,
                                       nonneg=nonneg),
            make_nonzero_random_int_expression(prefix,
                                               var_values,
                                               size,
                                               nonneg=nonneg))
    elif v < 800 and not nonneg and size[0] < 40:
        return p.Sum((
            make_random_int_expression(prefix, var_values, size,
                                       nonneg=nonneg),
            -make_random_int_expression(
                prefix, var_values, size, nonneg=nonneg),
        ))
    else:
        return make_random_int_value(nonneg)
Example #6
0
def _expression_flexiblyindexed(expr, ctx):
    var = expression(expr.children[0], ctx)

    rank = []
    for off, idxs in expr.dim2idxs:
        for index, stride in idxs:
            assert isinstance(index, gem.Index)

        rank_ = [off]
        for index, stride in idxs:
            rank_.append(p.Product((ctx.active_indices[index], stride)))
        rank.append(p.Sum(tuple(rank_)))

    return p.Subscript(var, tuple(rank))
Example #7
0
    def initialise_terminals(self, var2terminal, coefficients):
        """ Initilisation of the variables in which coefficients
            and the Tensors coming from TSFC are saved.

            :arg var2terminal: dictionary that maps Slate Tensors to gem Variables
        """

        tensor2temp = OrderedDict()
        inits = []
        for gem_tensor, slate_tensor in var2terminal.items():
            loopy_tensor = loopy.TemporaryVariable(gem_tensor.name,
                                                   shape=gem_tensor.shape,
                                                   address_space=loopy.AddressSpace.LOCAL)
            tensor2temp[slate_tensor] = loopy_tensor

            if isinstance(slate_tensor, slate.Tensor):
                indices = self.bag.index_creator(self.shape(slate_tensor))
                inames = {var.name for var in indices}
                var = pym.Subscript(pym.Variable(loopy_tensor.name), indices)
                inits.append(loopy.Assignment(var, "0.", id="init%d" % len(inits),
                                              within_inames=frozenset(inames)))

            elif isinstance(slate_tensor, slate.AssembledVector):
                f = slate_tensor._function
                coeff = coefficients[f]
                offset = 0
                ismixed = (type(f.ufl_element()) == MixedElement)
                names = [name for (name, ext) in coeff.values()] if ismixed else coeff[0]

                # Mixed coefficients come as seperate parameter (one per space)
                for i, shp in enumerate(*slate_tensor.shapes.values()):
                    indices = self.bag.index_creator((shp,))
                    inames = {var.name for var in indices}
                    offset_index = (pym.Sum((offset, indices[0])),)
                    name = names[i] if ismixed else names
                    var = pym.Subscript(pym.Variable(loopy_tensor.name), offset_index)
                    c = pym.Subscript(pym.Variable(name), indices)
                    inits.append(loopy.Assignment(var, c, id="init%d" % len(inits),
                                                  within_inames=frozenset(inames)))
                    offset += shp

        return inits, tensor2temp
Example #8
0
    def map_sum(self, expr):
        first_group = []
        second_group = []

        for child in expr.children:
            tchild = child
            if isinstance(tchild, prim.CommonSubexpression):
                tchild = tchild.child

            if isinstance(tchild, prim.Product):
                neg_int_count = 0
                for subchild in tchild.children:
                    if isinstance(subchild, int) and subchild < 0:
                        neg_int_count += 1

                if neg_int_count % 2 == 1:
                    second_group.append(child)
                else:
                    first_group.append(child)
            else:
                first_group.append(child)

        return prim.Sum(tuple(first_group+second_group))
Example #9
0
def make_random_fp_expression(prefix, var_values, size, use_complex):
    from random import randrange
    import pymbolic.primitives as p
    v = randrange(1500)
    size[0] += 1
    if v < 500 and size[0] < 40:
        term_count = randrange(2, 5)
        if randrange(2) < 1:
            cls = p.Sum
        else:
            cls = p.Product
        return cls(
            tuple(
                make_random_fp_expression(prefix, var_values, size,
                                          use_complex)
                for i in range(term_count)))
    elif v < 750:
        return make_random_fp_value(use_complex=use_complex)
    elif v < 1000:
        var_name = "var_%s_%d" % (prefix, len(var_values))
        assert var_name not in var_values
        var_values[var_name] = make_random_fp_value(use_complex=use_complex)
        return p.Variable(var_name)
    elif v < 1250:
        # FIXME: What does this comment mean?
        # Cannot use '-' because that destroys numpy constants.
        return p.Sum((
            make_random_fp_expression(prefix, var_values, size, use_complex),
            -make_random_fp_expression(prefix, var_values, size, use_complex)))
    elif v < 1500:
        # FIXME: What does this comment mean?
        # Cannot use '/' because that destroys numpy constants.
        return p.Quotient(
            make_random_fp_expression(prefix, var_values, size, use_complex),
            make_random_fp_expression(prefix, var_values, size, use_complex))
    else:
        assert False
Example #10
0
def test_structure_preservation():
    x = prim.Sum((5, 7))
    from pymbolic.mapper import IdentityMapper
    x2 = IdentityMapper()(x)
    assert x == x2
Example #11
0
def _expression_sum(expr, ctx):
    return p.Sum(tuple(expression(c, ctx) for c in expr.children))
Example #12
0
def _sub(x, y):
    return p.Sum((x, p.Product(((-1), y))))
Example #13
0
def _add(x, y):
    return p.Sum((x, y))
Example #14
0
 def map_Add(self, expr):
     return prim.Sum(tuple(self.rec(arg) for arg in expr.args))
Example #15
0
 def _add(x, y):  # noqa
     return p.Sum((x, y))
Example #16
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