From bfbc8ee3dd0be72dc5c1c2ea3735a94022aa108b Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Sun, 15 Jul 2012 16:28:26 -0400 Subject: [PATCH] Add expression fuzzing test, to check code generation. --- test/test_loopy.py | 97 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/test/test_loopy.py b/test/test_loopy.py index a40a157f4..e964f6013 100644 --- a/test/test_loopy.py +++ b/test/test_loopy.py @@ -180,6 +180,103 @@ def test_argmax(ctx_factory): +def make_random_value(): + from random import randrange, uniform + v = randrange(3) + if v == 0: + while True: + z = randrange(-1000, 1000) + if z: + return z + + elif v == 1: + return uniform(-10, 10) + else: + return uniform(-10, 10) + 1j*uniform(-10, 10) + + + + +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: + return make_random_expression(var_values, size) - make_random_expression(var_values, size) + elif v < 1500: + return make_random_expression(var_values, size) / make_random_expression(var_values, size) + + +def generate_random_fuzz_examples(): + for i in xrange(20): + size = [0] + var_values = {} + expr = make_random_expression(var_values, size) + yield expr, var_values + +def test_fuzz_code_generator(ctx_factory): + ctx = ctx_factory() + queue = cl.CommandQueue(ctx) + + from expr_fuzz import get_fuzz_examples + for expr, var_values in generate_random_fuzz_examples(): + #for expr, var_values in get_fuzz_examples(): + from pymbolic import evaluate + true_value = evaluate(expr, var_values) + + def get_dtype(x): + if isinstance(x, complex): + return np.complex128 + else: + return np.float64 + + knl = lp.make_kernel(ctx.devices[0], "{ : }", + [lp.Instruction(None, "value", expr)], + [lp.GlobalArg("value", np.complex128, shape=())] + + [ + lp.ScalarArg(name, get_dtype(val)) + for name, val in var_values.iteritems() + ]) + ck = lp.CompiledKernel(ctx, knl) + evt, (lp_value,) = ck(queue, **var_values) + err = abs(true_value-lp_value)/abs(true_value) + if abs(err) > 1e-10: + print "---------------------------------------------------------------------" + print "WRONG: rel error=%g" % err + print "true=%r" % true_value + print "loopy=%r" % lp_value + print "---------------------------------------------------------------------" + print ck.code + print "---------------------------------------------------------------------" + print var_values + print "---------------------------------------------------------------------" + print repr(expr) + print "---------------------------------------------------------------------" + print expr + print "---------------------------------------------------------------------" + 1/0 + + + + + if __name__ == "__main__": import sys -- GitLab