def test_codegen_with_DictOfNamedArrays(ctx_factory): # noqa ctx = ctx_factory() queue = cl.CommandQueue(ctx) namespace = pt.Namespace() x = Placeholder(namespace, "x", (5, ), np.int) y = Placeholder(namespace, "y", (5, ), np.int) x_in = np.array([1, 2, 3, 4, 5]) y_in = np.array([6, 7, 8, 9, 10]) result = pt.DictOfNamedArrays(dict(x_out=x, y_out=y)) # Without return_dict. prog = pt.generate_loopy(result, target=pt.PyOpenCLTarget(queue)) _, (x_out, y_out) = prog(x=x_in, y=y_in) assert (x_out == x_in).all() assert (y_out == y_in).all() # With return_dict. prog = pt.generate_loopy(result, target=pt.PyOpenCLTarget(queue), options=lp.Options(return_dict=True)) _, outputs = prog(x=x_in, y=y_in) assert (outputs["x_out"] == x_in).all() assert (outputs["y_out"] == y_in).all()
def test_unary_arith(ctx_factory, which): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) op = getattr(operator, which) x_orig = np.array([1, 2, 3, 4, 5]) namespace = pt.Namespace() exprs = {} for dtype in ARITH_DTYPES: exprs[dtype] = op(pt.make_data_wrapper(namespace, x_orig.astype(dtype))) prog = pt.generate_loopy(pt.make_dict_of_named_arrays(exprs), target=pt.PyOpenCLTarget(queue), options=lp.Options(return_dict=True)) _, outputs = prog() for dtype in ARITH_DTYPES: out = outputs[dtype] out_ref = op(x_orig.astype(dtype)) assert out.dtype == out_ref.dtype assert np.array_equal(out, out_ref)
def test_scalar_array_binary_arith(ctx_factory, which, reverse): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) op = getattr(operator, which) if reverse: op = reverse_args(op) x_orig = 7 y_orig = np.array([1, 2, 3, 4, 5]) for first_dtype in (int, float, complex): namespace = pt.Namespace() x_in = first_dtype(x_orig) exprs = {} for dtype in ARITH_DTYPES: y = pt.make_data_wrapper(namespace, y_orig.astype(dtype), name=f"y{dtype}") exprs[dtype] = op(x_in, y) prog = pt.generate_loopy(pt.make_dict_of_named_arrays(exprs), target=pt.PyOpenCLTarget(queue), options=lp.Options(return_dict=True)) _, outputs = prog() for dtype in exprs: out = outputs[dtype] out_ref = op(x_in, y_orig.astype(dtype)) assert out.dtype == out_ref.dtype, (out.dtype, out_ref.dtype) # In some cases ops are done in float32 in loopy but float64 in numpy. assert np.allclose(out, out_ref), (out, out_ref)
def test_slice(ctx_factory, shape): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) from numpy.random import default_rng rng = default_rng() x_in = rng.random(size=shape) namespace = pt.Namespace() x = pt.make_data_wrapper(namespace, x_in) outputs = {} ref_outputs = {} i = 0 for slice_ in generate_test_slices(shape): outputs[f"out_{i}"] = x[slice_] ref_outputs[f"out_{i}"] = x_in[slice_] i += 1 prog = pt.generate_loopy(pt.make_dict_of_named_arrays(outputs), target=pt.PyOpenCLTarget(queue), options=lp.Options(return_dict=True)) _, outputs = prog() for output in outputs: x_out = outputs[output] x_ref = ref_outputs[output] assert (x_out == x_ref).all()
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])
def test_basic_codegen(ctx_factory): ctx = ctx_factory() queue = cl.CommandQueue(ctx) namespace = pt.Namespace() x = Placeholder(namespace, "x", (5, ), np.int) prog = pt.generate_loopy(x * x, target=pt.PyOpenCLTarget(queue)) x_in = np.array([1, 2, 3, 4, 5]) _, (out, ) = prog(x=x_in) assert (out == x_in * x_in).all()
def test_scalar_placeholder(ctx_factory): ctx = ctx_factory() queue = cl.CommandQueue(ctx) namespace = pt.Namespace() x = Placeholder(namespace, "x", (), np.int) prog = pt.generate_loopy(x, target=pt.PyOpenCLTarget(queue)) x_in = np.array(1) _, (x_out, ) = prog(x=x_in) assert np.array_equal(x_out, x_in)
def test_data_wrapper(ctx_factory): ctx = ctx_factory() queue = cl.CommandQueue(ctx) # Without name/shape namespace = pt.Namespace() x_in = np.array([1, 2, 3, 4, 5]) x = pt.make_data_wrapper(namespace, x_in) prog = pt.generate_loopy(x, target=pt.PyOpenCLTarget(queue)) _, (x_out, ) = prog() assert (x_out == x_in).all() # With name/shape namespace = pt.Namespace() x_in = np.array([[1, 2], [3, 4], [5, 6]]) pt.make_size_param(namespace, "n") x = pt.make_data_wrapper(namespace, x_in, name="x", shape="(n, 2)") prog = pt.generate_loopy(x, target=pt.PyOpenCLTarget(queue)) _, (x_out, ) = prog() assert (x_out == x_in).all()
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
def test_transpose(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) shape = (2, 8) from numpy.random import default_rng rng = default_rng() x_in = rng.random(size=shape) namespace = pt.Namespace() x = pt.make_data_wrapper(namespace, x_in) prog = pt.generate_loopy(x.T, target=pt.PyOpenCLTarget(queue)) _, (x_out,) = prog() assert (x_out == x_in.T).all()
def test_roll(ctx_factory, shift, axis): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) namespace = pt.Namespace() pt.make_size_param(namespace, "n") x = pt.make_placeholder(namespace, name="x", shape=("n", "n"), dtype=np.float) prog = pt.generate_loopy( pt.roll(x, shift=shift, axis=axis), target=pt.PyOpenCLTarget(queue)) x_in = np.arange(1., 10.).reshape(3, 3) _, (x_out,) = prog(x=x_in) assert (x_out == np.roll(x_in, shift=shift, axis=axis)).all()
def test_matmul(ctx_factory, x1_ndim, x2_ndim): ctx = ctx_factory() queue = cl.CommandQueue(ctx) def get_array(ndim): arr = np.array([[1, 2], [3, 4]]) return arr[(0, ) * (arr.ndim - ndim)] x1_in = get_array(x1_ndim) x2_in = get_array(x2_ndim) namespace = pt.Namespace() x1 = pt.make_data_wrapper(namespace, x1_in) x2 = pt.make_data_wrapper(namespace, x2_in) prog = pt.generate_loopy(x1 @ x2, target=pt.PyOpenCLTarget(queue)) _, (out, ) = prog() assert (out == x1_in @ x2_in).all()
def test_axis_permutation(ctx_factory, axes): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) ndim = len(axes) shape = (3, 4, 5)[:ndim] from numpy.random import default_rng rng = default_rng() x_in = rng.random(size=shape) namespace = pt.Namespace() x = pt.make_data_wrapper(namespace, x_in) prog = pt.generate_loopy( pt.transpose(x, axes), target=pt.PyOpenCLTarget(queue)) _, (x_out,) = prog() assert (x_out == np.transpose(x_in, axes)).all()
def assert_allclose_to_numpy(expr: Array, queue: cl.CommandQueue, parameters: Dict[Placeholder, Any] = {}): """ Raises an :class:`AssertionError`, if there is a discrepancy between *expr* evaluated lazily via :mod:`pytato` and eagerly via :mod:`numpy`. :arg queue: An instance of :class:`pyopencl.CommandQueue` to which the generated kernel must be enqueued. """ np_result = NumpyBasedEvaluator(numpy, expr.namespace, parameters)(expr) prog = pt.generate_loopy(expr, target=pt.PyOpenCLTarget(queue)) evt, (pt_result, ) = prog( **{placeholder.name: data for placeholder, data in parameters.items()}) assert pt_result.shape == np_result.shape assert pt_result.dtype == np_result.dtype numpy.testing.assert_allclose(np_result, pt_result)
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) u_initial = np.sin(discr.nodes()) 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=flux_type, dg_ops=DGOps1D(discr, ns)) result = op.apply(u) prog = pt.generate_loopy(result, target=pt.PyOpenCLTarget(queue)) u = rk4( lambda t, y: prog(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
def test_array_array_binary_arith(ctx_factory, which, reverse): if which == "sub": pytest.skip("https://github.com/inducer/loopy/issues/131") cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) op = getattr(operator, which) if reverse: op = reverse_args(op) x_orig = np.array([1, 2, 3, 4, 5]) y_orig = np.array([10, 9, 8, 7, 6]) for first_dtype in ARITH_DTYPES: namespace = pt.Namespace() x_in = x_orig.astype(first_dtype) x = pt.make_data_wrapper(namespace, x_in, name="x") exprs = {} for dtype in ARITH_DTYPES: y = pt.make_data_wrapper(namespace, y_orig.astype(dtype), name=f"y{dtype}") exprs[dtype] = op(x, y) prog = pt.generate_loopy(pt.make_dict_of_named_arrays(exprs), target=pt.PyOpenCLTarget(queue), options=lp.Options(return_dict=True)) _, outputs = prog() for dtype in ARITH_DTYPES: out = outputs[dtype] out_ref = op(x_in, y_orig.astype(dtype)) assert out.dtype == out_ref.dtype, (out.dtype, out_ref.dtype) # In some cases ops are done in float32 in loopy but float64 in numpy. assert np.allclose(out, out_ref), (out, out_ref)
def test_stack(ctx_factory, input_dims): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) shape = (2, 2, 2)[:input_dims] from numpy.random import default_rng rng = default_rng() x_in = rng.random(size=shape) y_in = rng.random(size=shape) namespace = pt.Namespace() x = pt.make_data_wrapper(namespace, x_in) y = pt.make_data_wrapper(namespace, y_in) for axis in range(0, 1 + input_dims): prog = pt.generate_loopy( pt.stack((x, y), axis=axis), target=pt.PyOpenCLTarget(queue)) _, (out,) = prog() assert (out == np.stack((x_in, y_in), axis=axis)).all()