Beispiel #1
0
    def add_jit_method(self, function_place: JITFunctionHoldPlace,
                       argtypeids: call_record_t, argtypes: t.Tuple[type, ...]):
        method_arguments = function_place.method_arguments
        fn_ptr_name = function_place.fn_ptr_name
        actual_args = [cmc.typed_head + arg for arg in method_arguments]
        once_code_out = CodeOut()
        declaring: list = once_code_out[cmc.Import]
        typing: list = once_code_out[cmc.Customizable]

        typing.append("cdef {}({}):".format(fn_ptr_name, ', '.join(actual_args)))
        undef = object()
        for i, (actual_arg, arg, argtype) in enumerate(
                zip(actual_args, method_arguments, argtypes)):
            path = extension_type_pxd_paths.get(argtype, undef)
            if path is undef:
                # well, this type cannot JIT in fact, so still object and stop recording it.
                typing.append("{}{} = {}".format(cmc.IDENTATION_SECTION, arg, actual_arg))
            elif path is None:
                # it's builtin extension types, like dict, list, etc.
                typing.append("{}cdef {} {} = {}".format(cmc.IDENTATION_SECTION,
                                                         argtype.__name__, arg, actual_arg))
            else:
                # Good, user-defined extension types!
                # You'll see how fast it'll be!

                # Firstly we import the required type
                typename = "{}{}".format(cmc.typed_head, i)
                declaring.append('from {} cimport {} as {}'.format(
                    path, argtype.__name__, typename))
                typing.append("{}cdef {} {} = {}".format(cmc.IDENTATION_SECTION, typename,
                                                         arg, actual_arg))

        once_code_out.merge_update(function_place.memoize_partial_code)
        code = '\n'.join(once_code_out.to_code_lines())
        # TODO: use auto-evolution-able method lookup
        code = """
{}
method_addr = reinterpret_cast[int64_t](<void*>{})
        """.format(code, fn_ptr_name)

        unique_module = "Methods_{}_{}_JITed".format(
            id(function_place), function_place.name_that_makes_sense.replace('.', '__'))
        mod = compile_module(JIT_FUNCTION_DIR, unique_module, code)
        method_init_fptrs = getattr(mod, cmc.method_init_fptrs)
        method_init_globals = getattr(mod, cmc.method_init_globals)
        g = function_place.globals
        method_init_globals(**{k: g[k] for k in function_place.glob_deps})
        method_init_fptrs(self.jit_fptr_index)
        function_place.methods[argtypeids] = mod.method_addr
Beispiel #2
0
    def generate_base_method(self, function_place: JITFunctionHoldPlace, code):
        argc = function_place.argc
        method_argtype_comma_lst = ', '.join('object' for _ in range(argc))
        method_get_argument_comma_lst = ', '.join('int64_t _%d' % i for i in range(argc))
        # TODO: use auto-evolution-able method lookup
        fn_ptr_name = function_place.fn_ptr_name
        code = """
{}
ctypedef object (*method_t)({})
cdef method_t this_method_getter({}):
    return {}
base_method_addr = reinterpret_cast[int64_t](<void*>{})
method_getter_addr = reinterpret_cast[int64_t](<void*>this_method_getter)    
        """.format(code, method_argtype_comma_lst, method_get_argument_comma_lst,
                   fn_ptr_name, fn_ptr_name)

        if self.store_base_method_log:
            function_place.base_method_code = code

        unique_module = "Methods_{}_{}_base_method".format(
            id(function_place), function_place.name_that_makes_sense.replace('.', '__'))
        mod = compile_module(JIT_FUNCTION_DIR, unique_module, code)

        method_init_fptrs = getattr(mod, cmc.method_init_fptrs)
        method_init_globals = getattr(mod, cmc.method_init_globals)
        init_notifier = getattr(mod, cmc.method_init_recorder_and_notifier)
        method_getter_addr = getattr(mod, 'method_getter_addr')
        call_recorder = mod.NonJITCallRecorder()
        function_place.call_recorder = call_recorder
        init_notifier(
            call_recorder, lambda: self.jit_hotspot_analysis.trigger_jit(function_place))
        g = function_place.globals
        method_init_globals(**{k: g[k] for k in function_place.glob_deps})
        method_init_fptrs(self.jit_fptr_index)
        function_place.base_method_module = mod
        function_place.function_module.f.mut_method_get(method_getter_addr)
        function_place.base_method_addr = mod.base_method_addr
Beispiel #3
0
   float
   object

cdef class MyClass:
    pass

cdef f(C x):
    cdef int a = pytoint(cython.typeof(x))
    return a 

def g(C x):
   return f(x)

def h():
   z = cython.typeof(h)
   return check_ptr_eq(z, cython.typeof(object))  
"""

mod = compile_module('m', mod)
print(mod.h())

a = mod.g(mod.MyClass())
assert isinstance(a, int)
assert a == mod.g(mod.MyClass())

b = mod.g(1)
assert isinstance(b, int)
assert b == mod.g(1)

assert a != b
cdef fused ty_f_Arg1:
    object

cdef fused ty_f_Arg2:
    object

cdef fused ty_f_Arg3:
    object

    
cpdef ff(ty_f_Arg1 x, ty_f_Arg2 y, ty_f_Arg3 z):
    return x + y + z
        
"""

mod = compile_module("a", mod)
print(mod.s(1, 2, 3))


def f(x, y, z):
    return x + y + z


template = "f(1, 2, 3)"


def test(f):
    t = timeit(template, number=10_000_000, globals=dict(f=f))
    print(f, 'costs', t)

Beispiel #5
0
 def _rebuild_method_getter_and_set(self):
     code = mk_hard_coded_method_getter_module(self.methods, self.base_method_addr,
                                               self.argc)
     mod = compile_module(JIT_FUNCTION_DIR, "MethodGetter", code)
     self.function_module.f.mut_method_get(mod.method_get_addr)
Beispiel #6
0
 def generate_module_for_code(self, code_info: PyCodeInfo):
     code = mk_module_code(code_info)
     unique_module_name = "Functions_{}".format(self.fn_count)
     mod = compile_module(JIT_FUNCTION_DIR, unique_module_name, code)
     return mod