def repeat_data_as(input_data: np.ndarray, target_shape: Collection[int]) -> np.ndarray:
    """
    Repeat the first K dimensions of input_data where len(target_shape) == K.
    It should be guaranteed that each dimension of the K dimensions is divisible by the
    corresponding dimension given by the target_shape.

    For example, lut has shape [block_num0, block_num1, ..., 2**nbits, vector_size], so
    it needs to be interleaved repeated to make each block match the target shape.
    """
    if len(input_data.shape) < len(target_shape):
        raise ValueError(
            "The provided input_data's rank should be >= target shape's "
            f"length. But got {len(input_data.shape)} vs {len(target_shape)}"
        )
    repeated_data = input_data
    for axis, target_dim_size in enumerate(target_shape):
        input_dim_size = input_data.shape[axis]
        if target_dim_size % input_dim_size != 0:
            raise ValueError(
                "The dim size in each axis must be divisible by the tensor dimension. "
                f"Got invalid input_data shape {input_data.shape} for target shape "
                f"{target_shape[axis]} at axis {axis}"
            )
        block_size = target_dim_size // input_dim_size
        # Can use kron for higher efficiency, but repeat is easier to understand.
        if block_size > 1:
            repeated_data = np.repeat(repeated_data, block_size, axis=axis)
    return repeated_data

    Repeat the first K dimensions of input_data where len(target_shape) == K.
    It should be guaranteed that each dimension of the K dimensions is divisible by the
    corresponding dimension given by the target_shape.

    For example, lut has shape [block_num0, block_num1, ..., 2**nbits, vector_size], so
    it needs to be interleaved repeated to make each block match the target shape.
    
coremltools/optimize/_utils.py