Exemplo n.º 1
0
def gv_from_python(x, llvm_type = None):
  if isinstance(x, GenericValue):
    return x
  elif isinstance(x, (int,long)):
    llvm_type =  ty_int64 if llvm_type is None else llvm_type
    assert is_llvm_int_type(llvm_type), \
      "Expected LLVM integer type, not %s" % (llvm_type,) 
    return GenericValue.int(llvm_type, x)
  elif isinstance(x, float):
    llvm_type = ty_float64 if llvm_type is None else llvm_type
    assert is_llvm_float_type(llvm_type), \
        "Expected LLVM float type, not %s" % (llvm_type,)
    return GenericValue.real(llvm_type, x)  
  elif isinstance(x, bool):
    llvm_type = ty_int8 if llvm_type is None else llvm_type
    assert is_llvm_int_type(llvm_type), \
      "Expected LLVM integer type, not %s" % (llvm_type,)
    return GenericValue.int(llvm_type, x)
  else:
    assert isinstance(x, np.ndarray)
    assert llvm_type is not None 
    assert is_llvm_ptr_type(llvm_type), \
      "Native argument receiving numpy array must be a pointer, not %s" % (llvm_type,)
    elt_type = llvm_type.pointee
    assert is_llvm_float_type(elt_type) or is_llvm_int_type(elt_type)
    assert elt_type == python_to_lltype(x.dtype), \
        "Can't pass array with %s* data pointer to function that expects %s*" % (x.dtype, elt_type)
    return GenericValue.pointer(x.ctypes.data)
Exemplo n.º 2
0
def ctypes_to_generic_value(cval, t):
  if isinstance(t, FloatT):
    llvm_t = llvm_types.llvm_value_type(t)
    return GenericValue.real(llvm_t, cval.value)
  elif isinstance(t, SignedT):
    llvm_t = llvm_types.llvm_value_type(t)
    return GenericValue.int_signed(llvm_t, cval.value)
  elif isinstance(t, IntT):
    llvm_t = llvm_types.llvm_value_type(t)
    return GenericValue.int(llvm_t, cval.value)
  elif isinstance(t, NoneT):
    return GenericValue.int(llvm_types.int64_t, 0)
  elif isinstance(t, PtrT):
    return GenericValue.pointer(ctypes.addressof(cval.contents))
  else:
    return GenericValue.pointer(ctypes.addressof(cval))
Exemplo n.º 3
0
def ctypes_to_generic_value(cval, t):
    if isinstance(t, FloatT):
        llvm_t = llvm_types.llvm_value_type(t)
        return GenericValue.real(llvm_t, cval.value)
    elif isinstance(t, SignedT):
        llvm_t = llvm_types.llvm_value_type(t)
        return GenericValue.int_signed(llvm_t, cval.value)
    elif isinstance(t, IntT):
        llvm_t = llvm_types.llvm_value_type(t)
        return GenericValue.int(llvm_t, cval.value)
    elif isinstance(t, NoneT):
        return GenericValue.int(llvm_types.int64_t, 0)
    elif isinstance(t, PtrT):
        return GenericValue.pointer(ctypes.addressof(cval.contents))
    else:
        return GenericValue.pointer(ctypes.addressof(cval))
Exemplo n.º 4
0
def python_to_generic_value(x, t):
  if isinstance(t, core_types.FloatT):
    llvm_t = llvm_types.llvm_value_type(t)
    return GenericValue.real(llvm_t, x)
  elif isinstance(t, core_types.SignedT):
    llvm_t = llvm_types.llvm_value_type(t)
    return GenericValue.int_signed(llvm_t, x)
  elif isinstance(t, core_types.IntT):
    llvm_t = llvm_types.llvm_value_type(t)
    return GenericValue.int(llvm_t, x)
  elif isinstance(t, core_types.PtrT):
    return GenericValue.pointer(x)
  else:
    ctypes_obj = type_conv.from_python(x)
    return GenericValue.pointer(ctypes.addressof(ctypes_obj))
Exemplo n.º 5
0
def python_to_generic_value(x, t):
    if isinstance(t, FloatT):
        llvm_t = llvm_types.llvm_value_type(t)
        return GenericValue.real(llvm_t, x)
    elif isinstance(t, SignedT):
        llvm_t = llvm_types.llvm_value_type(t)
        return GenericValue.int_signed(llvm_t, x)
    elif isinstance(t, IntT):
        llvm_t = llvm_types.llvm_value_type(t)
        return GenericValue.int(llvm_t, x)
    elif isinstance(t, PtrT):
        return GenericValue.pointer(x)
    else:
        ctypes_obj = type_conv.from_python(x)
        return GenericValue.pointer(ctypes.addressof(ctypes_obj))
Exemplo n.º 6
0
def run( py_main_func, *call_args ):
    from rpy.rtypes import ConstantTypeRegistry
    registry = ConstantTypeRegistry()
    # Annotates call graph types (local var, functions param/return...)
    print( '\nAnalysing call graph...\n%s' % ('='*70) )
    annotator = CallableGraphAnnotator( registry )
    annotator.set_entry_point( py_main_func, call_args )
    annotator.annotate_dependencies()
    # Generate LLVM code
    from rpy.codegenerator import ModuleGenerator, FunctionCodeGenerator, L_INT_TYPE, L_BOOL_TYPE
    module = ModuleGenerator( registry )
    l_func_entry, l_func_type = None, None
    # Declares all function in modules
    fn_code_generators = []
    for r_func_type, type_annotator in annotator.annotator_by_callable.items():
        py_func = r_func_type.get_function_object()
        print( '\nDeclaring function:\n%s\nPython: %s\nRType: %s' % ('-'*70, py_func, r_func_type) )
        func_generator = FunctionCodeGenerator( py_func, module,
                                                annotator )
        fn_code_generators.append( (r_func_type, func_generator) )
    # Makes sure that all class type have their struct/attribute index dict initialized
    for r_func_type, _ in fn_code_generators:
        if r_func_type.is_constructor():
            module.llvm_type_from_rtype( r_func_type )
    # Generates function's code, possibly referencing previously declared functions
    for r_func_type, func_generator in fn_code_generators:
        print( '\nGenerating code for function:\n%s\n%s\nSouce:\n' % ('-'*70, r_func_type) )
        print( func_generator.annotation.get_function_source() )
        func_generator.generate_llvm_code()
        func_generator.report()
        if r_func_type.get_function_object() is py_main_func:
            l_func_entry = func_generator.l_func
            l_func_type = func_generator.l_func_type
    print( 'Generated module code:' )
    print( '----------------------\n%s', module.l_module )
    optimize( module )
    print( 'Generated module code after optimization:' )
    print( '-----------------------------------------\n', module.l_module )
    
    # Execute generate code
    # 1) Convert call args into generic value
    print( 'Invoking function with %r' % (call_args,) )
    from llvm.core import ModuleProvider, TYPE_VOID
    from llvm.ee import ExecutionEngine, GenericValue
    module_provider = ModuleProvider.new( module.l_module )
    engine = ExecutionEngine.new( module_provider )
    l_call_args = []
    for py_call_arg, l_arg in zip( call_args, l_func_entry.args ):
        if l_arg.type == L_INT_TYPE:
            l_call_args.append( GenericValue.int_signed( L_INT_TYPE, py_call_arg ) )
        elif l_arg.type == L_BOOL_TYPE:
            l_call_args.append( GenericValue.int( L_BOOL_TYPE, py_call_arg ) )
        else:
            raise ValueError( 'Unsupported parameter "%s" of type: %r' % (py_call_arg, l_arg_type) )
    # 2) run the functions
    l_return_value = engine.run_function( l_func_entry, l_call_args )
    # 3) convert LLVM return value into python type
    if l_func_type.return_type == L_INT_TYPE:
        return l_return_value.as_int_signed()
    elif l_func_type.return_type == L_BOOL_TYPE:
        return l_return_value.as_int() and True or False
    elif l_func_type.return_type.kind == TYPE_VOID:
        return None
    print( 'Return:',  l_return_value )
    raise ValueError( 'Unsupported return type "%s"' % l_func_entry.return_type )
    
Exemplo n.º 7
0
def run(py_main_func, *call_args):
    from rpy.rtypes import ConstantTypeRegistry
    registry = ConstantTypeRegistry()
    # Annotates call graph types (local var, functions param/return...)
    print('\nAnalysing call graph...\n%s' % ('=' * 70))
    annotator = CallableGraphAnnotator(registry)
    annotator.set_entry_point(py_main_func, call_args)
    annotator.annotate_dependencies()
    # Generate LLVM code
    from rpy.codegenerator import ModuleGenerator, FunctionCodeGenerator, L_INT_TYPE, L_BOOL_TYPE
    module = ModuleGenerator(registry)
    l_func_entry, l_func_type = None, None
    # Declares all function in modules
    fn_code_generators = []
    for r_func_type, type_annotator in annotator.annotator_by_callable.items():
        py_func = r_func_type.get_function_object()
        print('\nDeclaring function:\n%s\nPython: %s\nRType: %s' %
              ('-' * 70, py_func, r_func_type))
        func_generator = FunctionCodeGenerator(py_func, module, annotator)
        fn_code_generators.append((r_func_type, func_generator))
    # Makes sure that all class type have their struct/attribute index dict initialized
    for r_func_type, _ in fn_code_generators:
        if r_func_type.is_constructor():
            module.llvm_type_from_rtype(r_func_type)
    # Generates function's code, possibly referencing previously declared functions
    for r_func_type, func_generator in fn_code_generators:
        print('\nGenerating code for function:\n%s\n%s\nSouce:\n' %
              ('-' * 70, r_func_type))
        print(func_generator.annotation.get_function_source())
        func_generator.generate_llvm_code()
        func_generator.report()
        if r_func_type.get_function_object() is py_main_func:
            l_func_entry = func_generator.l_func
            l_func_type = func_generator.l_func_type
    print('Generated module code:')
    print('----------------------\n%s', module.l_module)
    optimize(module)
    print('Generated module code after optimization:')
    print('-----------------------------------------\n', module.l_module)

    # Execute generate code
    # 1) Convert call args into generic value
    print('Invoking function with %r' % (call_args, ))
    from llvm.core import ModuleProvider, TYPE_VOID
    from llvm.ee import ExecutionEngine, GenericValue
    module_provider = ModuleProvider.new(module.l_module)
    engine = ExecutionEngine.new(module_provider)
    l_call_args = []
    for py_call_arg, l_arg in zip(call_args, l_func_entry.args):
        if l_arg.type == L_INT_TYPE:
            l_call_args.append(GenericValue.int_signed(L_INT_TYPE,
                                                       py_call_arg))
        elif l_arg.type == L_BOOL_TYPE:
            l_call_args.append(GenericValue.int(L_BOOL_TYPE, py_call_arg))
        else:
            raise ValueError('Unsupported parameter "%s" of type: %r' %
                             (py_call_arg, l_arg_type))
    # 2) run the functions
    l_return_value = engine.run_function(l_func_entry, l_call_args)
    # 3) convert LLVM return value into python type
    if l_func_type.return_type == L_INT_TYPE:
        return l_return_value.as_int_signed()
    elif l_func_type.return_type == L_BOOL_TYPE:
        return l_return_value.as_int() and True or False
    elif l_func_type.return_type.kind == TYPE_VOID:
        return None
    print('Return:', l_return_value)
    raise ValueError('Unsupported return type "%s"' % l_func_entry.return_type)