def test_op_name_config_palettizer_blockwise(self):
        """
        set_op_name allow the user to set different config for each op specified by name.
        Also checking that the config can be overwritten.
        """
        conv_config_1 = cto.coreml.OpPalettizerConfig(
            mode="uniform",
            nbits=4,
            granularity="per_tensor",
            weight_threshold=500000,
        )
        # The conv_config_2 overwrites conv_config_1.
        conv_config_2 = cto.coreml.OpPalettizerConfig(
            mode="kmeans",
            nbits=8,
            granularity="per_grouped_channel",
            group_size=1,
            channel_axis=1,
            weight_threshold=2000,
        )
        # The weight_threshold is super large so linear is not going to be compressed.
        linear_config = cto.coreml.OpPalettizerConfig(
            mode="kmeans",
            nbits=4,
            weight_threshold=1000000,
        )
        conv_transpose_config = cto.coreml.OpPalettizerConfig(
            mode="uniform",
            nbits=4,
            granularity="per_grouped_channel",
            group_size=1,
            weight_threshold=2000,
        )

        config = cto.coreml.OptimizationConfig()
        config.set_op_name("conv", conv_config_1)
        config.set_op_name("conv", conv_config_2)
        config.set_op_name("linear", linear_config)
        config.set_op_name("conv_transpose", conv_transpose_config)

        prog = self._get_test_program_3()
        compressor = quantization.palettize_weights(config=config)
        compressor.apply(prog)

        expected_ops = [
            "constexpr_lut_to_dense",
            "conv",
            "reshape",
            "linear",
            "matmul",
            "reshape",
            "constexpr_lut_to_dense",
            "conv_transpose",
        ]
        assert get_op_types_in_program(prog) == expected_ops
        assert prog.find_ops(op_type="constexpr_lut_to_dense")[0].vector_axis is None
        # Makes sure the channel_axis in conv_config_2 is effective.
        conv_lut = prog.find_ops(op_type="constexpr_lut_to_dense")[0].lut
        assert conv_lut.shape[0] == 1
        assert conv_lut.shape[1] == 30

        set_op_name allow the user to set different config for each op specified by name.
        Also checking that the config can be overwritten.
        
coremltools/test/optimize/coreml/test_passes.py