def sanitize_quantization_block_size(self):
        """
        Validates and updates block_size attribute in quantization config for specified parameter.
        If compression should be skipped for param, returns False.
        Else, returns True and updates config inplace.
        """
        if self.config.granularity != _QuantizationGranularity.per_block:
            return True

        if len(self.config.block_size) > self.param.ndim:
            _logger.warning(
                f"{self.param_name}: Length of block_size tuple {len(self.config.block_size)} "
                f"should not exceed the number of dimensions in the parameter {self.param.ndim}"
            )
            return False

        # Verify that for non input or output channel axis, block size is either zero or equal to axis length
        for idx, bs in enumerate(self.config.block_size):
            if idx > 1:
                if bs != 0 and bs != self.param.shape[idx]:
                    _logger.warning(
                        f"{self.param_name}: Unsupported block_size={self.config.block_size}. "
                        "Blocking is currently only supported along input OR output channel axis."
                    )
                    return False

        # Determine whether it is an N-D block or a integer block size
        if len(self.config.block_size) >= 2:
            bs_output = self.config.block_size[0]
            bs_input = self.config.block_size[1]
        else:
            bs_output = None
            bs_input = self.config.block_size[0]

        should_block_output = (
            bs_output > 0 and bs_output < self.param.shape[0] if bs_output else False
        )
        should_block_input = bs_input > 0 and bs_input < self.param.shape[1]

        if should_block_input and not should_block_output:
            # By default we will always have per-channel on output-channel axis
            bs_output = 1
            should_block_output = True

        if not should_block_input and not should_block_output:
            _logger.warning(
                f"{self.param_name}: Valid block_size={self.config.block_size} not specified for any axis. "
                "Use per_channel or per_tensor granularity if blocking is not required."
            )
            return False

        # Check if the output-channel block size is divisible by the axis length
        if should_block_output and self.param.shape[0] % bs_output != 0:
            _logger.warning(
                f"{self.param_name}: block_size={bs_output} is not divisible by axis length={self.param.shape[0]}"
            )
            return False

        # Check if the input-channel block size is divisible by the axis length
        if should_block_input and self.param.shape[1] % bs_input != 0:
            _logger.warning(
                f"{self.param_name}: block_size={bs_input} is not divisible by axis length={self.param.shape[0]}"
            )
            return False

        self.config.block_size = (bs_output, bs_input)
        return True

        Validates and updates block_size attribute in quantization config for specified parameter.
        If compression should be skipped for param, returns False.
        Else, returns True and updates config inplace.
        
coremltools/optimize/torch/_utils/validation_utils.py