예제 #1
0
def _list_length(typingctx, l):
    """Wrap numba_list_length

    Returns the length of the list.
    """
    sig = types.intp(l)

    def codegen(context, builder, sig, args):
        [tl] = sig.args
        [l] = args
        fnty = ir.FunctionType(
            ll_ssize_t,
            [ll_list_type],
        )
        fname = 'numba_list_size_address'
        fn = builder.module.get_or_insert_function(fnty, name=fname)
        fn.attributes.add('alwaysinline')
        fn.attributes.add('readonly')
        fn.attributes.add('nounwind')
        lp = _container_get_data(context, builder, tl, l)
        len_addr = builder.call(
            fn,
            [
                lp,
            ],
        )
        ptr = builder.inttoptr(len_addr, cgutils.intp_t.as_pointer())
        return builder.load(ptr)

    return sig, codegen
예제 #2
0
def fix_index(tyctx, list_ty, index_ty):
    sig = types.intp(list_ty, index_ty)

    def codegen(context, builder, sig, args):
        [list_ty, index_ty] = sig.args
        [ll_list, ll_idx] = args
        is_negative = builder.icmp_signed('<', ll_idx,
                                          ir.Constant(ll_idx.type, 0))
        fast_len_sig, length_fn = _list_length._defn(context.typing_context,
                                                     list_ty)
        length = length_fn(context, builder, fast_len_sig, (ll_list, ))
        # length is an intp
        # index can be any sort of int
        # indexing in general is done with a ssize_t which correlates to an
        # intp. In llvmlite sext and trunc are guarded to return the value
        # itself if the types are the same, so there's no need to handle the
        # "equal widths" case separately. This sexts/truncs the index to the
        # length type such that `add` works for the wraparound case.
        st = 'sext' if ll_idx.type.width < length.type.width else 'trunc'
        op = getattr(builder, st)
        fixedup_idx = op(ll_idx, length.type)
        wrapped_index = builder.add(fixedup_idx, length)
        return builder.select(is_negative, wrapped_index, fixedup_idx)

    return sig, codegen
예제 #3
0
def iternext_BufferPointer(context, builder, sig, args, result):
    [iterbufty] = sig.args
    [bufiter] = args

    iterval = context.make_helper(builder, iterbufty, value=bufiter)

    buf = iterval.buffer
    idx = builder.load(iterval.index)

    len_fn = context.typing_context.resolve_value_type(len)
    len_sig = types.intp(sig.args[0].buffer_type)
    # if the intrinsic was not called before, one need to "register" it first
    len_fn.get_call_type(context.typing_context, len_sig.args, {})
    count = context.get_function(len_fn, len_sig)(builder, [buf])

    is_valid = builder.icmp_signed('<', idx, count)
    result.set_valid(is_valid)

    with builder.if_then(is_valid):
        getitem_fn = context.typing_context.resolve_value_type(
            operator.getitem)
        getitem_sig = iterbufty.buffer_type.eltype(iterbufty.buffer_type,
                                                   types.intp)
        # same here, "register" the intrinsic before calling it
        getitem_fn.get_call_type(context.typing_context, getitem_sig.args, {})
        getitem_out = context.get_function(getitem_fn, getitem_sig)(builder,
                                                                    [buf, idx])
        result.yield_(getitem_out)
        nidx = builder.add(idx, context.get_constant(types.intp, 1))
        builder.store(nidx, iterval.index)
예제 #4
0
def _prng_random_hash(tyctx):

    def impl(cgctx, builder, signature, args):
        state_ptr = get_state_ptr(cgctx, builder, "internal")
        bits = const_int(types.intp.bitwidth)
        value = get_next_int(cgctx, builder, state_ptr, bits, False)
        return value

    sig = types.intp()
    return sig, impl
예제 #5
0
    # then prepare the arg for a concrete instance
    if isinstance(tyinp, types.ArrayCompatible):
        ary = ctxt.make_array(tyinp)(ctxt, bld, inp)
        shape = cgutils.unpack_tuple(bld, ary.shape, tyinp.ndim)
        strides = cgutils.unpack_tuple(bld, ary.strides, tyinp.ndim)
        return _ArrayHelper(ctxt, bld, shape, strides, ary.data, tyinp.layout,
                            tyinp.dtype, tyinp.ndim, inp)
    elif (types.unliteral(tyinp) in types.number_domain | {types.boolean}
          or isinstance(tyinp, types.scalars._NPDatetimeBase)):
        return _ScalarHelper(ctxt, bld, inp, tyinp)
    else:
        raise NotImplementedError('unsupported type for {0}: {1}'.format(
            where, str(tyinp)))


_broadcast_onto_sig = types.intp(types.intp, types.CPointer(types.intp),
                                 types.intp, types.CPointer(types.intp))


def _broadcast_onto(src_ndim, src_shape, dest_ndim, dest_shape):
    '''Low-level utility function used in calculating a shape for
    an implicit output array.  This function assumes that the
    destination shape is an LLVM pointer to a C-style array that was
    already initialized to a size of one along all axes.

    Returns an integer value:
    >= 1  :  Succeeded.  Return value should equal the number of dimensions in
             the destination shape.
    0     :  Failed to broadcast because source shape is larger than the
             destination shape (this case should be weeded out at type
             checking).
    < 0   :  Failed to broadcast onto destination axis, at axis number ==