tensorflow/core/grappler/utils/pattern_utils_test.cc
// Pattern should not be matched if any of candidate remove nodes has external
// dependent.
Pattern should not be matched if any of candidate remove nodes has external
dependent.
Pattern should not be matched if any of candidate remove nodes has external dependent .
TEST_F(PatternMatcherTest, DAGExternalDependent) {
       Input graph              Subgraph for pattern matcher
           A
           |                           B
           B                          / \
          / \                        C   D
         C   D                        \ /
          \ / \                        E
           E   F
   E is the root of pattern syntax as shown below that the pattern matcher
   would match. Note D is a candidate for remove node as mentioned in the
   syntax. So Pattern matcher should not find a match.
    {"E", "my_e", NodeStatus::Replace,
      {
        {"C", "my_c", NodeStatus::kRemove,
          {
            {"B", "my_b", NodeStatus::kRemove}
          }
        },
        {"D", "my_d", NodeStatus::kRemove,
          {
            {"B", "my_b", NodeStatus::kRemove}
          }
        }
      }
    }
  ::tensorflow::Status status;
  GraphDef graph = CreateGraph({{"f", "F", {"d"}},
                                {"e", "E", {"c", "d"}},
                                {"c", "C", {"b"}},
                                {"d", "D", {"b"}},
                                {"b", "B", {"a"}},
                                {"a", "A", {}}});
   clang-format off
  OpTypePattern pattern{"E", "my_e", NodeStatus::kReplace,
    {
      {"C", "my_c", NodeStatus::kRemove,
        {
          {"B", "my_b", NodeStatus::kRemove}
        }
      },
      {"D", "my_d", NodeStatus::kRemove,
        {
          {"B", "my_b", NodeStatus::kRemove}
        }
      }
    }
  };   clang-format on
  MutableGraphView graph_view(&graph, &status);
  TF_ASSERT_OK(status);
  TF_EXPECT_OK(graph_view.SortTopologically(false, {}));
  auto root_node_view = graph_view.GetNode("e");
  SubGraphMatcher<MatchingDirection::kFollowInputs> graph_matcher(&graph_view);
  std::map<string, int> matched_nodes_map;   label to node index map
  std::set<int> remove_node_indices;
  bool found_match = graph_matcher.GetMatchedNodes(
      pattern, {}, root_node_view, &matched_nodes_map, &remove_node_indices);
  EXPECT_FALSE(found_match);
  EXPECT_TRUE(matched_nodes_map.empty());
  EXPECT_TRUE(remove_node_indices.empty());
}
TEST_F ( PatternMatcherTest , DAGExternalDependent ) { :: tensorflow :: Status status ; GraphDef graph = CreateGraph ( { { " " , " " , { " " } } , { " " , " " , { " " , " " } } , { " " , " " , { " " } } , { " " , " " , { " " } } , { " " , " " , { " " } } , { " " , " " , { } } } ) ; OpTypePattern pattern { " " , " " , NodeStatus :: kReplace , { { " " , " " , NodeStatus :: kRemove , { { " " , " " , NodeStatus :: kRemove } } } , { " " , " " , NodeStatus :: kRemove , { { " " , " " , NodeStatus :: kRemove } } } } } ; MutableGraphView graph_view ( & graph , & status ) ; TF_ASSERT_OK ( status ) ; TF_EXPECT_OK ( graph_view . SortTopologically ( false , { } ) ) ; auto root_node_view = graph_view . GetNode ( " " ) ; SubGraphMatcher < MatchingDirection :: kFollowInputs > graph_matcher ( & graph_view ) ; std :: map < string , int > matched_nodes_map ; std :: set < int > remove_node_indices ; bool found_match = graph_matcher . GetMatchedNodes ( pattern , { } , root_node_view , & matched_nodes_map , & remove_node_indices ) ; EXPECT_FALSE ( found_match ) ; EXPECT_TRUE ( matched_nodes_map . empty ( ) ) ; EXPECT_TRUE ( remove_node_indices . empty ( ) ) ; }
Pattern should not be matched if any of candidate remove nodes has external
dependent.
Pattern should not be matched if any of candidate remove nodes has external dependent .
// A Data flow graph. Data flows from top to bottom. Here A, B, C, D, E, and F // are ops. // //     Input graph              Subgraph for pattern matcher // //         A //         |                           B //         B                          / \
  //        / \                        C   D //       C   D                        \ / //        \ / \                        E //         E   F // // E is the root of pattern syntax as shown below that the pattern matcher // would match. Note D is a candidate for remove node as mentioned in the // syntax. So Pattern matcher should not find a match. //  {"E", "my_e", NodeStatus::Replace, //    { //      {"C", "my_c", NodeStatus::kRemove, //        { //          {"B", "my_b", NodeStatus::kRemove} //        } //      }, //      {"D", "my_d", NodeStatus::kRemove, //        { //          {"B", "my_b", NodeStatus::kRemove} //        } //      } //    } //  } // clang-format off // clang-format on /*ignore_cycles=*/ // label to node index map