[pypy-svn] r46065 - in pypy/dist/pypy/rpython/numpy: . test

simonb at codespeak.net simonb at codespeak.net
Tue Aug 28 02:30:38 CEST 2007


Author: simonb
Date: Tue Aug 28 02:30:36 2007
New Revision: 46065

Modified:
   pypy/dist/pypy/rpython/numpy/aarray.py
   pypy/dist/pypy/rpython/numpy/rarray.py
   pypy/dist/pypy/rpython/numpy/test/test_array.py
Log:
numpy: fix method handling, add attribute lookup

Modified: pypy/dist/pypy/rpython/numpy/aarray.py
==============================================================================
--- pypy/dist/pypy/rpython/numpy/aarray.py	(original)
+++ pypy/dist/pypy/rpython/numpy/aarray.py	Tue Aug 28 02:30:36 2007
@@ -2,14 +2,14 @@
 from pypy.annotation.pairtype import pairtype
 from pypy.annotation.model import SomeExternalObject, SomeList, SomeImpossibleValue
 from pypy.annotation.model import SomeObject, SomeInteger, SomeFloat, SomeString, SomeChar,\
-    SomeGenericCallable
+    SomeTuple
 from pypy.tool.error import AnnotatorError
 from pypy.rpython.lltypesystem import rffi
 from pypy.rlib import rarithmetic
 
 import numpy
 
-class SomeArray(SomeExternalObject):
+class SomeArray(SomeObject):
     """Stands for an object from the numpy module."""
     typecode_to_item = {
         'b' : SomeInteger(knowntype=rffi.r_signedchar),
@@ -25,10 +25,10 @@
         #'f' : SomeFloat(), # XX single precision float XX
         'd' : SomeFloat(),
     }
-    def __init__(self, knowntype, typecode, rank=1):
+    def __init__(self, knowntype, typecode, ndim=1):
         self.knowntype = knowntype # == numpy.ndarray (do we need this for anything?)
         self.typecode = typecode
-        self.rank = rank
+        self.ndim = ndim
 
     def can_be_none(self):
         return True
@@ -51,15 +51,17 @@
         s = None
         if s_attr.is_constant() and isinstance(s_attr.const, str):
             attr = s_attr.const
-            if attr in ('transpose',):
-                s_result = SomeArray(s_array.knowntype, s_array.typecode, s_array.rank)
-                s = SomeGenericCallable([], s_result)
-            elif attr == 'shape':
-                s = SomeTuple([SomeInteger()]*s_array.rank)
+            if attr == 'shape':
+                s = SomeTuple([SomeInteger()]*s_array.ndim)
+            elif attr == 'ndim':
+                s = SomeInteger()
         if s is None:
-            return SomeObject()
+            return SomeObject.getattr(s_array, s_attr)
         return s
 
+    def method_transpose(self):
+        return SomeArray(self.knowntype, self.typecode, self.ndim)
+
 class __extend__(pairtype(SomeArray, SomeArray)):
 
     def union((s_arr1, s_arr2)):
@@ -85,7 +87,7 @@
         pass
 
     def getitem((s_cto, s_index)):
-        # TODO: higher ranked arrays have getitem returns SomeArray
+        # TODO: higher ndimed arrays have getitem returns SomeArray
         return s_cto.get_item_type()
 
 numpy_typedict = {

Modified: pypy/dist/pypy/rpython/numpy/rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/numpy/rarray.py	(original)
+++ pypy/dist/pypy/rpython/numpy/rarray.py	Tue Aug 28 02:30:36 2007
@@ -6,7 +6,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.lltypesystem.lltype import \
      GcArray, GcStruct, Signed, Ptr, Unsigned, malloc, Void
-from pypy.annotation.model import SomeInteger
+from pypy.annotation.model import SomeObject, SomeInteger
 from pypy.rpython.numpy.aarray import SomeArray
 from pypy.annotation.pairtype import pairtype
 
@@ -17,16 +17,39 @@
         self.item_repr = rtyper.getrepr(self.s_value)
         ITEM = self.item_repr.lowleveltype
         ITEMARRAY = GcArray(ITEM)
+        SIZEARRAY = GcArray(Signed)
         self.ARRAY = Ptr(
-            GcStruct( "array",
-#                ("length", Signed),
-                ("data", Ptr(ITEMARRAY))))
+            GcStruct("array",
+                ("data", Ptr(ITEMARRAY)), # pointer to raw data buffer 
+                ("nd", Signed), # number of dimensions, also called ndim
+                ("dimensions", Ptr(SIZEARRAY)), # size in each dimension
+                ("strides", Ptr(SIZEARRAY)), # bytes to jump to get to the
+                                             # next element in each dimension 
+            ))
         self.lowleveltype = self.ARRAY
 
     def allocate_instance(self, llops, v_array):
         c1 = inputconst(lltype.Void, self.lowleveltype.TO) 
         return llops.gendirectcall(ll_allocate, c1, v_array)
 
+    def rtype_method_transpose(self, hop):
+        [v_self] = hop.inputargs(self)
+        cARRAY = hop.inputconst(Void, hop.r_result.ARRAY.TO)
+        return hop.gendirectcall(ll_transpose, cARRAY, v_self)
+
+    def rtype_getattr(self, hop):
+        s_attr = hop.args_s[1]
+        if s_attr.is_constant() and isinstance(s_attr.const, str):
+            attr = s_attr.const
+            s_obj = hop.args_s[0]
+            vobj, vattr = hop.inputargs(self, Void)
+            llops = hop.llops
+            if attr == 'ndim':
+                cname = inputconst(Void, 'nd')
+                return llops.genop('getfield', [vobj, cname], resulttype=Signed)
+        return Repr.rtype_getattr(self, hop)
+
+
 class __extend__(SomeArray):
     def rtyper_makerepr(self, rtyper):
         return ArrayRepr( rtyper, self )
@@ -34,14 +57,15 @@
     def rtyper_makekey(self):
         return self.__class__, self.knowntype
 
-class __extend__(pairtype(ArrayRepr,ArrayRepr)):
+
+class __extend__(pairtype(ArrayRepr, ArrayRepr)):
     def rtype_add((r_arr1,r_arr2), hop):
         v_arr1, v_arr2 = hop.inputargs(r_arr1, r_arr2)
         cARRAY = hop.inputconst(Void, hop.r_result.ARRAY.TO)
         return hop.gendirectcall(ll_add, cARRAY, v_arr1, v_arr2)
 
 
-class __extend__(pairtype(ArrayRepr,IntegerRepr)):
+class __extend__(pairtype(ArrayRepr, IntegerRepr)):
     def rtype_setitem((r_arr,r_int), hop):
         v_array, v_index, v_item = hop.inputargs(r_arr, Signed, r_arr.item_repr)
         return hop.gendirectcall(ll_setitem, v_array, v_index, v_item)
@@ -72,11 +96,13 @@
     while i < size:
         data[i] = lst.ll_getitem_fast(i)
         i += 1
+    array.nd = 1
     return array
 
 def ll_allocate(ARRAY, array):
     new_array = malloc(ARRAY)
-    new_array.data = array.data
+    new_array.data = array.data # alias data
+    new_array.nd = array.nd
     return new_array
 
 def ll_setitem(l, index, item):
@@ -97,5 +123,10 @@
         i += 1
     return array
 
+def ll_transpose(ARRAY, a1):
+    a2 = ll_allocate(ARRAY, a1)
+    # XX do something to a2
+    return a2
+    
 
 

Modified: pypy/dist/pypy/rpython/numpy/test/test_array.py
==============================================================================
--- pypy/dist/pypy/rpython/numpy/test/test_array.py	(original)
+++ pypy/dist/pypy/rpython/numpy/test/test_array.py	Tue Aug 28 02:30:36 2007
@@ -5,6 +5,7 @@
 import py
 import pypy.rpython.numpy.implementation
 from pypy.annotation import model as annmodel
+from pypy.annotation.model import SomeTuple
 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.translator.translator import TranslationContext
 from pypy import conftest
@@ -25,13 +26,13 @@
     return my_array[0]
 
 class Test_annotation:
-    def test_array_access_int(self):
+    def test_annotate_array_access_int(self):
         t = TranslationContext()
         a = t.buildannotator()
         s = a.build_types(access_array, [int])
         assert s.knowntype == rffi.r_int
 
-    def test_array_access_float(self):
+    def test_annotate_array_access_float(self):
         t = TranslationContext()
         a = t.buildannotator()
         s = a.build_types(access_array, [float])
@@ -40,7 +41,7 @@
         if conftest.option.view:
             t.view()
 
-    def test_array_access_bytype(self):
+    def test_annotate_array_access_bytype(self):
         def access_array_bytype(dummy):
             my_array = numpy.array([1],'d')
             return my_array[0]
@@ -53,7 +54,7 @@
         if conftest.option.view:
             t.view()
 
-    def test_array_access_variable(self):
+    def test_annotate_array_access_variable(self):
         def access_with_variable():
             my_array = numpy.array(range(10))
             my_array[2] = 2
@@ -68,7 +69,7 @@
         s = a.build_types(access_with_variable, [])
         assert s.knowntype == rffi.r_int
 
-    def test_array_add(self):
+    def test_annotate_array_add(self):
         def f():
             a1 = numpy.array([1,2])
             a2 = numpy.array([6,9])
@@ -79,7 +80,7 @@
         s = a.build_types(f, [])
         assert s.typecode == 'i'
 
-    def test_array_add_coerce(self):
+    def test_annotate_array_add_coerce(self):
         def f():
             a1 = numpy.array([1,2])
             a2 = numpy.array([6.,9.])
@@ -90,7 +91,17 @@
         s = a.build_types(f, [])
         assert s.typecode == 'd'
 
-    def test_array_method(self):
+    def test_annotate_array_attr(self):
+        def f():
+            a1 = numpy.array([1,2])
+            return a1.shape
+
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(f, [])
+        assert type(s) == SomeTuple
+
+    def test_annotate_array_method(self):
         def f():
             a1 = numpy.array([1,2])
             return a1.transpose()
@@ -134,6 +145,23 @@
         assert res.data[0] == 7
         assert res.data[1] == 11
 
+    def test_specialize_array_attr(self):
+        def create_array():
+            a = numpy.array([1,2])
+            return a.ndim
+
+        res = interpret(create_array, [])
+        assert res == 1
+
+    def test_specialize_array_method(self):
+        def create_array():
+            a = numpy.array([1,2])
+            return a.transpose()
+
+        res = interpret(create_array, [])
+        assert res.data[0] == 1
+        assert res.data[1] == 2
+
 class Test_compile:
     def setup_class(self):
         if not test_c_compile:



More information about the Pypy-commit mailing list