def test_redundant_ops_time_complexity_pattern_2(self):
        """
        Test the graph pass doesn't re-run right away after detecting a redundant pattern,
        in order to keep time complexity low.

        In this example, there are three groups of identical leaky_relu ops can be removed,
        and the algorithm should be run in the fashion that only goes through the
        program twice. As the result, the total ops visited is:

        8 + (8 - 3) = 13
        """

        @mb.program(input_specs=[mb.TensorSpec(shape=(2, 3, 5))])
        def prog(x):
            x = mb.cos(x=x)
            x1 = mb.leaky_relu(x=x, alpha=0.2)
            x2 = mb.leaky_relu(x=x, alpha=0.2)
            x3 = mb.leaky_relu(x=x, alpha=0.3)
            x4 = mb.leaky_relu(x=x, alpha=0.3)
            x5 = mb.leaky_relu(x=x, alpha=0.4)
            x6 = mb.leaky_relu(x=x, alpha=0.4)
            return mb.sin(x=x6)

        graph_pass = remove_redundant_ops()
        graph_pass.apply(prog)

        assert get_op_types_in_program(prog) == ["cos"] + ["leaky_relu"] * 3 + ["sin"]
        assert graph_pass._num_of_visited_ops == 13

        Test the graph pass doesn't re-run right away after detecting a redundant pattern,
        in order to keep time complexity low.

        In this example, there are three groups of identical leaky_relu ops can be removed,
        and the algorithm should be run in the fashion that only goes through the
        program twice. As the result, the total ops visited is:

        8 + (8 - 3) = 13
        
coremltools/converters/mil/mil/passes/tests/test_cleanup_passes.py