def run_test_with_prelude(self, code, prelude, *params, **interface): """Test if a function call return value is unchanged when executed using python eval or compiled with pythran. Args: code (str): python (pythran valid) module to test. params (tuple): arguments to pass to the function to test. prelude (fct): function to call between 'code' and the c++ generated code interface (dict): pythran interface for the module to test. Each key is the name of a function to call, the value is a list of the arguments' type. Returns: nothing. Raises: AssertionError by 'unittest' if return value differ. SyntaxError if code is not python valid. CalledProcessError if pythran generated code cannot be compiled. ...possible others... """ for name in sorted(interface.keys()): # Build the python function call. modname = "test_" + name arglist = ",".join(("'{0}'".format(p) if isinstance(p, str) else str(p)) for p in params) function_call = "{0}({1})".format(name, arglist) # Compile the python module, python-way, 'env' contains the module # and allow to call functions. # This may be done once before the loop, but the context might # need to be reset. compiled_code = compile(code, "", "exec") env = {'__builtin__' : __import__('__builtin__')} prelude and prelude() eval(compiled_code, env) python_ref = eval(function_call, env) # Produce the reference # Compile the code using pythran cxx_code = cxx_generator(modname, code, interface) cxx_compiled = pythran_compile(os.environ.get("CXX", "c++"), cxx_code, cxxflags=TestEnv.PYTHRAN_CXX_FLAGS, check=True) prelude and prelude() pymod = load_dynamic(modname, cxx_compiled) # Produce the pythran result pythran_res = getattr(pymod, name)(*params) # Compare pythran result against python ref and raise if mismatch if python_ref != pythran_res: print "Python result: ", python_ref print "Pythran result: ", pythran_res self.assertAlmostEqual(python_ref, pythran_res)
def run(self): import glob import timeit from pythran import cxx_generator, spec_parser from pythran import compile as pythran_compile where = "pythran/tests/cases/" candidates = glob.glob(where + '*.py') sys.path.append(where) median = lambda x: sorted(x)[len(x) / 2] for candidate in candidates: with file(candidate) as content: runas = [line for line in content.readlines() if line.startswith(BenchmarkCommand.runas_marker)] if runas: module_name, _ = os.path.splitext( os.path.basename(candidate)) runas_commands = runas[0].replace( BenchmarkCommand.runas_marker, '').split(";") runas_context = ";".join(["import {0}".format( module_name)] + runas_commands[:-1]) runas_command = module_name + '.' + runas_commands[-1] # cleaning sopath = module_name + ".so" if os.path.exists(sopath): os.remove(sopath) ti = timeit.Timer(runas_command, runas_context) # pythran part if self.mode.startswith('pythran'): specs = spec_parser(candidate) code = file(candidate).read() mod = cxx_generator(module_name, code, specs) cxxflags = ["-Ofast", "-DNDEBUG"] if self.mode == "pythran+omp": cxxflags.append("-fopenmp") pythran_compile(os.environ.get("CXX", "c++"), mod, cxxflags=cxxflags) timing = median(ti.repeat(self.nb_iter, number=1)) print module_name, timing