def choose(
        self,
        choices: Any,
        out: ndarray | None = None,
        mode: BoundsMode = "raise",
    ) -> ndarray:
        """a.choose(choices, out=None, mode='raise')

        Use an index array to construct a new array from a set of choices.

        Refer to :func:`cupynumeric.choose` for full documentation.

        See Also
        --------
        cupynumeric.choose : equivalent function

        Availability
        --------
        Multiple GPUs, Multiple CPUs

        """
        a = self

        if isinstance(choices, list):
            choices = tuple(choices)
        is_tuple = isinstance(choices, tuple)
        if is_tuple:
            if (n := len(choices)) == 0:
                raise ValueError("invalid entry in choice array")
            dtypes = [ch.dtype for ch in choices]
            ch_dtype = np.result_type(*dtypes)
            choices = tuple(
                convert_to_cupynumeric_ndarray(choices[i]).astype(ch_dtype)
                for i in range(n)
            )

        else:
            choices = convert_to_cupynumeric_ndarray(choices)
            n = choices.shape[0]
            ch_dtype = choices.dtype
            choices = tuple(choices[i, ...] for i in range(n))

        if not np.issubdtype(self.dtype, np.integer):
            raise TypeError("a array should be integer type")

        if self.dtype != np.int64:
            a = a.astype(np.int64)
        if mode == "raise":
            if (a < 0).any() or (a >= n).any():
                raise ValueError("invalid entry in choice array")
        elif mode == "wrap":
            a = a % n
            if not isinstance(a, ndarray):
                a = convert_to_cupynumeric_ndarray(a)  # type: ignore [unreachable] # noqa: E501
        elif mode == "clip":
            a = a.clip(0, n - 1)
        else:
            raise ValueError(
                f"mode={mode} not understood. Must "
                "be 'raise', 'wrap', or 'clip'"
            )

        # we need to broadcast all arrays in choices with
        # input and output arrays
        if out is not None:
            out_shape = np.broadcast_shapes(
                a.shape, choices[0].shape, out.shape
            )
        else:
            out_shape = np.broadcast_shapes(a.shape, choices[0].shape)

        for c in choices:
            out_shape = np.broadcast_shapes(out_shape, c.shape)

        # if output is provided, it shape should be the same as out_shape
        if out is not None and out.shape != out_shape:
            raise ValueError(
                f"non-broadcastable output operand with shape "
                f" {str(out.shape)}"
                f" doesn't match the broadcast shape {out_shape}"
            )

        if out is not None and out.dtype == ch_dtype:
            out_arr = out

        else:
            # no output, create one
            out_arr = ndarray(
                shape=out_shape,
                dtype=ch_dtype,
                inputs=(a, choices),
            )

        ch = tuple(c._thunk for c in choices)
        out_arr._thunk.choose(a._thunk, *ch)

        if out is not None and out.dtype != ch_dtype:
            out._thunk.convert(out_arr._thunk)
            return out

        return out_arr
a.choose(choices, out=None, mode='raise')

        Use an index array to construct a new array from a set of choices.

        Refer to :func:`cupynumeric.choose` for full documentation.

        See Also
        --------
        cupynumeric.choose : equivalent function

        Availability
        --------
        Multiple GPUs, Multiple CPUs

        
cupynumeric/_array/array.py