[pypy-svn] r64597 - pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test
arigo at codespeak.net
arigo at codespeak.net
Thu Apr 23 16:50:20 CEST 2009
Author: arigo
Date: Thu Apr 23 16:50:19 2009
New Revision: 64597
Added:
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/conftest.py
- copied, changed from r63006, pypy/branch/oo-jit/pypy/jit/codegen/demo/conftest.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py
- copied, changed from r63006, pypy/branch/oo-jit/pypy/jit/codegen/demo/test_random.py
Log:
Random test. Running it with --backend=x86 quickly shows crashes
and/or real bugs.
Copied: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/conftest.py (from r63006, pypy/branch/oo-jit/pypy/jit/codegen/demo/conftest.py)
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/demo/conftest.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/conftest.py Thu Apr 23 16:50:19 2009
@@ -1,38 +1,27 @@
import py, random
-from pypy.jit.codegen.ppc import conftest
+option = py.test.config.option
-Option = py.test.config.Option
+class RandomRunnerPlugin:
+ def pytest_addoption(self, parser):
+ group = parser.addgroup('random test options')
+ group.addoption('--seed', action="store", type="int",
+ default=random.randrange(0, 10000),
+ dest="randomseed",
+ help="choose a fixed random seed")
+ group.addoption('--backend', action="store",
+ default='llgraph',
+ choices=['llgraph', 'minimal', 'x86'],
+ dest="backend",
+ help="select the backend to run the functions with")
+ group.addoption('--block-length', action="store", type="int",
+ default=30,
+ dest="block_length",
+ help="insert up to this many operations in each test")
+ group.addoption('--n-vars', action="store", type="int",
+ default=10,
+ dest="n_vars",
+ help="supply this many randomly-valued arguments to "
+ "the function")
-option = py.test.config.addoptions("demo options",
- Option('--seed', action="store", type="int",
- default=random.randrange(0, 10000),
- dest="randomseed",
- help="choose a fixed random seed"),
- Option('--backend', action="store",
- default='llgraph',
- choices=['llgraph', 'dump', 'ppc', 'i386', 'ia32', 'llvm',
- 'ppcfew'],
- dest="backend",
- help="select the backend to run the functions with"),
- Option('--nb-blocks', action="store", type="int",
- default=15,
- dest="nb_blocks",
- help="how many blocks to include in the random function"),
- Option('--max-block-length', action="store", type="int",
- default=20,
- dest="max_block_length",
- help="insert up to this many operations in each block"),
- Option('--n-vars', action="store", type="int",
- default=26,
- dest="n_vars",
- help="supply this many randomly-valued arguments to the function"),
- Option('--iterations', action="store", type="int",
- default=0,
- dest="iterations",
- help="run the loop of the generated function this many times - "
- "the default is backend dependent"),
- )
-
-very_slow_backends = {'llgraph': True,
- 'dump': True}
+ConftestPlugin = RandomRunnerPlugin
Copied: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py (from r63006, pypy/branch/oo-jit/pypy/jit/codegen/demo/test_random.py)
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/demo/test_random.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py Thu Apr 23 16:50:19 2009
@@ -1,100 +1,182 @@
-import py
-from pypy.rlib.rarithmetic import intmask
-from pypy.jit.codegen.demo.support import rundemo, Random, udir
-from pypy.jit.codegen.demo import conftest as demo_conftest
+import py, sys, math
+from pypy.rlib.rarithmetic import intmask, LONG_BIT
+from pypy.jit.backend.test import conftest as demo_conftest
+from pypy.jit.metainterp.history import TreeLoop, BoxInt, ConstInt
+from pypy.jit.metainterp.resoperation import ResOperation, rop
+from pypy.jit.metainterp.executor import execute
+
+
+class OperationBuilder:
+ def __init__(self, cpu, loop, vars):
+ self.cpu = cpu
+ self.loop = loop
+ self.vars = vars
+ self.boolvars = [] # subset of self.vars
+
+ def do(self, opnum, argboxes):
+ v_result = execute(self.cpu, opnum, argboxes)
+ v_result = BoxInt(v_result.value)
+ self.loop.operations.append(ResOperation(opnum, argboxes, v_result))
+ return v_result
+
+class AbstractOperation:
+ def __init__(self, opnum, boolres=False):
+ self.opnum = opnum
+ self.boolres = boolres
+ def put(self, builder, args):
+ v_result = builder.do(self.opnum, args)
+ builder.vars.append(v_result)
+ if self.boolres:
+ builder.boolvars.append(v_result)
+
+class UnaryOperation(AbstractOperation):
+ def produce_into(self, builder, r):
+ self.put(builder, [r.choice(builder.vars)])
+
+class BooleanUnaryOperation(UnaryOperation):
+ def produce_into(self, builder, r):
+ if builder.boolvars:
+ v = r.choice(builder.boolvars)
+ else:
+ v = r.choice(builder.vars)
+ v = builder.do(rop.INT_IS_TRUE, [v])
+ self.put(builder, [v])
+
+class BinaryOperation(AbstractOperation):
+ def __init__(self, opnum, and_mask=-1, or_mask=0, boolres=False):
+ AbstractOperation.__init__(self, opnum, boolres=boolres)
+ self.and_mask = and_mask
+ self.or_mask = or_mask
+ def produce_into(self, builder, r):
+ k = r.random()
+ if k < 0.2:
+ v_first = ConstInt(r.random_integer())
+ else:
+ v_first = r.choice(builder.vars)
+ if k > 0.75:
+ value = r.random_integer()
+ v_second = ConstInt((value & self.and_mask) | self.or_mask)
+ else:
+ v = r.choice(builder.vars)
+ if self.and_mask != 1:
+ v = builder.do(rop.INT_AND, [v, ConstInt(self.and_mask)])
+ if self.or_mask != 0:
+ v = builder.do(rop.INT_OR, [v, ConstInt(self.or_mask)])
+ v_second = v
+ self.put(builder, [v_first, v_second])
+
+OPERATIONS = []
+
+for _op in [rop.INT_ADD,
+ rop.INT_SUB,
+ rop.INT_MUL,
+ rop.INT_AND,
+ rop.INT_OR,
+ rop.INT_XOR,
+ rop.UINT_MUL,
+ ]:
+ OPERATIONS.append(BinaryOperation(_op))
+
+for _op in [rop.INT_LT,
+ rop.INT_LE,
+ rop.INT_EQ,
+ rop.INT_NE,
+ rop.INT_GT,
+ rop.INT_GE,
+ rop.UINT_LT,
+ rop.UINT_LE,
+ #rop.UINT_EQ,
+ #rop.UINT_NE,
+ rop.UINT_GT,
+ rop.UINT_GE,
+ ]:
+ OPERATIONS.append(BinaryOperation(_op, boolres=True))
+
+OPERATIONS.append(BinaryOperation(rop.INT_FLOORDIV, ~3, 1))
+OPERATIONS.append(BinaryOperation(rop.INT_MOD, ~3, 1))
+OPERATIONS.append(BinaryOperation(rop.INT_RSHIFT, LONG_BIT-1))
+OPERATIONS.append(BinaryOperation(rop.INT_LSHIFT, LONG_BIT-1))
+OPERATIONS.append(BinaryOperation(rop.UINT_RSHIFT, LONG_BIT-1))
+
+for _op in [rop.INT_NEG,
+ rop.INT_INVERT,
+ rop.INT_ABS,
+ ]:
+ OPERATIONS.append(UnaryOperation(_op))
+
+OPERATIONS.append(UnaryOperation(rop.INT_IS_TRUE, boolres=True))
+OPERATIONS.append(BooleanUnaryOperation(rop.BOOL_NOT, boolres=True))
+
+# ____________________________________________________________
+
+def Random():
+ import random
+ seed = demo_conftest.option.randomseed
+ print
+ print 'Random seed value is %d.' % (seed,)
+ print
+ r = random.Random(seed)
+ def get_random_integer():
+ while True:
+ result = int(random.expovariate(0.05))
+ if result <= sys.maxint:
+ break
+ if random.randrange(0, 5) <= 1:
+ result = -result
+ return result
+ r.random_integer = get_random_integer
+ return r
+
+def get_cpu():
+ if demo_conftest.option.backend == 'llgraph':
+ from pypy.jit.backend.llgraph.runner import LLtypeCPU
+ return LLtypeCPU(None)
+ elif demo_conftest.option.backend == 'minimal':
+ from pypy.jit.backend.minimal.runner import CPU
+ return CPU(None)
+ elif demo_conftest.option.backend == 'x86':
+ from pypy.jit.backend.x86.runner import CPU386
+ return CPU386(None, None)
+ else:
+ assert 0, "unknown backend %r" % demo_conftest.option.backend
+# ____________________________________________________________
-def test_random_function(nb_blocks=demo_conftest.option.nb_blocks,
- max_block_length=demo_conftest.option.max_block_length):
- #py.test.skip("in-progress")
- blocklabels = range(nb_blocks)
+def test_random_function():
r = Random()
- vars = list("abcdefghijklmnopqrstuvwxyz"[:demo_conftest.option.n_vars])
- varlist = ', '.join(vars)
- magicsum = '+'.join(['%s*%d' % (v, hash(v)) for v in vars])
- operations = ['%s + %s',
- '%s + %s',
- '%s - %s',
- '%s - %s',
- '%s * %s',
- '%s & %s',
- '%s | %s',
- '%s ^ %s',
- '%s << (%s & 0x0000067f)',
- '%s >> (%s & 0x1234567f)',
- 'abs(%s)',
- '-%s',
- '~%s',
- '%s // ((%s & 0xfffff) + 1)',
- '%s // (-((%s & 0xfffff) + 2))',
- '%s %% ((%s & 0xfffff) + 1)',
- '%s %% (-((%s & 0xfffff) + 2))',
- '!%s or %s',
- '!%s and %s',
- '!not %s',
- '!bool(%s)',
- '!%s < %s',
- '!%s <= %s',
- '!%s == %s',
- '!%s != %s',
- '!%s > %s',
- '!%s >= %s',
- ]
- lines = ["def dummyfn(counter, %(varlist)s):" % locals(),
- " goto = 0",
- " while True:",
- ]
- for blocklabel in blocklabels:
- lines.append(" if goto == %d:" % blocklabel)
- for j in range(r.randrange(0, max_block_length)):
- v1 = r.choice(vars)
- constbytes = r.randrange(-15, 5)
- if constbytes <= 0:
- v2 = r.choice(vars)
- op = r.choice(operations)
- if op.count('%s') == 1:
- op = op % (v2,)
- else:
- v3 = r.choice(vars)
- op = op % (v2, v3)
- if op.startswith('!'):
- op = op[1:]
- else:
- op = 'intmask(%s)' % op
- lines.append(" %s = %s" % (v1, op))
- else:
- constant = r.randrange(-128, 128)
- for i in range(1, constbytes):
- constant = constant << 8 | r.randrange(0, 256)
- lines.append(" %s = %d" % (v1, constant))
- v1 = r.choice(vars)
- for line in [" if %s:" % v1,
- " else:"]:
- lines.append(line)
- j = r.choice(blocklabels)
- if j <= blocklabel:
- lines.append(" counter -= 1")
- lines.append(" if not counter: break")
- lines.append(" goto = %d" % j)
- lines.append(" return intmask(%(magicsum)s)" % locals())
-
- args = [r.randrange(-99, 100) for v1 in vars]
-
- src = py.code.Source('\n'.join(lines))
- print src
- udir.join('generated.py').write(
- 'from pypy.rlib.rarithmetic import intmask\n\n'
- '%s\n\n'
- 'args=%r\n'
- 'print dummyfn(10000, *args)\n' % (src, args))
- exec src.compile()
-
- if demo_conftest.option.iterations != 0:
- iterations = demo_conftest.option.iterations
- else:
- if demo_conftest.option.backend in demo_conftest.very_slow_backends:
- iterations = 50
+ block_length = demo_conftest.option.block_length
+ vars = [BoxInt(r.random_integer())
+ for i in range(demo_conftest.option.n_vars)]
+ valueboxes = [BoxInt(box.value) for box in vars]
+
+ cpu = get_cpu()
+ loop = TreeLoop('test_random_function')
+ loop.inputargs = vars[:]
+ loop.operations = []
+
+ builder = OperationBuilder(cpu, loop, vars)
+
+ for i in range(block_length):
+ r.choice(OPERATIONS).produce_into(builder, r)
+
+ endvars = []
+ for v in vars:
+ for op in loop.operations:
+ if v in op.args:
+ break
else:
- iterations = 10000
+ endvars.append(v)
+ r.shuffle(endvars)
+ loop.operations.append(ResOperation(rop.FAIL, endvars, None))
+
+ cpu.compile_operations(loop)
+
+ expected = {}
+ for v in endvars:
+ expected[v] = v.value
+ v.changevalue_int(-sys.maxint-1)
+
+ cpu.execute_operations(loop, valueboxes)
- rundemo(dummyfn, iterations, *args)
+ for v in endvars:
+ assert v.value == expected[v]
More information about the Pypy-commit
mailing list