Ejemplo n.º 1
0
def slice_indices(context, builder, sig, args):
    length = args[1]
    sli = context.make_helper(builder, sig.args[0], args[0])

    with builder.if_then(cgutils.is_neg_int(builder, length), likely=False):
        context.call_conv.return_user_exc(builder, ValueError,
                                          ("length should not be negative", ))
    with builder.if_then(cgutils.is_scalar_zero(builder, sli.step),
                         likely=False):
        context.call_conv.return_user_exc(builder, ValueError,
                                          ("slice step cannot be zero", ))

    fix_slice(builder, sli, length)

    return context.make_tuple(builder, sig.return_type,
                              (sli.start, sli.stop, sli.step))
Ejemplo n.º 2
0
    def impl(context, builder, sig, args):
        [tyinp1, tyinp2, tyout] = sig.args
        [inp1, inp2, out] = args

        if isinstance(tyinp1, types.Array):
            scalar_inp1 = False
            scalar_tyinp1 = tyinp1.dtype
            inp1_ndim = tyinp1.ndim
        elif tyinp1 in types.number_domain:
            scalar_inp1 = True
            scalar_tyinp1 = tyinp1
            inp1_ndim = 1
        else:
            raise TypeError('unknown type for first input operand')

        if isinstance(tyinp2, types.Array):
            scalar_inp2 = False
            scalar_tyinp2 = tyinp2.dtype
            inp2_ndim = tyinp2.ndim
        elif tyinp2 in types.number_domain:
            scalar_inp2 = True
            scalar_tyinp2 = tyinp2
            inp2_ndim = 1
        else:
            raise TypeError('unknown type for second input operand')

        out_ndim = tyout.ndim

        if asfloat:
            promote_type = types.float64
        elif scalar_tyinp1 in types.real_domain or \
                scalar_tyinp2 in types.real_domain:
            promote_type = types.float64
        elif scalar_tyinp1 in types.signed_domain or \
                scalar_tyinp2 in types.signed_domain:
            promote_type = types.int64
        else:
            promote_type = types.uint64

        result_type = promote_type

        # Temporary hack for __ftol2 llvm bug. Don't allow storing
        # float results in uint64 array on windows.
        if result_type in types.real_domain and \
                tyout.dtype is types.uint64 and \
                sys.platform.startswith('win32'):
            raise TypeError('Cannot store result in uint64 array')

        sig = typing.signature(result_type, promote_type, promote_type)

        if not scalar_inp1:
            i1ary = context.make_array(tyinp1)(context, builder, inp1)
        if not scalar_inp2:
            i2ary = context.make_array(tyinp2)(context, builder, inp2)
        oary = context.make_array(tyout)(context, builder, out)

        fnwork = context.get_function(funckey, sig)
        intpty = context.get_value_type(types.intp)

        if not scalar_inp1:
            inp1_shape = cgutils.unpack_tuple(builder, i1ary.shape, inp1_ndim)
            inp1_strides = cgutils.unpack_tuple(builder, i1ary.strides, inp1_ndim)
            inp1_data = i1ary.data
            inp1_layout = tyinp1.layout
        if not scalar_inp2:
            inp2_shape = cgutils.unpack_tuple(builder, i2ary.shape, inp2_ndim)
            inp2_strides = cgutils.unpack_tuple(builder, i2ary.strides, inp2_ndim)
            inp2_data = i2ary.data
            inp2_layout = tyinp2.layout
        out_shape = cgutils.unpack_tuple(builder, oary.shape, out_ndim)
        out_strides = cgutils.unpack_tuple(builder, oary.strides, out_ndim)
        out_data = oary.data
        out_layout = tyout.layout

        ZERO = Constant.int(Type.int(intpty.width), 0)
        ONE = Constant.int(Type.int(intpty.width), 1)

        inp1_indices = None
        if not scalar_inp1:
            inp1_indices = []
            for i in range(inp1_ndim):
                x = builder.alloca(Type.int(intpty.width))
                builder.store(ZERO, x)
                inp1_indices.append(x)

        inp2_indices = None
        if not scalar_inp2:
            inp2_indices = []
            for i in range(inp2_ndim):
                x = builder.alloca(Type.int(intpty.width))
                builder.store(ZERO, x)
                inp2_indices.append(x)

        loopshape = cgutils.unpack_tuple(builder, oary.shape, out_ndim)

        with cgutils.loop_nest(builder, loopshape, intp=intpty) as indices:

            # Increment input indices.
            # Since the output dimensions are already being incremented,
            # we'll use that to set the input indices. In order to
            # handle broadcasting, any input dimension of size 1 won't be
            # incremented.
            def build_increment_blocks(inp_indices, inp_shape, inp_ndim, inp_num):
                bb_inc_inp_index = [cgutils.append_basic_block(builder,
                    '.inc_inp{0}_index{1}'.format(inp_num, str(i))) for i in range(inp_ndim)]
                bb_end_inc_index = cgutils.append_basic_block(builder,
                                       '.end_inc{0}_index'.format(inp_num))

                builder.branch(bb_inc_inp_index[0])
                for i in range(inp_ndim):
                    with cgutils.goto_block(builder, bb_inc_inp_index[i]):
                        # If the shape of this dimension is 1, then leave the
                        # index at 0 so that this dimension is broadcasted over
                        # the corresponding input and output dimensions.
                        cond = builder.icmp(ICMP_UGT, inp_shape[i], ONE)
                        with cgutils.ifthen(builder, cond):
                            builder.store(indices[out_ndim-inp_ndim+i], inp_indices[i])
                        if i + 1 == inp_ndim:
                            builder.branch(bb_end_inc_index)
                        else:
                            builder.branch(bb_inc_inp_index[i+1])

                builder.position_at_end(bb_end_inc_index)

            if not scalar_inp1:
                build_increment_blocks(inp1_indices, inp1_shape, inp1_ndim, '1')
            if not scalar_inp2:
                build_increment_blocks(inp2_indices, inp2_shape, inp2_ndim, '2')

            if scalar_inp1:
                x = inp1
            else:
                inds = [builder.load(index) for index in inp1_indices]
                px = cgutils.get_item_pointer2(builder,
                                               data=inp1_data,
                                               shape=inp1_shape,
                                               strides=inp1_strides,
                                               layout=inp1_layout,
                                               inds=inds)
                x = builder.load(px)

            if scalar_inp2:
                y = inp2
            else:
                inds = [builder.load(index) for index in inp2_indices]
                py = cgutils.get_item_pointer2(builder,
                                               data=inp2_data,
                                               shape=inp2_shape,
                                               strides=inp2_strides,
                                               layout=inp2_layout,
                                               inds=inds)
                y = builder.load(py)

            po = cgutils.get_item_pointer2(builder,
                                           data=out_data,
                                           shape=out_shape,
                                           strides=out_strides,
                                           layout=out_layout,
                                           inds=indices)

            if divbyzero:
                # Handle division
                iszero = cgutils.is_scalar_zero(builder, y)
                with cgutils.ifelse(builder, iszero, expect=False) as (then,
                                                                       orelse):
                    with then:
                        # Divide by zero
                        if (scalar_tyinp1 in types.real_domain or
                                scalar_tyinp2 in types.real_domain) or \
                                not numpy_support.int_divbyzero_returns_zero:
                            # If y is float and is 0 also, return Nan; else
                            # return Inf
                            outltype = context.get_data_type(result_type)
                            shouldretnan = cgutils.is_scalar_zero(builder, x)
                            nan = Constant.real(outltype, float("nan"))
                            inf = Constant.real(outltype, float("inf"))
                            tempres = builder.select(shouldretnan, nan, inf)
                            res = context.cast(builder, tempres, result_type,
                                               tyout.dtype)
                        elif tyout.dtype in types.signed_domain and \
                                not numpy_support.int_divbyzero_returns_zero:
                            res = Constant.int(context.get_data_type(tyout.dtype),
                                               0x1 << (y.type.width-1))
                        else:
                            res = Constant.null(context.get_data_type(tyout.dtype))

                        assert res.type == po.type.pointee, \
                                        (str(res.type), str(po.type.pointee))
                        builder.store(res, po)
                    with orelse:
                        # Normal
                        d_x = context.cast(builder, x, scalar_tyinp1, promote_type)
                        d_y = context.cast(builder, y, scalar_tyinp2, promote_type)
                        tempres = fnwork(builder, [d_x, d_y])
                        res = context.cast(builder, tempres, result_type, tyout.dtype)

                        assert res.type == po.type.pointee, (res.type,
                                                             po.type.pointee)
                        builder.store(res, po)
            else:
                # Handle non-division operations
                d_x = context.cast(builder, x, scalar_tyinp1, promote_type)
                d_y = context.cast(builder, y, scalar_tyinp2, promote_type)
                tempres = fnwork(builder, [d_x, d_y])
                res = context.cast(builder, tempres, result_type, tyout.dtype)

                assert res.type == po.type.pointee, (res.type,
                                                     po.type.pointee)
                builder.store(res, po)

        return out
Ejemplo n.º 3
0
    def impl(context, builder, sig, args):
        [tyinp1, tyinp2, tyout] = sig.args
        [inp1, inp2, out] = args
        if scalar_inputs:
            ndim = 1
        else:
            ndim = tyinp1.ndim

        # Temporary hack for __ftol2 llvm bug. Don't allow storing
        # float results in uint64 array on windows.
        if scalar_inputs and tyinp1 in types.real_domain and \
                tyout.dtype is types.uint64 and \
                sys.platform.startswith('win32'):
            raise TypeError('Cannot store result in uint64 array')
        if not scalar_inputs and tyinp1.dtype in types.real_domain and \
                tyout.dtype is types.uint64 and \
                sys.platform.startswith('win32'):
            raise TypeError('Cannot store result in uint64 array')

        if not scalar_inputs:
            i1ary = context.make_array(tyinp1)(context, builder, inp1)
            i2ary = context.make_array(tyinp2)(context, builder, inp2)
        oary = context.make_array(tyout)(context, builder, out)

        if asfloat and not divbyzero:
            sig = typing.signature(types.float64, types.float64, types.float64)
        else:
            if scalar_inputs:
                sig = typing.signature(tyout.dtype, tyinp1, tyinp2)
            else:
                sig = typing.signature(tyout.dtype, tyinp1.dtype, tyinp2.dtype)

        fnwork = context.get_function(funckey, sig)
        intpty = context.get_value_type(types.intp)

        # TODO handle differing shape by mimicking broadcasting
        loopshape = cgutils.unpack_tuple(builder, oary.shape, ndim)

        if scalar_inputs:
            xyo_shape = [cgutils.unpack_tuple(builder, ary.shape, ndim)
                         for ary in (oary,)]
            xyo_strides = [cgutils.unpack_tuple(builder, ary.strides, ndim)
                           for ary in (oary,)]
            xyo_data = [ary.data for ary in (oary,)]
            xyo_layout = [ty.layout for ty in (tyout,)]
        else:
            xyo_shape = [cgutils.unpack_tuple(builder, ary.shape, ndim)
                         for ary in (i1ary, i2ary, oary)]
            xyo_strides = [cgutils.unpack_tuple(builder, ary.strides, ndim)
                           for ary in (i1ary, i2ary, oary)]
            xyo_data = [ary.data for ary in (i1ary, i2ary, oary)]
            xyo_layout = [ty.layout for ty in (tyinp1, tyinp2, tyout)]

        with cgutils.loop_nest(builder, loopshape, intp=intpty) as indices:
            if scalar_inputs:
                [po] = [cgutils.get_item_pointer2(builder,
                                               data=data, shape=shape,
                                               strides=strides,
                                               layout=layout,
                                               inds=indices)
                                for data, shape, strides, layout
                                in zip(xyo_data, xyo_shape, xyo_strides,
                                       xyo_layout)]
            else:
                [px, py, po] = [cgutils.get_item_pointer2(builder,
                                                          data=data, shape=shape,
                                                          strides=strides,
                                                          layout=layout,
                                                          inds=indices)
                                for data, shape, strides, layout
                                in zip(xyo_data, xyo_shape, xyo_strides,
                                       xyo_layout)]

            if scalar_inputs:
                x = inp1
                y = inp2
            else:
                x = builder.load(px)
                y = builder.load(py)
            if divbyzero:
                # Handle division
                iszero = cgutils.is_scalar_zero(builder, y)
                with cgutils.ifelse(builder, iszero, expect=False) as (then,
                                                                       orelse):
                    with then:
                        # Divide by zero
                        if ((scalar_inputs and tyinp2 in types.real_domain) or
                                (not scalar_inputs and
                                    tyinp2.dtype in types.real_domain) or
                                not numpy_support.int_divbyzero_returns_zero):
                            # If y is float and is 0 also, return Nan; else
                            # return Inf
                            outltype = context.get_data_type(tyout.dtype)
                            shouldretnan = cgutils.is_scalar_zero(builder, x)
                            nan = Constant.real(outltype, float("nan"))
                            inf = Constant.real(outltype, float("inf"))
                            res = builder.select(shouldretnan, nan, inf)
                        elif (scalar_inputs and tyout in types.signed_domain and
                                not numpy_support.int_divbyzero_returns_zero):
                            res = Constant.int(context.get_data_type(tyout),
                                               0x1 << (y.type.width-1))
                        elif (not scalar_inputs and
                                tyout.dtype in types.signed_domain and
                                not numpy_support.int_divbyzero_returns_zero):
                            res = Constant.int(context.get_data_type(tyout.dtype),
                                               0x1 << (y.type.width-1))
                        else:
                            res = Constant.null(context.get_data_type(tyout.dtype))

                        assert res.type == po.type.pointee, \
                                        (str(res.type), str(po.type.pointee))
                        builder.store(res, po)
                    with orelse:
                        # Normal
                        tempres = fnwork(builder, (x, y))
                        if scalar_inputs and tyinp1 in types.real_domain:
                            res = context.cast(builder, tempres,
                                               tyinp1, tyout.dtype)
                        elif (not scalar_inputs and
                                tyinp1.dtype in types.real_domain):
                            res = context.cast(builder, tempres,
                                               tyinp1.dtype, tyout.dtype)
                        else:
                            res = context.cast(builder, tempres,
                                               types.float64, tyout.dtype)
                        assert res.type == po.type.pointee, \
                                        (str(res.type), str(po.type.pointee))
                        builder.store(res, po)
            else:
                # Handle non-division operations
                if asfloat:
                    if scalar_inputs:
                        d_x = context.cast(builder, x, tyinp1, types.float64)
                        d_y = context.cast(builder, y, tyinp2, types.float64)
                    else:
                        d_x = context.cast(builder, x, tyinp1.dtype,
                                           types.float64)
                        d_y = context.cast(builder, y, tyinp2.dtype,
                                           types.float64)
                    tempres = fnwork(builder, [d_x, d_y])
                    res = context.cast(builder, tempres,
                                       types.float64, tyout.dtype)
                elif scalar_inputs:
                    if tyinp1 != tyout.dtype:
                        tempres = fnwork(builder, [x, y])
                        res = context.cast(builder, tempres, tyinp1,
                                           tyout.dtype)
                    else:
                        res = fnwork(builder, (x, y))
                elif tyinp1.dtype != tyout.dtype:
                    tempres = fnwork(builder, [x, y])
                    res = context.cast(builder, tempres, tyinp1.dtype,
                                       tyout.dtype)
                else:
                    res = fnwork(builder, (x, y))
                assert res.type == po.type.pointee, (res.type,
                                                     po.type.pointee)
                builder.store(res, po)

        return out
Ejemplo n.º 4
0
    def impl(context, builder, sig, args):
        [tyvx, tywy, tyout] = sig.args
        [vx, wy, out] = args
        assert tyvx.dtype == tywy.dtype
        ndim = tyvx.ndim

        xary = context.make_array(tyvx)(context, builder, vx)
        yary = context.make_array(tywy)(context, builder, wy)
        oary = context.make_array(tyout)(context, builder, out)

        intpty = context.get_value_type(types.intp)

        # TODO handle differing shape by mimicking broadcasting
        loopshape = cgutils.unpack_tuple(builder, xary.shape, ndim)

        xyo_shape = [cgutils.unpack_tuple(builder, ary.shape, ndim)
                     for ary in (xary, yary, oary)]
        xyo_strides = [cgutils.unpack_tuple(builder, ary.strides, ndim)
                       for ary in (xary, yary, oary)]
        xyo_data = [ary.data for ary in (xary, yary, oary)]
        xyo_layout = [ty.layout for ty in (tyvx, tywy, tyout)]

        with cgutils.loop_nest(builder, loopshape, intp=intpty) as indices:
            [px, py, po] = [cgutils.get_item_pointer2(builder,
                                                      data=data, shape=shape,
                                                      strides=strides,
                                                      layout=layout,
                                                      inds=indices)
                            for data, shape, strides, layout
                            in zip(xyo_data, xyo_shape, xyo_strides,
                                   xyo_layout)]

            x = builder.load(px)
            y = builder.load(py)
            if divbyzero:
                # Handle division
                iszero = cgutils.is_scalar_zero(builder, y)
                with cgutils.ifelse(builder, iszero, expect=False) as (then,
                                                                       orelse):
                    with then:
                        # Divide by zero
                        if tyout.dtype in types.real_domain:
                            # If x is float and is 0 also, return Nan; else
                            # return Inf
                            outltype = context.get_data_type(tyout.dtype)
                            shouldretnan = cgutils.is_scalar_zero(builder, x)
                            nan = Constant.real(outltype, float("nan"))
                            inf = Constant.real(outltype, float("inf"))
                            res = builder.select(shouldretnan, nan, inf)
                        elif (tyout.dtype in types.signed_domain and
                                not numpy_support.int_divbyzero_returns_zero):
                            res = Constant.int(y.type, 0x1 << (y.type.width-1))
                        else:
                            res = Constant.null(y.type)

                        assert res.type == po.type.pointee, \
                                        (str(res.type), str(po.type.pointee))
                        builder.store(res, po)
                    with orelse:
                        # Normal
                        res = core(builder, (x, y))
                        assert res.type == po.type.pointee, \
                                        (str(res.type), str(po.type.pointee))
                        builder.store(res, po)
            else:
                # Handle other operations
                res = core(builder, (x, y))
                assert res.type == po.type.pointee, (res.type,
                                                     po.type.pointee)
                builder.store(res, po)

        return out