Example #1
0
def register_binary_ufunc(ufunc, operator, asfloat=False, divbyzero=False):
    def binary_ufunc(context, builder, sig, args):
        imp = numpy_binary_ufunc(operator,
                                 asfloat=asfloat,
                                 divbyzero=divbyzero)
        return imp(context, builder, sig, args)

    def binary_ufunc_scalar_inputs(context, builder, sig, args):
        imp = numpy_binary_ufunc(operator,
                                 scalar_inputs=True,
                                 asfloat=asfloat,
                                 divbyzero=divbyzero)
        return imp(context, builder, sig, args)

    register(
        implement(ufunc, types.Kind(types.Array), types.Kind(types.Array),
                  types.Kind(types.Array))(binary_ufunc))
    for ty in types.number_domain:
        register(
            implement(ufunc, ty, types.Kind(types.Array),
                      types.Kind(types.Array))(binary_ufunc_scalar_inputs))
        register(
            implement(ufunc, types.Kind(types.Array), ty,
                      types.Kind(types.Array))(binary_ufunc_scalar_inputs))
    for ty1, ty2 in itertools.product(types.number_domain,
                                      types.number_domain):
        register(
            implement(ufunc, ty1, ty2,
                      types.Kind(types.Array))(binary_ufunc_scalar_inputs))
Example #2
0
def _implement_integer_operators():
    ty = types.Kind(types.Integer)
    register(implement(operator.add, ty, ty)(builtins.int_add_impl))
    register(implement(operator.iadd, ty, ty)(builtins.int_add_impl))
    register(implement(operator.sub, ty, ty)(builtins.int_sub_impl))
    register(implement(operator.isub, ty, ty)(builtins.int_sub_impl))
    register(implement(operator.mul, ty, ty)(builtins.int_mul_impl))
    register(implement(operator.imul, ty, ty)(builtins.int_mul_impl))
    register(implement(operator.eq, ty, ty)(builtins.int_eq_impl))
    register(implement(operator.ne, ty, ty)(builtins.int_ne_impl))
    register(implement(operator.lshift, ty, ty)(builtins.int_shl_impl))
    register(implement(operator.ilshift, ty, ty)(builtins.int_shl_impl))
    register(implement(operator.and_, ty, ty)(builtins.int_and_impl))
    register(implement(operator.iand, ty, ty)(builtins.int_and_impl))
    register(implement(operator.or_, ty, ty)(builtins.int_or_impl))
    register(implement(operator.ior, ty, ty)(builtins.int_or_impl))
    register(implement(operator.xor, ty, ty)(builtins.int_xor_impl))
    register(implement(operator.ixor, ty, ty)(builtins.int_xor_impl))
    register(implement(operator.neg, ty)(builtins.int_negate_impl))
    register(implement(operator.pos, ty)(builtins.int_positive_impl))
    register(implement(operator.invert, ty)(builtins.int_invert_impl))
    register(implement(operator.not_, ty)(builtins.number_not_impl))

    for ty in types.unsigned_domain:
        if not utils.IS_PY3:
            register(implement(operator.div, ty, ty)(builtins.int_udiv_impl))
            register(implement(operator.idiv, ty, ty)(builtins.int_udiv_impl))
        register(implement(operator.floordiv, ty, ty)(builtins.int_ufloordiv_impl))
        register(implement(operator.ifloordiv, ty, ty)(builtins.int_ufloordiv_impl))
        register(implement(operator.truediv, ty, ty)(builtins.int_utruediv_impl))
        register(implement(operator.itruediv, ty, ty)(builtins.int_utruediv_impl))
        register(implement(operator.mod, ty, ty)(builtins.int_urem_impl))
        register(implement(operator.imod, ty, ty)(builtins.int_urem_impl))
        register(implement(operator.lt, ty, ty)(builtins.int_ult_impl))
        register(implement(operator.le, ty, ty)(builtins.int_ule_impl))
        register(implement(operator.gt, ty, ty)(builtins.int_ugt_impl))
        register(implement(operator.ge, ty, ty)(builtins.int_uge_impl))
        register(implement(operator.pow, types.float64, ty)(builtins.int_power_impl))
        register(implement(operator.ipow, types.float64, ty)(builtins.int_power_impl))
        register(implement(operator.rshift, ty, ty)(builtins.int_lshr_impl))
        register(implement(operator.irshift, ty, ty)(builtins.int_lshr_impl))

    for ty in types.signed_domain:
        if not utils.IS_PY3:
            register(implement(operator.div, ty, ty)(builtins.int_sdiv_impl))
            register(implement(operator.idiv, ty, ty)(builtins.int_sdiv_impl))
        register(implement(operator.floordiv, ty, ty)(builtins.int_sfloordiv_impl))
        register(implement(operator.ifloordiv, ty, ty)(builtins.int_sfloordiv_impl))
        register(implement(operator.truediv, ty, ty)(builtins.int_struediv_impl))
        register(implement(operator.itruediv, ty, ty)(builtins.int_struediv_impl))
        register(implement(operator.mod, ty, ty)(builtins.int_srem_impl))
        register(implement(operator.imod, ty, ty)(builtins.int_srem_impl))
        register(implement(operator.lt, ty, ty)(builtins.int_slt_impl))
        register(implement(operator.le, ty, ty)(builtins.int_sle_impl))
        register(implement(operator.gt, ty, ty)(builtins.int_sgt_impl))
        register(implement(operator.ge, ty, ty)(builtins.int_sge_impl))
        register(implement(operator.pow, types.float64, ty)(builtins.int_power_impl))
        register(implement(operator.ipow, types.float64, ty)(builtins.int_power_impl))
        register(implement(operator.rshift, ty, ty)(builtins.int_ashr_impl))
        register(implement(operator.irshift, ty, ty)(builtins.int_ashr_impl))
Example #3
0
def _implement_real_operators():
    ty = types.Kind(types.Float)
    register(implement(operator.add, ty, ty)(builtins.real_add_impl))
    register(implement(operator.iadd, ty, ty)(builtins.real_add_impl))
    register(implement(operator.sub, ty, ty)(builtins.real_sub_impl))
    register(implement(operator.isub, ty, ty)(builtins.real_sub_impl))
    register(implement(operator.mul, ty, ty)(builtins.real_mul_impl))
    register(implement(operator.imul, ty, ty)(builtins.real_mul_impl))
    if not utils.IS_PY3:
        register(implement(operator.div, ty, ty)(builtins.real_div_impl))
        register(implement(operator.idiv, ty, ty)(builtins.real_div_impl))
    register(implement(operator.floordiv, ty, ty)(builtins.real_floordiv_impl))
    register(
        implement(operator.ifloordiv, ty, ty)(builtins.real_floordiv_impl))
    register(implement(operator.truediv, ty, ty)(builtins.real_div_impl))
    register(implement(operator.itruediv, ty, ty)(builtins.real_div_impl))
    register(implement(operator.mod, ty, ty)(builtins.real_mod_impl))
    register(implement(operator.imod, ty, ty)(builtins.real_mod_impl))
    register(implement(operator.pow, ty, ty)(builtins.real_power_impl))
    register(implement(operator.ipow, ty, ty)(builtins.real_power_impl))
    register(implement(operator.eq, ty, ty)(builtins.real_eq_impl))
    register(implement(operator.ne, ty, ty)(builtins.real_ne_impl))
    register(implement(operator.lt, ty, ty)(builtins.real_lt_impl))
    register(implement(operator.le, ty, ty)(builtins.real_le_impl))
    register(implement(operator.gt, ty, ty)(builtins.real_gt_impl))
    register(implement(operator.ge, ty, ty)(builtins.real_ge_impl))
    register(implement(operator.neg, ty)(builtins.real_negate_impl))
    register(implement(operator.pos, ty)(builtins.real_positive_impl))
    register(implement(operator.not_, ty)(builtins.number_not_impl))
Example #4
0
def register_unary_ufunc(ufunc, operator, asfloat=False):

    def unary_ufunc(context, builder, sig, args):
        imp = numpy_unary_ufunc(operator, asfloat=asfloat)
        return imp(context, builder, sig, args)

    def unary_ufunc_scalar_input(context, builder, sig, args):
        imp = numpy_unary_ufunc(operator, scalar_input=True, asfloat=asfloat)
        return imp(context, builder, sig, args)

    def scalar_unary_ufunc(context, builder, sig, args):
        imp = numpy_scalar_unary_ufunc(operator, asfloat)
        return imp(context, builder, sig, args)

    register(implement(ufunc, types.Kind(types.Array),
        types.Kind(types.Array))(unary_ufunc))
    for ty in types.number_domain:
        register(implement(ufunc, ty,
            types.Kind(types.Array))(unary_ufunc_scalar_input))
    for ty in types.number_domain:
        register(implement(ufunc, ty)(scalar_unary_ufunc))
Example #5
0
def _implement_complex_operators():
    ty = types.Kind(types.Complex)
    register(implement(operator.add, ty, ty)(builtins.complex_add_impl))
    register(implement(operator.iadd, ty, ty)(builtins.complex_add_impl))
    register(implement(operator.sub, ty, ty)(builtins.complex_sub_impl))
    register(implement(operator.isub, ty, ty)(builtins.complex_sub_impl))
    register(implement(operator.mul, ty, ty)(builtins.complex_mul_impl))
    register(implement(operator.imul, ty, ty)(builtins.complex_mul_impl))
    if not utils.IS_PY3:
        register(implement(operator.div, ty, ty)(builtins.complex_div_impl))
        register(implement(operator.idiv, ty, ty)(builtins.complex_div_impl))
    register(implement(operator.truediv, ty, ty)(builtins.complex_div_impl))
    register(implement(operator.itruediv, ty, ty)(builtins.complex_div_impl))
    register(implement(operator.eq, ty, ty)(builtins.complex_eq_impl))
    register(implement(operator.ne, ty, ty)(builtins.complex_ne_impl))
    register(implement(operator.neg, ty)(builtins.complex_negate_impl))
    register(implement(operator.pos, ty)(builtins.complex_positive_impl))
    register(implement(operator.not_, ty)(builtins.number_not_impl))
Example #6
0
"""
Implementation of various iterable and iterator types.
"""

from numba import types, cgutils
from numba.targets.imputils import (builtin, implement, iternext_impl,
                                    call_iternext, call_getiter,
                                    struct_factory)


@builtin
@implement('getiter', types.Kind(types.IteratorType))
def iterator_getiter(context, builder, sig, args):
    [it] = args
    return it


#-------------------------------------------------------------------------------
# builtin `enumerate` implementation


@struct_factory(types.EnumerateType)
def make_enumerate_cls(enum_type):
    """
    Return the Structure representation of the given *enum_type* (an
    instance of types.EnumerateType).
    """
    return cgutils.create_struct_proxy(enum_type)


@builtin
Example #7
0
unary_math_extern(math.sinh, "sinhf", "sinh")
unary_math_extern(math.cosh, "coshf", "cosh")
unary_math_extern(math.tanh, "tanhf", "tanh")
# math.floor and math.ceil return float on 2.x, int on 3.x
if utils.PYVERSION > (3, 0):
    unary_math_extern(math.ceil, "ceilf", "ceil", True)
    unary_math_extern(math.floor, "floorf", "floor", True)
else:
    unary_math_extern(math.ceil, "ceilf", "ceil")
    unary_math_extern(math.floor, "floorf", "floor")
unary_math_extern(math.sqrt, "sqrtf", "sqrt")
unary_math_extern(math.trunc, "truncf", "trunc", True)


@register
@implement(math.isnan, types.Kind(types.Float))
def isnan_float_impl(context, builder, sig, args):
    [val] = args
    return is_nan(builder, val)


@register
@implement(math.isnan, types.Kind(types.Integer))
def isnan_int_impl(context, builder, sig, args):
    return cgutils.false_bit


@register
@implement(math.isinf, types.Kind(types.Float))
def isinf_float_impl(context, builder, sig, args):
    [val] = args
Example #8
0
@register
@implement("random.random")
def random_impl(context, builder, sig, args):
    state_ptr = get_state_ptr(context, builder, "py")
    return get_next_double(context, builder, state_ptr)

@register
@implement("np.random.rand")
@implement("np.random.random")
def random_impl(context, builder, sig, args):
    state_ptr = get_state_ptr(context, builder, "np")
    return get_next_double(context, builder, state_ptr)


@register
@implement("random.gauss", types.Kind(types.Float), types.Kind(types.Float))
@implement("random.normalvariate", types.Kind(types.Float), types.Kind(types.Float))
def gauss_impl(context, builder, sig, args):
    return _gauss_impl(context, builder, sig, args, "py")


@register
@implement("np.random.randn")
@implement("np.random.standard_normal")
@implement("np.random.normal")
@implement("np.random.normal", types.Kind(types.Float))
@implement("np.random.normal", types.Kind(types.Float), types.Kind(types.Float))
def np_gauss_impl(context, builder, sig, args):
    sig, args = _fill_defaults(context, builder, sig, args, (0.0, 1.0))
    return _gauss_impl(context, builder, sig, args, "np")
Example #9
0
def real_print_impl(context, builder, sig, args):
    [x] = args
    py = context.get_python_api(builder)
    szval = context.cast(builder, x, sig.args[0], types.float64)
    intobj = py.float_from_double(szval)
    py.print_object(intobj)
    py.decref(intobj)
    return context.get_dummy_value()


for ty in types.real_domain:
    register(implement(types.print_item_type, ty)(real_print_impl))


@register
@implement(types.print_item_type, types.Kind(types.CharSeq))
def print_charseq(context, builder, sig, args):
    [x] = args
    py = context.get_python_api(builder)
    xp = cgutils.alloca_once(builder, x.type)
    builder.store(x, xp)
    byteptr = builder.bitcast(xp, Type.pointer(Type.int(8)))
    size = context.get_constant(types.intp, x.type.elements[0].count)
    cstr = py.bytes_from_string_and_size(byteptr, size)
    py.print_object(cstr)
    py.decref(cstr)
    return context.get_dummy_value()


@register
@implement(types.print_type, types.VarArg)
Example #10
0
from numba import npdatetime, types, typing, cgutils, utils
from numba.targets.imputils import (builtin, builtin_attr, implement,
                                    impl_attribute, impl_attribute_generic,
                                    iterator_impl, iternext_impl,
                                    struct_factory, type_factory)
from numba.typing import signature

if not npdatetime.NPDATETIME_SUPPORTED:
    raise NotImplementedError(
        "numpy.datetime64 unsupported in this configuration")

# datetime64 and timedelta64 use the same internal representation
DATETIME64 = TIMEDELTA64 = Type.int(64)
NAT = Constant.int(TIMEDELTA64, npdatetime.NAT)

TIMEDELTA_BINOP_SIG = (types.Kind(types.NPTimedelta), ) * 2


@type_factory(types.NPDatetime)
def llvm_datetime_type(context, tp):
    return DATETIME64


@type_factory(types.NPTimedelta)
def llvm_timedelta_type(context, tp):
    return TIMEDELTA64


def scale_by_constant(builder, val, factor):
    """
    Multiply *val* by the constant *factor*.
Example #11
0
unary_math_extern(math.sinh, "sinhf", "sinh")
unary_math_extern(math.cosh, "coshf", "cosh")
unary_math_extern(math.tanh, "tanhf", "tanh")
# math.floor and math.ceil return float on 2.x, int on 3.x
if utils.PYVERSION > (3, 0):
    unary_math_extern(math.ceil, "ceilf", "ceil", True)
    unary_math_extern(math.floor, "floorf", "floor", True)
else:
    unary_math_extern(math.ceil, "ceilf", "ceil")
    unary_math_extern(math.floor, "floorf", "floor")
unary_math_extern(math.sqrt, "sqrtf", "sqrt")
unary_math_extern(math.trunc, "truncf", "trunc", True)


@register
@implement(math.isnan, types.Kind(types.Float))
def isnan_float_impl(context, builder, sig, args):
    [val] = args
    return is_nan(builder, val)


@register
@implement(math.isnan, types.Kind(types.Integer))
def isnan_int_impl(context, builder, sig, args):
    return cgutils.false_bit


@register
@implement(math.isinf, types.Kind(types.Float))
def isinf_float_impl(context, builder, sig, args):
    [val] = args
Example #12
0
def build_list(context, builder, list_type, items):
    """
    Build a list of the given type, containing the given items.
    """
    nitems = len(items)
    inst = ListInstance.allocate(context, builder, list_type, nitems)
    # Populate list
    inst.size = context.get_constant(types.intp, nitems)
    for i, val in enumerate(items):
        inst.setitem(context.get_constant(types.intp, i), val)

    return impl_ret_new_ref(context, builder, list_type, inst.value)


@builtin
@implement(list, types.Kind(types.IterableType))
def list_constructor(context, builder, sig, args):
    def list_impl(iterable):
        res = []
        res.extend(iterable)
        return res

    return context.compile_internal(builder, list_impl, sig, args)


#-------------------------------------------------------------------------------
# Various operations


@builtin
@implement(types.len_type, types.Kind(types.List))
Example #13
0
                dval = context.cast(builder, ival, tyinp.dtype, types.float64)
                dres = fnwork(builder, [dval])
                res = context.cast(builder, dres, types.float64, tyout.dtype)
            elif tyinp.dtype != tyout.dtype:
                tempres = fnwork(builder, [ival])
                res = context.cast(builder, tempres, tyinp.dtype, tyout.dtype)
            else:
                res = fnwork(builder, [ival])
            builder.store(res, po)

        return out
    return impl


@register
@implement(numpy.absolute, types.Kind(types.Array), types.Kind(types.Array))
def numpy_absolute(context, builder, sig, args):
    imp = numpy_unary_ufunc(types.abs_type)
    return imp(context, builder, sig, args)


@register
@implement(numpy.absolute, types.float64)
def numpy_absolute_scalar(context, builder, sig, args):
    imp = context.get_function(math.fabs, sig)
    return imp(builder, args)


@register
@implement(numpy.exp, types.Kind(types.Array), types.Kind(types.Array))
def numpy_exp(context, builder, sig, args):
Example #14
0
    return builder.or_(mathimpl.is_nan(builder, z.real),
                       mathimpl.is_nan(builder, z.imag))


def is_inf(builder, z):
    return builder.or_(mathimpl.is_inf(builder, z.real),
                       mathimpl.is_inf(builder, z.imag))


def is_finite(builder, z):
    return builder.and_(mathimpl.is_finite(builder, z.real),
                        mathimpl.is_finite(builder, z.imag))


@register
@implement(cmath.isnan, types.Kind(types.Complex))
def isnan_float_impl(context, builder, sig, args):
    [typ] = sig.args
    [value] = args
    cplx_cls = context.make_complex(typ)
    z = cplx_cls(context, builder, value=value)
    res = is_nan(builder, z)
    return impl_ret_untracked(context, builder, sig.return_type, res)


@register
@implement(cmath.isinf, types.Kind(types.Complex))
def isinf_float_impl(context, builder, sig, args):
    [typ] = sig.args
    [value] = args
    cplx_cls = context.make_complex(typ)
Example #15
0
from __future__ import print_function, absolute_import, division
from llvmlite.llvmpy.core import Type, Constant
from numba import types, typing, cgutils
from numba.targets.imputils import implement, Registry
from . import nvvmutils

registry = Registry()
register = registry.register

voidptr = Type.pointer(Type.int(8))

@register
@implement(types.print_item_type, types.Kind(types.Integer))
def int_print_impl(context, builder, sig, args):
    [x] = args
    [srctype] = sig.args
    mod = builder.module
    vprint = nvvmutils.declare_vprint(mod)
    if srctype in types.unsigned_domain:
        rawfmt = "%llu"
        dsttype = types.uint64
    else:
        rawfmt = "%lld"
        dsttype = types.int64
    fmt = context.insert_string_const_addrspace(builder, rawfmt)
    lld = context.cast(builder, x, srctype, dsttype)
    valptr = cgutils.alloca_once(builder, context.get_value_type(dsttype))
    builder.store(lld, valptr)
    builder.call(vprint, [fmt, builder.bitcast(valptr, voidptr)])
    return context.get_dummy_value()
Example #16
0
"""
Implementation of some CFFI functions
"""

from __future__ import print_function, absolute_import, division

from numba.targets.imputils import implement, Registry
from numba import types
from . import arrayobj

registry = Registry()


@registry.register
@implement('ffi.from_buffer', types.Kind(types.Array))
def from_buffer(context, builder, sig, args):
    assert len(sig.args) == 1
    assert len(args) == 1
    [fromty] = sig.args
    [val] = args
    # Type inference should have prevented passing a buffer from an
    # array to a pointer of the wrong type
    assert fromty.dtype == sig.return_type.dtype
    ary = arrayobj.make_array(fromty)(context, builder, val)
    return ary.data
Example #17
0
@struct_factory(types.ArrayIterator)
def make_arrayiter_cls(iterator_type):
    """
    Return the Structure representation of the given *iterator_type* (an
    instance of types.ArrayIteratorType).
    """
    class ArrayIteratorStruct(cgutils.Structure):
        _fields = [('index', types.CPointer(types.intp)),
                   ('array', iterator_type.array_type)]

    return ArrayIteratorStruct


@builtin
@implement('getiter', types.Kind(types.Array))
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(builder, zero.type)
    builder.store(zero, indexptr)

    iterobj.index = indexptr
    iterobj.array = array

    return iterobj._getvalue()
Example #18
0
def build_list(context, builder, list_type, items):
    """
    Build a list of the given type, containing the given items.
    """
    nitems = len(items)
    inst = ListInstance.allocate(context, builder, list_type, nitems)
    # Populate list
    inst.size = context.get_constant(types.intp, nitems)
    for i, val in enumerate(items):
        inst.setitem(context.get_constant(types.intp, i), val)

    return impl_ret_new_ref(context, builder, list_type, inst.value)


@builtin
@implement(list, types.Kind(types.IterableType))
def list_constructor(context, builder, sig, args):

    def list_impl(iterable):
        res = []
        res.extend(iterable)
        return res

    return context.compile_internal(builder, list_impl, sig, args)


#-------------------------------------------------------------------------------
# Various operations

@builtin
@implement(types.len_type, types.Kind(types.List))
Example #19
0
@struct_factory(types.ArrayIterator)
def make_arrayiter_cls(iterator_type):
    """
    Return the Structure representation of the given *iterator_type* (an
    instance of types.ArrayIteratorType).
    """
    class ArrayIteratorStruct(cgutils.Structure):
        # We use an unsigned index to avoid the cost of negative index tests.
        _fields = [('index', types.CPointer(types.uintp)),
                   ('array', iterator_type.array_type)]

    return ArrayIteratorStruct


@builtin
@implement('getiter', types.Kind(types.Array))
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()

Example #20
0
    def ptx_sreg_impl(context, builder, sig, args):
        assert not args
        return nvvmutils.call_sreg(builder, sreg)

    return ptx_sreg_impl


# Dynamic create all special register
for sreg in nvvmutils.SREG_MAPPING.keys():
    register(implement(sreg)(ptx_sreg_template(sreg)))

# -----------------------------------------------------------------------------


@register
@implement('ptx.cmem.arylike', types.Kind(types.Array))
def ptx_cmem_arylike(context, builder, sig, args):
    lmod = cgutils.get_module(builder)
    [arr] = args
    flat = arr.flatten(order='A')
    aryty = sig.return_type
    dtype = aryty.dtype

    if isinstance(dtype, types.Complex):
        elemtype = (types.float32
                    if dtype == types.complex64 else types.float64)
        constvals = []
        for i in range(flat.size):
            elem = flat[i]
            real = context.get_constant(elemtype, elem.real)
            imag = context.get_constant(elemtype, elem.imag)
Example #21
0
    builder.call(barrier, [flags])
    return _void_value


@register
@implement(stubs.mem_fence, types.uint32)
def mem_fence_impl(context, builder, sig, args):
    [flags] = args
    mem_fence = _declare_function(context, builder, 'mem_fence', sig,
                                  ['unsigned int'])
    builder.call(mem_fence, [flags])
    return _void_value


@register
@implement(stubs.atomic.add, types.Kind(types.Array), types.intp, types.Any)
@implement(stubs.atomic.add, types.Kind(types.Array),
           types.Kind(types.UniTuple), types.Any)
@implement(stubs.atomic.add, types.Kind(types.Array), types.Kind(types.Tuple),
           types.Any)
def hsail_atomic_add_tuple(context, builder, sig, args):
    aryty, indty, valty = sig.args
    ary, inds, val = args
    dtype = aryty.dtype

    if indty == types.intp:
        indices = [inds]  # just a single integer
        indty = [indty]
    else:
        indices = cgutils.unpack_tuple(builder, inds, count=len(indty))
        indices = [