[Scipy-svn] r4502 - trunk/scipy/sandbox/mkufunc
scipy-svn at scipy.org
scipy-svn at scipy.org
Sun Jun 29 21:32:42 EDT 2008
Author: ilan
Date: 2008-06-29 20:32:41 -0500 (Sun, 29 Jun 2008)
New Revision: 4502
Modified:
trunk/scipy/sandbox/mkufunc/mkufunc.py
trunk/scipy/sandbox/mkufunc/test_mkufunc.py
Log:
Refactoring
Modified: trunk/scipy/sandbox/mkufunc/mkufunc.py
===================================================================
--- trunk/scipy/sandbox/mkufunc/mkufunc.py 2008-06-30 00:07:36 UTC (rev 4501)
+++ trunk/scipy/sandbox/mkufunc/mkufunc.py 2008-06-30 01:32:41 UTC (rev 4502)
@@ -5,7 +5,7 @@
"""
import sys
import re
-import os.path
+import os, os.path
import cStringIO
from types import FunctionType
@@ -15,40 +15,28 @@
from funcutil import func_hash
-verbose = False
-
def translate(f, argtypes):
- cache_fname = os.path.join(weave.catalog.default_dir(),
- 'pypy_%s.c' % func_hash(f, argtypes))
+ """ Return pypy's C output for a given function and argument types.
+
+ The cache files are in weave's directory.
+ """
+ cache_file_name = os.path.join(weave.catalog.default_dir(),
+ 'pypy_%s.c' % func_hash(f, salt=argtypes))
try:
- return open(cache_fname).read()
- except IOError:
- pass
+ return open(cache_file_name).read()
- from interactive import Translation
- if not verbose:
- tmp = sys.stderr
- sys.stderr = cStringIO.StringIO()
+ except IOError:
+ from interactive import Translation
- t = Translation(f, backend='c')
- t.annotate(argtypes)
- t.source()
-
- if not verbose:
- sys.stderr = tmp
-
- c_source_filename = t.driver.c_source_filename
- assert c_source_filename.endswith('.c')
-
- src = open(c_source_filename, 'r').read()
+ t = Translation(f, backend='c')
+ t.annotate(argtypes)
+ t.source()
+
+ os.rename(t.driver.c_source_filename, cache_file_name)
+
+ return translate(f, argtypes)
- fo = open(cache_fname, 'w')
- fo.write(src)
- fo.close()
- return src
-
-
class Ctype:
def __init__(self, npy, c):
self.npy = npy
@@ -98,7 +86,7 @@
self.f = f
self.n = n
self.sig = signature
- self.nin = f.func_code.co_argcount # input args
+ self.nin = f.func_code.co_argcount
self.nout = len(self.sig) - self.nin
assert self.nout == 1 # for now
@@ -193,11 +181,12 @@
}
''' % locals()
+
pypyc = os.path.join(weave.catalog.default_temp_dir(), 'pypy.c')
def write_pypyc(cfuncs):
""" Given a list of Cfunc instances, write the C code containing the
- functions into a file.
+ functions into a file.
"""
header = open(os.path.join(os.path.dirname(__file__),
'pypy_head.h')).read()
@@ -209,30 +198,15 @@
fo.close()
-def genufunc(f, signatures):
- """ Given a Python function and its signatures, do the following:
-
- - Compile the function to C for each signature
-
- - Write the C code for all these functions to a file
-
- - Generate the support code for weave
-
- - Generate the code for weave. This contains the actual call to
- PyUFuncGenericFunction
-
- - Return the Ufunc Python object
+def support_code(cfuncs):
+ """ Given a list of Cfunc instances, return the support_code for weave.
"""
- signatures.sort(key=lambda sig: [numpy.dtype(typ).num for typ in sig])
+ fname = cfuncs[0].f.__name__
- cfuncs = [Cfunc(f, sig, n) for n, sig in enumerate(signatures)]
-
- write_pypyc(cfuncs)
-
declarations = ''.join('\t%s\n' % cf.decl() for cf in cfuncs)
-
+
func_support = ''.join(cf.ufunc_support_code() for cf in cfuncs)
-
+
pyufuncs = ''.join('\tPyUFunc_%i,\n' % cf.n for cf in cfuncs)
data = ''.join('\t(void *) wrap_%s,\n' % cf.cname for cf in cfuncs)
@@ -240,10 +214,7 @@
types = ''.join('\t%s /* %i */\n' %
(''.join(typedict[t].npy + ', ' for t in cf.sig), cf.n)
for cf in cfuncs)
-
- fname = f.__name__
-
- support_code = '''
+ return '''
extern "C" {
%(declarations)s}
@@ -259,17 +230,22 @@
%(types)s};
''' % locals()
+
+def code(f, signatures):
+ """ Return the code for weave.
+ """
+ nin = f.func_code.co_argcount
ntypes = len(signatures)
- nin = cfuncs[0].nin
+ fname = f.__name__
fhash = func_hash(f)
- code = '''
+ return '''
import_ufunc();
/****************************************************************************
** function name: %(fname)s
** signatures: %(signatures)r
-** bytecode hash: %(fhash)s
+** fhash: %(fhash)s
*****************************************************************************/
return_val = PyUFunc_FromFuncAndData(
@@ -281,25 +257,29 @@
1, /* nout */
PyUFunc_None, /* identity */
"%(fname)s", /* name */
- "UFunc made by mkufunc", /* doc */
+ "UFunc created by mkufunc", /* doc */
0);
''' % locals()
+
+
+def genufunc(f, signatures):
+ """ Return the Ufunc Python object for given function and signatures.
+ """
+ if len(signatures) == 0:
+ raise ValueError("At least one signature needed")
- if 1:
- fo = open(f.__name__ + '_code.cc', 'w');
- fo.write(code);
- fo.close()
-
- fo = open(f.__name__ + '_support_code.cc', 'w');
- fo.write(support_code);
- fo.close()
+ signatures.sort(key=lambda sig: [numpy.dtype(typ).num for typ in sig])
+ cfuncs = [Cfunc(f, sig, n) for n, sig in enumerate(signatures)]
+
+ write_pypyc(cfuncs)
+
ufunc_info = weave.base_info.custom_info()
ufunc_info.add_header('"numpy/ufuncobject.h"')
- return weave.inline(code,
+ return weave.inline(code(f, signatures),
verbose=0,
- support_code=support_code,
+ support_code=support_code(cfuncs),
customize=ufunc_info,
sources=[pypyc])
Modified: trunk/scipy/sandbox/mkufunc/test_mkufunc.py
===================================================================
--- trunk/scipy/sandbox/mkufunc/test_mkufunc.py 2008-06-30 00:07:36 UTC (rev 4501)
+++ trunk/scipy/sandbox/mkufunc/test_mkufunc.py 2008-06-30 01:32:41 UTC (rev 4502)
@@ -102,6 +102,7 @@
self.assertRaises(TypeError, mkufunc([3*(float,)]), f)
self.assertRaises(TypeError, mkufunc([{}]), f)
self.assertRaises(TypeError, mkufunc([(int, {})]), f)
+ self.assertRaises(ValueError, mkufunc([]), f)
class Math_Tests(unittest.TestCase, Util):
More information about the Scipy-svn
mailing list