[pypy-commit] pypy numpy-minilang: progress on supporting strange language for test_zjit
fijal
noreply at buildbot.pypy.org
Thu Oct 27 22:31:30 CEST 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-minilang
Changeset: r48539:ced3b41aaacb
Date: 2011-10-27 22:07 +0200
http://bitbucket.org/pypy/pypy/changeset/ced3b41aaacb/
Log: progress on supporting strange language for test_zjit
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -4,8 +4,8 @@
"""
from pypy.interpreter.baseobjspace import InternalSpaceCache, W_Root
-from pypy.module.micronumpy.interp_dtype import W_Float64Dtype
-from pypy.module.micronumpy.interp_numarray import Scalar, SingleDimArray, BaseArray
+from pypy.module.micronumpy.interp_dtype import W_Float64Dtype, W_Int32Dtype
+from pypy.module.micronumpy.interp_numarray import Scalar, BaseArray, descr_new_array
from pypy.rlib.objectmodel import specialize
@@ -21,13 +21,20 @@
class FakeSpace(object):
w_ValueError = None
w_TypeError = None
+ w_None = None
+
+ w_bool = "bool"
+ w_int = "int"
+ w_float = "float"
+ w_list = "list"
+ w_long = "long"
def __init__(self):
"""NOT_RPYTHON"""
self.fromcache = InternalSpaceCache(self).getorbuild
def issequence_w(self, w_obj):
- return True
+ return w_obj.seq
@specialize.argtype(1)
def wrap(self, obj):
@@ -39,6 +46,13 @@
return IntObject(obj)
raise Exception
+ def newlist(self, items):
+ return ListObject(items)
+
+ def listview(self, obj):
+ assert isinstance(obj, ListObject)
+ return obj.items
+
def float(self, w_obj):
assert isinstance(w_obj, FloatObject)
return w_obj
@@ -46,23 +60,243 @@
def float_w(self, w_obj):
return w_obj.floatval
+ def is_w(self, w_obj, w_what):
+ return w_obj is w_what
+
+ def type(self, w_obj):
+ return w_obj.tp
+
+ def gettypefor(self, w_obj):
+ return None
+
+ def call_function(self, tp, w_dtype):
+ return w_dtype
+
+ @specialize.arg(1)
+ def interp_w(self, tp, what):
+ return what
class FloatObject(W_Root):
+ seq = False
+ tp = FakeSpace.w_float
def __init__(self, floatval):
self.floatval = floatval
class BoolObject(W_Root):
+ seq = False
+ tp = FakeSpace.w_bool
def __init__(self, boolval):
self.boolval = boolval
class IntObject(W_Root):
+ seq = False
+ tp = FakeSpace.w_int
def __init__(self, intval):
self.intval = intval
+class ListObject(W_Root):
+ seq = True
+ tp = FakeSpace.w_list
+ def __init__(self, items):
+ self.items = items
+
space = FakeSpace()
-def numpy_compile(bytecode, array_size):
+class InterpreterState(object):
+ def __init__(self, code):
+ self.code = code
+ self.variables = {}
+ self.results = []
+
+ def run(self, space):
+ self.space = space
+ for stmt in self.code.statements:
+ stmt.execute(self)
+
+class Node(object):
+ def __eq__(self, other):
+ return (self.__class__ == other.__class__ and
+ self.__dict__ == other.__dict__)
+
+ def __ne__(self, other):
+ return not self == other
+
+ def wrap(self, space):
+ raise NotImplementedError
+
+ def execute(self, interp):
+ raise NotImplementedError
+
+class Assignment(Node):
+ def __init__(self, id, expr):
+ self.id = id
+ self.expr = expr
+
+ def execute(self, interp):
+ interp.variables[self.id.name] = self.expr.execute(interp)
+
+ def __repr__(self):
+ return "%r = %r" % (self.id, self.expr)
+
+class Variable(Node):
+ def __init__(self, name):
+ self.name = name
+
+ def execute(self, interp):
+ return interp.variables[self.name]
+
+ def __repr__(self):
+ return 'v(%s)' % self.name
+
+class Operator(Node):
+ def __init__(self, lhs, name, rhs):
+ self.name = name
+ self.lhs = lhs
+ self.rhs = rhs
+
+ def execute(self, interp):
+ if self.name == '+':
+ w_lhs = self.lhs.execute(interp)
+ w_rhs = self.rhs.execute(interp)
+ return w_lhs.descr_add(interp.space, w_rhs)
+ elif self.name == '->':
+ w_lhs = self.lhs.execute(interp)
+ w_rhs = self.rhs.execute(interp)
+ if isinstance(w_rhs, Scalar):
+ index = int(space.float_w(w_rhs.value.wrap(interp.space)))
+ return w_lhs.get_concrete().eval(index)
+ else:
+ xxx
+
+ def __repr__(self):
+ return '(%r %s %r)' % (self.lhs, self.name, self.rhs)
+
+class FloatConstant(Node):
+ def __init__(self, v):
+ self.v = float(v)
+
+ def __repr__(self):
+ return "Const(%s)" % self.v
+
+ def wrap(self, space):
+ return space.wrap(self.v)
+
+ def execute(self, interp):
+ dtype = interp.space.fromcache(W_Float64Dtype)
+ return Scalar(dtype, dtype.box(self.v))
+
+class RangeConstant(Node):
+ def __init__(self, v):
+ self.v = int(v)
+
+ def __repr__(self):
+ return 'Range(%s)' % self.v
+
+class Code(Node):
+ def __init__(self, statements):
+ self.statements = statements
+
+ def __repr__(self):
+ return "\n".join([repr(i) for i in self.statements])
+
+class ArrayConstant(Node):
+ def __init__(self, items):
+ self.items = items
+
+ def wrap(self, space):
+ return space.newlist([item.wrap(space) for item in self.items])
+
+ def execute(self, interp):
+ w_list = self.wrap(interp.space)
+ return descr_new_array(interp.space, None, w_list)
+
+ def __repr__(self):
+ return "[" + ", ".join([repr(item) for item in self.items]) + "]"
+
+class Execute(Node):
+ def __init__(self, expr):
+ self.expr = expr
+
+ def __repr__(self):
+ return repr(self.expr)
+
+ def execute(self, interp):
+ interp.results.append(self.expr.execute(interp))
+
+class Parser(object):
+ def parse_identifier(self, id):
+ id = id.strip()
+ assert id.isalpha()
+ return Variable(id)
+
+ def parse_expression(self, expr):
+ tokens = [i for i in expr.split(" ") if i]
+ if len(tokens) == 1:
+ return self.parse_constant_or_identifier(tokens[0])
+ stack = []
+ tokens.reverse()
+ while tokens:
+ token = tokens.pop()
+ if token == ')':
+ xxx
+ elif self.is_identifier_or_const(token):
+ if stack:
+ name = stack.pop()
+ lhs = stack.pop()
+ rhs = self.parse_constant_or_identifier(token)
+ stack.append(Operator(lhs, name, rhs))
+ else:
+ stack.append(self.parse_constant_or_identifier(token))
+ else:
+ stack.append(token)
+ assert len(stack) == 1
+ return stack[-1]
+
+ def parse_constant(self, v):
+ if v[0] == '[':
+ return ArrayConstant([self.parse_constant(elem)
+ for elem in v[1:-1].split(",")])
+ if v[0] == '|':
+ return RangeConstant(v[1:-1])
+ return FloatConstant(v)
+
+ def is_identifier_or_const(self, v):
+ c = v[0]
+ if ((c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or
+ (c >= '0' and c <= '9') or c in '-.['):
+ if v == '-' or v == "->":
+ return False
+ return True
+ return False
+
+ def parse_constant_or_identifier(self, v):
+ c = v[0]
+ if (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z'):
+ return self.parse_identifier(v)
+ return self.parse_constant(v)
+
+ def parse_statement(self, line):
+ if '=' in line:
+ lhs, rhs = line.split("=")
+ return Assignment(self.parse_identifier(lhs),
+ self.parse_expression(rhs))
+ else:
+ return Execute(self.parse_expression(line))
+
+ def parse(self, code):
+ statements = []
+ for line in code.split("\n"):
+ line = line.strip(" ")
+ if line:
+ statements.append(self.parse_statement(line))
+ return Code(statements)
+
+def numpy_compile(code):
+ parser = Parser()
+ return InterpreterState(parser.parse(code))
+
+def xxx_numpy_compile(bytecode, array_size):
stack = []
i = 0
dtype = space.fromcache(W_Float64Dtype)
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -14,6 +14,27 @@
any_driver = jit.JitDriver(greens=['signature'], reds=['i', 'size', 'self', 'dtype'])
slice_driver = jit.JitDriver(greens=['signature'], reds=['i', 'j', 'step', 'stop', 'source', 'dest'])
+def descr_new_array(space, w_subtype, w_size_or_iterable, w_dtype=None):
+ l = space.listview(w_size_or_iterable)
+ if space.is_w(w_dtype, space.w_None):
+ w_dtype = None
+ for w_item in l:
+ w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_item, w_dtype)
+ if w_dtype is space.fromcache(interp_dtype.W_Float64Dtype):
+ break
+ if w_dtype is None:
+ w_dtype = space.w_None
+
+ dtype = space.interp_w(interp_dtype.W_Dtype,
+ space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)
+ )
+ arr = SingleDimArray(len(l), dtype=dtype)
+ i = 0
+ for w_elem in l:
+ dtype.setitem_w(space, arr.storage, i, w_elem)
+ i += 1
+ return arr
+
class BaseArray(Wrappable):
_attrs_ = ["invalidates", "signature"]
@@ -32,27 +53,6 @@
def add_invalidates(self, other):
self.invalidates.append(other)
- def descr__new__(space, w_subtype, w_size_or_iterable, w_dtype=None):
- l = space.listview(w_size_or_iterable)
- if space.is_w(w_dtype, space.w_None):
- w_dtype = None
- for w_item in l:
- w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_item, w_dtype)
- if w_dtype is space.fromcache(interp_dtype.W_Float64Dtype):
- break
- if w_dtype is None:
- w_dtype = space.w_None
-
- dtype = space.interp_w(interp_dtype.W_Dtype,
- space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)
- )
- arr = SingleDimArray(len(l), dtype=dtype)
- i = 0
- for w_elem in l:
- dtype.setitem_w(space, arr.storage, i, w_elem)
- i += 1
- return arr
-
def _unaryop_impl(ufunc_name):
def impl(self, space):
return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self])
@@ -571,7 +571,7 @@
BaseArray.typedef = TypeDef(
'numarray',
- __new__ = interp2app(BaseArray.descr__new__.im_func),
+ __new__ = interp2app(descr_new_array),
__len__ = interp2app(BaseArray.descr_len),
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -20,6 +20,13 @@
cls.uint64_dtype = cls.space.fromcache(W_UInt64Dtype)
cls.int32_dtype = cls.space.fromcache(W_Int32Dtype)
+ def run(self, code):
+ space = FakeSpace()
+ interp = numpy_compile(code)
+ def f():
+ interp.run(space)
+ self.meta_interpxxx
+
def test_add(self):
def f(i):
ar = SingleDimArray(i, dtype=self.float64_dtype)
More information about the pypy-commit
mailing list