def test_config_hierarchy(self):
        """
        This test is checking the graph pass compresses the program correctly according to the following hierarchical order (high -> low):
        1. op name
        2. op type
        3. global
        """
        prog = self._get_test_program_2()

        # global config
        global_config = cto.coreml.OpPalettizerConfig(
                nbits=8,
                mode="KMEANS",
                weight_threshold=100,
        )

        # op type config
        conv_config = cto.coreml.OpPalettizerConfig(
                nbits=6,
                mode="KMEANS",
                weight_threshold=100,
        )
        linear_config = cto.coreml.OpPalettizerConfig(
                nbits=4,
                mode="KMEANS",
                weight_threshold=100,
        )

        # op name config
        conv1_config = cto.coreml.OpPalettizerConfig(
                nbits=2,
                mode="KMEANS",
                weight_threshold=100,
        )
        linear2_config = cto.coreml.OpPalettizerConfig(
                nbits=1,
                mode="KMEANS",
                weight_threshold=100,
        )

        config = cto.coreml.OptimizationConfig()
        config.set_global(global_config)

        config.set_op_type("conv", conv_config)
        config.set_op_type("linear", linear_config)

        config.set_op_name("conv1", conv1_config)
        config.set_op_name("linear2", linear2_config)

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

        expected_ops = [
            "constexpr_lut_to_dense",
            "conv",
            "constexpr_lut_to_dense",
            "conv",
            "constexpr_lut_to_dense",
            "conv",
            "reshape",
            "constexpr_lut_to_dense",
            "linear",
            "constexpr_lut_to_dense",
            "linear",
            "reshape",
            "constexpr_lut_to_dense",
            "conv_transpose",
        ]
        assert get_op_types_in_program(prog) == expected_ops

        expected_nbits = [2, 6, 6, 4, 1, 8, 8]
        lut_ops = prog.find_ops(op_type="constexpr_lut_to_dense")

        for nbits, op in zip(expected_nbits, lut_ops):
            assert op.lut.val.shape == (2**nbits,)

        This test is checking the graph pass compresses the program correctly according to the following hierarchical order (high -> low):
        1. op name
        2. op type
        3. global
        
coremltools/test/optimize/coreml/test_passes.py