diff --git a/loopy/codegen/__init__.py b/loopy/codegen/__init__.py index 537e821aafd5583b946dda24679eb4d4c13139e6..142a78fa55a6c9fdb4b1b6ac4e6a29824687fa67 100644 --- a/loopy/codegen/__init__.py +++ b/loopy/codegen/__init__.py @@ -336,6 +336,11 @@ def generate_code(kernel, with_annotation=False, # {{{ handle preambles + for arg in kernel.args: + seen_dtypes.add(arg.dtype) + for tv in kernel.temporary_variables: + seen_dtypes.add(tv.dtype) + preambles = kernel.preambles[:] for prea_gen in kernel.preamble_generators: preambles.extend(prea_gen(seen_dtypes, seen_functions)) diff --git a/loopy/codegen/expression.py b/loopy/codegen/expression.py index e522b792934bac5c1b77b42e7aa8626b25de0baf..22f9624d15fffb28ea109e7f64caca3753cc993d 100644 --- a/loopy/codegen/expression.py +++ b/loopy/codegen/expression.py @@ -294,11 +294,9 @@ class LoopyCCodeMapper(CCodeMapper): if isinstance(expr, complex): # FIXME: type-variable return "(cdouble_t) (%s, %s)" % (repr(expr.real), repr(expr.imag)) - elif isinstance(expr, float): - # FIXME: type-variable - return "%s" % repr(expr) else: - return CCodeMapper.map_constant(self, expr, enclosing_prec) + # FIXME: type-variable + return repr(float(expr)) def map_call(self, expr, enclosing_prec): from pymbolic.primitives import Variable diff --git a/test/test_loopy.py b/test/test_loopy.py index e07854b7c1ccbfd2317e72e4ba95c4845e7470a0..015468497d90e29b26c57a09d756869bf382b68b 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 + + + + + def test_empty_reduction(ctx_factory): dtype = np.dtype(np.float32)