def _pack()

in bitpack.pyx [0:0]


def _pack(int16_t[::1] indexes, int nbits=0, int block_size=32):
    if nbits == 0:
        # automatically chose bitwidth
        nbits = int(math.ceil(math.log2(1 + np.max(indexes))))
    cdef int le = len(indexes)
    cdef int storage = 64
    assert le % (storage * block_size) == 0
    cdef int lines = le // (storage * block_size)
    out = np.zeros((lines, nbits, block_size), dtype=np.uint64)
    cdef uint64_t[:, :, ::1] out_view = out
    cdef int bit_in, bit_out, index, line
    cdef int16_t x
    cdef uint64_t tmp
    for line in range(lines):
        for bit_out in range(storage):
            for bit_in in range(nbits):
                for index in range(block_size):
                    x = indexes[line * block_size * storage + bit_out * block_size + index]
                    tmp = (x >> bit_in) & 1
                    out_view[line, bit_in, index] |= tmp << bit_out
    return out