Esempio n. 1
0
def test_call_loopy_shape_inference():
    from pytato.loopy import call_loopy
    from pytato.utils import are_shapes_equal
    import loopy as lp

    knl = lp.make_kernel(
            ["{[i, j]: 0<=i<(2*n + 3*m + 2) and 0<=j<(6*n + 4*m + 3)}",
             "{[ii, jj]: 0<=ii<m and 0<=jj<n}"],
            """
            <> tmp = sum([i, j], A[i, j])
            out[ii, jj] = tmp*(ii + jj)
            """, lang_version=(2018, 2))

    # {{{ variant 1

    A = pt.make_placeholder(name="x", shape=(20, 37), dtype=np.float64)  # noqa: N806
    y = call_loopy(knl, {"A": A})["out"]
    assert are_shapes_equal(y.shape, (4, 3))

    # }}}

    # {{{ variant 2

    n1 = pt.make_size_param("n1")
    n2 = pt.make_size_param("n2")
    A = pt.make_placeholder(name="x",  # noqa: N806
                            shape=(4*n1 + 6*n2 + 2, 12*n1 + 8*n2 + 3),
                            dtype=np.float64)

    y = call_loopy(knl, {"A": A})["out"]
    assert are_shapes_equal(y.shape, (2*n2, 2*n1))
Esempio n. 2
0
def test_matmul_input_validation():
    namespace = pt.Namespace()

    a = pt.make_placeholder(namespace,
                            name="a",
                            shape=(10, 10),
                            dtype=np.float)
    b = pt.make_placeholder(namespace,
                            name="b",
                            shape=(20, 10),
                            dtype=np.float)

    with pytest.raises(ValueError):
        a @ b

    c = pt.make_placeholder(namespace, name="c", shape=(), dtype=np.float)
    with pytest.raises(ValueError):
        c @ c

    pt.make_size_param(namespace, "n")
    d = pt.make_placeholder(namespace,
                            name="d",
                            shape="(n, n)",
                            dtype=np.float)
    d @ d
Esempio n. 3
0
def test_idx_lambda_to_hlo():
    from pytato.raising import index_lambda_to_high_level_op
    from pytato.raising import (BinaryOp, BinaryOpType, FullOp, ReduceOp,
                                C99CallOp, BroadcastOp)
    from pyrsistent import pmap
    from pytato.reductions import (SumReductionOperation,
                                   ProductReductionOperation)

    a = pt.make_placeholder("a", (10, 4), dtype=np.float64)
    b = pt.make_placeholder("b", (10, 4), dtype=np.float64)

    assert index_lambda_to_high_level_op(a + b) == BinaryOp(BinaryOpType.ADD,
                                                            a, b)
    assert index_lambda_to_high_level_op(a / 42) == BinaryOp(BinaryOpType.TRUEDIV,
                                                             a, 42)
    assert index_lambda_to_high_level_op(42 * a) == BinaryOp(BinaryOpType.MULT,
                                                             42, a)
    assert index_lambda_to_high_level_op(a ** b) == BinaryOp(BinaryOpType.POWER,
                                                             a, b)
    assert index_lambda_to_high_level_op(a - b) == BinaryOp(BinaryOpType.SUB,
                                                            a, b)
    assert (index_lambda_to_high_level_op(a & b)
            == BinaryOp(BinaryOpType.BITWISE_AND, a, b))
    assert (index_lambda_to_high_level_op(a ^ b)
            == BinaryOp(BinaryOpType.BITWISE_XOR, a, b))
    assert (index_lambda_to_high_level_op(a | b)
            == BinaryOp(BinaryOpType.BITWISE_OR, a, b))
    assert (index_lambda_to_high_level_op(pt.equal(a, b))
            == BinaryOp(BinaryOpType.EQUAL, a, b))
    assert (index_lambda_to_high_level_op(pt.not_equal(a, b))
            == BinaryOp(BinaryOpType.NOT_EQUAL, a, b))
    assert (index_lambda_to_high_level_op(pt.less(a, b))
            == BinaryOp(BinaryOpType.LESS, a, b))
    assert (index_lambda_to_high_level_op(pt.less_equal(a, b))
            == BinaryOp(BinaryOpType.LESS_EQUAL, a, b))
    assert (index_lambda_to_high_level_op(pt.greater(a, b))
            == BinaryOp(BinaryOpType.GREATER, a, b))
    assert (index_lambda_to_high_level_op(pt.greater_equal(a, b))
            == BinaryOp(BinaryOpType.GREATER_EQUAL, a, b))

    assert index_lambda_to_high_level_op(pt.zeros(6)) == FullOp(0)
    assert (index_lambda_to_high_level_op(pt.sum(b, axis=1))
            == ReduceOp(SumReductionOperation(),
                        b,
                        pmap({1: "_r0"})))
    assert (index_lambda_to_high_level_op(pt.prod(a))
            == ReduceOp(ProductReductionOperation(),
                        a,
                        {0: "_r0",
                         1: "_r1"}))
    assert index_lambda_to_high_level_op(pt.sinh(a)) == C99CallOp("sinh", (a,))
    assert index_lambda_to_high_level_op(pt.arctan2(b, a)) == C99CallOp("atan2",
                                                                        (b, a))
    assert (index_lambda_to_high_level_op(pt.broadcast_to(a, (100, 10, 4)))
            == BroadcastOp(a))
Esempio n. 4
0
def test_size_param(ctx_factory):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    namespace = pt.Namespace()
    n = pt.make_size_param(namespace, name="n")
    pt.make_placeholder(namespace, name="x", shape="(n,)", dtype=np.int)
    prog = pt.generate_loopy(n, target=pt.PyOpenCLTarget(queue))
    x_in = np.array([1, 2, 3, 4, 5])
    _, (n_out, ) = prog(x=x_in)
    assert n_out == 5
Esempio n. 5
0
def test_rec_get_user_nodes():
    x1 = pt.make_placeholder("x1", shape=(10, 4), dtype=np.float64)
    x2 = pt.make_placeholder("x2", shape=(10, 4), dtype=np.float64)

    expr = pt.make_dict_of_named_arrays({"out1": 2 * x1,
                                         "out2": 7 * x1 + 3 * x2})

    assert (pt.transform.rec_get_user_nodes(expr, x1)
            == frozenset({2 * x1, 7*x1, 7*x1 + 3 * x2, expr}))
    assert (pt.transform.rec_get_user_nodes(expr, x2)
            == frozenset({3 * x2, 7*x1 + 3 * x2, expr}))
Esempio n. 6
0
def test_index_type_validation():
    a = pt.make_placeholder(name="a", shape=(10,), dtype=np.float64)

    idx = pt.make_placeholder(name="idx", shape=(5,), dtype=np.int8)
    a[idx]

    idx = pt.make_placeholder(name="idx", shape=(5,), dtype=np.uint8)
    a[idx]

    idx = pt.make_placeholder(name="idx", shape=(5,), dtype=np.float64)
    with pytest.raises(IndexError):
        a[idx]
Esempio n. 7
0
def test_same_placeholder_name_raises():
    from pytato.diagnostic import NameClashError
    x = pt.make_placeholder(name="arr", shape=(10, 4), dtype=float)
    y = pt.make_placeholder(name="arr", shape=(10, 4), dtype=float)

    with pytest.raises(NameClashError):
        pt.generate_loopy(x+y)

    n1 = pt.make_size_param("n")
    n2 = pt.make_size_param("n")
    x = pt.make_placeholder(name="arr", shape=(n1, n2), dtype=float)
    with pytest.raises(NameClashError):
        pt.generate_loopy(2*x)
Esempio n. 8
0
def test_matmul_input_validation():
    a = pt.make_placeholder(name="a", shape=(10, 10), dtype=np.float64)
    b = pt.make_placeholder(name="b", shape=(20, 10), dtype=np.float64)

    with pytest.raises(ValueError):
        a @ b

    c = pt.make_placeholder(name="c", shape=(), dtype=np.float64)
    with pytest.raises(ValueError):
        c @ c

    n = pt.make_size_param("n")
    d = pt.make_placeholder(name="d", shape=(n, n), dtype=np.float64)
    d @ d
Esempio n. 9
0
def main():
    import pytato as pt
    import pyopencl as cl
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    nelements = 20
    nnodes = 3

    discr = DGDiscr1D(0, 2 * np.pi, nelements=nelements, nnodes=nnodes)

    ns = pt.Namespace()
    pt.make_size_param(ns, "nelements")
    pt.make_size_param(ns, "nnodes")
    u = pt.make_placeholder(ns,
                            name="u",
                            shape="(nelements, nnodes)",
                            dtype=np.float64)
    op = AdvectionOperator(discr,
                           c=1,
                           flux_type="central",
                           dg_ops=DGOps1D(discr, ns))
    result = op.apply(u)

    prog = pt.generate_loopy(result, target=pt.PyOpenCLTarget(queue))
    print(prog.program)

    u = np.sin(discr.nodes())
    print(prog(u=u.reshape(nelements, nnodes))[1][0])
Esempio n. 10
0
def test_einsum_is_similar_to_subscript(spec, argshapes):
    operands = [pt.make_placeholder(name=f"arg_{iarg}",
                                    shape=argshape,
                                    dtype=np.int32)
                for iarg, argshape in enumerate(argshapes)]
    expr = pt.einsum(spec, *operands)
    assert pt.analysis.is_einsum_similar_to_subscript(expr, spec)
Esempio n. 11
0
def test_asciidag():
    n = pt.make_size_param("n")
    array = pt.make_placeholder(name="array", shape=n, dtype=np.float64)
    stack = pt.stack([array, 2*array, array + 6])
    y = stack @ stack.T

    from pytato import get_ascii_graph

    res = get_ascii_graph(y, use_color=False)

    ref_str = r"""* Inputs
*-.   Placeholder
|\ \
* | | IndexLambda
| |/
|/|
| * IndexLambda
|/
*   Stack
|\
* | AxisPermutation
|/
* Einsum
* Outputs
"""

    assert res == ref_str
Esempio n. 12
0
def test_userscollector():
    from testlib import RandomDAGContext, make_random_dag
    from pytato.transform import UsersCollector, reverse_graph

    # Check that nodes without users are correctly reversed
    array = pt.make_placeholder(name="array", shape=1, dtype=np.int64)
    y = array+1

    uc = UsersCollector()
    uc(y)
    rev_graph = reverse_graph(uc.node_to_users)
    rev_graph2 = reverse_graph(reverse_graph(rev_graph))

    assert reverse_graph(rev_graph2) == uc.node_to_users

    # Test random DAGs
    axis_len = 5

    for i in range(100):
        rdagc = RandomDAGContext(np.random.default_rng(seed=i),
                axis_len=axis_len, use_numpy=False)

        dag = make_random_dag(rdagc)

        uc = UsersCollector()
        uc(dag)

        rev_graph = reverse_graph(uc.node_to_users)
        rev_graph2 = reverse_graph(reverse_graph(rev_graph))

        assert rev_graph2 == rev_graph
Esempio n. 13
0
def test_advection_convergence(order, flux_type):
    errors = []
    hs = []

    import pytato as pt
    import pyopencl as cl
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    for nelements in (8, 12, 16, 20):
        discr = DGDiscr1D(0, 2 * np.pi, nelements=nelements, nnodes=order)
        dg_ops = DGOps1D(discr)
        u_initial = np.sin(discr.nodes())

        u = pt.make_placeholder(name="u",
                                shape=(dg_ops.nelements, dg_ops.nnodes),
                                dtype=np.float64)
        op = AdvectionOperator(discr, c=1, flux_type=flux_type, dg_ops=dg_ops)
        result = op.apply(u)

        prog = pt.generate_loopy(result, cl_device=queue.device)

        u = rk4(lambda t, y: prog(queue, u=y.reshape(nelements, order))[1][0].
                reshape(-1),
                u_initial,
                t_initial=0,
                t_final=np.pi,
                dt=0.01)
        u_ref = -u_initial
        hs.append(discr.h)
        errors.append(integrate(discr, (u - u_ref)**2)**0.5)

    eoc, _ = np.polyfit(np.log(hs), np.log(errors), 1)
    assert eoc >= order - 0.1, eoc
Esempio n. 14
0
def test_accessing_dict_of_named_arrays_validation():
    x = pt.make_placeholder(name="x", shape=10, dtype=float)
    y1y2 = pt.make_dict_of_named_arrays({"y1": 2*x, "y2": 3*x})

    assert isinstance(y1y2["y1"], pt.array.NamedArray)
    assert y1y2["y1"].shape == (2*x).shape
    assert y1y2["y1"].dtype == (2*x).dtype
Esempio n. 15
0
def test_make_placeholder_noname():
    x = pt.make_placeholder("x", shape=(10, 4), dtype=float)
    y = 2*x

    knl = pt.generate_loopy(y).kernel

    assert x.name in knl.arg_dict
    assert x.name in knl.get_read_variables()
Esempio n. 16
0
def test_zero_length_arrays():
    x = pt.make_placeholder("x", shape=(0, 4), dtype=float)
    y = 2*x

    assert y.shape == (0, 4)

    knl = pt.generate_loopy(y).kernel
    assert all(dom.is_empty() for dom in knl.domains if dom.total_dim() != 0)
Esempio n. 17
0
def test_einsum_error_handling():
    with pytest.raises(ValueError):
        # operands not enough
        pt.einsum("ij,j->j", pt.make_placeholder("x", (2, 2), float))

    with pytest.raises(ValueError):
        # double index use in the out spec.
        pt.einsum("ij,j->jj", ("a", "b"))
Esempio n. 18
0
def test_stack_input_validation():
    x = pt.make_placeholder(name="x", shape=(10, 10), dtype=np.float64)
    y = pt.make_placeholder(name="y", shape=(1, 10), dtype=np.float64)

    assert pt.stack((x, x, x), axis=0).shape == (3, 10, 10)

    pt.stack((x,), axis=0)
    pt.stack((x,), axis=1)

    with pytest.raises(ValueError):
        pt.stack(())

    with pytest.raises(ValueError):
        pt.stack((x, y))

    with pytest.raises(ValueError):
        pt.stack((x, x), axis=3)
Esempio n. 19
0
def test_roll_input_validation():
    a = pt.make_placeholder(name="a", shape=(10, 10), dtype=np.float64)
    pt.roll(a, 1, axis=0)

    with pytest.raises(ValueError):
        pt.roll(a, 1, axis=2)

    with pytest.raises(ValueError):
        pt.roll(a, 1, axis=-1)
Esempio n. 20
0
def test_zero_length_arrays():
    ns = pt.Namespace()
    x = pt.make_placeholder(ns, shape=(0, 4), dtype=float)
    y = 2 * x

    assert y.shape == (0, 4)

    knl = pt.generate_loopy(y).program
    assert all(dom.is_empty() for dom in knl.domains if dom.total_dim() != 0)
Esempio n. 21
0
    def construct_intestine_graph(depth=100, seed=0):
        rng = default_rng(seed)
        x = pt.make_placeholder("x", shape=(10,), dtype=float)

        for _ in range(depth):
            coeff1, coeff2 = rng.integers(0, 10, 2)
            x = coeff1 * x + coeff2 * x

        return x
Esempio n. 22
0
def test_make_placeholder_noname():
    ns = pt.Namespace()
    x = pt.make_placeholder(ns, shape=(10, 4), dtype=float)
    y = 2 * x

    knl = pt.generate_loopy(y).program

    assert x.name in knl.arg_dict
    assert x.name in knl.get_read_variables()
Esempio n. 23
0
def test_dict_of_named_array_codegen_avoids_recomputation():
    ns = pt.Namespace()
    x = pt.make_placeholder(ns, shape=(10, 4), dtype=float, name="x")
    y = 2 * x
    z = y + 4 * x

    yz = pt.DictOfNamedArrays({"y": y, "z": z})

    knl = pt.generate_loopy(yz).program
    assert ("y" in knl.id_to_insn["z_store"].read_dependency_names())
Esempio n. 24
0
def test_dict_of_named_arrays_comparison():
    # See https://github.com/inducer/pytato/pull/137
    x = pt.make_placeholder("x", (10, 4), float)
    dict1 = pt.make_dict_of_named_arrays({"out": 2 * x})
    dict2 = pt.make_dict_of_named_arrays({"out": 2 * x})
    dict3 = pt.make_dict_of_named_arrays({"not_out": 2 * x})
    dict4 = pt.make_dict_of_named_arrays({"out": 3 * x})
    assert dict1 == dict2
    assert dict1 != dict3
    assert dict1 != dict4
Esempio n. 25
0
def test_reshape_input_validation():
    x = pt.make_placeholder("x", shape=(3, 3, 4), dtype=np.float64)

    assert pt.reshape(x, (-1,)).shape == (36,)
    assert pt.reshape(x, (-1, 6)).shape == (6, 6)
    assert pt.reshape(x, (4, -1)).shape == (4, 9)
    assert pt.reshape(x, (36, -1)).shape == (36, 1)

    with pytest.raises(ValueError):
        # 36 not a multiple of 25
        pt.reshape(x, (5, 5))

    with pytest.raises(ValueError):
        # 2 unknown dimensions
        pt.reshape(x, (-1, -1, 3))

    # Reporter by alexfikl
    # See https://github.com/inducer/pytato/issues/157
    x = pt.make_placeholder("x", shape=(0,), dtype=np.float64)
    assert pt.reshape(x, (128, 0, 17)).shape == (128, 0, 17)
Esempio n. 26
0
def test_tagging_array():
    from pytools.tag import Tag

    class BestArrayTag(Tag):
        """
        Best array known to humankind.
        """

    x = pt.make_placeholder(shape=(42, 1729), dtype=float, name="x")
    y = x.tagged(BestArrayTag())
    assert any(isinstance(tag, BestArrayTag) for tag in y.tags)
Esempio n. 27
0
def test_concatenate_input_validation():
    namespace = pt.Namespace()

    x = pt.make_placeholder(namespace, name="x", shape=(10, 10), dtype=np.float)
    y = pt.make_placeholder(namespace, name="y", shape=(1, 10), dtype=np.float)

    assert pt.concatenate((x, x, x), axis=0).shape == (30, 10)
    assert pt.concatenate((x, y), axis=0).shape == (11, 10)

    pt.concatenate((x,), axis=0)
    pt.concatenate((x,), axis=1)

    with pytest.raises(ValueError):
        pt.concatenate(())

    with pytest.raises(ValueError):
        pt.concatenate((x, y), axis=1)

    with pytest.raises(ValueError):
        pt.concatenate((x, x), axis=3)
Esempio n. 28
0
    def construct_intestine_graph(depth=100, seed=0):
        from numpy.random import default_rng
        rng = default_rng(seed)
        x = pt.make_placeholder("x", shape=(10,), dtype=float)
        y = x

        for _ in range(depth):
            coeff1, coeff2 = rng.integers(0, 10, 2)
            y = coeff1 * y + coeff2 * y

        return y, x
Esempio n. 29
0
def test_slice_input_validation():
    a = pt.make_placeholder(name="a", shape=(10, 10, 10), dtype=np.float64)

    a[0]
    a[0, 0]
    a[0, 0, 0]

    with pytest.raises(IndexError):
        a[0, 0, 0, 0]

    with pytest.raises(IndexError):
        a[10]
Esempio n. 30
0
def test_transpose_input_validation():
    a = pt.make_placeholder(name="a", shape=(10, 10), dtype=np.float64)
    pt.transpose(a)

    with pytest.raises(ValueError):
        pt.transpose(a, (2, 0, 1))

    with pytest.raises(ValueError):
        pt.transpose(a, (1, 1))

    with pytest.raises(ValueError):
        pt.transpose(a, (0,))