[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