[pypy-commit] pypy numpy-minilang: work more on test_zjit. now it shows a problem in our handling!!! (wow)

fijal noreply at buildbot.pypy.org
Fri Oct 28 12:14:35 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-minilang
Changeset: r48557:312b01650172
Date: 2011-10-28 12:13 +0200
http://bitbucket.org/pypy/pypy/changeset/312b01650172/

Log:	work more on test_zjit. now it shows a problem in our handling!!!
	(wow)

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
@@ -5,7 +5,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, BaseArray, descr_new_array
+from pypy.module.micronumpy.interp_numarray import (Scalar, BaseArray,
+     descr_new_array, scalar_w, SingleDimArray)
 from pypy.rlib.objectmodel import specialize
 
 
@@ -21,6 +22,8 @@
 class WrongFunctionName(Exception):
     pass
 
+SINGLE_ARG_FUNCTIONS = ["sum", "prod", "max", "min"]
+
 class FakeSpace(object):
     w_ValueError = None
     w_TypeError = None
@@ -31,6 +34,7 @@
     w_float = "float"
     w_list = "list"
     w_long = "long"
+    w_tuple = 'tuple'
 
     def __init__(self):
         """NOT_RPYTHON"""
@@ -38,11 +42,14 @@
         self.w_float64dtype = W_Float64Dtype(self)
 
     def issequence_w(self, w_obj):
-        return w_obj.seq
+        return isinstance(w_obj, ListObject) or isinstance(w_obj, SingleDimArray)
 
     def isinstance_w(self, w_obj, w_tp):
         return False
 
+    def decode_index4(self, w_idx, size):
+        return (self.int_w(w_idx), 0, 0, 1)
+
     @specialize.argtype(1)
     def wrap(self, obj):
         if isinstance(obj, float):
@@ -69,8 +76,11 @@
         return w_obj.floatval
 
     def int_w(self, w_obj):
-        assert isinstance(w_obj, IntObject)
-        return w_obj.intval
+        if isinstance(w_obj, IntObject):
+            return w_obj.intval
+        elif isinstance(w_obj, FloatObject):
+            return int(w_obj.floatval)
+        raise NotImplementedError
 
     def int(self, w_obj):
         return w_obj
@@ -97,25 +107,21 @@
         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
@@ -147,15 +153,30 @@
         raise NotImplementedError
 
 class Assignment(Node):
-    def __init__(self, id, expr):
-        self.id = id
+    def __init__(self, name, expr):
+        self.name = name
         self.expr = expr
 
     def execute(self, interp):
-        interp.variables[self.id.name] = self.expr.execute(interp)
+        interp.variables[self.name] = self.expr.execute(interp)
 
     def __repr__(self):
-        return "%r = %r" % (self.id, self.expr)
+        return "%% = %r" % (self.name, self.expr)
+
+class ArrayAssignment(Node):
+    def __init__(self, name, index, expr):
+        self.name = name
+        self.index = index
+        self.expr = expr
+
+    def execute(self, interp):
+        arr = interp.variables[self.name]
+        w_index = self.index.execute(interp).eval(0).wrap(interp.space)
+        w_val = self.expr.execute(interp).eval(0).wrap(interp.space)
+        arr.descr_setitem(interp.space, w_index, w_val)
+
+    def __repr__(self):
+        return "%s[%r] = %r" % (self.name, self.index, self.expr)
 
 class Variable(Node):
     def __init__(self, name):
@@ -178,12 +199,17 @@
         w_rhs = self.rhs.execute(interp)
         assert isinstance(w_lhs, BaseArray)
         if self.name == '+':
-            return w_lhs.descr_add(interp.space, w_rhs)
+            w_res = w_lhs.descr_add(interp.space, w_rhs)
+            if not isinstance(w_res, BaseArray):
+                dtype = interp.space.fromcache(W_Float64Dtype)
+                w_res = scalar_w(interp.space, dtype, w_res)
+            return w_res
         elif self.name == '->':
             if isinstance(w_rhs, Scalar):
                 index = int(interp.space.float_w(
                     w_rhs.value.wrap(interp.space)))
-                return w_lhs.get_concrete().eval(index).wrap(interp.space)
+                dtype = interp.space.fromcache(W_Float64Dtype)
+                return Scalar(dtype, w_lhs.get_concrete().eval(index))
             else:
                 raise NotImplementedError
         else:
@@ -262,13 +288,24 @@
                                                  for arg in self.args]))
 
     def execute(self, interp):
-        if self.name == 'sum':
+        if self.name in SINGLE_ARG_FUNCTIONS:
             if len(self.args) != 1:
                 raise ArgumentMismatch
             arr = self.args[0].execute(interp)
             if not isinstance(arr, BaseArray):
                 raise ArgumentNotAnArray
-            return arr.descr_sum(interp.space)
+            if self.name == "sum":
+                w_res = arr.descr_sum(interp.space)
+            elif self.name == "prod":
+                w_res = arr.descr_prod(interp.space)
+            elif self.name == "max":
+                w_res = arr.descr_max(interp.space)
+            elif self.name == "min":
+                w_res = arr.descr_min(interp.space)
+            else:
+                assert False # unreachable code
+            dtype = interp.space.fromcache(W_Float64Dtype)
+            return scalar_w(interp.space, dtype, w_res)
         else:
             raise WrongFunctionName
 
@@ -337,12 +374,24 @@
                 return self.parse_function_call(v)
             return self.parse_identifier(v)
         return self.parse_constant(v)
+
+    def parse_array_subscript(self, v):
+        v = v.strip(" ")
+        l = v.split("[")
+        lgt = len(l[1]) - 1
+        assert lgt >= 0
+        rhs = self.parse_constant_or_identifier(l[1][:lgt])
+        return l[0], rhs
         
     def parse_statement(self, line):
         if '=' in line:
             lhs, rhs = line.split("=")
-            return Assignment(self.parse_identifier(lhs),
-                              self.parse_expression(rhs))
+            lhs = lhs.strip(" ")
+            if '[' in lhs:
+                name, index = self.parse_array_subscript(lhs)
+                return ArrayAssignment(name, index, self.parse_expression(rhs))
+            else: 
+                return Assignment(lhs, self.parse_expression(rhs))
         else:
             return Execute(self.parse_expression(line))
 
diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py
--- a/pypy/module/micronumpy/test/test_compile.py
+++ b/pypy/module/micronumpy/test/test_compile.py
@@ -12,9 +12,9 @@
         """
         interp = self.compile(code)
         assert isinstance(interp.code.statements[0], Assignment)
-        assert interp.code.statements[0].id.name == 'a'
+        assert interp.code.statements[0].name == 'a'
         assert interp.code.statements[0].expr.v == 2
-        assert interp.code.statements[1].id.name == 'b'
+        assert interp.code.statements[1].name == 'b'
         assert interp.code.statements[1].expr.v == 3
 
     def test_array_literal(self):
@@ -104,7 +104,7 @@
         a + b -> 3
         """
         interp = self.run(code)
-        assert interp.results[0].floatval == 3 + 6
+        assert interp.results[0].value.val == 3 + 6
         
     def test_range_getitem(self):
         code = """
@@ -112,7 +112,7 @@
         r -> 3
         """
         interp = self.run(code)
-        assert interp.results[0].floatval == 6
+        assert interp.results[0].value.val == 6
 
     def test_sum(self):
         code = """
@@ -121,4 +121,31 @@
         r
         """
         interp = self.run(code)
-        assert interp.results[0].floatval == 15
+        assert interp.results[0].value.val == 15
+
+    def test_array_write(self):
+        code = """
+        a = [1,2,3,4,5]
+        a[3] = 15
+        a -> 3
+        """
+        interp = self.run(code)
+        assert interp.results[0].value.val == 15
+
+    def test_min(self):
+        interp = self.run("""
+        a = |30|
+        a[15] = -12
+        b = a + a
+        min(b)
+        """)
+        assert interp.results[0].value.val == -24
+
+    def test_max(self):
+        interp = self.run("""
+        a = |30|
+        a[13] = 128
+        b = a + a
+        max(b)
+        """)
+        assert interp.results[0].value.val == 256
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
@@ -23,7 +23,7 @@
             interp = numpy_compile(hlstr(code))
             interp.run(space)
             res = interp.results[0]
-            return interp.space.float_w(res)
+            return interp.space.float_w(res.eval(0).wrap(interp.space))
 
         if self.graph is None:
             interp, graph = self.meta_interp(f, [llstr(code)],
@@ -68,48 +68,45 @@
                           "int_add": 1,
                           "int_lt": 1, "guard_true": 1, "jump": 1})
 
-class DisabledTestNumpy(object):
-    def test_sum(self):
-        space = self.space
-        float64_dtype = self.float64_dtype
-        int64_dtype = self.int64_dtype
-
-        def f(i):
-            if NonConstant(False):
-                dtype = int64_dtype
-            else:
-                dtype = float64_dtype
-            ar = SingleDimArray(i, dtype=dtype)
-            v = ar.descr_add(space, ar).descr_sum(space)
-            assert isinstance(v, FloatObject)
-            return v.floatval
-
-        result = self.meta_interp(f, [5], listops=True, backendopt=True)
-        self.check_loops({"getarrayitem_raw": 2, "float_add": 2,
-                          "int_add": 1,
-                          "int_lt": 1, "guard_true": 1, "jump": 1})
-        assert result == f(5)
-
     def test_prod(self):
-        space = self.space
-        float64_dtype = self.float64_dtype
-        int64_dtype = self.int64_dtype
-
-        def f(i):
-            if NonConstant(False):
-                dtype = int64_dtype
-            else:
-                dtype = float64_dtype
-            ar = SingleDimArray(i, dtype=dtype)
-            v = ar.descr_add(space, ar).descr_prod(space)
-            assert isinstance(v, FloatObject)
-            return v.floatval
-
-        result = self.meta_interp(f, [5], listops=True, backendopt=True)
+        result = self.run("""
+        a = |30|
+        b = a + a
+        prod(b)
+        """)
+        expected = 1
+        for i in range(30):
+            expected *= i * 2
+        assert result == expected
         self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
                           "float_mul": 1, "int_add": 1,
                           "int_lt": 1, "guard_true": 1, "jump": 1})
-        assert result == f(5)
+
+    def test_max(self):
+        result = self.run("""
+        a = |30|
+        a[13] = 128
+        b = a + a
+        max(b)
+        """)
+        assert result == 256
+        self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
+                          "float_mul": 1, "int_add": 1,
+                          "int_lt": 1, "guard_true": 1, "jump": 1})
+
+    def test_min(self):
+        result = self.run("""
+        a = |30|
+        a[15] = -12
+        b = a + a
+        min(b)
+        """)
+        assert result == -24
+        self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
+                          "float_mul": 1, "int_add": 1,
+                          "int_lt": 1, "guard_true": 1, "jump": 1})
+
+class DisabledTestNumpy(object):
 
     def test_max(self):
         space = self.space


More information about the pypy-commit mailing list