def compute_post_training_report(
    uncompressed_model: torch.nn.Module,
    compressed_model: torch.nn.Module,
    supported_modules: Tuple[Type[torch.nn.Module]],
) -> _Report:
    """
    Computes rmse between compressed and uncompressed parameters
    """
    report = _Report()
    for name, module in compressed_model.named_modules():
        if not isinstance(module, supported_modules):
            continue

        compression_metadata = CompressionMetadata.from_state_dict(module.state_dict())

        for param_name in compression_metadata:
            module_summary = dict()
            param_key = f"{name}.{param_name}" if name else param_name

            with torch.no_grad():
                compression_types = [
                    CompressionType(x) for x in compression_metadata[param_name].compression_type
                ]

                uncompressed_module = uncompressed_model.get_submodule(name)
                compressed_param = module.get_parameter(param_name)
                uncompressed_param = uncompressed_module.get_parameter(param_name)

                module_summary["error"] = rmse_error(compressed_param, uncompressed_param).item()

                module_summary["#params"] = int(torch.numel(compressed_param))

                if CompressionType.pruning in compression_types:
                    sparse_summary = {
                        "structured_weight_sparsity": structured_sparsity(compressed_param),
                        "unstructured_weight_sparsity": unstructured_sparsity(compressed_param),
                    }

                    if compressed_param.size(0) % 2 == 0:
                        sparse_summary["block2_weight_sparsity"] = block2_sparsity(compressed_param)
                    else:
                        sparse_summary["block2_weight_sparsity"] = -1  # Not applicable

                    module_summary.update(sparse_summary)

                if CompressionType.quantization in compression_types:
                    quantization_n_bits = compression_metadata[param_name].quantization_n_bits
                    # FIXME: add sign of dtype here
                    module_summary["dtype"] = f"dtype=int{quantization_n_bits}"

                if CompressionType.palettization in compression_types:
                    lut_shape = compression_metadata[param_name].lut.shape

                    n_clusters = lut_shape[-2]
                    cluster_dim = lut_shape[-1]

                    module_summary[
                        "palettization_mode"
                    ] = f"num_clusters={n_clusters}, cluster_dim={cluster_dim}"

                report[param_key] = module_summary

    report = _normalize_report(report)
    return report

    Computes rmse between compressed and uncompressed parameters
    
coremltools/optimize/torch/_utils/report_utils.py