예제 #1
0
def lower_dist_arr_reduce(context, builder, sig, args):

    op_typ = args[1].type

    # store an int to specify data type
    typ_enum = _h5_typ_table[sig.args[0].dtype]
    typ_arg = cgutils.alloca_once_value(
        builder, lir.Constant(lir.IntType(32), typ_enum))
    ndims = sig.args[0].ndim

    out = make_array(sig.args[0])(context, builder, args[0])
    # store size vars array struct to pointer
    size_ptr = cgutils.alloca_once(builder, out.shape.type)
    builder.store(out.shape, size_ptr)
    size_arg = builder.bitcast(size_ptr, lir.IntType(64).as_pointer())

    ndim_arg = cgutils.alloca_once_value(
        builder, lir.Constant(lir.IntType(32), sig.args[0].ndim))
    call_args = [builder.bitcast(out.data, lir.IntType(8).as_pointer()),
                 size_arg, builder.load(ndim_arg), args[1], builder.load(typ_arg)]

    # array, shape, ndim, extra last arg type for type enum
    arg_typs = [lir.IntType(8).as_pointer(), lir.IntType(64).as_pointer(),
                lir.IntType(32), op_typ, lir.IntType(32)]
    fnty = lir.FunctionType(lir.IntType(32), arg_typs)
    fn = builder.module.get_or_insert_function(
        fnty, name="hpat_dist_arr_reduce")
    builder.call(fn, call_args)
    res = out._getvalue()
    return impl_ret_borrowed(context, builder, sig.return_type, res)
예제 #2
0
파일: dictobject.py 프로젝트: numba/numba
    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 = builder.module.get_or_insert_function(fnty, name='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)
        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 = _dict_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
예제 #3
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 = builder.module.get_or_insert_function(fnty,
                                                   name='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)
        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 = _dict_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
예제 #4
0
 def init_specific(self, context, builder, arrty, arr):
     zero = context.get_constant(types.intp, 0)
     self.index = cgutils.alloca_once_value(builder, zero)
     self.pointer = cgutils.alloca_once_value(builder, arr.data)
     # We can't trust strides[-1] to always contain the right
     # step value, see
     # http://docs.scipy.org/doc/numpy-dev/release.html#npy-relaxed-strides-checking
     self.stride = arr.itemsize
예제 #5
0
 def init_specific(self, context, builder, arrty, arr):
     zero = context.get_constant(types.intp, 0)
     self.index = cgutils.alloca_once_value(builder, zero)
     self.pointer = cgutils.alloca_once_value(builder, arr.data)
     # We can't trust strides[-1] to always contain the right
     # step value, see
     # http://docs.scipy.org/doc/numpy-dev/release.html#npy-relaxed-strides-checking
     self.stride = arr.itemsize
예제 #6
0
def array_nonzero(context, builder, sig, args):
    aryty = sig.args[0]
    # Return type is a N-tuple of 1D C-contiguous arrays
    retty = sig.return_type
    outaryty = retty.dtype
    ndim = aryty.ndim
    nouts = retty.count

    ary = make_array(aryty)(context, builder, args[0])
    shape = cgutils.unpack_tuple(builder, ary.shape)
    strides = cgutils.unpack_tuple(builder, ary.strides)
    data = ary.data
    layout = aryty.layout

    # First count the number of non-zero elements
    zero = context.get_constant(types.intp, 0)
    one = context.get_constant(types.intp, 1)
    count = cgutils.alloca_once_value(builder, zero)
    with cgutils.loop_nest(builder, shape, zero.type) as indices:
        ptr = cgutils.get_item_pointer2(builder, data, shape, strides, layout,
                                        indices)
        val = load_item(context, builder, aryty, ptr)
        nz = context.is_true(builder, aryty.dtype, val)
        with builder.if_then(nz):
            builder.store(builder.add(builder.load(count), one), count)

    # Then allocate output arrays of the right size
    out_shape = (builder.load(count), )
    outs = [
        _empty_nd_impl(context, builder, outaryty, out_shape)._getvalue()
        for i in range(nouts)
    ]
    outarys = [make_array(outaryty)(context, builder, out) for out in outs]
    out_datas = [out.data for out in outarys]

    # And fill them up
    index = cgutils.alloca_once_value(builder, zero)
    with cgutils.loop_nest(builder, shape, zero.type) as indices:
        ptr = cgutils.get_item_pointer2(builder, data, shape, strides, layout,
                                        indices)
        val = load_item(context, builder, aryty, ptr)
        nz = context.is_true(builder, aryty.dtype, val)
        with builder.if_then(nz):
            # Store element indices in output arrays
            if not indices:
                # For a 0-d array, store 0 in the unique output array
                indices = (zero, )
            cur = builder.load(index)
            for i in range(nouts):
                ptr = cgutils.get_item_pointer2(builder, out_datas[i],
                                                out_shape, (), 'C', [cur])
                store_item(context, builder, outaryty, indices[i], ptr)
            builder.store(builder.add(cur, one), index)

    tup = context.make_tuple(builder, sig.return_type, outs)
    return impl_ret_new_ref(context, builder, sig.return_type, tup)
예제 #7
0
def array_nonzero(context, builder, sig, args):
    aryty = sig.args[0]
    # Return type is a N-tuple of 1D C-contiguous arrays
    retty = sig.return_type
    outaryty = retty.dtype
    ndim = aryty.ndim
    nouts = retty.count

    ary = make_array(aryty)(context, builder, args[0])
    shape = cgutils.unpack_tuple(builder, ary.shape)
    strides = cgutils.unpack_tuple(builder, ary.strides)
    data = ary.data
    layout = aryty.layout

    # First count the number of non-zero elements
    zero = context.get_constant(types.intp, 0)
    one = context.get_constant(types.intp, 1)
    count = cgutils.alloca_once_value(builder, zero)
    with cgutils.loop_nest(builder, shape, zero.type) as indices:
        ptr = cgutils.get_item_pointer2(builder, data, shape, strides,
                                        layout, indices)
        val = load_item(context, builder, aryty, ptr)
        nz = context.is_true(builder, aryty.dtype, val)
        with builder.if_then(nz):
            builder.store(builder.add(builder.load(count), one), count)

    # Then allocate output arrays of the right size
    out_shape = (builder.load(count),)
    outs = [_empty_nd_impl(context, builder, outaryty, out_shape)._getvalue()
            for i in range(nouts)]
    outarys = [make_array(outaryty)(context, builder, out) for out in outs]
    out_datas = [out.data for out in outarys]

    # And fill them up
    index = cgutils.alloca_once_value(builder, zero)
    with cgutils.loop_nest(builder, shape, zero.type) as indices:
        ptr = cgutils.get_item_pointer2(builder, data, shape, strides,
                                        layout, indices)
        val = load_item(context, builder, aryty, ptr)
        nz = context.is_true(builder, aryty.dtype, val)
        with builder.if_then(nz):
            # Store element indices in output arrays
            if not indices:
                # For a 0-d array, store 0 in the unique output array
                indices = (zero,)
            cur = builder.load(index)
            for i in range(nouts):
                ptr = cgutils.get_item_pointer2(builder, out_datas[i],
                                                out_shape, (),
                                                'C', [cur])
                store_item(context, builder, outaryty, indices[i], ptr)
            builder.store(builder.add(cur, one), index)

    tup = context.make_tuple(builder, sig.return_type, outs)
    return impl_ret_new_ref(context, builder, sig.return_type, tup)
예제 #8
0
파일: pythonapi.py 프로젝트: molodiuc/numba
    def to_native_optional(self, obj, typ):
        """
        Convert object *obj* to a native optional structure.
        """
        noneval = self.context.make_optional_none(self.builder, typ.type)
        is_not_none = self.builder.icmp(lc.ICMP_NE, obj, self.borrow_none())

        retptr = cgutils.alloca_once(self.builder, noneval.type)
        errptr = cgutils.alloca_once_value(self.builder, cgutils.false_bit)

        with cgutils.ifelse(self.builder, is_not_none) as (then, orelse):
            with then:
                native = self.to_native_value(obj, typ.type)
                just = self.context.make_optional_value(self.builder,
                                                        typ.type, native.value)
                self.builder.store(just, retptr)
                self.builder.store(native.is_error, errptr)

            with orelse:
                self.builder.store(ir.Constant(noneval.type, ir.Undefined),
                                   retptr)
                self.builder.store(noneval, retptr)

        if native.cleanup is not None:
            def cleanup():
                with cgutils.ifthen(self.builder, is_not_none):
                    native.cleanup()
        else:
            cleanup = None

        ret = self.builder.load(retptr)
        return NativeValue(ret, is_error=self.builder.load(errptr),
                           cleanup=cleanup)
예제 #9
0
    def downsize(self, nitems):
        """
        When removing from the set, ensure it is properly sized for the given
        number of used entries.
        """
        context = self._context
        builder = self._builder
        intp_t = nitems.type

        one = ir.Constant(intp_t, 1)
        two = ir.Constant(intp_t, 2)
        minsize = ir.Constant(intp_t, MINSIZE)

        payload = self.payload

        # Ensure entries >= max(2 * used, MINSIZE)
        min_entries = builder.shl(nitems, one)
        min_entries = builder.select(
            builder.icmp_unsigned('>=', min_entries, minsize), min_entries,
            minsize)
        # Shrink only if size >= 4 * min_entries && size > MINSIZE
        max_size = builder.shl(min_entries, two)
        size = builder.add(payload.mask, one)
        need_resize = builder.and_(builder.icmp_unsigned('<=', max_size, size),
                                   builder.icmp_unsigned('<', minsize, size))

        with builder.if_then(need_resize, likely=False):
            # Find out next suitable size
            new_size_p = cgutils.alloca_once_value(builder, size)

            bb_body = builder.append_basic_block("calcsize.body")
            bb_end = builder.append_basic_block("calcsize.end")

            builder.branch(bb_body)

            with builder.goto_block(bb_body):
                # Divide by 2 (ensuring size remains a power of two)
                new_size = builder.load(new_size_p)
                new_size = builder.lshr(new_size, one)
                # Keep current size if new size would be < min_entries
                is_too_small = builder.icmp_unsigned('>', min_entries,
                                                     new_size)
                with builder.if_then(is_too_small):
                    builder.branch(bb_end)
                builder.store(new_size, new_size_p)
                builder.branch(bb_body)

            builder.position_at_end(bb_end)

            # Ensure new_size >= MINSIZE
            new_size = builder.load(new_size_p)
            # At this point, new_size should be < size if the factors
            # above were chosen carefully!

            if DEBUG_ALLOCS:
                context.printf(
                    builder, "downsize to %zd items: current size = %zd, "
                    "min entries = %zd, new size = %zd\n", nitems, size,
                    min_entries, new_size)
            self._resize(payload, new_size, "cannot shrink set")
예제 #10
0
    def choose_alloc_size(cls, context, builder, nitems):
        """
        Choose a suitable number of entries for the given number of items.
        """
        intp_t = nitems.type
        one = ir.Constant(intp_t, 1)
        minsize = ir.Constant(intp_t, MINSIZE)

        # Ensure number of entries >= 2 * used
        min_entries = builder.shl(nitems, one)
        # Find out first suitable power of 2, starting from MINSIZE
        size_p = cgutils.alloca_once_value(builder, minsize)

        bb_body = builder.append_basic_block("calcsize.body")
        bb_end = builder.append_basic_block("calcsize.end")

        builder.branch(bb_body)

        with builder.goto_block(bb_body):
            size = builder.load(size_p)
            is_large_enough = builder.icmp_unsigned('>=', size, min_entries)
            with builder.if_then(is_large_enough, likely=False):
                builder.branch(bb_end)
            next_size = builder.shl(size, one)
            builder.store(next_size, size_p)
            builder.branch(bb_body)

        builder.position_at_end(bb_end)
        return builder.load(size_p)
예제 #11
0
    def isdisjoint(self, other):
        context = self._context
        builder = self._builder
        payload = self.payload
        other_payload = other.payload

        res = cgutils.alloca_once_value(builder, cgutils.true_bit)

        def check(smaller, larger):
            # Loop over the smaller of the two, and search in the larger
            with smaller._iterate() as loop:
                entry = loop.entry
                found, _ = larger._lookup(entry.key, entry.hash)
                with builder.if_then(found):
                    builder.store(cgutils.false_bit, res)
                    loop.do_break()

        with builder.if_else(
                builder.icmp_unsigned('>', payload.used,
                                      other_payload.used)) as (if_larger,
                                                               otherwise):

            with if_larger:
                # len(self) > len(other)
                check(other_payload, payload)

            with otherwise:
                # len(self) <= len(other)
                check(payload, other_payload)

        return builder.load(res)
예제 #12
0
    def issubset(self, other, strict=False):
        context = self._context
        builder = self._builder
        payload = self.payload
        other_payload = other.payload

        cmp_op = '<' if strict else '<='

        res = cgutils.alloca_once_value(builder, cgutils.true_bit)
        with builder.if_else(
                builder.icmp_unsigned(cmp_op, payload.used,
                                      other_payload.used)) as (if_smaller,
                                                               if_larger):
            with if_larger:
                # self larger than other => self cannot possibly a subset
                builder.store(cgutils.false_bit, res)
            with if_smaller:
                # check whether each key of self is in other
                with payload._iterate() as loop:
                    entry = loop.entry
                    found, _ = other_payload._lookup(entry.key, entry.hash)
                    with builder.if_then(builder.not_(found)):
                        builder.store(cgutils.false_bit, res)
                        loop.do_break()

        return builder.load(res)
예제 #13
0
    def codegen(context, builder, sig, args):
        out_str_arr, in_str_arr = args

        in_string_array = context.make_helper(builder, string_array_type,
                                              in_str_arr)
        out_string_array = context.make_helper(builder, string_array_type,
                                               out_str_arr)
        n = in_string_array.num_items
        zero = context.get_constant(offset_typ, 0)
        curr_offset_ptr = cgutils.alloca_once_value(builder, zero)
        # XXX: assuming last offset is already set by allocate_string_array

        # for i in range(n)
        #   if not isna():
        #     out_offset[curr] = offset[i]
        with cgutils.for_range(builder, n) as loop:
            isna = lower_is_na(context, builder, in_string_array.null_bitmap,
                               loop.index)
            with cgutils.if_likely(builder, builder.not_(isna)):
                in_val = builder.load(
                    builder.gep(in_string_array.offsets, [loop.index]))
                curr_offset = builder.load(curr_offset_ptr)
                builder.store(
                    in_val, builder.gep(out_string_array.offsets,
                                        [curr_offset]))
                builder.store(
                    builder.add(
                        curr_offset,
                        lir.Constant(context.get_data_type(offset_typ), 1)),
                    curr_offset_ptr)

        return context.get_dummy_value()
예제 #14
0
def lower_dist_quantile(context, builder, sig, args):

    # store an int to specify data type
    typ_enum = _h5_typ_table[sig.args[0].dtype]
    typ_arg = cgutils.alloca_once_value(builder, lir.Constant(lir.IntType(32), typ_enum))
    assert sig.args[0].ndim == 1

    arr = make_array(sig.args[0])(context, builder, args[0])
    local_size = builder.extract_value(arr.shape, 0)

    if len(args) == 3:
        total_size = args[2]
    else:
        # sequential case
        total_size = local_size

    call_args = [builder.bitcast(arr.data, lir.IntType(8).as_pointer()),
                local_size, total_size, args[1], builder.load(typ_arg)]

    # array, size, total_size, quantile, type enum
    arg_typs = [lir.IntType(8).as_pointer(), lir.IntType(64), lir.IntType(64),
                                            lir.DoubleType(), lir.IntType(32)]
    fnty = lir.FunctionType(lir.DoubleType(), arg_typs)
    fn = builder.module.get_or_insert_function(fnty, name="quantile_parallel")
    return builder.call(fn, call_args)
예제 #15
0
def _unbox_native_field(typ, obj, field_name: str, c):
    ret_ptr = cgutils.alloca_once(c.builder, c.context.get_value_type(typ))
    is_error_ptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
    fail_obj = c.context.get_constant_null(typ)

    with local_return(c.builder) as ret:
        fail_blk = c.builder.append_basic_block("fail")
        with c.builder.goto_block(fail_blk):
            c.builder.store(cgutils.true_bit, is_error_ptr)
            c.builder.store(fail_obj, ret_ptr)
            ret()

        field_obj = c.pyapi.object_getattr_string(obj, field_name)
        with cgutils.if_unlikely(c.builder,
                                 cgutils.is_null(c.builder, field_obj)):
            c.builder.branch(fail_blk)

        field_native = c.unbox(typ, field_obj)
        c.pyapi.decref(field_obj)
        with cgutils.if_unlikely(c.builder, field_native.is_error):
            c.builder.branch(fail_blk)

        c.builder.store(cgutils.false_bit, is_error_ptr)
        c.builder.store(field_native.value, ret_ptr)

    return NativeValue(c.builder.load(ret_ptr),
                       is_error=c.builder.load(is_error_ptr))
예제 #16
0
def lower_get_sendrecv_counts(context, builder, sig, args):
    # prepare buffer args
    pointer_to_cbuffer_typ = lir.IntType(8).as_pointer().as_pointer()
    send_counts = cgutils.alloca_once(builder, lir.IntType(8).as_pointer())
    recv_counts = cgutils.alloca_once(builder, lir.IntType(8).as_pointer())
    send_disp = cgutils.alloca_once(builder, lir.IntType(8).as_pointer())
    recv_disp = cgutils.alloca_once(builder, lir.IntType(8).as_pointer())

    # prepare key array args
    key_arr = make_array(sig.args[0])(context, builder, args[0])
    # XXX: assuming key arr is 1D
    assert key_arr.shape.type.count == 1
    arr_len = builder.extract_value(key_arr.shape, 0)
    # TODO: extend to other key types
    assert sig.args[0].dtype == types.intp
    key_typ_enum = _h5_typ_table[sig.args[0].dtype]
    key_typ_arg = builder.load(cgutils.alloca_once_value(builder,
                                                         lir.Constant(lir.IntType(32), key_typ_enum)))
    key_arr_data = builder.bitcast(key_arr.data, lir.IntType(8).as_pointer())

    call_args = [send_counts, recv_counts, send_disp, recv_disp, arr_len,
                 key_typ_arg, key_arr_data]

    fnty = lir.FunctionType(lir.IntType(64), [pointer_to_cbuffer_typ] * 4
                            + [lir.IntType(64), lir.IntType(32), lir.IntType(8).as_pointer()])
    fn = builder.module.get_or_insert_function(fnty,
                                               name="get_join_sendrecv_counts")
    total_size = builder.call(fn, call_args)
    items = [builder.load(send_counts), builder.load(recv_counts),
             builder.load(send_disp), builder.load(recv_disp), total_size]
    out_tuple_typ = types.Tuple([c_buffer_type, c_buffer_type, c_buffer_type,
                                 c_buffer_type, types.intp])
    return context.make_tuple(builder, out_tuple_typ, items)
예제 #17
0
def lower_dist_reduce(context, builder, sig, args):
    val_typ = args[0].type
    op_typ = args[1].type

    target_typ = sig.args[0]
    if isinstance(target_typ, IndexValueType):
        target_typ = target_typ.val_typ
        supported_typs = [types.int32, types.float32, types.float64]
        import sys
        if not sys.platform.startswith('win'):
            # long is 4 byte on Windows
            supported_typs.append(types.int64)
        if target_typ not in supported_typs:  # pragma: no cover
            raise TypeError("argmin/argmax not supported for type {}".format(
                target_typ))

    in_ptr = cgutils.alloca_once(builder, val_typ)
    out_ptr = cgutils.alloca_once(builder, val_typ)
    builder.store(args[0], in_ptr)
    # cast to char *
    in_ptr = builder.bitcast(in_ptr, lir.IntType(8).as_pointer())
    out_ptr = builder.bitcast(out_ptr, lir.IntType(8).as_pointer())

    typ_enum = _h5_typ_table[target_typ]
    typ_arg = cgutils.alloca_once_value(builder, lir.Constant(lir.IntType(32),
                                                              typ_enum))

    fnty = lir.FunctionType(lir.VoidType(), [lir.IntType(8).as_pointer(),
                                             lir.IntType(8).as_pointer(), op_typ, lir.IntType(32)])
    fn = builder.module.get_or_insert_function(fnty, name="hpat_dist_reduce")
    builder.call(fn, [in_ptr, out_ptr, args[1], builder.load(typ_arg)])
    # cast back to value type
    out_ptr = builder.bitcast(out_ptr, val_typ.as_pointer())
    return builder.load(out_ptr)
예제 #18
0
 def from_list(cls, context, builder, iter_type, list_val):
     list_inst = ListInstance(context, builder, iter_type.container, list_val)
     self = cls(context, builder, iter_type, None)
     index = context.get_constant(types.intp, 0)
     self._iter.index = cgutils.alloca_once_value(builder, index)
     self._iter.meminfo = list_inst.meminfo
     return self
예제 #19
0
    def issubset(self, other, strict=False):
        context = self._context
        builder = self._builder
        payload = self.payload
        other_payload = other.payload

        cmp_op = '<' if strict else '<='

        res = cgutils.alloca_once_value(builder, cgutils.true_bit)
        with builder.if_else(
            builder.icmp_unsigned(cmp_op, payload.used, other_payload.used)
            ) as (if_smaller, if_larger):
            with if_larger:
                # self larger than other => self cannot possibly a subset
                builder.store(cgutils.false_bit, res)
            with if_smaller:
                # check whether each key of self is in other
                with payload._iterate() as loop:
                    entry = loop.entry
                    found, _ = other_payload._lookup(entry.key, entry.hash)
                    with builder.if_then(builder.not_(found)):
                        builder.store(cgutils.false_bit, res)
                        loop.do_break()

        return builder.load(res)
예제 #20
0
            def init_specific(self, context, builder, arrty, arr):
                zero = context.get_constant(types.intp, 0)
                data = arr.data
                ndim = arrty.ndim
                shapes = cgutils.unpack_tuple(builder, arr.shape, ndim)

                indices = cgutils.alloca_once(builder, zero.type,
                                              size=context.get_constant(types.intp,
                                                                        arrty.ndim))
                pointers = cgutils.alloca_once(builder, data.type,
                                               size=context.get_constant(types.intp,
                                                                         arrty.ndim))
                strides = cgutils.unpack_tuple(builder, arr.strides, ndim)
                exhausted = cgutils.alloca_once_value(builder, cgutils.false_byte)

                # Initialize indices and pointers with their start values.
                for dim in range(ndim):
                    idxptr = cgutils.gep(builder, indices, dim)
                    ptrptr = cgutils.gep(builder, pointers, dim)
                    builder.store(data, ptrptr)
                    builder.store(zero, idxptr)
                    # 0-sized dimensions really indicate an empty array,
                    # but we have to catch that condition early to avoid
                    # a bug inside the iteration logic (see issue #846).
                    dim_size = shapes[dim]
                    dim_is_empty = builder.icmp(lc.ICMP_EQ, dim_size, zero)
                    with cgutils.if_unlikely(builder, dim_is_empty):
                        builder.store(cgutils.true_byte, exhausted)

                self.indices = indices
                self.pointers = pointers
                self.exhausted = exhausted
예제 #21
0
 def from_set(cls, context, builder, iter_type, set_val):
     set_inst = SetInstance(context, builder, iter_type.container, set_val)
     self = cls(context, builder, iter_type, None)
     index = context.get_constant(types.intp, 0)
     self._iter.index = cgutils.alloca_once_value(builder, index)
     self._iter.meminfo = set_inst.meminfo
     return self
예제 #22
0
파일: pio_lower.py 프로젝트: samaid/sdc
def h5_read(context, builder, sig, args):
    # extra last arg type for type enum
    arg_typs = [h5file_lir_type, lir.IntType(32),
                lir.IntType(64).as_pointer(), lir.IntType(64).as_pointer(),
                lir.IntType(64), lir.IntType(8).as_pointer(), lir.IntType(32)]
    fnty = lir.FunctionType(lir.IntType(32), arg_typs)

    fn = builder.module.get_or_insert_function(fnty, name="hpat_h5_read")
    out = make_array(sig.args[5])(context, builder, args[5])
    # store size vars array struct to pointer
    count_ptr = cgutils.alloca_once(builder, args[2].type)
    builder.store(args[2], count_ptr)
    size_ptr = cgutils.alloca_once(builder, args[3].type)
    builder.store(args[3], size_ptr)
    # store an int to specify data type
    typ_enum = _numba_to_c_type_map[sig.args[5].dtype]
    typ_arg = cgutils.alloca_once_value(
        builder, lir.Constant(lir.IntType(32), typ_enum))
    call_args = [args[0], args[1],
                 builder.bitcast(count_ptr, lir.IntType(64).as_pointer()),
                 builder.bitcast(size_ptr, lir.IntType(
                     64).as_pointer()), args[4],
                 builder.bitcast(out.data, lir.IntType(8).as_pointer()),
                 builder.load(typ_arg)]

    return builder.call(fn, call_args)
예제 #23
0
def lower_dist_isend(context, builder, sig, args):
    # store an int to specify data type
    typ_enum = hpat.pio_lower._h5_typ_table[sig.args[0].dtype]
    typ_arg = cgutils.alloca_once_value(
        builder, lir.Constant(lir.IntType(32), typ_enum))

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

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

    # 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(lir.IntType(32), arg_typs)
    fn = builder.module.get_or_insert_function(fnty, name="hpat_dist_isend")
    return builder.call(fn, call_args)
예제 #24
0
파일: randomimpl.py 프로젝트: smtlify/numba
def get_next_int(context, builder, state_ptr, nbits):
    """
    Get the next integer with width *nbits*.
    """
    c32 = ir.Constant(nbits.type, 32)
    def get_shifted_int(nbits):
        shift = builder.sub(c32, nbits)
        y = get_next_int32(context, builder, state_ptr)
        return builder.lshr(y, builder.zext(shift, y.type))

    ret = cgutils.alloca_once_value(builder, ir.Constant(int64_t, 0))

    is_32b = builder.icmp_unsigned('<=', nbits, c32)
    with cgutils.ifelse(builder, is_32b) as (ifsmall, iflarge):
        with ifsmall:
            low = get_shifted_int(nbits)
            builder.store(builder.zext(low, int64_t), ret)
        with iflarge:
            # XXX This assumes nbits <= 64
            low = get_next_int32(context, builder, state_ptr)
            high = get_shifted_int(builder.sub(nbits, c32))
            total = builder.add(
                builder.zext(low, int64_t),
                builder.shl(builder.zext(high, int64_t), ir.Constant(int64_t, 32)))
            builder.store(total, ret)

    return builder.load(ret)
예제 #25
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 = builder.module.get_or_insert_function(fnty,
                                                   name='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
예제 #26
0
파일: listobj.py 프로젝트: dhavide/numba
 def from_list(cls, context, builder, iter_type, list_val):
     list_inst = ListInstance(context, builder, iter_type.list_type, list_val)
     self = cls(context, builder, iter_type, None)
     index = context.get_constant(types.intp, 0)
     self._iter.index = cgutils.alloca_once_value(builder, index)
     self._iter.meminfo = list_inst.meminfo
     return self
예제 #27
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 _h5_typ_table, "invalid allgather type"
    typ_enum = _h5_typ_table[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 = builder.module.get_or_insert_function(fnty, name="allgather")
    builder.call(fn, call_args)
    return context.get_dummy_value()
예제 #28
0
파일: iterators.py 프로젝트: numba/numba
def iternext_zip(context, builder, sig, args, result):
    [zip_type] = sig.args
    [zipobj] = args

    zipobj = context.make_helper(builder, zip_type, value=zipobj)

    if len(zipobj) == 0:
        # zip() is an empty iterator
        result.set_exhausted()
        return

    p_ret_tup = cgutils.alloca_once(builder,
                                    context.get_value_type(zip_type.yield_type))
    p_is_valid = cgutils.alloca_once_value(builder, value=cgutils.true_bit)

    for i, (iterobj, srcty) in enumerate(zip(zipobj, zip_type.source_types)):
        is_valid = builder.load(p_is_valid)
        # Avoid calling the remaining iternext if a iterator has been exhausted
        with builder.if_then(is_valid):
            srcres = call_iternext(context, builder, srcty, iterobj)
            is_valid = builder.and_(is_valid, srcres.is_valid())
            builder.store(is_valid, p_is_valid)
            val = srcres.yielded_value()
            ptr = cgutils.gep_inbounds(builder, p_ret_tup, 0, i)
            builder.store(val, ptr)

    is_valid = builder.load(p_is_valid)
    result.set_valid(is_valid)

    with builder.if_then(is_valid):
        result.yield_(builder.load(p_ret_tup))
예제 #29
0
            def init_specific(self, context, builder, arrty, arr):
                zero = context.get_constant(types.intp, 0)
                data = arr.data
                ndim = arrty.ndim
                shapes = cgutils.unpack_tuple(builder, arr.shape, ndim)

                indices = cgutils.alloca_once(builder,
                                              zero.type,
                                              size=context.get_constant(
                                                  types.intp, arrty.ndim))
                pointers = cgutils.alloca_once(builder,
                                               data.type,
                                               size=context.get_constant(
                                                   types.intp, arrty.ndim))
                strides = cgutils.unpack_tuple(builder, arr.strides, ndim)
                exhausted = cgutils.alloca_once_value(builder,
                                                      cgutils.false_byte)

                # Initialize indices and pointers with their start values.
                for dim in range(ndim):
                    idxptr = cgutils.gep(builder, indices, dim)
                    ptrptr = cgutils.gep(builder, pointers, dim)
                    builder.store(data, ptrptr)
                    builder.store(zero, idxptr)
                    # 0-sized dimensions really indicate an empty array,
                    # but we have to catch that condition early to avoid
                    # a bug inside the iteration logic (see issue #846).
                    dim_size = shapes[dim]
                    dim_is_empty = builder.icmp(lc.ICMP_EQ, dim_size, zero)
                    with cgutils.if_unlikely(builder, dim_is_empty):
                        builder.store(cgutils.true_byte, exhausted)

                self.indices = indices
                self.pointers = pointers
                self.exhausted = exhausted
예제 #30
0
파일: randomimpl.py 프로젝트: yuguen/numba
def get_next_int(context, builder, state_ptr, nbits):
    """
    Get the next integer with width *nbits*.
    """
    c32 = ir.Constant(nbits.type, 32)
    def get_shifted_int(nbits):
        shift = builder.sub(c32, nbits)
        y = get_next_int32(context, builder, state_ptr)
        return builder.lshr(y, builder.zext(shift, y.type))

    ret = cgutils.alloca_once_value(builder, ir.Constant(int64_t, 0))

    is_32b = builder.icmp_unsigned('<=', nbits, c32)
    with builder.if_else(is_32b) as (ifsmall, iflarge):
        with ifsmall:
            low = get_shifted_int(nbits)
            builder.store(builder.zext(low, int64_t), ret)
        with iflarge:
            # XXX This assumes nbits <= 64
            low = get_next_int32(context, builder, state_ptr)
            high = get_shifted_int(builder.sub(nbits, c32))
            total = builder.add(
                builder.zext(low, int64_t),
                builder.shl(builder.zext(high, int64_t), ir.Constant(int64_t, 32)))
            builder.store(total, ret)

    return builder.load(ret)
예제 #31
0
    def isdisjoint(self, other):
        context = self._context
        builder = self._builder
        payload = self.payload
        other_payload = other.payload

        res = cgutils.alloca_once_value(builder, cgutils.true_bit)

        def check(smaller, larger):
            # Loop over the smaller of the two, and search in the larger
            with smaller._iterate() as loop:
                entry = loop.entry
                found, _ = larger._lookup(entry.key, entry.hash)
                with builder.if_then(found):
                    builder.store(cgutils.false_bit, res)
                    loop.do_break()

        with builder.if_else(
            builder.icmp_unsigned('>', payload.used, other_payload.used)
            ) as (if_larger, otherwise):

            with if_larger:
                # len(self) > len(other)
                check(other_payload, payload)

            with otherwise:
                # len(self) <= len(other)
                check(payload, other_payload)

        return builder.load(res)
예제 #32
0
def iternext_zip(context, builder, sig, args, result):
    [zip_type] = sig.args
    [zipobj] = args

    zipobj = context.make_helper(builder, zip_type, value=zipobj)

    if len(zipobj) == 0:
        # zip() is an empty iterator
        result.set_exhausted()
        return

    p_ret_tup = cgutils.alloca_once(builder,
                                    context.get_value_type(zip_type.yield_type))
    p_is_valid = cgutils.alloca_once_value(builder, value=cgutils.true_bit)

    for i, (iterobj, srcty) in enumerate(zip(zipobj, zip_type.source_types)):
        is_valid = builder.load(p_is_valid)
        # Avoid calling the remaining iternext if a iterator has been exhausted
        with builder.if_then(is_valid):
            srcres = call_iternext(context, builder, srcty, iterobj)
            is_valid = builder.and_(is_valid, srcres.is_valid())
            builder.store(is_valid, p_is_valid)
            val = srcres.yielded_value()
            ptr = cgutils.gep_inbounds(builder, p_ret_tup, 0, i)
            builder.store(val, ptr)

    is_valid = builder.load(p_is_valid)
    result.set_valid(is_valid)

    with builder.if_then(is_valid):
        result.yield_(builder.load(p_ret_tup))
예제 #33
0
    def choose_alloc_size(cls, context, builder, nitems):
        """
        Choose a suitable number of entries for the given number of items.
        """
        intp_t = nitems.type
        one = ir.Constant(intp_t, 1)
        minsize = ir.Constant(intp_t, MINSIZE)

        # Ensure number of entries >= 2 * used
        min_entries = builder.shl(nitems, one)
        # Find out first suitable power of 2, starting from MINSIZE
        size_p = cgutils.alloca_once_value(builder, minsize)

        bb_body = builder.append_basic_block("calcsize.body")
        bb_end = builder.append_basic_block("calcsize.end")

        builder.branch(bb_body)

        with builder.goto_block(bb_body):
            size = builder.load(size_p)
            is_large_enough = builder.icmp_unsigned('>=', size, min_entries)
            with builder.if_then(is_large_enough, likely=False):
                builder.branch(bb_end)
            next_size = builder.shl(size, one)
            builder.store(next_size, size_p)
            builder.branch(bb_body)

        builder.position_at_end(bb_end)
        return builder.load(size_p)
예제 #34
0
    def downsize(self, nitems):
        """
        When removing from the set, ensure it is properly sized for the given
        number of used entries.
        """
        context = self._context
        builder = self._builder
        intp_t = nitems.type

        one = ir.Constant(intp_t, 1)
        two = ir.Constant(intp_t, 2)
        minsize = ir.Constant(intp_t, MINSIZE)

        payload = self.payload

        # Ensure entries >= max(2 * used, MINSIZE)
        min_entries = builder.shl(nitems, one)
        min_entries = builder.select(builder.icmp_unsigned('>=', min_entries, minsize),
                                     min_entries, minsize)
        # Shrink only if size >= 4 * min_entries && size > MINSIZE
        max_size = builder.shl(min_entries, two)
        size = builder.add(payload.mask, one)
        need_resize = builder.and_(
            builder.icmp_unsigned('<=', max_size, size),
            builder.icmp_unsigned('<', minsize, size))

        with builder.if_then(need_resize, likely=False):
            # Find out next suitable size
            new_size_p = cgutils.alloca_once_value(builder, size)

            bb_body = builder.append_basic_block("calcsize.body")
            bb_end = builder.append_basic_block("calcsize.end")

            builder.branch(bb_body)

            with builder.goto_block(bb_body):
                # Divide by 2 (ensuring size remains a power of two)
                new_size = builder.load(new_size_p)
                new_size = builder.lshr(new_size, one)
                # Keep current size if new size would be < min_entries
                is_too_small = builder.icmp_unsigned('>', min_entries, new_size)
                with builder.if_then(is_too_small):
                    builder.branch(bb_end)
                builder.store(new_size, new_size_p)
                builder.branch(bb_body)

            builder.position_at_end(bb_end)

            # Ensure new_size >= MINSIZE
            new_size = builder.load(new_size_p)
            # At this point, new_size should be < size if the factors
            # above were chosen carefully!

            if DEBUG_ALLOCS:
                context.printf(builder,
                               "downsize to %zd items: current size = %zd, "
                               "min entries = %zd, new size = %zd\n",
                               nitems, size, min_entries, new_size)
            self._resize(payload, new_size, "cannot shrink set")
예제 #35
0
 def alloca_buffer(self):
     """
     Return a pointer to a stack-allocated, zero-initialized Py_buffer.
     """
     # Treat the buffer as an opaque array of bytes
     ptr = cgutils.alloca_once_value(self.builder,
                                     lc.Constant.null(self.py_buffer_t))
     return ptr
예제 #36
0
파일: pythonapi.py 프로젝트: ibtawfik/numba
 def alloca_buffer(self):
     """
     Return a pointer to a stack-allocated, zero-initialized Py_buffer.
     """
     # Treat the buffer as an opaque array of bytes
     ptr = cgutils.alloca_once_value(self.builder,
                                     lc.Constant.null(self.py_buffer_t))
     return ptr
예제 #37
0
    def codegen(context, builder, sig, args):
        fnty = ir.FunctionType(
            ll_ssize_t,
            [ll_dict_type, ll_bytes, ll_hash, ll_bytes],
        )
        [td, tkey, thashval] = sig.args
        [d, key, hashval] = args
        fn = builder.module.get_or_insert_function(fnty,
                                                   name='numba_dict_lookup')

        dm_key = context.data_model_manager[tkey]
        dm_val = context.data_model_manager[td.value_type]

        data_key = dm_key.as_data(builder, key)
        ptr_key = cgutils.alloca_once_value(builder, data_key)

        ll_val = context.get_data_type(td.value_type)
        ptr_val = cgutils.alloca_once(builder, ll_val)

        dp = _dict_get_data(context, builder, td, d)
        ix = builder.call(
            fn,
            [
                dp,
                _as_bytes(builder, ptr_key),
                hashval,
                _as_bytes(builder, ptr_val),
            ],
        )
        # Load value if output is available
        found = builder.icmp_signed('>=', ix, ix.type(int(DKIX.EMPTY)))

        out = context.make_optional_none(builder, td.value_type)
        pout = cgutils.alloca_once_value(builder, out)

        with builder.if_then(found):
            val = dm_val.load_from_data_pointer(builder, ptr_val)
            context.nrt.incref(builder, td.value_type, val)
            loaded = context.make_optional_value(builder, td.value_type, val)
            builder.store(loaded, pout)

        out = builder.load(pout)
        return context.make_tuple(builder, resty, [ix, out])
예제 #38
0
    def _copy_payload(self, src_payload):
        """
        Raw-copy the given payload into self.
        """
        context = self._context
        builder = self._builder

        ok = cgutils.alloca_once_value(builder, cgutils.true_bit)

        intp_t = context.get_value_type(types.intp)
        zero = ir.Constant(intp_t, 0)
        one = ir.Constant(intp_t, 1)

        payload_type = context.get_data_type(types.SetPayload(self._ty))
        payload_size = context.get_abi_sizeof(payload_type)
        entry_size = self._entrysize
        # Account for the fact that the payload struct already contains an entry
        payload_size -= entry_size

        mask = src_payload.mask
        nentries = builder.add(one, mask)

        # Total allocation size = <payload header size> + nentries * entry_size
        # (note there can't be any overflow since we're reusing an existing
        #  payload's parameters)
        allocsize = builder.add(
            ir.Constant(intp_t, payload_size),
            builder.mul(ir.Constant(intp_t, entry_size), nentries))

        with builder.if_then(builder.load(ok), likely=True):
            meminfo = context.nrt.meminfo_new_varsize(builder, size=allocsize)
            alloc_ok = cgutils.is_null(builder, meminfo)

            with builder.if_else(cgutils.is_null(builder, meminfo),
                                 likely=False) as (if_error, if_ok):
                with if_error:
                    builder.store(cgutils.false_bit, ok)
                with if_ok:
                    self._set.meminfo = meminfo
                    payload = self.payload
                    payload.used = src_payload.used
                    payload.fill = src_payload.fill
                    payload.finger = zero
                    payload.mask = mask
                    cgutils.raw_memcpy(builder, payload.entries,
                                       src_payload.entries, nentries,
                                       entry_size)

                    if DEBUG_ALLOCS:
                        context.printf(
                            builder,
                            "allocated %zd bytes for set at %p: mask = %zd\n",
                            allocsize, payload.ptr, mask)

        return builder.load(ok)
예제 #39
0
파일: dictobject.py 프로젝트: numba/numba
    def codegen(context, builder, sig, args):
        fnty = ir.FunctionType(
            ll_ssize_t,
            [ll_dict_type, ll_bytes, ll_hash, ll_bytes],
        )
        [td, tkey, thashval] = sig.args
        [d, key, hashval] = args
        fn = builder.module.get_or_insert_function(fnty, name='numba_dict_lookup')

        dm_key = context.data_model_manager[tkey]
        dm_val = context.data_model_manager[td.value_type]

        data_key = dm_key.as_data(builder, key)
        ptr_key = cgutils.alloca_once_value(builder, data_key)

        ll_val = context.get_data_type(td.value_type)
        ptr_val = cgutils.alloca_once(builder, ll_val)

        dp = _dict_get_data(context, builder, td, d)
        ix = builder.call(
            fn,
            [
                dp,
                _as_bytes(builder, ptr_key),
                hashval,
                _as_bytes(builder, ptr_val),
            ],
        )
        # Load value if output is available
        found = builder.icmp_signed('>=', ix, ix.type(int(DKIX.EMPTY)))

        out = context.make_optional_none(builder, td.value_type)
        pout = cgutils.alloca_once_value(builder, out)

        with builder.if_then(found):
            val = dm_val.load_from_data_pointer(builder, ptr_val)
            context.nrt.incref(builder, td.value_type, val)
            loaded = context.make_optional_value(builder, td.value_type, val)
            builder.store(loaded, pout)

        out = builder.load(pout)
        return context.make_tuple(builder, resty, [ix, out])
예제 #40
0
def impl_string_array_single(context, builder, sig, args):
    typ = sig.return_type
    string_array = cgutils.create_struct_proxy(typ)(context, builder)
    if not sig.args:  # return empty string array if no args
        return string_array._getvalue()

    string_list = ListInstance(context, builder, sig.args[0], args[0])

    # get total size of string buffer
    fnty = lir.FunctionType(lir.IntType(64), [lir.IntType(8).as_pointer()])
    fn_len = builder.module.get_or_insert_function(fnty, name="get_str_len")
    zero = context.get_constant(types.intp, 0)
    total_size = cgutils.alloca_once_value(builder, zero)
    string_array.size = string_list.size

    # loop through all strings and get length
    with cgutils.for_range(builder, string_list.size) as loop:
        str_value = string_list.getitem(loop.index)
        str_len = builder.call(fn_len, [str_value])
        builder.store(builder.add(builder.load(total_size), str_len),
                      total_size)

    # allocate string array
    fnty = lir.FunctionType(lir.VoidType(), [
        lir.IntType(8).as_pointer().as_pointer(),
        lir.IntType(8).as_pointer().as_pointer(),
        lir.IntType(64),
        lir.IntType(64)
    ])
    fn_alloc = builder.module.get_or_insert_function(
        fnty, name="allocate_string_array")
    builder.call(fn_alloc, [
        string_array._get_ptr_by_name('offsets'),
        string_array._get_ptr_by_name('data'), string_list.size,
        builder.load(total_size)
    ])

    # set string array values
    fnty = lir.FunctionType(lir.VoidType(), [
        lir.IntType(8).as_pointer(),
        lir.IntType(8).as_pointer(),
        lir.IntType(8).as_pointer(),
        lir.IntType(64)
    ])
    fn_setitem = builder.module.get_or_insert_function(
        fnty, name="setitem_string_array")

    with cgutils.for_range(builder, string_list.size) as loop:
        str_value = string_list.getitem(loop.index)
        builder.call(
            fn_setitem,
            [string_array.offsets, string_array.data, str_value, loop.index])

    return string_array._getvalue()
예제 #41
0
            def init_specific(self, context, builder, arrty, arr):
                zero = context.get_constant(types.intp, 0)
                self.index = cgutils.alloca_once_value(builder, zero)
                self.pointer = cgutils.alloca_once_value(builder, arr.data)
                # We can't trust strides[-1] to always contain the right
                # step value, see
                # http://docs.scipy.org/doc/numpy-dev/release.html#npy-relaxed-strides-checking
                self.stride = arr.itemsize

                if kind == 'ndenumerate':
                    # Zero-initialize the indices array.
                    indices = cgutils.alloca_once(
                        builder, zero.type,
                        size=context.get_constant(types.intp, arrty.ndim))

                    for dim in range(arrty.ndim):
                        idxptr = cgutils.gep(builder, indices, dim)
                        builder.store(zero, idxptr)

                    self.indices = indices
예제 #42
0
    def _copy_payload(self, src_payload):
        """
        Raw-copy the given payload into self.
        """
        context = self._context
        builder = self._builder

        ok = cgutils.alloca_once_value(builder, cgutils.true_bit)

        intp_t = context.get_value_type(types.intp)
        zero = ir.Constant(intp_t, 0)
        one = ir.Constant(intp_t, 1)

        payload_type = context.get_data_type(types.SetPayload(self._ty))
        payload_size = context.get_abi_sizeof(payload_type)
        entry_size = self._entrysize
        # Account for the fact that the payload struct already contains an entry
        payload_size -= entry_size

        mask = src_payload.mask
        nentries = builder.add(one, mask)

        # Total allocation size = <payload header size> + nentries * entry_size
        # (note there can't be any overflow since we're reusing an existing
        #  payload's parameters)
        allocsize = builder.add(ir.Constant(intp_t, payload_size),
                                builder.mul(ir.Constant(intp_t, entry_size),
                                            nentries))

        with builder.if_then(builder.load(ok), likely=True):
            meminfo = context.nrt.meminfo_new_varsize(builder, size=allocsize)
            alloc_ok = cgutils.is_null(builder, meminfo)

            with builder.if_else(cgutils.is_null(builder, meminfo),
                                 likely=False) as (if_error, if_ok):
                with if_error:
                    builder.store(cgutils.false_bit, ok)
                with if_ok:
                    self._set.meminfo = meminfo
                    payload = self.payload
                    payload.used = src_payload.used
                    payload.fill = src_payload.fill
                    payload.finger = zero
                    payload.mask = mask
                    cgutils.raw_memcpy(builder, payload.entries,
                                       src_payload.entries, nentries,
                                       entry_size)

                    if DEBUG_ALLOCS:
                        context.printf(builder,
                                       "allocated %zd bytes for set at %p: mask = %zd\n",
                                       allocsize, payload.ptr, mask)

        return builder.load(ok)
예제 #43
0
            def init_specific(self, context, builder, arrty, arr):
                zero = context.get_constant(types.intp, 0)
                self.index = cgutils.alloca_once_value(builder, zero)
                self.pointer = cgutils.alloca_once_value(builder, arr.data)
                # We can't trust strides[-1] to always contain the right
                # step value, see
                # http://docs.scipy.org/doc/numpy-dev/release.html#npy-relaxed-strides-checking
                self.stride = arr.itemsize

                if kind == 'ndenumerate':
                    # Zero-initialize the indices array.
                    indices = cgutils.alloca_once(builder,
                                                  zero.type,
                                                  size=context.get_constant(
                                                      types.intp, arrty.ndim))

                    for dim in range(arrty.ndim):
                        idxptr = cgutils.gep(builder, indices, dim)
                        builder.store(zero, idxptr)

                    self.indices = indices
예제 #44
0
def getiter_array(context, builder, sig, args):
    [arrayty] = sig.args
    [array] = args

    iterobj = make_arrayiter_cls(sig.return_type)(context, builder)

    zero = context.get_constant(types.intp, 0)
    indexptr = cgutils.alloca_once_value(builder, zero)

    iterobj.index = indexptr
    iterobj.array = array

    return iterobj._getvalue()
예제 #45
0
def make_array_flatiter(context, builder, arrty, arr):
    flatitercls = make_array_flat_cls(types.NumpyFlatType(arrty))
    flatiter = flatitercls(context, builder)

    arrayptr = cgutils.alloca_once_value(builder, arr)
    flatiter.array = arrayptr

    arrcls = context.make_array(arrty)
    arr = arrcls(context, builder, ref=arrayptr)

    flatiter.init_specific(context, builder, arrty, arr)

    return flatiter._getvalue()
예제 #46
0
def getiter_array(context, builder, sig, args):
    [arrayty] = sig.args
    [array] = args

    iterobj = make_arrayiter_cls(sig.return_type)(context, builder)

    zero = context.get_constant(types.intp, 0)
    indexptr = cgutils.alloca_once_value(builder, zero)

    iterobj.index = indexptr
    iterobj.array = array

    return iterobj._getvalue()
예제 #47
0
파일: printimpl.py 프로젝트: kumsh/numba
def const_print_impl(context, builder, sig, args):
    ty, = sig.args
    pyval = ty.value
    # This is ensured by lowering
    assert isinstance(pyval, str)

    vprint = nvvmutils.declare_vprint(builder.module)
    rawfmt = "%s"
    fmt = context.insert_string_const_addrspace(builder, rawfmt)
    val = context.insert_string_const_addrspace(builder, pyval)
    valptr = cgutils.alloca_once_value(builder, val)
    builder.call(vprint, (fmt, builder.bitcast(valptr, voidptr)))
    return context.get_dummy_value()
예제 #48
0
def make_array_flatiter(context, builder, arrty, arr):
    flatitercls = make_array_flat_cls(types.NumpyFlatType(arrty))
    flatiter = flatitercls(context, builder)

    arrayptr = cgutils.alloca_once_value(builder, arr)
    flatiter.array = arrayptr

    arrcls = context.make_array(arrty)
    arr = arrcls(context, builder, ref=arrayptr)

    flatiter.init_specific(context, builder, arrty, arr)

    return flatiter._getvalue()
예제 #49
0
def make_array_ndenumerate(context, builder, sig, args):
    arrty, = sig.args
    arr, = args
    nditercls = make_array_ndenumerate_cls(types.NumpyNdEnumerateType(arrty))
    nditer = nditercls(context, builder)

    arrayptr = cgutils.alloca_once_value(builder, arr)
    nditer.array = arrayptr

    arrcls = context.make_array(arrty)
    arr = arrcls(context, builder, ref=arrayptr)

    nditer.init_specific(context, builder, arrty, arr)

    return nditer._getvalue()
예제 #50
0
def make_array_ndenumerate(context, builder, sig, args):
    arrty, = sig.args
    arr, = args
    nditercls = make_array_ndenumerate_cls(types.NumpyNdEnumerateType(arrty))
    nditer = nditercls(context, builder)

    arrayptr = cgutils.alloca_once_value(builder, arr)
    nditer.array = arrayptr

    arrcls = context.make_array(arrty)
    arr = arrcls(context, builder, ref=arrayptr)

    nditer.init_specific(context, builder, arrty, arr)

    return nditer._getvalue()
예제 #51
0
파일: pythonapi.py 프로젝트: ibtawfik/numba
    def nrt_adapt_ndarray_to_python(self, aryty, ary, dtypeptr):
        assert self.context.enable_nrt, "NRT required"

        intty = ir.IntType(32)
        fnty = Type.function(self.pyobj,
                             [self.voidptr, intty, intty, self.pyobj])
        fn = self._get_function(fnty, name="NRT_adapt_ndarray_to_python")
        fn.args[0].add_attribute(lc.ATTR_NO_CAPTURE)

        ndim = self.context.get_constant(types.int32, aryty.ndim)
        writable = self.context.get_constant(types.int32, int(aryty.mutable))

        aryptr = cgutils.alloca_once_value(self.builder, ary)
        return self.builder.call(fn, [self.builder.bitcast(aryptr,
                                                           self.voidptr),
                                      ndim, writable, dtypeptr])
예제 #52
0
    def nrt_adapt_ndarray_to_python(self, aryty, ary, dtypeptr):
        assert self.context.enable_nrt, "NRT required"

        intty = ir.IntType(32)
        fnty = Type.function(self.pyobj,
                             [self.voidptr, intty, intty, self.pyobj])
        fn = self._get_function(fnty, name="NRT_adapt_ndarray_to_python")
        fn.args[0].add_attribute(lc.ATTR_NO_CAPTURE)

        ndim = self.context.get_constant(types.int32, aryty.ndim)
        writable = self.context.get_constant(types.int32, int(aryty.mutable))

        aryptr = cgutils.alloca_once_value(self.builder, ary)
        return self.builder.call(fn, [self.builder.bitcast(aryptr,
                                                           self.voidptr),
                                      ndim, writable, dtypeptr])
예제 #53
0
파일: listobj.py 프로젝트: cpcloud/numba
    def allocate_ex(cls, context, builder, list_type, nitems):
        """
        Allocate a ListInstance with its storage.
        Return a (ok, instance) tuple where *ok* is a LLVM boolean and
        *instance* is a ListInstance object (the object's contents are
        only valid when *ok* is true).
        """
        intp_t = context.get_value_type(types.intp)

        if isinstance(nitems, int):
            nitems = ir.Constant(intp_t, nitems)

        payload_type = context.get_data_type(types.ListPayload(list_type))
        payload_size = context.get_abi_sizeof(payload_type)

        itemsize = get_itemsize(context, list_type)
        # Account for the fact that the payload struct contains one entry
        payload_size -= itemsize

        ok = cgutils.alloca_once_value(builder, cgutils.true_bit)
        self = cls(context, builder, list_type, None)

        # Total allocation size = <payload header size> + nitems * itemsize
        allocsize, ovf = cgutils.muladd_with_overflow(builder, nitems,
                                                      ir.Constant(intp_t, itemsize),
                                                      ir.Constant(intp_t, payload_size))
        with builder.if_then(ovf, likely=False):
            builder.store(cgutils.false_bit, ok)

        with builder.if_then(builder.load(ok), likely=True):
            meminfo = context.nrt.meminfo_new_varsize_dtor(
                builder, size=allocsize, dtor=self.get_dtor())
            with builder.if_else(cgutils.is_null(builder, meminfo),
                                 likely=False) as (if_error, if_ok):
                with if_error:
                    builder.store(cgutils.false_bit, ok)
                with if_ok:
                    self._list.meminfo = meminfo
                    self._list.parent = context.get_constant_null(types.pyobject)
                    self._payload.allocated = nitems
                    self._payload.size = ir.Constant(intp_t, 0)  # for safety
                    self._payload.dirty = cgutils.false_bit
                    # Zero the allocated region
                    self.zfill(self.size.type(0), nitems)

        return builder.load(ok), self
예제 #54
0
    def upsize(self, nitems):
        """
        When adding to the set, ensure it is properly sized for the given
        number of used entries.
        """
        context = self._context
        builder = self._builder
        intp_t = nitems.type

        one = ir.Constant(intp_t, 1)
        two = ir.Constant(intp_t, 2)

        payload = self.payload

        # Ensure number of entries >= 2 * used
        min_entries = builder.shl(nitems, one)
        size = builder.add(payload.mask, one)
        need_resize = builder.icmp_unsigned('>=', min_entries, size)

        with builder.if_then(need_resize, likely=False):
            # Find out next suitable size
            new_size_p = cgutils.alloca_once_value(builder, size)

            bb_body = builder.append_basic_block("calcsize.body")
            bb_end = builder.append_basic_block("calcsize.end")

            builder.branch(bb_body)

            with builder.goto_block(bb_body):
                # Multiply by 4 (ensuring size remains a power of two)
                new_size = builder.load(new_size_p)
                new_size = builder.shl(new_size, two)
                builder.store(new_size, new_size_p)
                is_too_small = builder.icmp_unsigned('>=', min_entries, new_size)
                builder.cbranch(is_too_small, bb_body, bb_end)

            builder.position_at_end(bb_end)

            new_size = builder.load(new_size_p)
            if DEBUG_ALLOCS:
                context.printf(builder,
                               "upsize to %zd items: current size = %zd, "
                               "min entries = %zd, new size = %zd\n",
                               nitems, size, min_entries, new_size)
            self._resize(payload, new_size, "cannot grow set")
예제 #55
0
def build_set(context, builder, set_type, items):
    """
    Build a set of the given type, containing the given items.
    """
    nitems = len(items)
    inst = SetInstance.allocate(context, builder, set_type, nitems)

    # Populate set.  Inlining the insertion code for each item would be very
    # costly, instead we create a LLVM array and iterate over it.
    array = cgutils.pack_array(builder, items)
    array_ptr = cgutils.alloca_once_value(builder, array)

    count = context.get_constant(types.intp, nitems)
    with cgutils.for_range(builder, count) as loop:
        item = builder.load(cgutils.gep(builder, array_ptr, 0, loop.index))
        inst.add(item)

    return impl_ret_new_ref(context, builder, set_type, inst.value)
예제 #56
0
파일: listobj.py 프로젝트: dhavide/numba
    def clamp_index(self, idx):
        """
        Clamp the index in [0, size].
        """
        builder = self._builder
        idxptr = cgutils.alloca_once_value(builder, idx)

        zero = ir.Constant(idx.type, 0)
        size = self.size

        underflow = self._builder.icmp_signed('<', idx, zero)
        with builder.if_then(underflow, likely=False):
            builder.store(zero, idxptr)
        overflow = self._builder.icmp_signed('>=', idx, size)
        with builder.if_then(overflow, likely=False):
            builder.store(size, idxptr)
            
        return builder.load(idxptr)
예제 #57
0
            def init_specific(self, context, builder, arrty, arr):
                zero = context.get_constant(types.intp, 0)
                one = context.get_constant(types.intp, 1)
                data = arr.data
                ndim = arrty.ndim
                shapes = cgutils.unpack_tuple(builder, arr.shape, ndim)

                indices = cgutils.alloca_once(builder, zero.type,
                                              size=context.get_constant(types.intp,
                                                                        arrty.ndim))
                pointers = cgutils.alloca_once(builder, data.type,
                                               size=context.get_constant(types.intp,
                                                                         arrty.ndim))
                strides = cgutils.unpack_tuple(builder, arr.strides, ndim)
                empty = cgutils.alloca_once_value(builder, cgutils.false_byte)

                # Initialize each dimension with the next index and pointer
                # values.  For the last (inner) dimension, this is 0 and the
                # start pointer, for the other dimensions, this is 1 and the
                # pointer to the next subarray after start.
                for dim in range(ndim):
                    idxptr = cgutils.gep(builder, indices, dim)
                    ptrptr = cgutils.gep(builder, pointers, dim)
                    if dim == ndim - 1:
                        builder.store(zero, idxptr)
                        builder.store(data, ptrptr)
                    else:
                        p = cgutils.pointer_add(builder, data, strides[dim])
                        builder.store(p, ptrptr)
                        builder.store(one, idxptr)
                    # 0-sized dimensions really indicate an empty array,
                    # but we have to catch that condition early to avoid
                    # a bug inside the iteration logic (see issue #846).
                    dim_size = shapes[dim]
                    dim_is_empty = builder.icmp(lc.ICMP_EQ, dim_size, zero)
                    with cgutils.if_unlikely(builder, dim_is_empty):
                        builder.store(cgutils.true_byte, empty)

                self.indices = indices
                self.pointers = pointers
                self.empty = empty
예제 #58
0
def list_eq(context, builder, sig, args):
    aty, bty = sig.args
    a = ListInstance(context, builder, aty, args[0])
    b = ListInstance(context, builder, bty, args[1])

    a_size = a.size
    same_size = builder.icmp_signed("==", a_size, b.size)

    res = cgutils.alloca_once_value(builder, same_size)

    with builder.if_then(same_size):
        with cgutils.for_range(builder, a_size) as loop:
            v = a.getitem(loop.index)
            w = b.getitem(loop.index)
            itemres = context.generic_compare(builder, "==", (aty.dtype, bty.dtype), (v, w))
            with builder.if_then(builder.not_(itemres)):
                # Exit early
                builder.store(cgutils.false_bit, res)
                loop.do_break()

    return builder.load(res)
예제 #59
0
        def init_specific(self, context, builder, shapes):
            zero = context.get_constant(types.intp, 0)
            indices = cgutils.alloca_once(builder, zero.type,
                                          size=context.get_constant(types.intp,
                                                                    ndim))
            exhausted = cgutils.alloca_once_value(builder, cgutils.false_byte)

            for dim in range(ndim):
                idxptr = cgutils.gep(builder, indices, dim)
                builder.store(zero, idxptr)
                # 0-sized dimensions really indicate an empty array,
                # but we have to catch that condition early to avoid
                # a bug inside the iteration logic.
                dim_size = shapes[dim]
                dim_is_empty = builder.icmp(lc.ICMP_EQ, dim_size, zero)
                with cgutils.if_unlikely(builder, dim_is_empty):
                    builder.store(cgutils.true_byte, exhausted)

            self.indices = indices
            self.exhausted = exhausted
            self.shape = cgutils.pack_array(builder, shapes)
예제 #60
0
파일: unicode.py 프로젝트: numba/numba
def getiter_unicode(context, builder, sig, args):
    [ty] = sig.args
    [data] = args

    iterobj = context.make_helper(builder, sig.return_type)

    # set the index to zero
    zero = context.get_constant(types.uintp, 0)
    indexptr = cgutils.alloca_once_value(builder, zero)

    iterobj.index = indexptr

    # wire in the unicode type data
    iterobj.data = data

    # incref as needed
    if context.enable_nrt:
        context.nrt.incref(builder, ty, data)

    res = iterobj._getvalue()
    return impl_ret_new_ref(context, builder, sig.return_type, res)