Added test for constants -- int, float, double, string, struct, vector.
This commit is contained in:
parent
54a0a95faf
commit
6fb55db69d
1 changed files with 299 additions and 0 deletions
299
test/constants.py
Executable file
299
test/constants.py
Executable file
|
|
@ -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()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue