[Scipy-svn] r4479 - in trunk/scipy/sandbox: . mkufunc
scipy-svn at scipy.org
scipy-svn at scipy.org
Wed Jun 25 11:43:59 EDT 2008
Author: ilan
Date: 2008-06-25 10:43:39 -0500 (Wed, 25 Jun 2008)
New Revision: 4479
Added:
trunk/scipy/sandbox/mkufunc/
trunk/scipy/sandbox/mkufunc/bar_code.cc
trunk/scipy/sandbox/mkufunc/bar_support_code.cc
trunk/scipy/sandbox/mkufunc/driver.py
trunk/scipy/sandbox/mkufunc/head.c
trunk/scipy/sandbox/mkufunc/interactive.py
trunk/scipy/sandbox/mkufunc/mkufunc.py
trunk/scipy/sandbox/mkufunc/pypy.c
trunk/scipy/sandbox/mkufunc/test_1.py
Log:
Adding project mkufunc (make U function decorator) to sandbox
Added: trunk/scipy/sandbox/mkufunc/bar_code.cc
===================================================================
--- trunk/scipy/sandbox/mkufunc/bar_code.cc 2008-06-24 17:48:31 UTC (rev 4478)
+++ trunk/scipy/sandbox/mkufunc/bar_code.cc 2008-06-25 15:43:39 UTC (rev 4479)
@@ -0,0 +1,14 @@
+
+import_ufunc();
+
+return_val = PyUFunc_FromFuncAndData(
+ foo_functions,
+ foo_data,
+ foo_signatures,
+ 2, /* ntypes */
+ 1, /* nin */
+ 1, /* nout */
+ PyUFunc_None, /* identity */
+ "foo", /* name */
+ "", /* doc */
+ 0);
Added: trunk/scipy/sandbox/mkufunc/bar_support_code.cc
===================================================================
--- trunk/scipy/sandbox/mkufunc/bar_support_code.cc 2008-06-24 17:48:31 UTC (rev 4478)
+++ trunk/scipy/sandbox/mkufunc/bar_support_code.cc 2008-06-25 15:43:39 UTC (rev 4479)
@@ -0,0 +1,78 @@
+
+extern "C" {
+ double f1_pypy_g_bar(long l_n_1);
+ double f2_pypy_g_bar(double l_n_5);
+}
+
+
+static long foo_1(long x)
+{
+ return f1_pypy_g_bar(x);
+}
+
+typedef long Func_1(long);
+
+static void
+PyUFunc_1(char **args, npy_intp *dimensions, npy_intp *steps, void *func)
+{
+ /* printf("PyUFunc_1\n"); */
+
+ npy_intp n = dimensions[0];
+ npy_intp is0 = steps[0];
+ npy_intp os = steps[1];
+ char *ip0 = args[0];
+ char *op = args[1];
+ Func_1 *f = (Func_1 *) func;
+ npy_intp i;
+
+ for(i = 0; i < n; i++, ip0 += is0, op += os) {
+ long *in1 = (long *)ip0;
+ long *out = (long *)op;
+
+ *out = f(*in1);
+ }
+}
+
+static double foo_2(double x)
+{
+ return f2_pypy_g_bar(x);
+}
+
+typedef double Func_2(double);
+
+static void
+PyUFunc_2(char **args, npy_intp *dimensions, npy_intp *steps, void *func)
+{
+ /* printf("PyUFunc_2\n"); */
+
+ npy_intp n = dimensions[0];
+ npy_intp is0 = steps[0];
+ npy_intp os = steps[1];
+ char *ip0 = args[0];
+ char *op = args[1];
+ Func_2 *f = (Func_2 *) func;
+ npy_intp i;
+
+ for(i = 0; i < n; i++, ip0 += is0, op += os) {
+ double *in1 = (double *)ip0;
+ double *out = (double *)op;
+
+ *out = f(*in1);
+ }
+}
+
+
+static PyUFuncGenericFunction foo_functions[] = {
+ PyUFunc_1,
+ PyUFunc_2,
+};
+
+static void *foo_data[] = {
+ (void *) foo_1,
+ (void *) foo_2,
+};
+
+static char foo_signatures[] = {
+ NPY_LONG, NPY_LONG, /* 1 */
+ NPY_DOUBLE, NPY_DOUBLE, /* 2 */
+};
Added: trunk/scipy/sandbox/mkufunc/driver.py
===================================================================
--- trunk/scipy/sandbox/mkufunc/driver.py 2008-06-24 17:48:31 UTC (rev 4478)
+++ trunk/scipy/sandbox/mkufunc/driver.py 2008-06-25 15:43:39 UTC (rev 4479)
@@ -0,0 +1,728 @@
+import sys, os
+
+from pypy.translator.translator import TranslationContext, graphof
+from pypy.translator.tool.taskengine import SimpleTaskEngine
+from pypy.translator.goal import query
+from pypy.translator.goal.timing import Timer
+from pypy.annotation import model as annmodel
+from pypy.annotation.listdef import s_list_of_strings
+from pypy.annotation import policy as annpolicy
+from py.compat import optparse
+from pypy.tool.udir import udir
+
+import py
+from pypy.tool.ansi_print import ansi_log
+log = py.log.Producer("translation")
+py.log.setconsumer("translation", ansi_log)
+
+DEFAULTS = {
+ 'translation.gc': 'ref',
+ 'translation.cc': None,
+ 'translation.profopt': None,
+
+ 'translation.thread': False, # influences GC policy
+
+ 'translation.stackless': False,
+ 'translation.debug': True,
+ 'translation.insist': False,
+ 'translation.backend': 'c',
+ 'translation.fork_before': None,
+ 'translation.backendopt.raisingop2direct_call' : False,
+ 'translation.backendopt.merge_if_blocks': True,
+}
+
+
+def taskdef(taskfunc, deps, title, new_state=None, expected_states=[],
+ idemp=False, earlycheck=None):
+ taskfunc.task_deps = deps
+ taskfunc.task_title = title
+ taskfunc.task_newstate = None
+ taskfunc.task_expected_states = expected_states
+ taskfunc.task_idempotent = idemp
+ taskfunc.task_earlycheck = earlycheck
+ return taskfunc
+
+# TODO:
+# sanity-checks using states
+
+_BACKEND_TO_TYPESYSTEM = {
+ 'c': 'lltype',
+ 'llvm': 'lltype'
+}
+
+def backend_to_typesystem(backend):
+ return _BACKEND_TO_TYPESYSTEM.get(backend, 'ootype')
+
+# set of translation steps to profile
+PROFILE = set([])
+
+class Instrument(Exception):
+ pass
+
+
+class ProfInstrument(object):
+ name = "profinstrument"
+ def __init__(self, datafile, compiler):
+ self.datafile = datafile
+ self.compiler = compiler
+
+ def first(self):
+ self.compiler._build()
+
+ def probe(self, exe, args):
+ from py.compat import subprocess
+ env = os.environ.copy()
+ env['_INSTRUMENT_COUNTERS'] = str(self.datafile)
+ subprocess.call("'%s' %s" % (exe, args), env=env, shell=True)
+
+ def after(self):
+ # xxx
+ os._exit(0)
+
+
+class TranslationDriver(SimpleTaskEngine):
+
+ def __init__(self, setopts=None, default_goal=None,
+ disable=[],
+ exe_name=None, extmod_name=None,
+ config=None, overrides=None):
+ self.timer = Timer()
+ SimpleTaskEngine.__init__(self)
+
+ self.log = log
+
+ if config is None:
+ from pypy.config.pypyoption import get_pypy_config
+ config = get_pypy_config(DEFAULTS, translating=True)
+ self.config = config
+ if overrides is not None:
+ self.config.override(overrides)
+
+ if setopts is not None:
+ self.config.set(**setopts)
+
+ self.exe_name = exe_name
+ self.extmod_name = extmod_name
+
+ self.done = {}
+
+ self.disable(disable)
+
+ if default_goal:
+ default_goal, = self.backend_select_goals([default_goal])
+ if default_goal in self._maybe_skip():
+ default_goal = None
+
+ self.default_goal = default_goal
+ self.extra_goals = []
+ self.exposed = []
+
+ # expose tasks
+ def expose_task(task, backend_goal=None):
+ if backend_goal is None:
+ backend_goal = task
+ def proc():
+ return self.proceed(backend_goal)
+ self.exposed.append(task)
+ setattr(self, task, proc)
+
+ backend, ts = self.get_backend_and_type_system()
+ for task in self.tasks:
+ explicit_task = task
+ parts = task.split('_')
+ if len(parts) == 1:
+ if task in ('annotate'):
+ expose_task(task)
+ else:
+ task, postfix = parts
+ if task in ('rtype', 'backendopt', 'llinterpret',
+ 'prehannotatebackendopt', 'hintannotate',
+ 'timeshift'):
+ if ts:
+ if ts == postfix:
+ expose_task(task, explicit_task)
+ else:
+ expose_task(explicit_task)
+ elif task in ('source', 'compile', 'run'):
+ if backend:
+ if backend == postfix:
+ expose_task(task, explicit_task)
+ elif ts:
+ if ts == backend_to_typesystem(postfix):
+ expose_task(explicit_task)
+ else:
+ expose_task(explicit_task)
+
+ def set_extra_goals(self, goals):
+ self.extra_goals = goals
+
+ def get_info(self): # XXX more?
+ d = {'backend': self.config.translation.backend}
+ return d
+
+ def get_backend_and_type_system(self):
+ type_system = self.config.translation.type_system
+ backend = self.config.translation.backend
+ return backend, type_system
+
+ def backend_select_goals(self, goals):
+ backend, ts = self.get_backend_and_type_system()
+ postfixes = [''] + ['_'+p for p in (backend, ts) if p]
+ l = []
+ for goal in goals:
+ for postfix in postfixes:
+ cand = "%s%s" % (goal, postfix)
+ if cand in self.tasks:
+ new_goal = cand
+ break
+ else:
+ raise Exception, "cannot infer complete goal from: %r" % goal
+ l.append(new_goal)
+ return l
+
+ def disable(self, to_disable):
+ self._disabled = to_disable
+
+ def _maybe_skip(self):
+ maybe_skip = []
+ if self._disabled:
+ for goal in self.backend_select_goals(self._disabled):
+ maybe_skip.extend(self._depending_on_closure(goal))
+ return dict.fromkeys(maybe_skip).keys()
+
+
+ def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None):
+ standalone = inputtypes is None
+ self.standalone = standalone
+
+ if standalone:
+ inputtypes = [s_list_of_strings]
+ self.inputtypes = inputtypes
+
+ if policy is None:
+ policy = annpolicy.AnnotatorPolicy()
+ if standalone:
+ policy.allow_someobjects = False
+ self.policy = policy
+
+ self.extra = extra
+
+ if empty_translator:
+ translator = empty_translator
+ else:
+ translator = TranslationContext(config=self.config)
+
+ self.entry_point = entry_point
+ self.translator = translator
+ self.libdef = None
+
+ self.translator.driver_instrument_result = self.instrument_result
+
+ def setup_library(self, libdef, policy=None, extra={}, empty_translator=None):
+ self.setup(None, None, policy, extra, empty_translator)
+ self.libdef = libdef
+
+ def instrument_result(self, args):
+ backend, ts = self.get_backend_and_type_system()
+ if backend != 'c' or sys.platform == 'win32':
+ raise Exception("instrumentation requires the c backend"
+ " and unix for now")
+ from pypy.tool.udir import udir
+
+ datafile = udir.join('_instrument_counters')
+ makeProfInstrument = lambda compiler: ProfInstrument(datafile, compiler)
+
+ pid = os.fork()
+ if pid == 0:
+ # child compiling and running with instrumentation
+ self.config.translation.instrument = True
+ self.config.translation.instrumentctl = (makeProfInstrument,
+ args)
+ raise Instrument
+ else:
+ pid, status = os.waitpid(pid, 0)
+ if os.WIFEXITED(status):
+ status = os.WEXITSTATUS(status)
+ if status != 0:
+ raise Exception, "instrumentation child failed: %d" % status
+ else:
+ raise Exception, "instrumentation child aborted"
+ import array, struct
+ n = datafile.size()//struct.calcsize('L')
+ datafile = datafile.open('rb')
+ counters = array.array('L')
+ counters.fromfile(datafile, n)
+ datafile.close()
+ return counters
+
+ def info(self, msg):
+ log.info(msg)
+
+ def _profile(self, goal, func):
+ from cProfile import Profile
+ from pypy.tool.lsprofcalltree import KCacheGrind
+ d = {'func':func}
+ prof = Profile()
+ prof.runctx("res = func()", globals(), d)
+ KCacheGrind(prof).output(open(goal + ".out", "w"))
+ return d['res']
+
+ def _do(self, goal, func, *args, **kwds):
+ title = func.task_title
+ if goal in self.done:
+ self.log.info("already done: %s" % title)
+ return
+ else:
+ self.log.info("%s..." % title)
+ self.timer.start_event(goal)
+ try:
+ instrument = False
+ try:
+ if goal in PROFILE:
+ res = self._profile(goal, func)
+ else:
+ res = func()
+ except Instrument:
+ instrument = True
+ if not func.task_idempotent:
+ self.done[goal] = True
+ if instrument:
+ self.proceed('compile')
+ assert False, 'we should not get here'
+ finally:
+ self.timer.end_event(goal)
+ return res
+
+ def task_annotate(self):
+ # includes annotation and annotatation simplifications
+ translator = self.translator
+ policy = self.policy
+ self.log.info('with policy: %s.%s' %
+ (policy.__class__.__module__, policy.__class__.__name__))
+
+ annmodel.DEBUG = self.config.translation.debug
+ annotator = translator.buildannotator(policy=policy)
+
+ if self.entry_point:
+ s = annotator.build_types(self.entry_point, self.inputtypes)
+
+ self.sanity_check_annotation()
+ if self.standalone and s.knowntype != int:
+ raise Exception("stand-alone program entry point must return an "
+ "int (and not, e.g., None or always raise an "
+ "exception).")
+ annotator.simplify()
+ return s
+ else:
+ assert self.libdef is not None
+ for func, inputtypes in self.libdef.functions:
+ annotator.build_types(func, inputtypes)
+ self.sanity_check_annotation()
+ annotator.simplify()
+ #
+ task_annotate = taskdef(task_annotate, [], "Annotating&simplifying")
+
+
+ def sanity_check_annotation(self):
+ translator = self.translator
+ irreg = query.qoutput(query.check_exceptblocks_qgen(translator))
+ if irreg:
+ self.log.info("Some exceptblocks seem insane")
+
+ lost = query.qoutput(query.check_methods_qgen(translator))
+ assert not lost, "lost methods, something gone wrong with the annotation of method defs"
+
+ so = query.qoutput(query.polluted_qgen(translator))
+ tot = len(translator.graphs)
+ percent = int(tot and (100.0*so / tot) or 0)
+ # if there are a few SomeObjects even if the policy doesn't allow
+ # them, it means that they were put there in a controlled way
+ # and then it's not a warning.
+ if not translator.annotator.policy.allow_someobjects:
+ pr = self.log.info
+ elif percent == 0:
+ pr = self.log.info
+ else:
+ pr = log.WARNING
+ pr("-- someobjectness %2d%% (%d of %d functions polluted by SomeObjects)" % (percent, so, tot))
+
+
+
+ def task_rtype_lltype(self):
+ rtyper = self.translator.buildrtyper(type_system='lltype')
+ insist = not self.config.translation.insist
+ rtyper.specialize(dont_simplify_again=True,
+ crash_on_first_typeerror=insist)
+ #
+ task_rtype_lltype = taskdef(task_rtype_lltype, ['annotate'], "RTyping")
+ RTYPE = 'rtype_lltype'
+
+ def task_rtype_ootype(self):
+ # Maybe type_system should simply be an option used in task_rtype
+ insist = not self.config.translation.insist
+ rtyper = self.translator.buildrtyper(type_system="ootype")
+ rtyper.specialize(dont_simplify_again=True,
+ crash_on_first_typeerror=insist)
+ #
+ task_rtype_ootype = taskdef(task_rtype_ootype, ['annotate'], "ootyping")
+ OOTYPE = 'rtype_ootype'
+
+ def task_prehannotatebackendopt_lltype(self):
+ from pypy.translator.backendopt.all import backend_optimizations
+ backend_optimizations(self.translator,
+ inline_threshold=0,
+ merge_if_blocks=True,
+ constfold=True,
+ raisingop2direct_call=False,
+ remove_asserts=True)
+ #
+ task_prehannotatebackendopt_lltype = taskdef(
+ task_prehannotatebackendopt_lltype,
+ [RTYPE],
+ "Backendopt before Hint-annotate")
+
+ def task_hintannotate_lltype(self):
+ from pypy.jit.hintannotator.annotator import HintAnnotator
+ from pypy.jit.hintannotator.model import OriginFlags
+ from pypy.jit.hintannotator.model import SomeLLAbstractConstant
+
+ get_portal = self.extra['portal']
+ PORTAL, POLICY = get_portal(self)
+ t = self.translator
+ self.portal_graph = graphof(t, PORTAL)
+
+ hannotator = HintAnnotator(base_translator=t, policy=POLICY)
+ self.hint_translator = hannotator.translator
+ hs = hannotator.build_types(self.portal_graph,
+ [SomeLLAbstractConstant(v.concretetype,
+ {OriginFlags(): True})
+ for v in self.portal_graph.getargs()])
+ count = hannotator.bookkeeper.nonstuboriggraphcount
+ stubcount = hannotator.bookkeeper.stuboriggraphcount
+ self.log.info("The hint-annotator saw %d graphs"
+ " (and made stubs for %d graphs)." % (count, stubcount))
+ n = len(list(hannotator.translator.graphs[0].iterblocks()))
+ self.log.info("portal has %d blocks" % n)
+ self.hannotator = hannotator
+ #
+ task_hintannotate_lltype = taskdef(task_hintannotate_lltype,
+ ['prehannotatebackendopt_lltype'],
+ "Hint-annotate")
+
+ def task_timeshift_lltype(self):
+ from pypy.jit.timeshifter.hrtyper import HintRTyper
+ from pypy.jit.codegen import detect_cpu
+ cpu = detect_cpu.autodetect()
+ if cpu == 'i386':
+ from pypy.jit.codegen.i386.rgenop import RI386GenOp as RGenOp
+ RGenOp.MC_SIZE = 32 * 1024 * 1024
+ elif cpu == 'ppc':
+ from pypy.jit.codegen.ppc.rgenop import RPPCGenOp as RGenOp
+ RGenOp.MC_SIZE = 32 * 1024 * 1024
+ else:
+ raise Exception('Unsuported cpu %r'%cpu)
+
+ del self.hint_translator
+ ha = self.hannotator
+ t = self.translator
+ # make the timeshifted graphs
+ hrtyper = HintRTyper(ha, t.rtyper, RGenOp)
+ hrtyper.specialize(origportalgraph=self.portal_graph, view=False)
+ #
+ task_timeshift_lltype = taskdef(task_timeshift_lltype,
+ ["hintannotate_lltype"],
+ "Timeshift")
+
+ def task_backendopt_lltype(self):
+ from pypy.translator.backendopt.all import backend_optimizations
+ backend_optimizations(self.translator)
+ #
+ task_backendopt_lltype = taskdef(task_backendopt_lltype,
+ [RTYPE,
+ '??timeshift_lltype'],
+ "lltype back-end optimisations")
+ BACKENDOPT = 'backendopt_lltype'
+
+ def task_backendopt_ootype(self):
+ from pypy.translator.backendopt.all import backend_optimizations
+ backend_optimizations(self.translator)
+ #
+ task_backendopt_ootype = taskdef(task_backendopt_ootype,
+ [OOTYPE], "ootype back-end optimisations")
+ OOBACKENDOPT = 'backendopt_ootype'
+
+
+ def task_stackcheckinsertion_lltype(self):
+ from pypy.translator.transform import insert_ll_stackcheck
+ count = insert_ll_stackcheck(self.translator)
+ self.log.info("inserted %d stack checks." % (count,))
+
+ task_stackcheckinsertion_lltype = taskdef(
+ task_stackcheckinsertion_lltype,
+ ['?'+BACKENDOPT, RTYPE, 'annotate'],
+ "inserting stack checks")
+ STACKCHECKINSERTION = 'stackcheckinsertion_lltype'
+
+ def possibly_check_for_boehm(self):
+ if self.config.translation.gc == "boehm":
+ from pypy.translator.tool.cbuild import check_boehm_presence
+ from pypy.translator.tool.cbuild import CompilationError
+ try:
+ check_boehm_presence(noerr=False)
+ except CompilationError, e:
+ i = 'Boehm GC not installed. Try e.g. "translate.py --gc=hybrid"'
+ raise CompilationError('%s\n--------------------\n%s' % (e, i))
+
+ def task_database_c(self):
+ translator = self.translator
+ if translator.annotator is not None:
+ translator.frozen = True
+
+ standalone = self.standalone
+
+ if standalone:
+ from pypy.translator.c.genc import CStandaloneBuilder as CBuilder
+ else:
+ from pypy.translator.c.genc import CExtModuleBuilder as CBuilder
+ cbuilder = CBuilder(self.translator, self.entry_point,
+ config=self.config)
+ cbuilder.stackless = self.config.translation.stackless
+ if not standalone: # xxx more messy
+ cbuilder.modulename = self.extmod_name
+ database = cbuilder.build_database()
+ self.log.info("database for generating C source was created")
+ self.cbuilder = cbuilder
+ self.database = database
+ #
+ task_database_c = taskdef(task_database_c,
+ [STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE, '?annotate'],
+ "Creating database for generating c source",
+ earlycheck = possibly_check_for_boehm)
+
+ def task_source_c(self): # xxx messy
+ translator = self.translator
+ cbuilder = self.cbuilder
+ database = self.database
+ c_source_filename = cbuilder.generate_source(database)
+ self.log.info("written: %s" % (c_source_filename,))
+ self.c_source_filename = str(c_source_filename)
+ #
+ task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
+
+ def task_compile_c(self): # xxx messy
+ cbuilder = self.cbuilder
+ cbuilder.compile()
+
+ if self.standalone:
+ self.c_entryp = cbuilder.executable_name
+ self.create_exe()
+ else:
+ self.c_entryp = cbuilder.get_entry_point()
+ #
+ task_compile_c = taskdef(task_compile_c, ['source_c'], "Compiling c source")
+
+
+ def task_run_c(self):
+ self.backend_run('c')
+ #
+ task_run_c = taskdef(task_run_c, ['compile_c'],
+ "Running compiled c source",
+ idemp=True)
+
+ def task_llinterpret_lltype(self):
+ from pypy.rpython.llinterp import LLInterpreter
+ py.log.setconsumer("llinterp operation", None)
+
+ translator = self.translator
+ interp = LLInterpreter(translator.rtyper)
+ bk = translator.annotator.bookkeeper
+ graph = bk.getdesc(self.entry_point).getuniquegraph()
+ v = interp.eval_graph(graph,
+ self.extra.get('get_llinterp_args',
+ lambda: [])())
+
+ log.llinterpret.event("result -> %s" % v)
+ #
+ task_llinterpret_lltype = taskdef(task_llinterpret_lltype,
+ [STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE],
+ "LLInterpreting")
+
+ def task_source_llvm(self):
+ translator = self.translator
+ if translator.annotator is None:
+ raise ValueError, "llvm requires annotation."
+
+ from pypy.translator.llvm import genllvm
+
+ self.llvmgen = genllvm.GenLLVM(translator, self.standalone)
+
+ llvm_filename = self.llvmgen.gen_source(self.entry_point)
+ self.log.info("written: %s" % (llvm_filename,))
+ #
+ task_source_llvm = taskdef(task_source_llvm,
+ [STACKCHECKINSERTION, BACKENDOPT, RTYPE],
+ "Generating llvm source")
+
+ def task_compile_llvm(self):
+ gen = self.llvmgen
+ if self.standalone:
+ exe_name = (self.exe_name or 'testing') % self.get_info()
+ self.c_entryp = gen.compile_standalone(exe_name)
+ self.create_exe()
+ else:
+ self.c_module, self.c_entryp = gen.compile_module()
+ #
+ task_compile_llvm = taskdef(task_compile_llvm,
+ ['source_llvm'],
+ "Compiling llvm source")
+
+ def task_run_llvm(self):
+ self.backend_run('llvm')
+ #
+ task_run_llvm = taskdef(task_run_llvm, ['compile_llvm'],
+ "Running compiled llvm source",
+ idemp=True)
+
+ def task_source_js(self):
+ from pypy.translator.js.js import JS
+ self.gen = JS(self.translator, functions=[self.entry_point],
+ stackless=self.config.translation.stackless)
+ filename = self.gen.write_source()
+ self.log.info("Wrote %s" % (filename,))
+ task_source_js = taskdef(task_source_js,
+ [OOTYPE],
+ 'Generating Javascript source')
+
+ def task_compile_js(self):
+ pass
+ task_compile_js = taskdef(task_compile_js, ['source_js'],
+ 'Skipping Javascript compilation')
+
+ def task_run_js(self):
+ pass
+ task_run_js = taskdef(task_run_js, ['compile_js'],
+ 'Please manually run the generated code')
+
+ def task_source_cli(self):
+ from pypy.translator.cli.gencli import GenCli
+ from pypy.translator.cli.entrypoint import get_entrypoint
+
+ if self.entry_point is not None: # executable mode
+ entry_point_graph = self.translator.graphs[0]
+ entry_point = get_entrypoint(entry_point_graph)
+ else:
+ # library mode
+ assert self.libdef is not None
+ bk = self.translator.annotator.bookkeeper
+ entry_point = self.libdef.get_entrypoint(bk)
+
+ self.gen = GenCli(udir, self.translator, entry_point, config=self.config)
+ filename = self.gen.generate_source()
+ self.log.info("Wrote %s" % (filename,))
+ task_source_cli = taskdef(task_source_cli, ["?" + OOBACKENDOPT, OOTYPE],
+ 'Generating CLI source')
+
+ def task_compile_cli(self):
+ from pypy.translator.oosupport.support import unpatch_os
+ from pypy.translator.cli.test.runtest import CliFunctionWrapper
+ filename = self.gen.build_exe()
+ self.c_entryp = CliFunctionWrapper(filename)
+ # restore original os values
+ if hasattr(self, 'old_cli_defs'):
+ unpatch_os(self.old_cli_defs)
+
+ self.log.info("Compiled %s" % filename)
+ if self.standalone and self.exe_name:
+ self.copy_cli_exe()
+ task_compile_cli = taskdef(task_compile_cli, ['source_cli'],
+ 'Compiling CLI source')
+
+ def task_run_cli(self):
+ pass
+ task_run_cli = taskdef(task_run_cli, ['compile_cli'],
+ 'XXX')
+
+ def task_source_jvm(self):
+ from pypy.translator.jvm.genjvm import GenJvm
+ from pypy.translator.jvm.node import EntryPoint
+
+ entry_point_graph = self.translator.graphs[0]
+ is_func = not self.standalone
+ entry_point = EntryPoint(entry_point_graph, is_func, is_func)
+ self.gen = GenJvm(udir, self.translator, entry_point)
+ self.jvmsource = self.gen.generate_source()
+ self.log.info("Wrote JVM code")
+ task_source_jvm = taskdef(task_source_jvm, ["?" + OOBACKENDOPT, OOTYPE],
+ 'Generating JVM source')
+
+ def task_compile_jvm(self):
+ from pypy.translator.oosupport.support import unpatch_os
+ from pypy.translator.jvm.test.runtest import JvmGeneratedSourceWrapper
+ self.jvmsource.compile()
+ self.c_entryp = JvmGeneratedSourceWrapper(self.jvmsource)
+ # restore original os values
+ if hasattr(self, 'old_cli_defs'):
+ unpatch_os(self.old_cli_defs)
+ self.log.info("Compiled JVM source")
+ if self.standalone and self.exe_name:
+ self.copy_jvm_jar()
+ task_compile_jvm = taskdef(task_compile_jvm, ['source_jvm'],
+ 'Compiling JVM source')
+
+ def task_run_jvm(self):
+ pass
+ task_run_jvm = taskdef(task_run_jvm, ['compile_jvm'],
+ 'XXX')
+
+ def proceed(self, goals):
+ if not goals:
+ if self.default_goal:
+ goals = [self.default_goal]
+ else:
+ self.log.info("nothing to do")
+ return
+ elif isinstance(goals, str):
+ goals = [goals]
+ goals.extend(self.extra_goals)
+ goals = self.backend_select_goals(goals)
+ return self._execute(goals, task_skip = self._maybe_skip())
+
+ def from_targetspec(targetspec_dic, config=None, args=None,
+ empty_translator=None,
+ disable=[],
+ default_goal=None):
+ if args is None:
+ args = []
+
+ driver = TranslationDriver(config=config, default_goal=default_goal,
+ disable=disable)
+ # patch some attributes of the os module to make sure they
+ # have the same value on every platform.
+ backend, ts = driver.get_backend_and_type_system()
+ if backend in ('cli', 'jvm'):
+ from pypy.translator.oosupport.support import patch_os
+ driver.old_cli_defs = patch_os()
+
+ target = targetspec_dic['target']
+ spec = target(driver, args)
+
+ try:
+ entry_point, inputtypes, policy = spec
+ except ValueError:
+ entry_point, inputtypes = spec
+ policy = None
+
+ driver.setup(entry_point, inputtypes,
+ policy=policy,
+ extra=targetspec_dic,
+ empty_translator=empty_translator)
+
+ return driver
+
+ from_targetspec = staticmethod(from_targetspec)
+
+ def prereq_checkpt_rtype(self):
+ assert 'pypy.rpython.rmodel' not in sys.modules, (
+ "cannot fork because the rtyper has already been imported")
+ prereq_checkpt_rtype_lltype = prereq_checkpt_rtype
+ prereq_checkpt_rtype_ootype = prereq_checkpt_rtype
Added: trunk/scipy/sandbox/mkufunc/head.c
===================================================================
--- trunk/scipy/sandbox/mkufunc/head.c 2008-06-24 17:48:31 UTC (rev 4478)
+++ trunk/scipy/sandbox/mkufunc/head.c 2008-06-25 15:43:39 UTC (rev 4479)
@@ -0,0 +1,380 @@
+
+#include <math.h>
+
+/* ================================================== g_prerequisite.h === */
+
+typedef unsigned char bool_t;
+
+/* ================================================== exception.h ======== */
+
+#define RPY_DEBUG_RETURN() /* nothing */
+
+
+/* ================================================== int.h ============== */
+
+/*** unary operations ***/
+
+#define OP_INT_IS_TRUE(x,r) OP_INT_NE(x,0,r)
+
+#define OP_INT_INVERT(x,r) r = ~((x))
+
+#define OP_INT_NEG(x,r) r = -(x)
+
+#define OP_INT_NEG_OVF(x,r) \
+ if ((x) == LONG_MIN) FAIL_OVF("integer negate"); \
+ OP_INT_NEG(x,r)
+#define OP_LLONG_NEG_OVF(x,r) \
+ if ((x) == LLONG_MIN) FAIL_OVF("integer negate"); \
+ OP_LLONG_NEG(x,r)
+
+#define OP_INT_ABS(x,r) r = (x) >= 0 ? x : -(x)
+
+#define OP_INT_ABS_OVF(x,r) \
+ if ((x) == LONG_MIN) FAIL_OVF("integer absolute"); \
+ OP_INT_ABS(x,r)
+#define OP_LLONG_ABS_OVF(x,r) \
+ if ((x) == LLONG_MIN) FAIL_OVF("integer absolute"); \
+ OP_LLONG_ABS(x,r)
+
+/*** binary operations ***/
+
+#define OP_INT_EQ(x,y,r) r = ((x) == (y))
+#define OP_INT_NE(x,y,r) r = ((x) != (y))
+#define OP_INT_LE(x,y,r) r = ((x) <= (y))
+#define OP_INT_GT(x,y,r) r = ((x) > (y))
+#define OP_INT_LT(x,y,r) r = ((x) < (y))
+#define OP_INT_GE(x,y,r) r = ((x) >= (y))
+
+/* addition, subtraction */
+
+#define OP_INT_ADD(x,y,r) r = (x) + (y)
+
+#define OP_INT_ADD_OVF(x,y,r) \
+ OP_INT_ADD(x,y,r); \
+ if ((r^(x)) >= 0 || (r^(y)) >= 0); \
+ else FAIL_OVF("integer addition")
+
+#define OP_INT_ADD_NONNEG_OVF(x,y,r) /* y can be assumed >= 0 */ \
+ OP_INT_ADD(x,y,r); \
+ if (r >= (x)); \
+ else FAIL_OVF("integer addition")
+/* XXX can a C compiler be too clever and think it can "prove" that
+ * r >= x always hold above? */
+
+#define OP_INT_SUB(x,y,r) r = (x) - (y)
+
+#define OP_INT_SUB_OVF(x,y,r) \
+ OP_INT_SUB(x,y,r); \
+ if ((r^(x)) >= 0 || (r^~(y)) >= 0); \
+ else FAIL_OVF("integer subtraction")
+
+#define OP_INT_MUL(x,y,r) r = (x) * (y)
+
+#if defined(HAVE_LONG_LONG) && SIZE_OF_LONG_LONG < SIZE_OF_LONG
+# define OP_INT_MUL_OVF_LL 1
+#lse
+# define OP_INT_MUL_OVF_LL 0
+#endif
+
+#if !OP_INT_MUL_OVF_LL
+
+#define OP_INT_MUL_OVF(x,y,r) \
+ if (op_int_mul_ovf(x,y,&r)); \
+ else FAIL_OVF("integer multiplication")
+
+#else
+
+#define OP_INT_MUL_OVF(x,y,r) \
+ { \
+ PY_LONG_LONG lr = (PY_LONG_LONG)(x) * (PY_LONG_LONG)(y); \
+ r = (long)lr; \
+ if ((PY_LONG_LONG)r == lr); \
+ else FAIL_OVF("integer multiplication"); \
+ }
+#endif
+
+/* shifting */
+
+/* NB. shifting has same limitations as C: the shift count must be
+ >= 0 and < LONG_BITS. */
+#define OP_INT_RSHIFT(x,y,r) r = Py_ARITHMETIC_RIGHT_SHIFT(long, x, y)
+#define OP_UINT_RSHIFT(x,y,r) r = (x) >> (y)
+#define OP_LLONG_RSHIFT(x,y,r) r = Py_ARITHMETIC_RIGHT_SHIFT(PY_LONG_LONG,x,y)
+#define OP_ULLONG_RSHIFT(x,y,r) r = (x) >> (y)
+
+#define OP_INT_LSHIFT(x,y,r) r = (x) << (y)
+#define OP_UINT_LSHIFT(x,y,r) r = (x) << (y)
+#define OP_LLONG_LSHIFT(x,y,r) r = (x) << (y)
+#define OP_ULLONG_LSHIFT(x,y,r) r = (x) << (y)
+
+#define OP_INT_LSHIFT_OVF(x,y,r) \
+ OP_INT_LSHIFT(x,y,r); \
+ if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(long, r, (y))) \
+ FAIL_OVF("x<<y losing bits or changing sign")
+
+/* the safe value-checking version of the above macros */
+
+#define OP_INT_RSHIFT_VAL(x,y,r) \
+ if ((y) >= 0) { OP_INT_RSHIFT(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+#define OP_LLONG_RSHIFT_VAL(x,y,r) \
+ if ((y) >= 0) { OP_LLONG_RSHIFT(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+
+#define OP_INT_LSHIFT_VAL(x,y,r) \
+ if ((y) >= 0) { OP_INT_LSHIFT(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+#define OP_LLONG_LSHIFT_VAL(x,y,r) \
+ if ((y) >= 0) { OP_LLONG_LSHIFT(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+
+#define OP_INT_LSHIFT_OVF_VAL(x,y,r) \
+ if ((y) >= 0) { OP_INT_LSHIFT_OVF(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+
+/* pff */
+#define OP_UINT_LSHIFT_VAL(x,y,r) \
+ if ((y) >= 0) { OP_UINT_LSHIFT(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+#define OP_ULLONG_LSHIFT_VAL(x,y,r) \
+ if ((y) >= 0) { OP_ULLONG_LSHIFT(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+
+#define OP_UINT_RSHIFT_VAL(x,y,r) \
+ if ((y) >= 0) { OP_UINT_RSHIFT(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+#define OP_ULLONG_RSHIFT_VAL(x,y,r) \
+ if ((y) >= 0) { OP_ULLONG_RSHIFT(x,y,r); } \
+ else FAIL_VAL("negative shift count")
+
+
+/* floor division */
+
+#define OP_INT_FLOORDIV(x,y,r) r = (x) / (y)
+#define OP_UINT_FLOORDIV(x,y,r) r = (x) / (y)
+#define OP_LLONG_FLOORDIV(x,y,r) r = (x) / (y)
+#define OP_ULLONG_FLOORDIV(x,y,r) r = (x) / (y)
+
+#define OP_INT_FLOORDIV_OVF(x,y,r) \
+ if ((y) == -1 && (x) == LONG_MIN) \
+ { FAIL_OVF("integer division"); } \
+ else OP_INT_FLOORDIV(x,y,r)
+
+#define OP_INT_FLOORDIV_ZER(x,y,r) \
+ if ((y)) { OP_INT_FLOORDIV(x,y,r); } \
+ else FAIL_ZER("integer division")
+#define OP_UINT_FLOORDIV_ZER(x,y,r) \
+ if ((y)) { OP_UINT_FLOORDIV(x,y,r); } \
+ else FAIL_ZER("unsigned integer division")
+#define OP_LLONG_FLOORDIV_ZER(x,y,r) \
+ if ((y)) { OP_LLONG_FLOORDIV(x,y,r); } \
+ else FAIL_ZER("integer division")
+#define OP_ULLONG_FLOORDIV_ZER(x,y,r) \
+ if ((y)) { OP_ULLONG_FLOORDIV(x,y,r); } \
+ else FAIL_ZER("unsigned integer division")
+
+#define OP_INT_FLOORDIV_OVF_ZER(x,y,r) \
+ if ((y)) { OP_INT_FLOORDIV_OVF(x,y,r); } \
+ else FAIL_ZER("integer division")
+
+/* modulus */
+
+#define OP_INT_MOD(x,y,r) r = (x) % (y)
+#define OP_UINT_MOD(x,y,r) r = (x) % (y)
+#define OP_LLONG_MOD(x,y,r) r = (x) % (y)
+#define OP_ULLONG_MOD(x,y,r) r = (x) % (y)
+
+#define OP_INT_MOD_OVF(x,y,r) \
+ if ((y) == -1 && (x) == LONG_MIN) \
+ { FAIL_OVF("integer modulo"); }\
+ else OP_INT_MOD(x,y,r)
+
+#define OP_INT_MOD_ZER(x,y,r) \
+ if ((y)) { OP_INT_MOD(x,y,r); } \
+ else FAIL_ZER("integer modulo")
+#define OP_UINT_MOD_ZER(x,y,r) \
+ if ((y)) { OP_UINT_MOD(x,y,r); } \
+ else FAIL_ZER("unsigned integer modulo")
+#define OP_LLONG_MOD_ZER(x,y,r) \
+ if ((y)) { OP_LLONG_MOD(x,y,r); } \
+ else FAIL_ZER("integer modulo")
+#define OP_ULLONG_MOD_ZER(x,y,r) \
+ if ((y)) { OP_ULLONG_MOD(x,y,r); } \
+ else FAIL_ZER("integer modulo")
+
+#define OP_INT_MOD_OVF_ZER(x,y,r) \
+ if ((y)) { OP_INT_MOD_OVF(x,y,r); } \
+ else FAIL_ZER("integer modulo")
+
+/* bit operations */
+
+#define OP_INT_AND(x,y,r) r = (x) & (y)
+#define OP_INT_OR( x,y,r) r = (x) | (y)
+#define OP_INT_XOR(x,y,r) r = (x) ^ (y)
+
+/*** conversions ***/
+
+#define OP_CAST_BOOL_TO_INT(x,r) r = (long)(x)
+#define OP_CAST_BOOL_TO_UINT(x,r) r = (unsigned long)(x)
+#define OP_CAST_UINT_TO_INT(x,r) r = (long)(x)
+#define OP_CAST_INT_TO_UINT(x,r) r = (unsigned long)(x)
+#define OP_CAST_INT_TO_LONGLONG(x,r) r = (long long)(x)
+#define OP_CAST_CHAR_TO_INT(x,r) r = (long)((unsigned char)(x))
+#define OP_CAST_INT_TO_CHAR(x,r) r = (char)(x)
+#define OP_CAST_PTR_TO_INT(x,r) r = (long)(x) /* XXX */
+
+#define OP_TRUNCATE_LONGLONG_TO_INT(x,r) r = (long)(x)
+
+#define OP_CAST_UNICHAR_TO_INT(x,r) r = (long)((unsigned long)(x)) /*?*/
+#define OP_CAST_INT_TO_UNICHAR(x,r) r = (unsigned int)(x)
+
+/* bool operations */
+
+#define OP_BOOL_NOT(x, r) r = !(x)
+
+/* _________________ certain implementations __________________ */
+
+#if !OP_INT_MUL_OVF_LL
+/* adjusted from intobject.c, Python 2.3.3 */
+
+/* prototypes */
+
+int op_int_mul_ovf(long a, long b, long *longprod);
+
+/* implementations */
+
+#ifndef PYPY_NOT_MAIN_FILE
+
+int
+op_int_mul_ovf(long a, long b, long *longprod)
+{
+ double doubled_longprod; /* (double)longprod */
+ double doubleprod; /* (double)a * (double)b */
+
+ *longprod = a * b;
+ doubleprod = (double)a * (double)b;
+ doubled_longprod = (double)*longprod;
+
+ /* Fast path for normal case: small multiplicands, and no info
+ is lost in either method. */
+ if (doubled_longprod == doubleprod)
+ return 1;
+
+ /* Somebody somewhere lost info. Close enough, or way off? Note
+ that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
+ The difference either is or isn't significant compared to the
+ true value (of which doubleprod is a good approximation).
+ */
+ {
+ const double diff = doubled_longprod - doubleprod;
+ const double absdiff = diff >= 0.0 ? diff : -diff;
+ const double absprod = doubleprod >= 0.0 ? doubleprod :
+ -doubleprod;
+ /* absdiff/absprod <= 1/32 iff
+ 32 * absdiff <= absprod -- 5 good bits is "close enough" */
+ if (32.0 * absdiff <= absprod)
+ return 1;
+ return 0;
+ }
+}
+
+#endif /* PYPY_NOT_MAIN_FILE */
+
+#endif /* !OP_INT_MUL_OVF_LL */
+
+/* implementations */
+
+#define OP_UINT_IS_TRUE OP_INT_IS_TRUE
+#define OP_UINT_INVERT OP_INT_INVERT
+#define OP_UINT_ADD OP_INT_ADD
+#define OP_UINT_SUB OP_INT_SUB
+#define OP_UINT_MUL OP_INT_MUL
+#define OP_UINT_LT OP_INT_LT
+#define OP_UINT_LE OP_INT_LE
+#define OP_UINT_EQ OP_INT_EQ
+#define OP_UINT_NE OP_INT_NE
+#define OP_UINT_GT OP_INT_GT
+#define OP_UINT_GE OP_INT_GE
+#define OP_UINT_AND OP_INT_AND
+#define OP_UINT_OR OP_INT_OR
+#define OP_UINT_XOR OP_INT_XOR
+
+#define OP_LLONG_IS_TRUE OP_INT_IS_TRUE
+#define OP_LLONG_NEG OP_INT_NEG
+#define OP_LLONG_ABS OP_INT_ABS
+#define OP_LLONG_INVERT OP_INT_INVERT
+
+#define OP_LLONG_ADD OP_INT_ADD
+#define OP_LLONG_SUB OP_INT_SUB
+#define OP_LLONG_MUL OP_INT_MUL
+#define OP_LLONG_LT OP_INT_LT
+#define OP_LLONG_LE OP_INT_LE
+#define OP_LLONG_EQ OP_INT_EQ
+#define OP_LLONG_NE OP_INT_NE
+#define OP_LLONG_GT OP_INT_GT
+#define OP_LLONG_GE OP_INT_GE
+#define OP_LLONG_AND OP_INT_AND
+#define OP_LLONG_OR OP_INT_OR
+#define OP_LLONG_XOR OP_INT_XOR
+
+#define OP_ULLONG_IS_TRUE OP_LLONG_IS_TRUE
+#define OP_ULLONG_INVERT OP_LLONG_INVERT
+#define OP_ULLONG_ADD OP_LLONG_ADD
+#define OP_ULLONG_SUB OP_LLONG_SUB
+#define OP_ULLONG_MUL OP_LLONG_MUL
+#define OP_ULLONG_LT OP_LLONG_LT
+#define OP_ULLONG_LE OP_LLONG_LE
+#define OP_ULLONG_EQ OP_LLONG_EQ
+#define OP_ULLONG_NE OP_LLONG_NE
+#define OP_ULLONG_GT OP_LLONG_GT
+#define OP_ULLONG_GE OP_LLONG_GE
+#define OP_ULLONG_AND OP_LLONG_AND
+#define OP_ULLONG_OR OP_LLONG_OR
+#define OP_ULLONG_XOR OP_LLONG_XOR
+
+/* ================================================== float.h ============ */
+
+/*** unary operations ***/
+
+#define OP_FLOAT_IS_TRUE(x,r) OP_FLOAT_NE(x,0.0,r)
+#define OP_FLOAT_NEG(x,r) r = -x
+#define OP_FLOAT_ABS(x,r) r = fabs(x)
+
+/*** binary operations ***/
+
+#define OP_FLOAT_EQ(x,y,r) r = (x == y)
+#define OP_FLOAT_NE(x,y,r) r = (x != y)
+#define OP_FLOAT_LE(x,y,r) r = (x <= y)
+#define OP_FLOAT_GT(x,y,r) r = (x > y)
+#define OP_FLOAT_LT(x,y,r) r = (x < y)
+#define OP_FLOAT_GE(x,y,r) r = (x >= y)
+
+#define OP_FLOAT_CMP(x,y,r) \
+ r = ((x > y) - (x < y))
+
+/* addition, subtraction */
+
+#define OP_FLOAT_ADD(x,y,r) r = x + y
+#define OP_FLOAT_SUB(x,y,r) r = x - y
+#define OP_FLOAT_MUL(x,y,r) r = x * y
+#define OP_FLOAT_TRUEDIV(x,y,r) r = x / y
+#define OP_FLOAT_POW(x,y,r) r = pow(x, y)
+
+/*** conversions ***/
+
+#define OP_CAST_FLOAT_TO_INT(x,r) r = (long)(x)
+#define OP_CAST_FLOAT_TO_UINT(x,r) r = (unsigned long)(x)
+#define OP_CAST_INT_TO_FLOAT(x,r) r = (double)(x)
+#define OP_CAST_UINT_TO_FLOAT(x,r) r = (double)(x)
+#define OP_CAST_LONGLONG_TO_FLOAT(x,r) r = (double)(x)
+#define OP_CAST_BOOL_TO_FLOAT(x,r) r = (double)(x)
+
+#ifdef HAVE_LONG_LONG
+#define OP_CAST_FLOAT_TO_LONGLONG(x,r) r = (long long)(x)
+#endif
+
+
+
+
+/* ================================================== EOF ================ */
+/* ================================================== EOF ================ */
Added: trunk/scipy/sandbox/mkufunc/interactive.py
===================================================================
--- trunk/scipy/sandbox/mkufunc/interactive.py 2008-06-24 17:48:31 UTC (rev 4478)
+++ trunk/scipy/sandbox/mkufunc/interactive.py 2008-06-25 15:43:39 UTC (rev 4479)
@@ -0,0 +1,115 @@
+import driver
+
+from pypy.translator.translator import TranslationContext
+
+
+DEFAULTS = {
+ 'translation.backend': None,
+ 'translation.type_system': None,
+ 'translation.verbose': False,
+}
+
+class Translation(object):
+
+ def __init__(self, entry_point, argtypes=None, **kwds):
+ self.driver = driver.TranslationDriver(overrides=DEFAULTS)
+ self.config = self.driver.config
+
+ self.entry_point = entry_point
+ self.context = TranslationContext(config=self.config)
+
+ # hook into driver events
+ driver_own_event = self.driver._event
+ def _event(kind, goal, func):
+ self.driver_event(kind, goal, func)
+ driver_own_event(kind, goal, func)
+ self.driver._event = _event
+ self.driver_setup = False
+
+ self.update_options(argtypes, kwds)
+ # for t.view() to work just after construction
+ graph = self.context.buildflowgraph(entry_point)
+ self.context._prebuilt_graphs[entry_point] = graph
+
+ def driver_event(self, kind, goal, func):
+ if kind == 'pre':
+ self.ensure_setup()
+
+ def ensure_setup(self, argtypes=None, policy=None, standalone=False):
+ if not self.driver_setup:
+ if standalone:
+ assert argtypes is None
+ else:
+ if argtypes is None:
+ argtypes = []
+ self.driver.setup(self.entry_point, argtypes, policy,
+ empty_translator=self.context)
+ self.ann_argtypes = argtypes
+ self.ann_policy = policy
+ self.driver_setup = True
+ else:
+ # check consistency
+ if standalone:
+ assert argtypes is None
+ assert self.ann_argtypes is None
+ elif argtypes is not None and argtypes != self.ann_argtypes:
+ raise Exception("inconsistent argtype supplied")
+ if policy is not None and policy != self.ann_policy:
+ raise Exception("inconsistent annotation polish supplied")
+
+ def update_options(self, argtypes, kwds):
+ if argtypes or kwds.get('policy') or kwds.get('standalone'):
+ self.ensure_setup(argtypes, kwds.get('policy'),
+ kwds.get('standalone'))
+ kwds.pop('policy', None)
+ kwds.pop('standalone', None)
+ self.config.translation.set(**kwds)
+
+ def ensure_opt(self, name, value=None, fallback=None):
+ if value is not None:
+ self.update_options(None, {name: value})
+ return value
+ val = getattr(self.config.translation, name, None)
+ if fallback is not None and val is None:
+ self.update_options(None, {name: fallback})
+ return fallback
+ if val is not None:
+ return val
+ raise Exception(
+ "the %r option should have been specified at this point" %name)
+
+ def ensure_type_system(self, type_system=None):
+ if self.config.translation.backend is not None:
+ return self.ensure_opt('type_system')
+ return self.ensure_opt('type_system', type_system, 'lltype')
+
+ def ensure_backend(self, backend=None):
+ backend = self.ensure_opt('backend', backend)
+ self.ensure_type_system()
+ return backend
+
+ # backend independent
+
+ def annotate(self, argtypes=None, **kwds):
+ self.update_options(argtypes, kwds)
+ return self.driver.annotate()
+
+ # type system dependent
+
+ def rtype(self, argtypes=None, **kwds):
+ self.update_options(argtypes, kwds)
+ ts = self.ensure_type_system()
+ return getattr(self.driver, 'rtype_'+ts)()
+
+ # backend depedent
+
+ def source(self, argtypes=None, **kwds):
+ self.update_options(argtypes, kwds)
+ backend = self.ensure_backend()
+ self.driver.source_c()
+
+ def compile(self, argtypes=None, **kwds):
+ self.update_options(argtypes, kwds)
+ backend = self.ensure_backend()
+ self.driver.compile_c()
+ return self.driver.c_entryp
Added: trunk/scipy/sandbox/mkufunc/mkufunc.py
===================================================================
--- trunk/scipy/sandbox/mkufunc/mkufunc.py 2008-06-24 17:48:31 UTC (rev 4478)
+++ trunk/scipy/sandbox/mkufunc/mkufunc.py 2008-06-25 15:43:39 UTC (rev 4479)
@@ -0,0 +1,240 @@
+import sys
+import re
+import cStringIO
+
+import numpy
+import scipy.weave as weave
+
+from interactive import Translation
+
+verbose = False
+_cnt = 0
+
+typedict = {
+ int: ['NPY_LONG', 'long' ],
+ long: ['NPY_LONG', 'long' ],
+ float: ['NPY_DOUBLE', 'double'],
+}
+
+class Cfunc(object):
+
+ def __init__(self, f, signature):
+ global _cnt
+ _cnt += 1
+ self.n = _cnt
+ self.sig = signature
+ self.nin = f.func_code.co_argcount # input args
+ self.nout = len(self.sig) - self.nin
+ assert self.nout == 1 # for now
+
+ if not verbose:
+ rem = sys.stderr
+ sys.stderr = cStringIO.StringIO()
+
+ t = Translation(f, backend='c')
+ t.annotate(signature[:self.nin])
+ t.source()
+
+ if not verbose:
+ sys.stderr = rem
+
+ c_source_filename = t.driver.c_source_filename
+ assert c_source_filename.endswith('.c')
+ src = open(c_source_filename, 'r').read()
+
+ self.prefix = 'f%i_' % self.n
+ self.allCsrc = src.replace('pypy_', self.prefix + 'pypy_')
+ self.cname = self.prefix + 'pypy_g_' + f.__name__
+
+ def cfunc(self):
+ p = re.compile(r'^\w+[*\s\w]+' + self.cname +
+ r'\s*\([^)]*\)\s*\{.*?[\n\r]\}[\n\r]',
+ re.DOTALL | re.MULTILINE | re.VERBOSE)
+
+ found = p.findall(self.allCsrc)
+ assert len(found) == 1
+ res = found[0]
+ res = res.replace(self.prefix + 'pypy_g_ll_math_ll_math_', '')
+ return res + '\n'
+
+ def decl(self):
+ p = re.compile(r'^\w+[*\s\w]+' + self.cname +
+ r'\s*\([^)]*\);',
+ re.DOTALL | re.MULTILINE | re.VERBOSE)
+
+ found = p.findall(self.allCsrc)
+ assert len(found) == 1
+ return found[0]
+
+
+ def support_code(self):
+ arg0type = typedict[self.sig[0]][1]
+ rettype = typedict[self.sig[-1]][1]
+ n = self.n
+ cname = self.cname
+ return '''
+static %(rettype)s foo_%(n)i(%(arg0type)s x)
+{
+ return %(cname)s(x);
+}
+
+typedef %(rettype)s Func_%(n)i(%(arg0type)s);
+
+static void
+PyUFunc_%(n)i(char **args, npy_intp *dimensions, npy_intp *steps, void *func)
+{
+ /* printf("PyUFunc_%(n)i\\n"); */
+
+ npy_intp n = dimensions[0];
+ npy_intp is0 = steps[0];
+ npy_intp os = steps[1];
+ char *ip0 = args[0];
+ char *op = args[1];
+ Func_%(n)i *f = (Func_%(n)i *) func;
+ npy_intp i;
+
+ for(i = 0; i < n; i++, ip0 += is0, op += os) {
+ %(arg0type)s *in1 = (%(arg0type)s *)ip0;
+ %(rettype)s *out = (%(rettype)s *)op;
+
+ *out = f(*in1);
+ }
+}
+''' % locals()
+
+
+def test1():
+ def sqr(x):
+ return x * x
+ #verbose = True
+ for argtypes in ([int, int], [float, float]):
+ x = Cfunc(sqr, argtypes)
+ print x.cname, x.nin, x.nout, x.sig
+ print x.cfunc()
+ print '{{{%s}}}' % x.decl()
+ print x.support_code()
+
+
+def write_pypyc(cfuncs):
+ fo = open('pypy.c', 'w');
+ fo.write('#include "head.c"\n\n')
+ for cf in cfuncs:
+ fo.write(cf.cfunc())
+ fo.close()
+
+
+def genufunc(f, signatures):
+
+ signatures.sort(key=lambda sig: [numpy.dtype(typ).num for typ in sig])
+
+ cfuncs = [Cfunc(f, sig) for sig in signatures]
+
+ write_pypyc(cfuncs)
+
+ declarations = ''.join('\t%s\n' % cf.decl() for cf in cfuncs)
+
+ func_support = ''.join(cf.support_code() for cf in cfuncs)
+
+ pyufuncs = ''.join('\tPyUFunc_%i,\n' % cf.n for cf in cfuncs)
+
+ data = ''.join('\t(void *) foo_%i,\n' % cf.n for cf in cfuncs)
+
+ foo_signatures = ''.join('\t%s /* %i */\n' %
+ (''.join(typedict[t][0] + ', ' for t in cf.sig), cf.n)
+ for cf in cfuncs)
+
+ support_code = '''
+extern "C" {
+%(declarations)s}
+
+%(func_support)s
+
+static PyUFuncGenericFunction foo_functions[] = {
+%(pyufuncs)s};
+
+static void *foo_data[] = {
+%(data)s};
+
+static char foo_signatures[] = {
+%(foo_signatures)s};
+''' % locals()
+
+ ntypes = len(signatures)
+ nin = cfuncs[0].nin
+
+ code = '''
+import_ufunc();
+
+return_val = PyUFunc_FromFuncAndData(
+ foo_functions,
+ foo_data,
+ foo_signatures,
+ %(ntypes)i, /* ntypes */
+ %(nin)i, /* nin */
+ 1, /* nout */
+ PyUFunc_None, /* identity */
+ "foo", /* name */
+ "", /* doc */
+ 0);
+''' % locals()
+
+ 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()
+
+ ufunc_info = weave.base_info.custom_info()
+ ufunc_info.add_header('"numpy/ufuncobject.h"')
+ ufunc_info.add_include_dir('"."')
+
+ return weave.inline(code,
+ verbose=0, force=1, # XXX
+ support_code=support_code,
+ customize=ufunc_info,
+ sources=['pypy.c'])
+
+
+def test2():
+
+ def sqr(x):
+ return x * x
+
+ ufunc = genufunc(sqr, [
+ (float, float),
+ (int, int),
+ ])
+
+ x = array([0.0, 1.0, 2.5, 12.0])
+ print "x =", x, x.dtype
+ y = ufunc(x)
+ print "y =", y, y.dtype
+
+ x = array([0, 1, 2, 15])
+ print "x =", x, x.dtype
+ y = ufunc(x)
+ print "y =", y, y.dtype
+
+
+def mkufunc(signatures):
+ print 'signatures', signatures
+
+ class Compile(object):
+
+ def __init__(self, f):
+ self.ufunc = genufunc(f, signatures)
+
+ def __call__(self, *args):
+ return self.ufunc(*args)
+
+ return Compile
+
+
+if __name__ == '__main__':
+ # test1(); exit()
+
+ mkufunc([int, (float, int, float)])
+
Added: trunk/scipy/sandbox/mkufunc/pypy.c
===================================================================
--- trunk/scipy/sandbox/mkufunc/pypy.c 2008-06-24 17:48:31 UTC (rev 4478)
+++ trunk/scipy/sandbox/mkufunc/pypy.c 2008-06-25 15:43:39 UTC (rev 4479)
@@ -0,0 +1,168 @@
+#include "head.c"
+
+double f1_pypy_g_bar(long l_n_2) {
+ long l_n_3; bool_t l_v190; bool_t l_v192; bool_t l_v196;
+ double l_v191; double l_v194; double l_v195; double l_v199;
+ double l_v200; long l_v187; long l_v188; long l_v189; long l_v193;
+ long l_v197; long l_v198; long l_v201;
+
+ block0:
+ OP_INT_LT(l_n_2, 10L, l_v190);
+ if (l_v190) {
+ l_v201 = 0L;
+ l_n_3 = l_n_2;
+ l_v188 = 1L;
+ l_v189 = 10L;
+ goto block6;
+ }
+ goto block1;
+
+ block1:
+ switch (l_n_2) {
+ case 10L:
+ l_v200 = 42.0;
+ goto block2;
+ case 11L:
+ l_v200 = 3.1400000000000001;
+ goto block2;
+ case 12L:
+ goto block3;
+ default:
+ goto block4;
+ }
+
+ block2:
+ RPY_DEBUG_RETURN();
+ return l_v200;
+
+ block3:
+ l_v191 = cos(3.1415926535897931);
+ l_v200 = l_v191;
+ goto block2;
+
+ block4:
+ OP_INT_GT(l_n_2, 12L, l_v192);
+ if (l_v192) {
+ goto block5;
+ }
+ l_v200 = 5.0;
+ goto block2;
+
+ block5:
+ OP_INT_MUL(l_n_2, l_n_2, l_v193);
+ OP_CAST_INT_TO_FLOAT(l_v193, l_v194);
+ OP_FLOAT_TRUEDIV(l_v194, 1.2345600000000001, l_v195);
+ l_v200 = l_v195;
+ goto block2;
+
+ block6:
+ OP_INT_ADD(l_n_3, l_v201, l_v187);
+ OP_INT_GE(l_v188, l_v189, l_v196);
+ while (!l_v196) {
+ goto block7;
+ block6_back:
+ OP_INT_ADD(l_n_3, l_v201, l_v187);
+ OP_INT_GE(l_v188, l_v189, l_v196);
+ }
+ goto block8;
+
+ block7:
+ OP_INT_ADD(l_v188, 1L, l_v197);
+ OP_INT_MUL(l_v188, l_v188, l_v198);
+ l_v201 = l_v198;
+ l_n_3 = l_v187;
+ l_v188 = l_v197;
+ goto block6_back;
+
+ block8:
+ OP_CAST_INT_TO_FLOAT(l_v187, l_v199);
+ l_v200 = l_v199;
+ goto block2;
+}
+
+double f2_pypy_g_bar(double l_n_6) {
+ double l_n_7; bool_t l_v546; bool_t l_v547; bool_t l_v548;
+ bool_t l_v549; bool_t l_v550; bool_t l_v554; double l_v545;
+ double l_v551; double l_v552; double l_v553; double l_v557;
+ double l_v558; double l_v559; long l_v543; long l_v544; long l_v555;
+ long l_v556;
+
+ block0:
+ OP_FLOAT_LT(l_n_6, 10.0, l_v546);
+ if (l_v546) {
+ l_v559 = 0.0;
+ l_v543 = 10L;
+ l_n_7 = l_n_6;
+ l_v544 = 1L;
+ goto block8;
+ }
+ goto block1;
+
+ block1:
+ OP_FLOAT_EQ(l_n_6, 10.0, l_v547);
+ if (l_v547) {
+ l_v558 = 42.0;
+ goto block5;
+ }
+ goto block2;
+
+ block2:
+ OP_FLOAT_EQ(l_n_6, 11.0, l_v548);
+ if (l_v548) {
+ l_v558 = 3.1400000000000001;
+ goto block5;
+ }
+ goto block3;
+
+ block3:
+ OP_FLOAT_EQ(l_n_6, 12.0, l_v549);
+ if (l_v549) {
+ goto block7;
+ }
+ goto block4;
+
+ block4:
+ OP_FLOAT_GT(l_n_6, 12.0, l_v550);
+ if (l_v550) {
+ goto block6;
+ }
+ l_v558 = 5.0;
+ goto block5;
+
+ block5:
+ RPY_DEBUG_RETURN();
+ return l_v558;
+
+ block6:
+ OP_FLOAT_MUL(l_n_6, l_n_6, l_v551);
+ OP_FLOAT_TRUEDIV(l_v551, 1.2345600000000001, l_v552);
+ l_v558 = l_v552;
+ goto block5;
+
+ block7:
+ l_v553 = cos(3.1415926535897931);
+ l_v558 = l_v553;
+ goto block5;
+
+ block8:
+ OP_FLOAT_ADD(l_n_7, l_v559, l_v545);
+ OP_INT_GE(l_v544, l_v543, l_v554);
+ while (!l_v554) {
+ goto block9;
+ block8_back:
+ OP_FLOAT_ADD(l_n_7, l_v559, l_v545);
+ OP_INT_GE(l_v544, l_v543, l_v554);
+ }
+ l_v558 = l_v545;
+ goto block5;
+
+ block9:
+ OP_INT_ADD(l_v544, 1L, l_v555);
+ OP_INT_MUL(l_v544, l_v544, l_v556);
+ OP_CAST_INT_TO_FLOAT(l_v556, l_v557);
+ l_v559 = l_v557;
+ l_n_7 = l_v545;
+ l_v544 = l_v555;
+ goto block8_back;
+}
+
Added: trunk/scipy/sandbox/mkufunc/test_1.py
===================================================================
--- trunk/scipy/sandbox/mkufunc/test_1.py 2008-06-24 17:48:31 UTC (rev 4478)
+++ trunk/scipy/sandbox/mkufunc/test_1.py 2008-06-25 15:43:39 UTC (rev 4479)
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+from math import sin, cos, pi
+
+from numpy import array
+
+from mkufunc import mkufunc
+
+int_const = 42
+
+float_const = 3.14
+
+def my_sqr(x):
+ return x * x / 1.23456
+
+ at mkufunc([(float, float), (int, int)])
+def bar(n):
+ "Bar docstring"
+ if n < 10:
+ for i in xrange(10):
+ n += i*i
+ return n
+ elif n == 10:
+ return int_const
+ elif n == 11:
+ return float_const
+ elif n == 12:
+ return cos(pi)
+ #return 1
+ elif n > 12:
+ return my_sqr(n)
+ else:
+ return 5
+
+
+#@mkufunc(float)
+#def baz(n):
+# "Baz docstring"
+# return n * n + 1000
+
+
+#print bar
+
+x = array([0.0, 1.0, 2.5, 12.0])
+print "x =", x, x.dtype
+y = bar(x)
+print "y =", y, y.dtype
+
+print bar(5)
+print bar(15)
+print bar(10)
+print bar(11)
+print bar(12)
+print bar(12.5)
Property changes on: trunk/scipy/sandbox/mkufunc/test_1.py
___________________________________________________________________
Name: svn:executable
+ *
More information about the Scipy-svn
mailing list