def get_random_quantization_params(
        float_dtype: np.dtype,
        quant_dtype: np.dtype,
        input_rank: int,
        is_zp_present: bool = True,
        axis: int = None,
    ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
        """
        return floating-point input, floating-point scale, integer zero point
        """

        x_shape = np.random.randint(low=1, high=5, size=(input_rank,))

        low, high = (-128, 128) if quant_dtype == np.int8 else (0, 256)

        # create quantized x
        x_q = np.random.randint(low=low, high=high, size=x_shape)

        # create scale and zero point, the dequantize x
        x_fp = None
        scale = None
        zp = None
        # quantize per tensor
        if axis is None:
            scale = np.array(np.random.rand())
            if is_zp_present:
                zp = np.array(np.random.randint(low=low, high=high))
                x_fp = (x_q - zp) * scale
            else:
                x_fp = x_q * scale
        # quantize per channel
        else:
            # prepare broadcast shape for latter dequantize
            broadcastable_shape = np.ones(input_rank, dtype=np.int32)
            broadcastable_shape[axis] = x_shape[axis]

            scale = np.random.rand(x_shape[axis])
            broadcasted_scale = np.reshape(scale, broadcastable_shape)

            if is_zp_present:
                zp = np.random.randint(low=low, high=high, size=x_shape[axis])
                broadcasted_zp = np.reshape(zp, broadcastable_shape)
                x_fp = (x_q - broadcasted_zp) * broadcasted_scale
            else:
                x_fp = x_q * broadcasted_scale

        x_fp = x_fp.astype(float_dtype)
        scale = scale.astype(float_dtype)
        zero_point = zp.astype(quant_dtype) if is_zp_present else None
        return x_fp, scale, zero_point

        return floating-point input, floating-point scale, integer zero point
        
coremltools/converters/mil/mil/ops/tests/iOS17/test_quantization.py