Esempio n. 1
0
def cprint_lower(context, builder, sig, args):
    from sdc.str_ext import string_type, char_type

    for i, val in enumerate(args):
        typ = sig.args[i]
        if typ == string_type:
            fnty = lir.FunctionType(lir.VoidType(),
                                    [lir.IntType(8).as_pointer()])
            fn = cgutils.get_or_insert_function(builder.module,
                                                fnty,
                                                name="print_str")
            builder.call(fn, [val])
            cgutils.printf(builder, " ")
            continue
        if typ == char_type:
            fnty = lir.FunctionType(lir.VoidType(), [lir.IntType(8)])
            fn = cgutils.get_or_insert_function(builder.module,
                                                fnty,
                                                name="print_char")
            builder.call(fn, [val])
            cgutils.printf(builder, " ")
            continue
        if isinstance(typ, types.ArrayCTypes):
            cgutils.printf(builder, "%p ", val)
            continue
        format_str = typ_to_format[typ]
        cgutils.printf(builder, "%{} ".format(format_str), val)
    cgutils.printf(builder, "\n")
    return context.get_dummy_value()
Esempio n. 2
0
    def impl(context, builder, sig, args):
        context.nrt._require_nrt()
        size, align = args

        mod = builder.module
        u32 = ir.IntType(32)
        voidptr = cgutils.voidptr_t

        get_alloc_fnty = ir.FunctionType(voidptr, ())
        get_alloc_fn = cgutils.get_or_insert_function(
            mod, get_alloc_fnty, name="_nrt_get_sample_external_allocator"
        )
        ext_alloc = builder.call(get_alloc_fn, ())

        fnty = ir.FunctionType(voidptr, [cgutils.intp_t, u32, voidptr])
        fn = cgutils.get_or_insert_function(
            mod, fnty, name="NRT_MemInfo_alloc_safe_aligned_external"
        )
        fn.return_value.add_attribute("noalias")
        if isinstance(align, builtins.int):
            align = context.get_constant(types.uint32, align)
        else:
            assert align.type == u32, "align must be a uint32"
        call = builder.call(fn, [size, align, ext_alloc])
        call.name = "allocate_MyArray"
        return call
Esempio n. 3
0
    def impl(context, builder, sig, args):
        context.nrt._require_nrt()
        size, align = args

        mod = builder.module
        u32 = ir.IntType(32)

        # Get the Numba external allocator for USM memory.
        ext_allocator_fnty = ir.FunctionType(cgutils.voidptr_t, [])
        ext_allocator_fn = cgutils.get_or_insert_function(
            mod, ext_allocator_fnty, name="usmarray_get_ext_allocator"
        )
        ext_allocator = builder.call(ext_allocator_fn, [])
        # Get the Numba function to allocate an aligned array with an external allocator.
        fnty = ir.FunctionType(
            cgutils.voidptr_t, [cgutils.intp_t, u32, cgutils.voidptr_t]
        )
        fn = cgutils.get_or_insert_function(
            mod, fnty, name="NRT_MemInfo_alloc_safe_aligned_external"
        )
        fn.return_value.add_attribute("noalias")
        if isinstance(align, builtins.int):
            align = context.get_constant(types.uint32, align)
        else:
            assert align.type == u32, "align must be a uint32"
        call = builder.call(fn, [size, align, ext_allocator])
        call.name = "allocate_UsmArray"
        return call
Esempio n. 4
0
def _get_equal(context, module, datamodel, container_element_type):
    assert datamodel.contains_nrt_meminfo()

    fe_type = datamodel.fe_type
    data_ptr_ty = datamodel.get_data_type().as_pointer()

    wrapfnty = context.call_conv.get_function_type(types.int32,
                                                   [fe_type, fe_type])
    argtypes = [fe_type, fe_type]

    def build_wrapper(fn):
        builder = Builder(fn.append_basic_block())
        args = context.call_conv.decode_arguments(builder, argtypes, fn)

        sig = typing.signature(types.boolean, fe_type, fe_type)
        op = operator.eq
        fnop = context.typing_context.resolve_value_type(op)
        fnop.get_call_type(context.typing_context, sig.args, {})
        eqfn = context.get_function(fnop, sig)
        res = eqfn(builder, args)
        intres = context.cast(builder, res, types.boolean, types.int32)
        context.call_conv.return_value(builder, intres)

    wrapfn = cgutils.get_or_insert_function(
        module,
        wrapfnty,
        name='.numba_{}.{}_equal.wrap'.format(context.fndesc.mangled_name,
                                              container_element_type))
    build_wrapper(wrapfn)

    equal_fnty = ir.FunctionType(ir.IntType(32), [data_ptr_ty, data_ptr_ty])
    equal_fn = cgutils.get_or_insert_function(
        module,
        equal_fnty,
        name='.numba_{}.{}_equal'.format(context.fndesc.mangled_name,
                                         container_element_type),
    )
    builder = Builder(equal_fn.append_basic_block())
    lhs = datamodel.load_from_data_pointer(builder, equal_fn.args[0])
    rhs = datamodel.load_from_data_pointer(builder, equal_fn.args[1])

    status, retval = context.call_conv.call_function(
        builder,
        wrapfn,
        types.boolean,
        argtypes,
        [lhs, rhs],
    )
    with builder.if_then(status.is_ok, likely=True):
        with builder.if_then(status.is_none):
            builder.ret(context.get_constant(types.int32, 0))
        retval = context.cast(builder, retval, types.boolean, types.int32)
        builder.ret(retval)
    # Error out
    builder.ret(context.get_constant(types.int32, -1))

    return equal_fn
Esempio n. 5
0
        def codegen(cgctx, builder, sig, llargs):
            name = overloadable_function.__name__
            struct_ptr = cgutils.create_struct_proxy(inst)(cgctx,
                                                           builder,
                                                           value=llargs[0])

            # Get the 'state' and 'fnptr_next_(type)' members of the struct
            state = struct_ptr.state
            next_double_addr = getattr(struct_ptr, f'fnptr_{name}')

            # LLVM IR types needed
            ll_void_ptr_t = cgctx.get_value_type(types.voidptr)
            ll_return_t = cgctx.get_value_type(return_type)
            ll_uintp_t = cgctx.get_value_type(types.uintp)

            # Convert the stored Generator function address to a pointer
            next_fn_fnptr = builder.inttoptr(next_double_addr, ll_void_ptr_t)
            # Add the function to the module
            fnty = ir.FunctionType(ll_return_t, (ll_uintp_t, ))
            next_fn = cgutils.get_or_insert_function(builder.module, fnty,
                                                     name)
            # Bit cast the function pointer to the function type
            fnptr_as_fntype = builder.bitcast(next_fn_fnptr, next_fn.type)
            # call it with the "state" address as the arg
            ret = builder.call(fnptr_as_fntype, (state, ))
            return ret
Esempio n. 6
0
    def define_dtor(self):
        "Define the destructor if not already defined"
        context = self._context
        builder = self._builder
        mod = builder.module
        # Declare dtor
        fnty = ir.FunctionType(ir.VoidType(), [cgutils.voidptr_t])
        fn = cgutils.get_or_insert_function(mod, fnty,
                                            '.dtor.list.{}'.format(self.dtype))
        if not fn.is_declaration:
            # End early if the dtor is already defined
            return fn
        fn.linkage = 'linkonce_odr'
        # Populate the dtor
        builder = ir.IRBuilder(fn.append_basic_block())
        base_ptr = fn.args[0]  # void*

        # get payload
        payload = ListPayloadAccessor(context, builder, self._ty, base_ptr)

        # Loop over all data to decref
        intp = payload.size.type
        with cgutils.for_range_slice(builder,
                                     start=intp(0),
                                     stop=payload.size,
                                     step=intp(1),
                                     intp=intp) as (idx, _):
            val = payload.getitem(idx)
            context.nrt.decref(builder, self.dtype, val)
        builder.ret_void()
        return fn
Esempio n. 7
0
    def codegen(context, builder, sig, args):
        fnty = ir.FunctionType(
            ll_status,
            [ll_list_type, ll_bytes],
        )
        [l, item] = args
        [tl, titem] = sig.args
        fn = cgutils.get_or_insert_function(builder.module, fnty,
                                            'numba_list_append')

        dm_item = context.data_model_manager[titem]

        data_item = dm_item.as_data(builder, item)

        ptr_item = cgutils.alloca_once_value(builder, data_item)

        lp = _container_get_data(context, builder, tl, l)
        status = builder.call(
            fn,
            [
                lp,
                _as_bytes(builder, ptr_item),
            ],
        )
        return status
Esempio n. 8
0
def _list_codegen_set_method_table(context, builder, lp, itemty):
    vtablety = ir.LiteralStructType([
        ll_voidptr_type,  # item incref
        ll_voidptr_type,  # item decref
    ])
    setmethod_fnty = ir.FunctionType(
        ir.VoidType(), [ll_list_type, vtablety.as_pointer()])

    setmethod_fn = cgutils.get_or_insert_function(
        builder.module, setmethod_fnty, 'numba_list_set_method_table')
    vtable = cgutils.alloca_once(builder, vtablety, zfill=True)

    # install item incref/decref
    item_incref_ptr = cgutils.gep_inbounds(builder, vtable, 0, 0)
    item_decref_ptr = cgutils.gep_inbounds(builder, vtable, 0, 1)

    dm_item = context.data_model_manager[itemty]
    if dm_item.contains_nrt_meminfo():
        item_incref, item_decref = _get_incref_decref(context, builder.module,
                                                      dm_item, "list")
        builder.store(
            builder.bitcast(item_incref, item_incref_ptr.type.pointee),
            item_incref_ptr,
        )
        builder.store(
            builder.bitcast(item_decref, item_decref_ptr.type.pointee),
            item_decref_ptr,
        )

    builder.call(setmethod_fn, [lp, vtable])
Esempio n. 9
0
    def mark_variable(self,
                      builder,
                      allocavalue,
                      name,
                      lltype,
                      size,
                      line,
                      datamodel=None,
                      argidx=None):

        arg_index = 0 if argidx is None else argidx
        m = self.module
        fnty = ir.FunctionType(ir.VoidType(), [ir.MetaDataType()] * 3)
        decl = cgutils.get_or_insert_function(m, fnty, 'llvm.dbg.declare')

        mdtype = self._var_type(lltype, size, datamodel=datamodel)
        name = name.replace('.', '$')  # for gdb to work correctly
        mdlocalvar = m.add_debug_info(
            'DILocalVariable', {
                'name': name,
                'arg': arg_index,
                'scope': self.subprograms[-1],
                'file': self.difile,
                'line': line,
                'type': mdtype,
            })
        mdexpr = m.add_debug_info('DIExpression', {})

        return builder.call(decl, [allocavalue, mdlocalvar, mdexpr])
Esempio n. 10
0
def lower_dist_comm_req_dealloc(context, builder, sig, args):
    fnty = lir.FunctionType(lir.VoidType(), [lir.IntType(8).as_pointer()])
    fn = cgutils.get_or_insert_function(builder.module,
                                        fnty,
                                        name="comm_req_dealloc")
    builder.call(fn, args)
    return context.get_dummy_value()
Esempio n. 11
0
def lower_dist_wait(context, builder, sig, args):
    fnty = lir.FunctionType(
        lir.IntType(32), [mpi_req_llvm_type, lir.IntType(1)])
    fn = cgutils.get_or_insert_function(builder.module,
                                        fnty,
                                        name="hpat_dist_wait")
    return builder.call(fn, args)
Esempio n. 12
0
def lower_dist_isend(context, builder, sig, args):
    # store an int to specify data type
    typ_enum = _numba_to_c_type_map[sig.args[0].dtype]
    typ_arg = context.get_constant(types.int32, typ_enum)
    out = make_array(sig.args[0])(context, builder, args[0])

    if len(args) == 4:
        cond_arg = context.get_constant(types.boolean, True)
    else:
        cond_arg = args[4]

    call_args = [
        builder.bitcast(out.data,
                        lir.IntType(8).as_pointer()), args[1], typ_arg,
        args[2], args[3], cond_arg
    ]

    # array, size, extra arg type for type enum
    # pe, tag, cond
    arg_typs = [
        lir.IntType(8).as_pointer(),
        lir.IntType(32),
        lir.IntType(32),
        lir.IntType(32),
        lir.IntType(32),
        lir.IntType(1)
    ]
    fnty = lir.FunctionType(mpi_req_llvm_type, arg_typs)
    fn = cgutils.get_or_insert_function(builder.module,
                                        fnty,
                                        name="hpat_dist_isend")
    return builder.call(fn, call_args)
Esempio n. 13
0
def getpointer_from_string(context, builder, sig, args):
    val = args[0]
    fnty = lir.FunctionType(lir.IntType(8).as_pointer(),
                            [lir.IntType(8).as_pointer()])
    fn = cgutils.get_or_insert_function(builder.module, fnty, name="get_c_str")
    c_str = builder.call(fn, [val])
    return c_str
Esempio n. 14
0
 def core(context, builder, sig, args):
     lmod = builder.module
     fretty = context.get_value_type(retty)
     fargtys = [context.get_value_type(arg.ty) for arg in nbargs]
     fnty = ir.FunctionType(fretty, fargtys)
     fn = cgutils.get_or_insert_function(lmod, fnty, func)
     return builder.call(fn, args)
Esempio n. 15
0
def call_native_getiter(context, builder, dict_type, dict_val, it):
    """ This function should produce LLVM code for calling native
    hashmap_getiter and fill iterator data accordingly """

    ty_key, ty_val = dict_type.key_type, dict_type.value_type
    key_type_postfix, value_type_postfix = _get_types_postfixes(ty_key, ty_val)

    nrt_table = context.nrt.get_nrt_api(builder)
    llvoidptr = context.get_value_type(types.voidptr)
    fnty = lir.FunctionType(
        llvoidptr, [it.meminfo.type.as_pointer(), llvoidptr, llvoidptr])
    func_name = f"hashmap_getiter_{key_type_postfix}_to_{value_type_postfix}"
    fn_hashmap_getiter = cgutils.get_or_insert_function(builder.module,
                                                        fnty,
                                                        name=func_name)

    cdict = cgutils.create_struct_proxy(dict_type)(context,
                                                   builder,
                                                   value=dict_val)
    it.state = builder.call(
        fn_hashmap_getiter,
        [it._get_ptr_by_name('meminfo'), nrt_table, cdict.data_ptr])

    # store the reference to parent and incref
    it.parent = dict_val
    if context.enable_nrt:
        context.nrt.incref(builder, dict_type, dict_val)
Esempio n. 16
0
def declare_vprint(lmod):
    voidptrty = ir.PointerType(ir.IntType(8))
    # NOTE: the second argument to vprintf() points to the variable-length
    # array of arguments (after the format)
    vprintfty = ir.FunctionType(ir.IntType(32), [voidptrty, voidptrty])
    vprintf = cgutils.get_or_insert_function(lmod, vprintfty, "vprintf")
    return vprintf
Esempio n. 17
0
def ptx_syncwarp_mask(context, builder, sig, args):
    fname = 'llvm.nvvm.bar.warp.sync'
    lmod = builder.module
    fnty = ir.FunctionType(ir.VoidType(), (ir.IntType(32), ))
    sync = cgutils.get_or_insert_function(lmod, fnty, fname)
    builder.call(sync, args)
    return context.get_dummy_value()
Esempio n. 18
0
def lower_dist_allgather(context, builder, sig, args):
    arr_typ = sig.args[0]
    val_typ = sig.args[1]
    assert val_typ == arr_typ.dtype

    # type enum arg
    assert val_typ in _numba_to_c_type_map, "invalid allgather type"
    typ_enum = _numba_to_c_type_map[val_typ]
    typ_arg = context.get_constant(types.int32, typ_enum)

    # size arg is 1 for now
    size_arg = context.get_constant(types.int32, 1)

    val_ptr = cgutils.alloca_once_value(builder, args[1])

    out = make_array(sig.args[0])(context, builder, args[0])

    call_args = [
        builder.bitcast(out.data,
                        lir.IntType(8).as_pointer()), size_arg, val_ptr,
        typ_arg
    ]

    fnty = lir.FunctionType(lir.VoidType(), [
        lir.IntType(8).as_pointer(),
        lir.IntType(32), val_ptr.type,
        lir.IntType(32)
    ])
    fn = cgutils.get_or_insert_function(builder.module, fnty, name="allgather")
    builder.call(fn, call_args)
    return context.get_dummy_value()
Esempio n. 19
0
 def declare_external_function(self, module, fndesc):
     fnty = self.get_external_function_type(fndesc)
     fn = cgutils.get_or_insert_function(module, fnty, fndesc.mangled_name)
     assert fn.is_declaration
     for ak, av in zip(fndesc.args, fn.args):
         av.name = "arg.%s" % ak
     return fn
Esempio n. 20
0
    def codegen(context, builder, sig, args):
        table_pyobject = args[1]

        nrt_table = context.nrt.get_nrt_api(builder)
        arrow_table = cgutils.create_struct_proxy(sig.return_type)(context,
                                                                   builder)
        fnty = lir.FunctionType(
            lir.VoidType(),
            [
                lir.IntType(8).as_pointer(),  # ptr to pyarrow table
                arrow_table.meminfo.type.as_pointer(),  # meminfo to fill
                lir.IntType(8).as_pointer(),
            ])  # NRT API func table
        func_name = f"create_arrow_table"
        fn = cgutils.get_or_insert_function(builder.module,
                                            fnty,
                                            name=func_name)

        builder.call(fn, [
            table_pyobject,
            arrow_table._get_ptr_by_name('meminfo'), nrt_table
        ])

        arrow_table.table_ptr = context.nrt.meminfo_data(
            builder, arrow_table.meminfo)
        return arrow_table._getvalue()
Esempio n. 21
0
 def codegen(cgctx, builder, signature, args):
     mod = builder.module
     fnty = ir.FunctionType(ir.VoidType(), tuple())
     breakpoint = cgutils.get_or_insert_function(mod, fnty,
                                                 "numba_gdb_breakpoint")
     builder.call(breakpoint, tuple())
     return cgctx.get_constant(types.none, None)
Esempio n. 22
0
def _declare_function(context, builder, name, sig, cargs, mangler=mangle_c):
    """Insert declaration for a opencl builtin function.
    Uses the Itanium mangler.

    Args
    ----
    context: target context

    builder: llvm builder

    name: str
        symbol name

    sig: signature
        function signature of the symbol being declared

    cargs: sequence of str
        C type names for the arguments

    mangler: a mangler function
        function to use to mangle the symbol

    """
    mod = builder.module
    if sig.return_type == types.void:
        llretty = lc.Type.void()
    else:
        llretty = context.get_value_type(sig.return_type)
    llargs = [context.get_value_type(t) for t in sig.args]
    fnty = Type.function(llretty, llargs)
    mangled = mangler(name, cargs)
    fn = cgutils.get_or_insert_function(mod, fnty, mangled)
    fn.calling_convention = target.CC_SPIR_FUNC
    return fn
Esempio n. 23
0
    def codegen(context, builder, sig, args):
        fnty = ir.FunctionType(
            ll_status,
            [ll_dict_type, ll_bytes, ll_hash, ll_bytes, ll_bytes],
        )
        [d, key, hashval, val] = args
        [td, tkey, thashval, tval] = sig.args
        fn = cgutils.get_or_insert_function(builder.module, fnty,
                                            'numba_dict_insert')

        dm_key = context.data_model_manager[tkey]
        dm_val = context.data_model_manager[tval]

        data_key = dm_key.as_data(builder, key)
        data_val = dm_val.as_data(builder, val)

        ptr_key = cgutils.alloca_once_value(builder, data_key)
        cgutils.memset_padding(builder, ptr_key)

        ptr_val = cgutils.alloca_once_value(builder, data_val)
        # TODO: the ptr_oldval is not used.  needed for refct
        ptr_oldval = cgutils.alloca_once(builder, data_val.type)

        dp = _container_get_data(context, builder, td, d)
        status = builder.call(
            fn,
            [
                dp,
                _as_bytes(builder, ptr_key),
                hashval,
                _as_bytes(builder, ptr_val),
                _as_bytes(builder, ptr_oldval),
            ],
        )
        return status
Esempio n. 24
0
def impl_dict_getiter(context, builder, sig, args):
    """Implement iter(Dict).  Semantically equivalent to dict.keys()
    """
    [td] = sig.args
    [d] = args
    iterablety = types.DictKeysIterableType(td)
    it = context.make_helper(builder, iterablety.iterator_type)

    fnty = ir.FunctionType(
        ir.VoidType(),
        [ll_dictiter_type, ll_dict_type],
    )

    fn = cgutils.get_or_insert_function(builder.module, fnty,
                                        'numba_dict_iter')

    proto = ctypes.CFUNCTYPE(ctypes.c_size_t)
    dictiter_sizeof = proto(_helperlib.c_helpers['dict_iter_sizeof'])
    state_type = ir.ArrayType(ir.IntType(8), dictiter_sizeof())

    pstate = cgutils.alloca_once(builder, state_type, zfill=True)
    it.state = _as_bytes(builder, pstate)
    it.parent = d

    dp = _container_get_data(context, builder, iterablety.parent, args[0])
    builder.call(fn, [it.state, dp])
    return impl_ret_borrowed(
        context,
        builder,
        sig.return_type,
        it._getvalue(),
    )
Esempio n. 25
0
 def codegen(context, builder, sig, args):
     fnty = ir.FunctionType(
         ll_status,
         [ll_dict_type.as_pointer(), ll_ssize_t, ll_ssize_t],
     )
     fn = cgutils.get_or_insert_function(builder.module, fnty,
                                         'numba_dict_new_minsize')
     # Determine sizeof key and value types
     ll_key = context.get_data_type(keyty.instance_type)
     ll_val = context.get_data_type(valty.instance_type)
     sz_key = context.get_abi_sizeof(ll_key)
     sz_val = context.get_abi_sizeof(ll_val)
     refdp = cgutils.alloca_once(builder, ll_dict_type, zfill=True)
     status = builder.call(
         fn,
         [refdp, ll_ssize_t(sz_key),
          ll_ssize_t(sz_val)],
     )
     _raise_if_error(
         context,
         builder,
         status,
         msg="Failed to allocate dictionary",
     )
     dp = builder.load(refdp)
     return dp
Esempio n. 26
0
def ptx_round(context, builder, sig, args):
    fn = cgutils.get_or_insert_function(
        builder.module, ir.FunctionType(ir.IntType(64), (ir.DoubleType(), )),
        '__nv_llrint')
    return builder.call(fn, [
        context.cast(builder, args[0], sig.args[0], types.double),
    ])
Esempio n. 27
0
def copysign_float_impl(context, builder, sig, args):
    lty = args[0].type
    mod = builder.module
    fn = cgutils.get_or_insert_function(
        mod, lc.Type.function(lty, (lty, lty)),
        'llvm.copysign.%s' % lty.intrinsic_name)
    res = builder.call(fn, args)
    return impl_ret_untracked(context, builder, sig.return_type, res)
Esempio n. 28
0
def ptx_cbrt(context, builder, sig, args):
    ty = sig.return_type
    fname = cbrt_funcs[ty]
    fty = context.get_value_type(ty)
    lmod = builder.module
    fnty = ir.FunctionType(fty, [fty])
    fn = cgutils.get_or_insert_function(lmod, fnty, fname)
    return builder.call(fn, args)
Esempio n. 29
0
def pq_size_lower(context, builder, sig, args):
    fnty = lir.FunctionType(lir.IntType(64),
                            [lir.IntType(8).as_pointer(),
                             lir.IntType(64)])
    fn = cgutils.get_or_insert_function(builder.module,
                                        fnty,
                                        name="pq_get_size")
    return builder.call(fn, args)
Esempio n. 30
0
def ptx_brev_u8(context, builder, sig, args):
    # FIXME the llvm.bitreverse.i64 intrinsic isn't supported by nvcc
    # return builder.bitreverse(args[0])

    fn = cgutils.get_or_insert_function(
        builder.module, ir.FunctionType(ir.IntType(64), (ir.IntType(64), )),
        '__nv_brevll')
    return builder.call(fn, args)