From 6fb55db69d3bba737ff893ed971d155950d266ea Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Mon, 23 Jul 2012 13:05:11 -0700 Subject: [PATCH] Added test for constants -- int, float, double, string, struct, vector. --- test/constants.py | 299 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100755 test/constants.py diff --git a/test/constants.py b/test/constants.py new file mode 100755 index 0000000..4a2e543 --- /dev/null +++ b/test/constants.py @@ -0,0 +1,299 @@ +#! /usr/bin/env python + +''' +Test and stress Constants. +''' + +from llvm.core import * +from llvm.ee import * +from ctypes import * + +import unittest, logging + +# logging.basicConfig(level=logging.DEBUG) + +def _build_test_module(datatype, constants): + mod = Module.new('module_test_const_%s' % datatype) + fnty_callback = Type.function(Type.void(), [datatype]) + fnty_subject = Type.function(Type.void(), [Type.pointer(fnty_callback)]) + func_subject = mod.add_function(fnty_subject, 'test_const_%s' % datatype) + + bb_entry = func_subject.append_basic_block('entry') + builder = Builder.new(bb_entry) + + + + for k in constants: + builder.call(func_subject.args[0], [k]) + + builder.ret_void() + + func_subject.verify() + + return mod, func_subject + +def _build_test_module_array(datatype, constants): + mod = Module.new('module_test_const_%s' % datatype) + fnty_callback = Type.function(Type.void(), [datatype]) + fnty_subject = Type.function(Type.void(), [Type.pointer(fnty_callback)]) + func_subject = mod.add_function(fnty_subject, 'test_const_%s' % datatype) + + bb_entry = func_subject.append_basic_block('entry') + builder = Builder.new(bb_entry) + + + for k in constants: + ptr = builder.alloca(k.type) + builder.store(k, ptr) + builder.call(func_subject.args[0], + [builder.gep(ptr, [Constant.int(Type.int(), 0)]*2)]) + + builder.ret_void() + + func_subject.verify() + + return mod, func_subject + +def _build_test_module_struct(datatype, constants): + mod = Module.new('module_test_const_%s' % datatype) + fnty_callback = Type.function(Type.void(), [datatype]) + fnty_subject = Type.function(Type.void(), [Type.pointer(fnty_callback)]) + func_subject = mod.add_function(fnty_subject, 'test_const_%s' % datatype) + + bb_entry = func_subject.append_basic_block('entry') + builder = Builder.new(bb_entry) + + for k in constants: + ptr = builder.alloca(k.type) + builder.store(k, ptr) + builder.call(func_subject.args[0], [ptr]) + + builder.ret_void() + + func_subject.verify() + + return mod, func_subject + +class TestConstants(unittest.TestCase): + def test_const_int(self): + from random import randint + values = [0, -1, 1, 0xfffffffe, 0xffffffff, 0x100000000] + values += [randint(0, 0xffffffff) for x in range(100)] + + constant_list = map(lambda X: Constant.int(Type.int(), X), values) + mod, func_subject = _build_test_module(Type.int(), constant_list) + + # done function generation + logging.debug(func_subject) + + # prepare execution + ee = ExecutionEngine.new(mod) + + cf_callback = CFUNCTYPE(None, c_uint32) + cf_test = CFUNCTYPE(None, cf_callback) + + test_subject = cf_test(ee.get_pointer_to_function(func_subject)) + + # setup callback + results = [] + def callback(value): + results.append(value) + + test_subject(cf_callback(callback)) + + # check result + for result, golden in zip(results, values): + self.assertEqual(result, golden & 0xffffffff) + + def test_const_float(self): + from random import random + values = [0., 1., -1.] + [random() for x in range(100)] + + constant_list = map(lambda X: Constant.real(Type.float(), X), values) + mod, func_subject = _build_test_module(Type.float(), constant_list) + + # done function generation + logging.debug(func_subject) + + # prepare execution + ee = ExecutionEngine.new(mod) + + cf_callback = CFUNCTYPE(None, c_float) + cf_test = CFUNCTYPE(None, cf_callback) + + test_subject = cf_test(ee.get_pointer_to_function(func_subject)) + + # setup callback + results = [] + def callback(value): + results.append(value) + + test_subject(cf_callback(callback)) + + # check result + for result, golden in zip(results, values): + if golden == 0: + self.assertEqual(result, golden) + else: + self.assertLess(abs(result-golden)/golden, 1e-7) + + def test_const_double(self): + from random import random + values = [0., 1., -1.] + [random() for x in range(100)] + + constant_list = map(lambda X: Constant.real(Type.double(), X), values) + mod, func_subject = _build_test_module(Type.double(), constant_list) + + # done function generation + logging.debug(func_subject) + + # prepare execution + ee = ExecutionEngine.new(mod) + + cf_callback = CFUNCTYPE(None, c_double) + cf_test = CFUNCTYPE(None, cf_callback) + + test_subject = cf_test(ee.get_pointer_to_function(func_subject)) + + # setup callback + results = [] + def callback(value): + results.append(value) + + test_subject(cf_callback(callback)) + + # check result + for result, golden in zip(results, values): + self.assertEqual(result, golden) + + def test_const_string(self): + values = ["hello", "world", "", "\n"] + + constant_list = map(Constant.stringz, values) + mod, func_subject = _build_test_module_array(Type.pointer(Type.int(8)), + constant_list) + + # done function generation + logging.debug(func_subject) + + # prepare execution + ee = ExecutionEngine.new(mod) + + cf_callback = CFUNCTYPE(None, c_char_p) + cf_test = CFUNCTYPE(None, cf_callback) + + test_subject = cf_test(ee.get_pointer_to_function(func_subject)) + + # setup callback + results = [] + def callback(value): + results.append(value) + + test_subject(cf_callback(callback)) + + # check result + for result, golden in zip(results, values): + self.assertEqual(result, golden) + + def test_const_struct(self): + from random import randint, random + values = [ + (0, 0., 0.), + (-1, -1., -1.), + (1, 1., 1.), + ] + [(randint(0, 0xffffffff), random(), random()) for _ in xrange(100)] + + struct_type = Type.struct([Type.int(), Type.float(), Type.double()]) + + def map_constant(packed_values): + vi, vf, vd = packed_values + return Constant.struct([ + Constant.int(Type.int(), vi), + Constant.real(Type.float(), vf), + Constant.real(Type.double(), vd), + ]) + + constant_list = map(map_constant, values) + + mod, func_subject = _build_test_module_struct(Type.pointer(struct_type), + constant_list) + + # done function generation + logging.debug(func_subject) + + # prepare execution + ee = ExecutionEngine.new(mod) + + class c_struct_type(Structure): + _fields_ = [ ('vi', c_uint32), + ('vf', c_float), + ('vd', c_double), ] + + def __iter__(self): + return iter([self.vi, self.vf, self.vd]) + + cf_callback = CFUNCTYPE(None, POINTER(c_struct_type)) + cf_test = CFUNCTYPE(None, cf_callback) + + test_subject = cf_test(ee.get_pointer_to_function(func_subject)) + + # setup callback + results = [] + def callback(value): + results.append(tuple(value[0])) + + test_subject(cf_callback(callback)) + + # check result + for result, golden in zip(results, values): + self.assertEqual(result[0], golden[0] & 0xffffffff) + if golden[1] == 0: + self.assertEqual(result[1], golden[1]) + else: + self.assertLess(abs(result[1]-golden[1])/golden[1], 1e-7) + self.assertEqual(result[2], golden[2]) + + def test_const_vector(self): + from random import randint + randgen = lambda: randint(0, 0xffffffff) + values = [ + (0, 0, 0, 0), + (1, 1, 1, 1), + (-1, -1, -1, -1), + ] + [ (randgen(), randgen(), randgen(), randgen()) for _ in xrange(100) ] + + def map_constant(packed_values): + consts = [ Constant.int(Type.int(), i) for i in packed_values ] + return Constant.vector(consts) + + constant_list = map(map_constant, values) + mod, func_subject = _build_test_module_array(Type.pointer(Type.int()), + constant_list) + + # done function generation + logging.debug(func_subject) + + # prepare execution + ee = ExecutionEngine.new(mod) + + cf_callback = CFUNCTYPE(None, POINTER(c_uint32)) + cf_test = CFUNCTYPE(None, cf_callback) + + test_subject = cf_test(ee.get_pointer_to_function(func_subject)) + + # setup callback + results = [] + def callback(value): + results.append(tuple(value[0:4])) + + test_subject(cf_callback(callback)) + + # check result + for result, golden in zip(results, values): + self.assertEqual(result, + tuple(map(lambda X: X & 0xffffffff, golden))) + + +if __name__ == '__main__': + unittest.main() +