[pypy-svn] r68765 - in pypy/branch/logging/pypy: rlib rlib/test rpython/lltypesystem

arigo at codespeak.net arigo at codespeak.net
Mon Oct 26 19:20:42 CET 2009


Author: arigo
Date: Mon Oct 26 19:20:41 2009
New Revision: 68765

Modified:
   pypy/branch/logging/pypy/rlib/rlog.py
   pypy/branch/logging/pypy/rlib/test/test_rlog.py
   pypy/branch/logging/pypy/rpython/lltypesystem/rffi.py
Log:
Implement floats logging.  Note that they are written
as 4 bytes, i.e. C floats.


Modified: pypy/branch/logging/pypy/rlib/rlog.py
==============================================================================
--- pypy/branch/logging/pypy/rlib/rlog.py	(original)
+++ pypy/branch/logging/pypy/rlib/rlog.py	Mon Oct 26 19:20:41 2009
@@ -1,7 +1,7 @@
-import py, os, time
+import py, os, time, struct
 from pypy.tool.ansi_print import ansi_log
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.rarithmetic import r_uint
+from pypy.rlib.rarithmetic import r_uint, r_singlefloat
 from pypy.rpython.extregistry import ExtRegistryEntry
 
 _log = py.log.Producer("rlog") 
@@ -61,7 +61,7 @@
 
 import re
 
-r_entry = re.compile(r"%\((\w+)\)([sd])")
+r_entry = re.compile(r"%\((\w+)\)([sdf])")
 
 
 class LogCategory(object):
@@ -128,7 +128,7 @@
             for c in 'RLog\n':
                 self.write_int(ord(c))
             self.write_int(-1)
-            self.write_int(0)
+            self.write_float(1.0)
         self.initialized_file = True
 
     def define_new_category(self, cat):
@@ -161,9 +161,10 @@
 
 class LLLogWriter(AbstractLogWriter):
     BUFSIZE = 8192
+    SIZEOF_FLOAT = struct.calcsize("f")
 
     def do_write(self, fd, buf, size):
-        "NOT_RPYTHON"
+        "NOT_RPYTHON (too slow :-)"
         l = [buf[i] for i in range(size)]
         s = ''.join(l)
         os.write(fd, s)
@@ -224,6 +225,15 @@
                 buf[p + i] = s[i]
             self.buffer_position = p + len(s)
 
+    def write_float(self, f):
+        from pypy.rpython.lltypesystem import rffi
+        p = self.buffer_position
+        ptr = rffi.cast(rffi.FLOATP, rffi.ptradd(self.buffer, p))
+        ptr[0] = r_singlefloat(f)
+        self.buffer_position = p + self.SIZEOF_FLOAT
+        if self.buffer_position > self.BUFSIZE-48:
+            self._flush()
+
     def _flush(self):
         if self.buffer_position > 0:
             self.do_write(self.fd, self.buffer, self.buffer_position)

Modified: pypy/branch/logging/pypy/rlib/test/test_rlog.py
==============================================================================
--- pypy/branch/logging/pypy/rlib/test/test_rlog.py	(original)
+++ pypy/branch/logging/pypy/rlib/test/test_rlog.py	Mon Oct 26 19:20:41 2009
@@ -1,9 +1,13 @@
+import struct
 from pypy.rlib import rlog
 from pypy.rlib.rarithmetic import intmask
 from pypy.tool.udir import udir
 
 
 def test_log_direct():
+    # this should produce some output via py.log...
+    rlog.debug_log("Aa", "hello %(foo)d %(bar)d", foo=5, bar=7)
+    # let's replace py.log with our own class to check
     messages = []
     class MyLog:
         def Aa(self, msg):
@@ -38,6 +42,9 @@
     def write_str(self, s):
         assert isinstance(s, str)
         self.content.append(s)
+    def write_float(self, f):
+        assert isinstance(f, float)
+        self.content.append(f)
 
 def test_logwriter():
     class FakeCategory:
@@ -55,7 +62,7 @@
     logwriter.add_entry(cat5)
     #
     assert logwriter.content == [
-        ord('R'), ord('L'), ord('o'), ord('g'), ord('\n'), -1, 0,
+        ord('R'), ord('L'), ord('o'), ord('g'), ord('\n'), -1, 1.0,
         0, 5, "F5", "foobar",
         5,
         5,
@@ -72,12 +79,15 @@
     call(2873, "woooooorld")
     #
     assert logwriter.content == [
-        ord('R'), ord('L'), ord('o'), ord('g'), ord('\n'), -1, 0,
+        ord('R'), ord('L'), ord('o'), ord('g'), ord('\n'), -1, 1.0,
         0, 17, "Aa", message,
         17, 515, "hellooo",
         17, 2873, "woooooorld"]
 
 
+TIMESTAMP = object()
+SIZEOF_FLOAT = rlog.LLLogWriter.SIZEOF_FLOAT
+
 class TestLLLogWriter:
     COUNTER = 0
 
@@ -105,6 +115,9 @@
         result |= (lastbyte << shift)
         return result
 
+    def read_float(self, f):
+        return struct.unpack("f", f.read(SIZEOF_FLOAT))[0]
+
     def check(self, expected):
         f = self.path.open('rb')
         f.seek(0, 2)
@@ -112,8 +125,10 @@
         f.seek(0, 0)
         header = f.read(5)
         assert header == 'RLog\n'
-        for expect in [-1, 0] + expected:
-            if isinstance(expect, int):
+        for expect in [-1, 1.0] + expected:
+            if expect is TIMESTAMP:
+                f.read(SIZEOF_FLOAT)        # ignore result
+            elif isinstance(expect, int):
                 result = self.read_uint(f)
                 assert intmask(result) == expect
             elif isinstance(expect, str):
@@ -121,6 +136,9 @@
                 assert length < totalsize
                 got = f.read(length)
                 assert got == expect
+            elif isinstance(expect, float):
+                result = self.read_float(f)
+                assert abs(result - expect) < 1E-6
             else:
                 assert 0, expect
         moredata = f.read(10)
@@ -167,3 +185,38 @@
         logwriter._close()
         self.check(slist)
         assert logwriter.writecount <= 9
+
+    def test_write_float(self):
+        import math
+        logwriter = self.open()
+        flist = [math.log(x+0.1) for x in range(logwriter.BUFSIZE)]
+        for f in flist:
+            logwriter.write_float(f)
+        logwriter._close()
+        self.check(flist)
+        assert logwriter.writecount <= 6
+
+
+class TestCompiled:
+    COUNTER = 0
+
+    def f(x):
+        rlog.debug_log("Aa", "hello %(foo)d %(bar)d", foo=x, bar=7)
+        rlog.debug_log("Ab", "<<%(baz)s>>", baz="hi there")
+
+    def setup_method(self, _):
+        self.old_pypylog = os.environ.get('PYPYLOG')
+        self.pypylog = str(udir.join('test_rlog.TestCompiled%d' %
+                                     TestCompiled.COUNTER))
+        TestCompiled.COUNTER += 1
+        os.environ['PYPYLOG'] = self.pypylog
+
+    def teardown_method(self, _):
+        if self.old_pypylog is None:
+            del os.environ['PYPYLOG']
+        else:
+            os.environ['PYPYLOG'] = self.old_pypylog
+
+    #def test_interpret(self):
+    #    self.interpret(self.f.im_func, [132])
+    #    ...

Modified: pypy/branch/logging/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/logging/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/branch/logging/pypy/rpython/lltypesystem/rffi.py	Mon Oct 26 19:20:41 2009
@@ -494,7 +494,8 @@
 DOUBLE = lltype.Float
 
 # float - corresponds to pypy.rlib.rarithmetic.r_float, and supports no
-#         operation except rffi.cast() between FLOAT and DOUBLE
+#         operation except casts between FLOAT and DOUBLE, by using
+#         r_singlefloat(x) or float(x).
 FLOAT = lltype.SingleFloat
 r_singlefloat = rarithmetic.r_singlefloat
 



More information about the Pypy-commit mailing list