def test_prof_inline(self): py.test.skip("broken by 5b0e029514d4, but we don't use it any more") if sys.platform == 'win32': py.test.skip("instrumentation support is unix only for now") def add(a, b): return a + b - b + b - b + b - b + b - b + b - b + b - b + b def entry_point(argv): tot = 0 x = int(argv[1]) while x > 0: tot = add(tot, x) x -= 1 os.write(1, str(tot)) return 0 from rpython.translator.interactive import Translation t = Translation(entry_point, backend='c') # no counters t.backendopt(inline_threshold=100, profile_based_inline="500") exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500 * 501 / 2 t = Translation(entry_point, backend='c') # counters t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST * 0.5, profile_based_inline="500") exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500 * 501 / 2
def test_compiled(): class MyCode: pass def get_name(mycode): raise NotImplementedError rvmprof.register_code_object_class(MyCode, get_name) @rvmprof.vmprof_execute_code("mycode", lambda code, level: code) def mainloop(code, level): if level > 0: mainloop(code, level - 1) else: p, length = traceback.traceback(20) traceback.walk_traceback(MyCode, my_callback, 42, p, length) lltype.free(p, flavor="raw") def my_callback(code, loc, arg): print code, loc, arg return 0 def f(argv): code1 = MyCode() rvmprof.register_code(code1, "foo") mainloop(code1, 2) return 0 t = Translation(f, None, gc="boehm") t.compile_c() stdout = t.driver.cbuilder.cmdexec("") r = re.compile("[<]MyCode object at 0x([0-9a-f]+)[>] 0 42\n") got = r.findall(stdout) assert got == [got[0]] * 3
def compile(f, gc='ref'): t = Translation(f, backend='c', sandbox=True, gc=gc, check_str_without_nul=True) return str(t.compile())
def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, mode=ctypes.RTLD_GLOBAL, **kwargs): # NOTE: requires mu-client-pypy from rpython.rtyper.lltypesystem import rffi from rpython.translator.interactive import Translation from rpython.config.translationoption import set_opt_level preload_libmu() emit_dir = os.environ.get('MU_EMIT_DIR', str(bin_dir)) kwargs.setdefault('backend', 'mu') kwargs.setdefault('impl', 'zebu') kwargs.setdefault('codegen', 'api') kwargs.setdefault('testjit', True) kwargs.setdefault('vmargs', "--aot-emit-dir=" + emit_dir) kwargs.setdefault('suplibdir', str(bin_dir)) kwargs.setdefault('no_ovf', True) t = Translation(rpy_fnc, llargtypes, **kwargs) set_opt_level(t.config, '3') if kwargs['backend'] == 'mu': db, bdlgen, fnc_name = t.compile_mu() emit_dir = py.path.local(emit_dir) libpath = emit_dir.join('lib%(fnc_name)s' % locals() + libext) bdlgen.mu.compile_to_sharedlib(libpath.strpath, []) extras = (db, bdlgen) else: libpath = t.compile_c() fnc_name = 'pypy_g_' + rpy_fnc.__name__ extras = None return rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, llrestype, mode), extras
def _makefunc_str_int(cls, f): def main(argv): arg0 = argv[1] arg1 = int(argv[2]) try: res = f(arg0, arg1) except MemoryError: print "MEMORY-ERROR" else: print res return 0 t = Translation(main, gc=cls.gcpolicy, taggedpointers=cls.taggedpointers, gcremovetypeptr=cls.removetypeptr) t.disable(['backendopt']) t.set_backend_extra_options(c_debug_defines=True) t.rtype() if option.view: t.viewcg() exename = t.compile() def run(s, i): data = py.process.cmdexec("%s %s %d" % (exename, s, i)) data = data.strip() if data == 'MEMORY-ERROR': raise MemoryError return data return run
def test_compiled(): class MyCode: pass def get_name(mycode): raise NotImplementedError rvmprof.register_code_object_class(MyCode, get_name) @rvmprof.vmprof_execute_code("mycode", lambda code, level: code) def mainloop(code, level): if level > 0: mainloop(code, level - 1) else: p, length = traceback.traceback(20) traceback.walk_traceback(MyCode, my_callback, 42, p, length) lltype.free(p, flavor='raw') def my_callback(code, loc, arg): print code, loc, arg return 0 def f(argv): code1 = MyCode() rvmprof.register_code(code1, "foo") mainloop(code1, 2) return 0 t = Translation(f, None, gc="boehm") t.compile_c() stdout = t.driver.cbuilder.cmdexec('') r = re.compile("[<]MyCode object at 0x([0-9a-f]+)[>] 0 42\n") got = r.findall(stdout) assert got == [got[0]] * 3
def test_enter_leave_portal_frame(self): from rpython.translator.interactive import Translation def g(): enter_portal_frame(1) leave_portal_frame() t = Translation(g, []) t.compile_c() # does not crash
def test_annotator_folding(): from rpython.translator.interactive import Translation gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref') gcgroup = OptionDescription('gc', '', [gcoption]) descr = OptionDescription('pypy', '', [gcgroup]) config = Config(descr) def f(x): if config.gc.name == 'ref': return x + 1 else: return 'foo' t = Translation(f, [int]) t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 assert len(block.operations) == 1 assert len(block.exits) == 1 assert block.operations[0].opname == 'int_add' assert config._freeze_() # does not raise, since it does not change the attribute config.gc.name = "ref" py.test.raises(TypeError, 'config.gc.name = "framework"')
def test_profopt(self): if sys.platform == 'win32': py.test.skip("no profopt on win32") def add(a, b): return a + b - b + b - b + b - b + b - b + b - b + b - b + b def entry_point(argv): tot = 0 x = int(argv[1]) while x > 0: tot = add(tot, x) x -= 1 os.write(1, str(tot)) return 0 from rpython.translator.interactive import Translation # XXX this is mostly a "does not crash option" t = Translation(entry_point, backend='c', profopt="100") # no counters t.backendopt() exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500 * 501 / 2 t = Translation(entry_point, backend='c', profopt="100", noprofopt=True) # no counters t.backendopt() exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500 * 501 / 2
def get_generated_c_source(fn, types): """Return the generated C source for fn.""" t = Translation(fn, types, backend="c") t.annotate() merge_if_blocks(t.driver.translator.graphs[0]) c_filename_path = t.source_c() return t.driver.cbuilder.c_source_filename.join( '..', 'rpython_translator_c_test.c').read()
def get_generated_c_source(fn, types): """Return the generated C source for fn.""" t = Translation(fn, types, backend="c") t.annotate() merge_if_blocks(t.driver.translator.graphs[0]) c_filename_path = t.source_c() return t.driver.cbuilder.c_source_filename.join('..', 'rpython_translator_c_test.c').read()
def test_simple_backendopt(): def f(x, y): return x,y t = Translation(f, [int, int], backend='c') t.backendopt() assert 'backendopt_lltype' in t.driver.done
def test_simple_rtype(): def f(x,y): return x+y t = Translation(f, [int, int]) t.annotate() t.rtype() assert 'rtype_lltype' in t.driver.done
def build_adi(function, types): t = Translation(function, types) t.rtype() if option.view: t.view() adi = AbstractDataFlowInterpreter(t.context) graph = graphof(t.context, function) adi.schedule_function(graph) adi.complete() return t.context, adi, graph
def test_disable_logic(): def f(x,y): return x+y t = Translation(f, [int, int]) t.disable(['backendopt']) t.source_c() assert 'backendopt' not in t.driver.done
def test_check_that_driver_uses_replace_we_are_jitted(): from rpython.rlib import jit def f(): if jit.we_are_jitted(): return 1 return 2 + jit.we_are_jitted() t = Translation(f, []) t.backendopt() graph = t.driver.translator.graphs[0] assert graph.startblock.exits[0].args[0].value == 2
def test_tagged_boehm(): t = Translation(entry_point, gc='boehm', taggedpointers=True) try: exename = str(t.compile_c()) finally: if option.view: t.view() g = os.popen(exename, 'r') data = g.read() g.close() assert data.rstrip().endswith('ALL OK')
def test_simple_compile_c(): import ctypes def f(x,y): return x+y t = Translation(f, [int, int]) t.source(backend='c') t.compile() dll = ctypes.CDLL(str(t.driver.c_entryp)) f = dll.pypy_g_f assert f(2, 3) == 5
def test_enforced_args(): from rpython.annotator.model import s_None from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator from rpython.translator.interactive import Translation def f1(): str2charp("hello") def f2(): str2charp("world") t = Translation(f1, []) t.rtype() mixann = MixLevelHelperAnnotator(t.context.rtyper) mixann.getgraph(f2, [], s_None) mixann.finish()
def test_jitted(): from rpython.jit.backend import detect_cpu if not detect_cpu.autodetect().startswith("x86"): py.test.skip("HAS_CODEMAP is only in the x86 jit backend for now") class MyCode: pass def get_name(mycode): raise NotImplementedError rvmprof.register_code_object_class(MyCode, get_name) jitdriver = jit.JitDriver( greens=["code"], reds="auto", is_recursive=True, get_unique_id=lambda code: rvmprof.get_unique_id(code) ) @rvmprof.vmprof_execute_code("mycode", lambda code, level, total_i: code) def mainloop(code, level, total_i): i = 20 while i > 0: jitdriver.jit_merge_point(code=code) i -= 1 if level > 0: mainloop(code, level - 1, total_i + i) if level == 0 and total_i == 0: p, length = traceback.traceback(20) traceback.walk_traceback(MyCode, my_callback, 42, p, length) lltype.free(p, flavor="raw") def my_callback(code, loc, arg): print code, loc, arg return 0 def f(argv): jit.set_param(jitdriver, "inlining", 0) code1 = MyCode() rvmprof.register_code(code1, "foo") mainloop(code1, 2, 0) return 0 t = Translation(f, None, gc="boehm") t.rtype() t.driver.pyjitpl_lltype() t.compile_c() stdout = t.driver.cbuilder.cmdexec("") r = re.compile("[<]MyCode object at 0x([0-9a-f]+)[>] (\d) 42\n") got = r.findall(stdout) addr = got[0][0] assert got == [(addr, "1"), (addr, "1"), (addr, "0")]
def test_prof_inline(self): py.test.skip("broken by 5b0e029514d4, but we don't use it any more") if sys.platform == 'win32': py.test.skip("instrumentation support is unix only for now") def add(a,b): return a + b - b + b - b + b - b + b - b + b - b + b - b + b def entry_point(argv): tot = 0 x = int(argv[1]) while x > 0: tot = add(tot, x) x -= 1 os.write(1, str(tot)) return 0 from rpython.translator.interactive import Translation t = Translation(entry_point, backend='c') # no counters t.backendopt(inline_threshold=100, profile_based_inline="500") exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 t = Translation(entry_point, backend='c') # counters t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST*0.5, profile_based_inline="500") exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2
def test_profopt(self): if sys.platform == 'win32': py.test.skip("no profopt on win32") def add(a,b): return a + b - b + b - b + b - b + b - b + b - b + b - b + b def entry_point(argv): tot = 0 x = int(argv[1]) while x > 0: tot = add(tot, x) x -= 1 os.write(1, str(tot)) return 0 from rpython.translator.interactive import Translation # XXX this is mostly a "does not crash option" t = Translation(entry_point, backend='c', profopt="100") # no counters t.backendopt() exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 t = Translation(entry_point, backend='c', profopt="100", noprofopt=True) # no counters t.backendopt() exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2
def test_simple_annotate(): def f(x,y): return x+y t = Translation(f, [int, int]) assert t.context is t.driver.translator assert t.config is t.driver.config is t.context.config s = t.annotate() assert s.knowntype == int t = Translation(f, [int, int]) s = t.annotate() assert s.knowntype == int
def translate_to_graph(function, arguments): """ Translate a function to basic blocks and visualize these blocks (see requirements.txt for necessary pip packages); use this mechanism in conjunction with interpret_from_graph :param function: the RPython function to interpret :param arguments: a list of the arguments passed to 'function' :return: the translator RTyper and the basic block graph for the function passed """ assert callable(function) assert isinstance(arguments, list) translation = Translation(function, arguments) translation.annotate() translation.rtype() translation.backendopt() translation.view() return translation.driver.translator.rtyper, translation.driver.translator.graphs[0]
def test_computed_int_symbolic(): too_early = True def compute_fn(): assert not too_early return 7 k = ComputedIntSymbolic(compute_fn) def f(ignored): return k*6 t = Translation(f) t.rtype() if option.view: t.view() too_early = False fn = compile(f, [int]) res = fn(0) assert res == 42
def test_get_translation_config(): from rpython.translator.interactive import Translation from rpython.config import config def f(x): config = get_translation_config() if config is not None: return config.translating return False t = Translation(f, [int]) config = t.config # do the patching t.annotate() retvar = t.context.graphs[0].returnblock.inputargs[0] assert t.context.annotator.binding(retvar).const assert get_translation_config() is config # check during import time
def test_simple_source(): def f(x, y): return x,y t = Translation(f, [int, int], backend='c') t.annotate() t.source() assert 'source_c' in t.driver.done t = Translation(f, [int, int]) t.source_c() assert 'source_c' in t.driver.done t = Translation(f, [int, int]) py.test.raises(Exception, "t.source()")
def test_record_known_result(self): from rpython.translator.interactive import Translation @elidable def f(x): return x + 1 @elidable def g(x): return x - 1 def call_f(x): y = f(x) record_known_result(x, g, y) return y call_f(10) # doesn't crash t = Translation(call_f, [int]) t.rtype() # does not crash
def test_name(): def f(): return 3 f.c_name = 'pypy_xyz_f' f.exported_symbol = True t = Translation(f, [], backend="c") t.annotate() t.compile_c() if py.test.config.option.view: t.view() assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'pypy_xyz_f')
def test_parser(): def f(x): if x: s = "a(X, Y, Z)." else: s = "f(a, X, _, _, X, f(X, 2.455))." term = parsing.parse_file(s) assert isinstance(term, parsing.Nonterminal) return term.symbol assert f(True) == "file" assert f(True) == "file" t = Translation(f) t.annotate([bool]) t.rtype() t.backendopt() func = t.compile_c() assert func(True) == "file" assert func(False) == "file"
def test_entrypoints(): def f(): return 3 key = "test_entrypoints42" @entrypoint(key, [int], "foobar") def g(x): return x + 42 t = Translation(f, [], backend="c", secondaryentrypoints="test_entrypoints42") t.annotate() t.compile_c() if py.test.config.option.view: t.view() assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'foobar')
def test_name(): def f(): return 3 f.c_name = 'pypy_xyz_f' t = Translation(f, [], backend="c") t.annotate() t.compile_c() if py.test.config.option.view: t.view() assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'pypy_xyz_f')
def test_exportstruct(): from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.exports import export_struct def f(): return 42 FOO = Struct("FOO", ("field1", Signed)) foo = malloc(FOO, flavor="raw") foo.field1 = 43 export_struct("BarStruct", foo._obj) t = Translation(f, [], backend="c") t.annotate() t.compile_c() if py.test.config.option.view: t.view() assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'BarStruct') free(foo, flavor="raw")
def test_nonmoving_raw_ptr_for_resizable_list(): def f(n): lst = ['a', 'b', 'c'] lst = rgc.resizable_list_supporting_raw_ptr(lst) lst.append(chr(n)) assert lst[3] == chr(n) assert lst[-1] == chr(n) # ptr = rgc.nonmoving_raw_ptr_for_resizable_list(lst) assert lst[:] == ['a', 'b', 'c', chr(n)] assert lltype.typeOf(ptr) == rffi.CCHARP assert [ptr[i] for i in range(4)] == ['a', 'b', 'c', chr(n)] # lst[-3] = 'X' assert ptr[1] == 'X' ptr[2] = 'Y' assert lst[-2] == 'Y' # addr = rffi.cast(lltype.Signed, ptr) ptr = rffi.cast(rffi.CCHARP, addr) rgc.collect() # should not move lst.items lst[-4] = 'g' assert ptr[0] == 'g' ptr[3] = 'H' assert lst[-1] == 'H' return lst # # direct untranslated run lst = f(35) assert isinstance(lst, rgc._ResizableListSupportingRawPtr) # # llinterp run interpret(f, [35]) # # compilation with the GC transformer import subprocess from rpython.translator.interactive import Translation # def main(argv): f(len(argv)) print "OK!" return 0 # t = Translation(main, gc="incminimark") t.disable(['backendopt']) t.set_backend_extra_options(c_debug_defines=True) exename = t.compile() data = subprocess.check_output([str(exename), '.', '.', '.']) assert data.strip().endswith('OK!')
def test_disable_logic(): def f(x, y): return x + y t = Translation(f, [int, int]) t.disable(['backendopt']) t.source_c() assert 'backendopt' not in t.driver.done
def test_simple_rtype(): def f(x, y): return x + y t = Translation(f, [int, int]) t.annotate() t.rtype() assert 'rtype_lltype' in t.driver.done
def test_profopt_mac_osx_bug(self): if sys.platform == 'win32': py.test.skip("no profopt on win32") def entry_point(argv): import os pid = os.fork() if pid: os.waitpid(pid, 0) else: os._exit(0) return 0 from rpython.translator.interactive import Translation # XXX this is mostly a "does not crash option" t = Translation(entry_point, backend='c', profopt="") # no counters t.backendopt() exe = t.compile() #py.process.cmdexec(exe) t = Translation(entry_point, backend='c', profopt="", noprofopt=True) # no counters t.backendopt() exe = t.compile()
def test_jitted(): from rpython.jit.backend import detect_cpu if not detect_cpu.autodetect().startswith('x86'): py.test.skip("HAS_CODEMAP is only in the x86 jit backend for now") class MyCode: pass def get_name(mycode): raise NotImplementedError rvmprof.register_code_object_class(MyCode, get_name) jitdriver = jit.JitDriver( greens=['code'], reds='auto', is_recursive=True, get_unique_id=lambda code: rvmprof.get_unique_id(code)) @rvmprof.vmprof_execute_code("mycode", lambda code, level, total_i: code) def mainloop(code, level, total_i): i = 20 while i > 0: jitdriver.jit_merge_point(code=code) i -= 1 if level > 0: mainloop(code, level - 1, total_i + i) if level == 0 and total_i == 0: p, length = traceback.traceback(20) traceback.walk_traceback(MyCode, my_callback, 42, p, length) lltype.free(p, flavor='raw') def my_callback(code, loc, arg): print code, loc, arg return 0 def f(argv): jit.set_param(jitdriver, "inlining", 0) code1 = MyCode() rvmprof.register_code(code1, "foo") mainloop(code1, 2, 0) return 0 t = Translation(f, None, gc="boehm") t.rtype() t.driver.pyjitpl_lltype() t.compile_c() stdout = t.driver.cbuilder.cmdexec('') r = re.compile("[<]MyCode object at 0x([0-9a-f]+)[>] (\d) 42\n") got = r.findall(stdout) addr = got[0][0] assert got == [(addr, '1'), (addr, '1'), (addr, '0')]
def test_simple_annotate(): def f(x, y): return x + y t = Translation(f, [int, int]) assert t.context is t.driver.translator assert t.config is t.driver.config is t.context.config s = t.annotate() assert s.knowntype == int t = Translation(f, [int, int]) s = t.annotate() assert s.knowntype == int
def test_ll_for_resizable_list(): def f(n): lst = ['a', 'b', 'c'] lst = rgc.resizable_list_supporting_raw_ptr(lst) lst.append(chr(n)) assert lst[3] == chr(n) assert lst[-1] == chr(n) # ll_list = rgc.ll_for_resizable_list(lst) assert lst[:] == ['a', 'b', 'c', chr(n)] assert ll_list.length == 4 assert [ll_list.items[i] for i in range(4)] == ['a', 'b', 'c', chr(n)] # lst[-3] = 'X' assert ll_list.items[1] == 'X' ll_list.items[2] = 'Y' assert lst[-2] == 'Y' # return lst # # direct untranslated run lst = f(35) assert isinstance(lst, rgc._ResizableListSupportingRawPtr) # # llinterp run interpret(f, [35]) # # compilation with the GC transformer import subprocess from rpython.translator.interactive import Translation # def main(argv): f(len(argv)) print "OK!" return 0 # t = Translation(main, gc="incminimark") t.disable(['backendopt']) t.set_backend_extra_options(c_debug_defines=True) exename = t.compile() data = subprocess.check_output([str(exename), '.', '.', '.']) assert data.strip().endswith('OK!')
def test_exportstruct(): from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.exports import export_struct def f(): return 42 FOO = Struct("FOO", ("field1", Signed)) foo = malloc(FOO, flavor="raw") foo.field1 = 43 # maybe export_struct should add the struct name to eci automatically? # https://bugs.pypy.org/issue1361 foo._obj._compilation_info = ExternalCompilationInfo(export_symbols=['BarStruct']) export_struct("BarStruct", foo._obj) t = Translation(f, [], backend="c") t.annotate() t.compile_c() if py.test.config.option.view: t.view() assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'BarStruct') free(foo, flavor="raw")
def test_engine(): e = get_engine(""" g(a, a). g(a, b). g(b, c). f(X, Z) :- g(X, Y), g(Y, Z). """) t1 = parse_query_term("f(a, c).") t2 = parse_query_term("f(X, c).") def run(): e.run(t1) e.run(t2) v0 = e.heap.getvar(0) if isinstance(v0, Atom): return v0.name() return "no!" assert run() == "a" t = Translation(run) t.annotate() t.rtype() func = t.compile_c() assert func() == "a"
def test_inhibit_tail_call(): def foobar_fn(n): return 42 foobar_fn._dont_inline_ = True def main(n): return foobar_fn(n) # t = Translation(main, [int], backend="c") t.rtype() t.context._graphof(foobar_fn).inhibit_tail_call = True t.source_c() lines = t.driver.cbuilder.c_source_filename.join('..', 'rpython_translator_c_test_test_genc.c').readlines() for i, line in enumerate(lines): if '= pypy_g_foobar_fn' in line: break else: assert 0, "the call was not found in the C source" assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1]