def unpackbits(
    a: ndarray,
    axis: int | None = None,
    count: int | None = None,
    bitorder: BitOrder = "big",
) -> ndarray:
    """
    Unpacks elements of a uint8 array into a binary-valued output array.

    Each element of `a` represents a bit-field that should be unpacked
    into a binary-valued output array. The shape of the output array is
    either 1-D (if `axis` is ``None``) or the same shape as the input
    array with unpacking done along the axis specified.

    Parameters
    ----------
    a : ndarray[uint8]
       Input array.
    axis : int, optional
        The dimension over which bit-unpacking is done.
        ``None`` implies unpacking the flattened array.
    count : int or None, optional
        The number of elements to unpack along `axis`, provided as a way
        of undoing the effect of packing a size that is not a multiple
        of eight. A non-negative number means to only unpack `count`
        bits. A negative number means to trim off that many bits from
        the end. ``None`` means to unpack the entire array (the
        default). Counts larger than the available number of bits will
        add zero padding to the output. Negative counts must not
        exceed the available number of bits.

    bitorder : ``{"big", "little"}``, optional
        The order of the returned bits. 'big' will mimic bin(val),
        ``3 = 0b00000011 => [0, 0, 0, 0, 0, 0, 1, 1]``, 'little' will reverse
        the order to ``[1, 1, 0, 0, 0, 0, 0, 0]``.
        Defaults to 'big'.

    Returns
    -------
    unpacked : ndarray[uint8]
       The elements are binary-valued (0 or 1).

    See Also
    --------
    numpy.unpackbits

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

    if a.dtype != "B":
        raise TypeError("Expected an input array of unsigned byte data type")

    if count is not None and not isinstance(count, int):
        raise TypeError("count must be an integer or None")

    a, sanitized_axis = _sanitize_arguments(a, axis, bitorder)

    axis_extent = a.shape[sanitized_axis] * 8
    out_shape = tuple(
        axis_extent if dim == sanitized_axis else extent
        for dim, extent in enumerate(a.shape)
    )
    out = empty(out_shape, dtype="B")
    out._thunk.unpackbits(a._thunk, sanitized_axis, bitorder)

    if count is not None and count != axis_extent:
        # TODO: We could handle `count` directly in the unpack task to avoid
        # generating the full unpack result. For now we simply slice out the
        # output for the count.
        slices = tuple(
            slice(None, count if dim == sanitized_axis else None)
            for dim in range(a.ndim)
        )
        out = out[slices]
    return out

    Unpacks elements of a uint8 array into a binary-valued output array.

    Each element of `a` represents a bit-field that should be unpacked
    into a binary-valued output array. The shape of the output array is
    either 1-D (if `axis` is ``None``) or the same shape as the input
    array with unpacking done along the axis specified.

    Parameters
    ----------
    a : ndarray[uint8]
       Input array.
    axis : int, optional
        The dimension over which bit-unpacking is done.
        ``None`` implies unpacking the flattened array.
    count : int or None, optional
        The number of elements to unpack along `axis`, provided as a way
        of undoing the effect of packing a size that is not a multiple
        of eight. A non-negative number means to only unpack `count`
        bits. A negative number means to trim off that many bits from
        the end. ``None`` means to unpack the entire array (the
        default). Counts larger than the available number of bits will
        add zero padding to the output. Negative counts must not
        exceed the available number of bits.

    bitorder : ``{"big", "little"}``, optional
        The order of the returned bits. 'big' will mimic bin(val),
        ``3 = 0b00000011 => [0, 0, 0, 0, 0, 0, 1, 1]``, 'little' will reverse
        the order to ``[1, 1, 0, 0, 0, 0, 0, 0]``.
        Defaults to 'big'.

    Returns
    -------
    unpacked : ndarray[uint8]
       The elements are binary-valued (0 or 1).

    See Also
    --------
    numpy.unpackbits

    Availability
    --------
    Multiple GPUs, Multiple CPUs
    
cupynumeric/_module/binary_bit_packing.py