Exemplo n.º 1
0
def test_step_matrix_vector_state(show_matrix=True, show_dag=False):
    from leap.step_matrix import StepMatrixFinder
    from pymbolic import var

    component_id = 'y'
    code = euler(component_id, show_dag)
    J = np.diag([-3, -2, -1])  # noqa

    def rhs_sym(t, y):
        return J.dot(y)

    finder = StepMatrixFinder(code,
                              function_map={"<func>" + component_id: rhs_sym},
                              variables=["<state>" + component_id])

    mat = finder.get_phase_step_matrix("primary",
                                       shapes={"<state>" + component_id: 3})

    if show_matrix:
        print('Variables: %s' % finder.variables)
        from pytools import indices_in_shape
        for i in indices_in_shape(mat.shape):
            print(i, mat[i])

    # XXX: brittle
    dt = var("<dt>")
    true_mat = np.eye(3, dtype=np.object) + dt * J
    assert (mat == true_mat).all()
Exemplo n.º 2
0
 def map_numpy_array(self, expr):
     import numpy
     result = numpy.empty(expr.shape, dtype=object)
     from pytools import indices_in_shape
     for i in indices_in_shape(expr.shape):
         result[i] = self.rec(expr[i])
     return result
Exemplo n.º 3
0
def with_object_array_or_scalar_n_args(f, *args):
    oarray_arg_indices = []
    for i, arg in enumerate(args):
        if is_obj_array(arg):
            oarray_arg_indices.append(i)

    if not oarray_arg_indices:
        return f(*args)

    leading_oa_index = oarray_arg_indices[0]

    ls = log_shape(args[leading_oa_index])
    if ls != ():
        from pytools import indices_in_shape
        result = np.zeros(ls, dtype=object)

        new_args = list(args)
        for i in indices_in_shape(ls):
            for arg_i in oarray_arg_indices:
                new_args[arg_i] = args[arg_i][i]

            result[i] = f(*new_args)
        return result
    else:
        return f(*args)
Exemplo n.º 4
0
    def map_numpy_array(self, expr):
        if not self.visit(expr):
            return

        from pytools import indices_in_shape
        for i in indices_in_shape(expr.shape):
            self.rec(expr[i])
Exemplo n.º 5
0
def make_common_subexpression(field, prefix=None):
    from pytools.obj_array import log_shape
    from hedge.tools import is_zero
    from pymbolic.primitives import CommonSubexpression

    ls = log_shape(field)
    if ls != ():
        from pytools import indices_in_shape
        result = numpy.zeros(ls, dtype=object)

        for i in indices_in_shape(ls):
            if prefix is not None:
                component_prefix = prefix+"_".join(str(i_i) for i_i in i)
            else:
                component_prefix = None

            if is_zero(field[i]):
                result[i] = 0
            else:
                result[i] = CommonSubexpression(field[i], component_prefix)

        return result
    else:
        if is_zero(field):
            return 0
        else:
            return CommonSubexpression(field, prefix)
Exemplo n.º 6
0
def with_object_array_or_scalar_n_args(f, *args):
    oarray_arg_indices = []
    for i, arg in enumerate(args):
        if is_obj_array(arg):
            oarray_arg_indices.append(i)

    if not oarray_arg_indices:
        return f(*args)

    leading_oa_index = oarray_arg_indices[0]

    ls = log_shape(args[leading_oa_index])
    if ls != ():
        from pytools import indices_in_shape
        result = np.zeros(ls, dtype=object)

        new_args = list(args)
        for i in indices_in_shape(ls):
            for arg_i in oarray_arg_indices:
                new_args[arg_i] = args[arg_i][i]

            result[i] = f(*new_args)
        return result
    else:
        return f(*args)
Exemplo n.º 7
0
 def map_numpy_array(self, expr, *args, **kwargs):
     import numpy
     result = numpy.empty(expr.shape, dtype=object)
     from pytools import indices_in_shape
     for i in indices_in_shape(expr.shape):
         result[i] = self.rec(expr[i], *args, **kwargs)
     return result
Exemplo n.º 8
0
    def __call__(self, a):
        from pytools import indices_in_shape

        # assumes nonempty, which is reasonable
        return max(
                abs(self.scalar_kernel(a[i]))
                for i in indices_in_shape(a.shape))
Exemplo n.º 9
0
    def map_numpy_array(self, expr):
        if not self.visit(expr):
            return

        from pytools import indices_in_shape
        for i in indices_in_shape(expr.shape):
            self.rec(expr[i])
Exemplo n.º 10
0
    def __call__(self, a):
        from pytools import indices_in_shape

        # assumes nonempty, which is reasonable
        return max(
                abs(self.scalar_kernel(a[i]))
                for i in indices_in_shape(a.shape))
Exemplo n.º 11
0
def make_common_subexpression(field, prefix=None):
    try:
        from pytools.obj_array import log_shape
    except ImportError:
        have_obj_array = False
    else:
        have_obj_array = True

    if have_obj_array:
        ls = log_shape(field)

    if have_obj_array and ls != ():
        from pytools import indices_in_shape
        result = numpy.zeros(ls, dtype=object)

        for i in indices_in_shape(ls):
            if prefix is not None:
                component_prefix = prefix+"_".join(str(i_i) for i_i in i)
            else:
                component_prefix = None

            if is_constant(field[i]):
                result[i] = field[i]
            else:
                result[i] = CommonSubexpression(field[i], component_prefix)

        return result
    else:
        if is_constant(field):
            return field
        else:
            return CommonSubexpression(field, prefix)
Exemplo n.º 12
0
def to_obj_array(ary):
    ls = log_shape(ary)
    result = np.empty(ls, dtype=object)

    from pytools import indices_in_shape
    for i in indices_in_shape(ls):
        result[i] = ary[i]

    return result
Exemplo n.º 13
0
    def apply_mask(field):
        from hedge.tools import log_shape
        ls = log_shape(field)
        result = discr.volume_empty(ls)
        from pytools import indices_in_shape
        for i in indices_in_shape(ls):
            result[i] = mask * field[i]

        return result
Exemplo n.º 14
0
    def map_numpy_array(self, expr, *args, **kwargs):
        if not self.visit(expr, *args, **kwargs):
            return

        from pytools import indices_in_shape
        for i in indices_in_shape(expr.shape):
            self.rec(expr[i], *args, **kwargs)

        self.post_visit(expr, *args, **kwargs)
Exemplo n.º 15
0
def to_obj_array(ary):
    ls = log_shape(ary)
    result = np.empty(ls, dtype=object)

    from pytools import indices_in_shape
    for i in indices_in_shape(ls):
        result[i] = ary[i]

    return result
Exemplo n.º 16
0
def grad_S(kernel, arg, dim):
    from pytools.obj_array import log_shape
    arg_shape = log_shape(arg)
    result = np.zeros(arg_shape + (dim, ), dtype=object)
    from pytools import indices_in_shape
    for i in indices_in_shape(arg_shape):
        for j in range(dim):
            result[i + (j, )] = IntGdTarget(kernel, arg[i], j)
    return result
Exemplo n.º 17
0
    def map_numpy_array(self, expr, *args, **kwargs):
        if not self.visit(expr, *args, **kwargs):
            return

        from pytools import indices_in_shape
        for i in indices_in_shape(expr.shape):
            self.rec(expr[i], *args, **kwargs)

        self.post_visit(expr, *args, **kwargs)
Exemplo n.º 18
0
def grad_D(kernel, arg, dim):
    from pytools.obj_array import log_shape
    arg_shape = log_shape(arg)
    result = np.zeros(arg_shape+(dim,), dtype=object)
    from pytools import indices_in_shape
    for i in indices_in_shape(arg_shape):
        for j in range(dim):
            result[i+(j,)] = IntGdMixed(kernel, arg[i], j)
    return result
Exemplo n.º 19
0
    def apply_mask(field):
        from grudge.tools import log_shape
        ls = log_shape(field)
        result = discr.volume_empty(ls)
        from pytools import indices_in_shape
        for i in indices_in_shape(ls):
            result[i] = mask * field[i]

        return result
Exemplo n.º 20
0
def ptwise_mul(a, b):
    from pytools.obj_array import log_shape
    a_log_shape = log_shape(a)
    b_log_shape = log_shape(b)

    from pytools import indices_in_shape

    if a_log_shape == ():
        result = np.empty(b_log_shape, dtype=object)
        for i in indices_in_shape(b_log_shape):
            result[i] = a * b[i]
    elif b_log_shape == ():
        result = np.empty(a_log_shape, dtype=object)
        for i in indices_in_shape(a_log_shape):
            result[i] = a[i] * b
    else:
        raise ValueError("ptwise_mul can't handle two non-scalars")

    return result
Exemplo n.º 21
0
    def __call__(self, a, b):
        from pytools import indices_in_shape

        assert a.shape == b.shape

        result = 0
        for i in indices_in_shape(a.shape):
            result += self.scalar_kernel(a[i], b[i])

        return result
Exemplo n.º 22
0
    def __call__(self, a, b):
        from pytools import indices_in_shape

        assert a.shape == b.shape

        result = 0
        for i in indices_in_shape(a.shape):
            result += self.scalar_kernel(a[i], b[i])

        return result
Exemplo n.º 23
0
def ptwise_dot(logdims1, logdims2, a1, a2):
    a1_log_shape = a1.shape[:logdims1]
    a2_log_shape = a1.shape[:logdims2]

    assert a1_log_shape[-1] == a2_log_shape[0]
    len_k = a2_log_shape[0]

    result = np.empty(a1_log_shape[:-1] + a2_log_shape[1:], dtype=object)

    from pytools import indices_in_shape
    for a1_i in indices_in_shape(a1_log_shape[:-1]):
        for a2_i in indices_in_shape(a2_log_shape[1:]):
            result[a1_i + a2_i] = sum(a1[a1_i + (k, )] * a2[(k, ) + a2_i]
                                      for k in range(len_k))

    if result.shape == ():
        return result[()]
    else:
        return result
Exemplo n.º 24
0
def ptwise_mul(a, b):
    from pytools.obj_array import log_shape
    a_log_shape = log_shape(a)
    b_log_shape = log_shape(b)

    from pytools import indices_in_shape

    if a_log_shape == ():
        result = np.empty(b_log_shape, dtype=object)
        for i in indices_in_shape(b_log_shape):
            result[i] = a*b[i]
    elif b_log_shape == ():
        result = np.empty(a_log_shape, dtype=object)
        for i in indices_in_shape(a_log_shape):
            result[i] = a[i]*b
    else:
        raise ValueError("ptwise_mul can't handle two non-scalars")

    return result
Exemplo n.º 25
0
    def __call__(self, *args):
        from pytools import indices_in_shape, single_valued

        oa_shape = single_valued(ary.shape for fac, ary in args)
        result = numpy.zeros(oa_shape, dtype=object)

        for i in indices_in_shape(oa_shape):
            args_i = [(fac, ary[i]) for fac, ary in args]
            result[i] = self.scalar_kernel(*args_i)

        return result
Exemplo n.º 26
0
    def __call__(self, *args):
        from pytools import indices_in_shape, single_valued

        oa_shape = single_valued(ary.shape for fac, ary in args)
        result = numpy.zeros(oa_shape, dtype=object)

        for i in indices_in_shape(oa_shape):
            args_i = [(fac, ary[i]) for fac, ary in args]
            result[i] = self.scalar_kernel(*args_i)

        return result
Exemplo n.º 27
0
def make_sym_array(name, shape):
    vfld = Variable(name)
    if shape == ():
        return vfld

    import numpy as np
    result = np.zeros(shape, dtype=object)
    from pytools import indices_in_shape
    for i in indices_in_shape(shape):
        result[i] = vfld[i]

    return result
Exemplo n.º 28
0
def make_sym_array(name, shape, var_factory=Variable):
    vfld = var_factory(name)
    if shape == ():
        return vfld

    import numpy as np
    result = np.zeros(shape, dtype=object)
    from pytools import indices_in_shape
    for i in indices_in_shape(shape):
        result[i] = vfld.index(i)

    return result
Exemplo n.º 29
0
def ptwise_dot(logdims1, logdims2, a1, a2):
    a1_log_shape = a1.shape[:logdims1]
    a2_log_shape = a1.shape[:logdims2]

    assert a1_log_shape[-1] == a2_log_shape[0]
    len_k = a2_log_shape[0]

    result = np.empty(a1_log_shape[:-1]+a2_log_shape[1:], dtype=object)

    from pytools import indices_in_shape
    for a1_i in indices_in_shape(a1_log_shape[:-1]):
        for a2_i in indices_in_shape(a2_log_shape[1:]):
            result[a1_i+a2_i] = sum(
                    a1[a1_i+(k,)] * a2[(k,)+a2_i]
                    for k in xrange(len_k)
                    )

    if result.shape == ():
        return result[()]
    else:
        return result
Exemplo n.º 30
0
    def map_numpy_array(self, expr, enclosing_prec, *args, **kwargs):
        import numpy

        from pytools import indices_in_shape
        str_array = numpy.zeros(expr.shape, dtype="object")
        max_length = 0
        for i in indices_in_shape(expr.shape):
            s = self.rec(expr[i], PREC_NONE, *args, **kwargs)
            max_length = max(len(s), max_length)
            str_array[i] = s.replace("\n", "\n  ")

        if len(expr.shape) == 1 and max_length < 15:
            return "array(%s)" % ", ".join(str_array)
        else:
            lines = ["  %s: %s\n" % (
                ",".join(str(i_i) for i_i in i), str_array[i])
                for i in indices_in_shape(expr.shape)]
            if max_length > 70:
                splitter = "  " + "-"*75 + "\n"
                return "array(\n%s)" % splitter.join(lines)
            else:
                return "array(\n%s)" % "".join(lines)
Exemplo n.º 31
0
    def map_numpy_array(self, expr, enclosing_prec, *args, **kwargs):
        import numpy

        from pytools import indices_in_shape
        str_array = numpy.zeros(expr.shape, dtype="object")
        max_length = 0
        for i in indices_in_shape(expr.shape):
            s = self.rec(expr[i], PREC_NONE, *args, **kwargs)
            max_length = max(len(s), max_length)
            str_array[i] = s.replace("\n", "\n  ")

        if len(expr.shape) == 1 and max_length < 15:
            return "array(%s)" % ", ".join(str_array)
        else:
            lines = ["  %s: %s\n" % (
                ",".join(str(i_i) for i_i in i), str_array[i])
                for i in indices_in_shape(expr.shape)]
            if max_length > 70:
                splitter = "  " + "-"*75 + "\n"
                return "array(\n%s)" % splitter.join(lines)
            else:
                return "array(\n%s)" % "".join(lines)
Exemplo n.º 32
0
    def __call__(self, discr, t, fields, x, make_empty):
        result = self.make_func(discr)(t=numpy.float64(t), x=x, fields=fields)

        # make sure we return no scalars in the result
        from pytools.obj_array import log_shape, is_obj_array
        if is_obj_array(result):
            from pytools import indices_in_shape
            from hedge.optemplate.tools import is_scalar
            for i in indices_in_shape(log_shape(result)):
                if is_scalar(result[i]):
                    result[i] = make_empty().fill(result[i])

        return result
Exemplo n.º 33
0
    def __call__(self, discr, t, fields, x, make_empty):
        result = self.make_func(discr)(
                t=numpy.float64(t), x=x, fields=fields)

        # make sure we return no scalars in the result
        from pytools.obj_array import log_shape, is_obj_array
        if is_obj_array(result):
            from pytools import indices_in_shape
            from hedge.optemplate.tools import is_scalar
            for i in indices_in_shape(log_shape(result)):
                if is_scalar(result[i]):
                    result[i] = make_empty().fill(result[i])

        return result
Exemplo n.º 34
0
def make_sym_array(name, shape, var_factory=None):
    if var_factory is None:
        var_factory = Variable

    vfld = var_factory(name)
    if shape == ():
        return vfld

    import numpy as np
    result = np.zeros(shape, dtype=object)
    from pytools import indices_in_shape
    for i in indices_in_shape(shape):
        result[i] = vfld.index(i)

    return result
Exemplo n.º 35
0
def count_dofs(vec):
    try:
        dtype = vec.dtype
        size = vec.size
        shape = vec.shape
    except AttributeError:
        from warnings import warn
        warn("could not count dofs of vector")
        return 0

    if dtype == object:
        from pytools import indices_in_shape
        return sum(count_dofs(vec[i]) for i in indices_in_shape(vec.shape))
    else:
        return size
Exemplo n.º 36
0
    def split(self, whole_vol_vector):
        from pytools import indices_in_shape
        from hedge.tools import log_shape

        ls = log_shape(whole_vol_vector)

        if ls != ():
            result = [numpy.zeros(ls, dtype=object)
                    for part_emb in self._embeddings()]
            for p, part_emb in enumerate(self._embeddings()):
                for i in indices_in_shape(ls):
                    result[p][i] = whole_vol_vector[part_emb]
            return result
        else:
            return [whole_vol_vector[part_emb]
                    for part_emb in self._embeddings()]
Exemplo n.º 37
0
def with_object_array_or_scalar(f, field, obj_array_only=False):
    if obj_array_only:
        if is_obj_array(field):
            ls = field.shape
        else:
            ls = ()
    else:
        ls = log_shape(field)
    if ls != ():
        from pytools import indices_in_shape
        result = np.zeros(ls, dtype=object)
        for i in indices_in_shape(ls):
            result[i] = f(field[i])
        return result
    else:
        return f(field)
Exemplo n.º 38
0
def with_object_array_or_scalar(f, field, obj_array_only=False):
    if obj_array_only:
        if is_obj_array(field):
            ls = field.shape
        else:
            ls = ()
    else:
        ls = log_shape(field)
    if ls != ():
        from pytools import indices_in_shape
        result = np.zeros(ls, dtype=object)
        for i in indices_in_shape(ls):
            result[i] = f(field[i])
        return result
    else:
        return f(field)
Exemplo n.º 39
0
def count_dofs(vec):
    try:
        dtype = vec.dtype
        size = vec.size
        shape = vec.shape
    except AttributeError:
        from warnings import warn
        warn("could not count dofs of vector")
        return 0

    if dtype == object:
        from pytools import indices_in_shape
        return sum(count_dofs(vec[i])
                for i in indices_in_shape(vec.shape))
    else:
        return size
Exemplo n.º 40
0
    def split(self, whole_vol_vector):
        from pytools import indices_in_shape
        from hedge.tools import log_shape

        ls = log_shape(whole_vol_vector)

        if ls != ():
            result = [
                numpy.zeros(ls, dtype=object)
                for part_emb in self._embeddings()
            ]
            for p, part_emb in enumerate(self._embeddings()):
                for i in indices_in_shape(ls):
                    result[p][i] = whole_vol_vector[part_emb]
            return result
        else:
            return [
                whole_vol_vector[part_emb] for part_emb in self._embeddings()
            ]
Exemplo n.º 41
0
    def subscripts_and_names(self):
        sep_shape = self.sep_shape()

        if not sep_shape:
            return None

        def unwrap_1d_indices(idx):
            # This allows these indices to work on Python sequences, too, not
            # just numpy arrays.

            if len(idx) == 1:
                return idx[0]
            else:
                return idx

        from pytools import indices_in_shape
        return [(unwrap_1d_indices(i), self.name + "".join("_s%d" % sub_i
                                                           for sub_i in i))
                for i in indices_in_shape(sep_shape)]
Exemplo n.º 42
0
    def subscripts_and_names(self):
        sep_shape = self.sep_shape()

        if not sep_shape:
            return None

        def unwrap_1d_indices(idx):
            # This allows these indices to work on Python sequences, too, not
            # just numpy arrays.

            if len(idx) == 1:
                return idx[0]
            else:
                return idx

        from pytools import indices_in_shape
        return [
                (unwrap_1d_indices(i),
                    self.name + "".join("_s%d" % sub_i for sub_i in i))
                for i in indices_in_shape(sep_shape)]
Exemplo n.º 43
0
    def reassemble(self, parts_vol_vectors):
        from pytools import single_valued, indices_in_shape
        from hedge.tools import log_shape
        ls = single_valued(log_shape(pvv) for pvv in parts_vol_vectors)

        def remap_scalar_field(idx):
            result = self.whole_discr.volume_zeros()
            for part_emb, part_vol_vector in zip(self._embeddings(),
                                                 parts_vol_vectors):
                result[part_emb] = part_vol_vector[idx]

            return result

        if ls != ():
            result = numpy.zeros(ls, dtype=object)
            for i in indices_in_shape(ls):
                result[i] = remap_scalar_field(i)
            return result
        else:
            return remap_scalar_field(())
Exemplo n.º 44
0
    def basis(self):
        """"
        :returns: a :class:`list` containing functions that realize
            a high-order interpolation basis on the :attr:`points`.
        """

        from pytools import indices_in_shape
        from scipy.special import eval_chebyt

        def eval_basis(ind, x):
            result = 1
            for i in range(self.dim):
                coord = (x[i] - self.center[i])/(self.h/2)
                result *= eval_chebyt(ind[i], coord)
            return result

        from functools import partial
        return [
                partial(eval_basis, ind)
                for ind in indices_in_shape((self.npoints,)*self.dim)]
Exemplo n.º 45
0
    def reassemble(self, parts_vol_vectors):
        from pytools import single_valued, indices_in_shape
        from hedge.tools import log_shape
        ls = single_valued(log_shape(pvv) for pvv in parts_vol_vectors)

        def remap_scalar_field(idx):
            result = self.whole_discr.volume_zeros()
            for part_emb, part_vol_vector in zip(
                    self._embeddings(), parts_vol_vectors):
                result[part_emb] = part_vol_vector[idx]

            return result

        if ls != ():
            result = numpy.zeros(ls, dtype=object)
            for i in indices_in_shape(ls):
                result[i] = remap_scalar_field(i)
            return result
        else:
            return remap_scalar_field(())
Exemplo n.º 46
0
    def basis(self):
        """
        :returns: a :class:`list` containing functions that realize
            a high-order interpolation basis on the :py:attr:`points`.
        """

        from pytools import indices_in_shape
        from scipy.special import eval_chebyt

        def eval_basis(ind, x):
            result = 1
            for i in range(self.dim):
                coord = (x[i] - self.center[i]) / (self.h / 2)
                result *= eval_chebyt(ind[i], coord)
            return result

        from functools import partial
        return [
            partial(eval_basis, ind)
            for ind in indices_in_shape((self.npoints, ) * self.dim)
        ]
Exemplo n.º 47
0
def generate_linearized_array(array, value):
    from pytools import product
    size = product(shape_ax for shape_ax in array.shape)

    if not isinstance(size, int):
        raise LoopyError("cannot produce literal for array '%s': "
                "shape is not a compile-time constant"
                % array.name)

    strides = []

    data = np.zeros(size, array.dtype.numpy_dtype)

    from loopy.kernel.array import FixedStrideArrayDimTag
    for i, dim_tag in enumerate(array.dim_tags):
        if isinstance(dim_tag, FixedStrideArrayDimTag):

            if not isinstance(dim_tag.stride, int):
                raise LoopyError("cannot produce literal for array '%s': "
                        "stride along axis %d (1-based) is not a "
                        "compile-time constant"
                        % (array.name, i+1))

            strides.append(dim_tag.stride)

        else:
            raise LoopyError("cannot produce literal for array '%s': "
                    "dim_tag type '%s' not supported"
                    % (array.name, type(dim_tag).__name__))

    assert array.offset == 0

    from pytools import indices_in_shape
    for ituple in indices_in_shape(value.shape):
        i = sum(i_ax * strd_ax for i_ax, strd_ax in zip(ituple, strides))
        data[i] = value[ituple]

    return data
Exemplo n.º 48
0
def generate_linearized_array(array, value):
    from pytools import product
    size = product(shape_ax for shape_ax in array.shape)

    if not isinstance(size, int):
        raise LoopyError("cannot produce literal for array '%s': "
                "shape is not a compile-time constant"
                % array.name)

    strides = []

    data = np.zeros(size, array.dtype.numpy_dtype)

    from loopy.kernel.array import FixedStrideArrayDimTag
    for i, dim_tag in enumerate(array.dim_tags):
        if isinstance(dim_tag, FixedStrideArrayDimTag):

            if not isinstance(dim_tag.stride, int):
                raise LoopyError("cannot produce literal for array '%s': "
                        "stride along axis %d (1-based) is not a "
                        "compile-time constant"
                        % (array.name, i+1))

            strides.append(dim_tag.stride)

        else:
            raise LoopyError("cannot produce literal for array '%s': "
                    "dim_tag type '%s' not supported"
                    % (array.name, type(dim_tag).__name__))

    assert array.offset == 0

    from pytools import indices_in_shape
    for ituple in indices_in_shape(value.shape):
        i = sum(i_ax * strd_ax for i_ax, strd_ax in zip(ituple, strides))
        data[i] = value[ituple]

    return data
Exemplo n.º 49
0
def make_common_subexpression(field, prefix=None, scope=None):
    """Wrap *field* in a :class:`CommonSubexpression` with
    *prefix*. If *field* is a :mod:`numpy` object array,
    each individual entry is instead wrapped. If *field* is a
    :class:`pymbolic.geometric_algebra.MultiVector`, each
    coefficient is individually wrapped.

    See :class:`CommonSubexpression` for the meaning of *prefix*
    and *scope*.
    """

    if isinstance(field, CommonSubexpression) and (
            scope is None or scope == cse_scope.EVALUATION
            or field.scope == scope):
        # Don't re-wrap
        return field

    try:
        from pytools.obj_array import log_shape
    except ImportError:
        have_obj_array = False
    else:
        have_obj_array = True

    if have_obj_array:
        ls = log_shape(field)

    from pymbolic.geometric_algebra import MultiVector
    if isinstance(field, MultiVector):
        new_data = {}
        for bits, coeff in six.iteritems(field.data):
            if prefix is not None:
                blade_str = field.space.blade_bits_to_str(bits, "")
                component_prefix = prefix+"_"+blade_str
            else:
                component_prefix = None

            new_data[bits] = make_common_subexpression(
                    coeff, component_prefix, scope)

        return MultiVector(new_data, field.space)

    elif have_obj_array and ls != ():
        from pytools import indices_in_shape
        result = numpy.zeros(ls, dtype=object)

        for i in indices_in_shape(ls):
            if prefix is not None:
                component_prefix = prefix+"_".join(str(i_i) for i_i in i)
            else:
                component_prefix = None

            if is_constant(field[i]):
                result[i] = field[i]
            else:
                result[i] = make_common_subexpression(
                        field[i], component_prefix, scope)

        return result
    else:
        if is_constant(field):
            return field
        else:
            return CommonSubexpression(field, prefix, scope)
Exemplo n.º 50
0
def make_common_subexpression(field, prefix=None, scope=None):
    """Wrap *field* in a :class:`CommonSubexpression` with
    *prefix*. If *field* is a :mod:`numpy` object array,
    each individual entry is instead wrapped. If *field* is a
    :class:`pymbolic.geometric_algebra.MultiVector`, each
    coefficient is individually wrapped.

    See :class:`CommonSubexpression` for the meaning of *prefix*
    and *scope*.
    """

    if isinstance(field, CommonSubexpression) and (scope is None or scope
                                                   == cse_scope.EVALUATION
                                                   or field.scope == scope):
        # Don't re-wrap
        return field

    try:
        from pytools.obj_array import log_shape
    except ImportError:
        have_obj_array = False
    else:
        have_obj_array = True

    if have_obj_array:
        ls = log_shape(field)

    from pymbolic.geometric_algebra import MultiVector
    if isinstance(field, MultiVector):
        new_data = {}
        for bits, coeff in six.iteritems(field.data):
            if prefix is not None:
                blade_str = field.space.blade_bits_to_str(bits, "")
                component_prefix = prefix + "_" + blade_str
            else:
                component_prefix = None

            new_data[bits] = make_common_subexpression(coeff, component_prefix,
                                                       scope)

        return MultiVector(new_data, field.space)

    elif have_obj_array and ls != ():
        from pytools import indices_in_shape
        result = numpy.zeros(ls, dtype=object)

        for i in indices_in_shape(ls):
            if prefix is not None:
                component_prefix = prefix + "_".join(str(i_i) for i_i in i)
            else:
                component_prefix = None

            if is_constant(field[i]):
                result[i] = field[i]
            else:
                result[i] = make_common_subexpression(field[i],
                                                      component_prefix, scope)

        return result
    else:
        if is_constant(field):
            return field
        else:
            return CommonSubexpression(field, prefix, scope)
Exemplo n.º 51
0
def interpolate_from_meshmode(queue,
                              dof_vec,
                              elements_to_sources_lookup,
                              order="tree"):
    """Interpolate a DoF vector from :mod:`meshmode`.

    :arg dof_vec: a DoF vector representing a field in :mod:`meshmode`
        of shape ``(..., nnodes)``.
    :arg elements_to_sources_lookup: a :class:`ElementsToSourcesLookup`.
    :arg order: order of the output potential, either "tree" or "user".

    .. note:: This function currently supports meshes with just one element
        group. Also, the element group must be simplex-based.

    .. note:: This function does some heavy-lifting computation in Python,
        which we intend to optimize in the future. In particular, we plan
        to shift the batched linear solves and basis evaluations to
        :mod:`loopy`.

    TODO: make linear solvers available as :mod:`loopy` callables.
    TODO: make :mod:`modepy` emit :mod:`loopy` callables for basis evaluation.
    """
    if not isinstance(dof_vec, cl.array.Array):
        raise TypeError("non-array passed to interpolator")

    assert len(elements_to_sources_lookup.discr.groups) == 1
    assert len(elements_to_sources_lookup.discr.mesh.groups) == 1
    degroup = elements_to_sources_lookup.discr.groups[0]
    megroup = elements_to_sources_lookup.discr.mesh.groups[0]

    if not degroup.is_affine:
        raise ValueError(
            "interpolation requires global-to-local map, "
            "which is only available for affinely mapped elements")

    mesh = elements_to_sources_lookup.discr.mesh
    dim = elements_to_sources_lookup.discr.dim
    template_simplex = mesh.groups[0].vertex_unit_coordinates().T

    # -------------------------------------------------------
    # Inversely map source points with a global-to-local map.
    #
    # 1. For each element, solve for the affine map.
    #
    # 2. Apply the map to corresponding source points.
    #
    # This step computes `unit_sources`, the list of inversely
    # mapped source points.

    sources_in_element_starts = \
        elements_to_sources_lookup.sources_in_element_starts.get(queue)
    sources_in_element_lists = \
        elements_to_sources_lookup.sources_in_element_lists.get(queue)
    tree = elements_to_sources_lookup.tree.get(queue)

    unit_sources_host = make_obj_array(
        [np.zeros_like(srccrd) for srccrd in tree.sources])

    for iel in range(degroup.nelements):
        vertex_ids = megroup.vertex_indices[iel]
        vertices = mesh.vertices[:, vertex_ids]
        afa, afb = compute_affine_transform(vertices, template_simplex)

        beg = sources_in_element_starts[iel]
        end = sources_in_element_starts[iel + 1]
        source_ids_in_el = sources_in_element_lists[beg:end]
        sources_in_el = np.vstack(
            [tree.sources[iaxis][source_ids_in_el] for iaxis in range(dim)])

        ivmapped_el_sources = afa @ sources_in_el + afb.reshape([dim, 1])
        for iaxis in range(dim):
            unit_sources_host[iaxis][source_ids_in_el] = \
                ivmapped_el_sources[iaxis, :]

    unit_sources = make_obj_array(
        [cl.array.to_device(queue, usc) for usc in unit_sources_host])

    # -----------------------------------------------------
    # Carry out evaluations in the local (template) frames.
    #
    # 1. Assemble a resampling matrix for each element, with
    #    the basis functions and the local source points.
    #
    # 2. For each element, perform matvec on the resampling
    #    matrix and the local DoF coefficients.
    #
    # This step assumes `unit_sources` computed on device, so
    # that the previous step can be swapped with a kernel without
    # interrupting the followed computation.

    mapped_sources = np.vstack([usc.get(queue) for usc in unit_sources])

    basis_funcs = degroup.basis()

    arr_ctx = PyOpenCLArrayContext(queue)
    dof_vec_view = unflatten(arr_ctx, elements_to_sources_lookup.discr,
                             dof_vec)[0]
    dof_vec_view = dof_vec_view.get()

    sym_shape = dof_vec.shape[:-1]
    source_vec = np.zeros(sym_shape + (tree.nsources, ))

    for iel in range(degroup.nelements):
        beg = sources_in_element_starts[iel]
        end = sources_in_element_starts[iel + 1]
        source_ids_in_el = sources_in_element_lists[beg:end]
        mapped_sources_in_el = mapped_sources[:, source_ids_in_el]
        local_dof_vec = dof_vec_view[..., iel, :]

        # resampling matrix built from Vandermonde matrices
        import modepy as mp
        rsplm = mp.resampling_matrix(basis=basis_funcs,
                                     new_nodes=mapped_sources_in_el,
                                     old_nodes=degroup.unit_nodes)

        if len(sym_shape) == 0:
            local_coeffs = local_dof_vec
            source_vec[source_ids_in_el] = rsplm @ local_coeffs
        else:
            from pytools import indices_in_shape
            for sym_id in indices_in_shape(sym_shape):
                source_vec[sym_id + (source_ids_in_el, )] = \
                    rsplm @ local_dof_vec[sym_id]

    source_vec = cl.array.to_device(queue, source_vec)

    if order == "tree":
        pass  # no need to do anything
    elif order == "user":
        source_vec = source_vec[tree.sorted_target_ids]  # into user order
    else:
        raise ValueError(f"order must be 'tree' or 'user' (got {order}).")

    return source_vec
Exemplo n.º 52
0
def test_step_matrix(method, show_matrix=True, show_dag=False):
    component_id = 'y'
    code = method.generate()
    if show_dag:
        from dagrt.language import show_dependency_graph
        show_dependency_graph(code)
    from dagrt.exec_numpy import NumpyInterpreter
    from leap.step_matrix import StepMatrixFinder

    from pymbolic import var

    # {{{ build matrix

    def rhs_sym(t, y):
        return var("lambda") * y

    finder = StepMatrixFinder(code,
                              function_map={"<func>" + component_id: rhs_sym})

    mat = finder.get_phase_step_matrix("primary")

    if show_matrix:
        print('Variables: %s' % finder.variables)
        from pytools import indices_in_shape
        for i in indices_in_shape(mat.shape):
            print(i, mat[i])

    # }}}

    dt = 0.1
    lambda_ = -0.4

    def rhs(t, y):
        return lambda_ * y

    interp = NumpyInterpreter(code,
                              function_map={"<func>" + component_id: rhs})
    interp.set_up(t_start=0, dt_start=dt, context={component_id: 15})

    assert interp.next_phase == "initial"
    for event in interp.run_single_step():
        pass
    assert interp.next_phase == "primary"

    start_values = np.array([interp.context[v] for v in finder.variables])

    for event in interp.run_single_step():
        pass
    assert interp.next_phase == "primary"

    stop_values = np.array([interp.context[v] for v in finder.variables])

    from dagrt.expression import EvaluationMapper
    concrete_mat = EvaluationMapper({
        "lambda": lambda_,
        "<dt>": dt,
    }, {})(mat)

    stop_values_from_mat = concrete_mat.dot(start_values)

    rel_err = (
        la.norm(stop_values - stop_values_from_mat) /  # noqa: W504
        la.norm(stop_values))

    assert rel_err < 1e-12