| 879 | } |
| 880 | |
| 881 | Status GraphExecutionState::BuildGraph(const BuildGraphOptions& options, |
| 882 | std::unique_ptr<ClientGraph>* out) { |
| 883 | VLOG(1) << "BuildGraph"; |
| 884 | const uint64 start_time_usecs = Env::Default()->NowMicros(); |
| 885 | if (!graph_) { |
| 886 | // It is only valid to call this method directly when the original graph |
| 887 | // was created with the option `place_pruned_graph == false`. |
| 888 | return errors::Internal( |
| 889 | "Attempted to prune a graph that has not been fully initialized."); |
| 890 | } |
| 891 | |
| 892 | // Grappler optimization might change the structure of a graph itself, and |
| 893 | // also it can add/prune functions to/from the library. |
| 894 | std::unique_ptr<Graph> optimized_graph; |
| 895 | std::unique_ptr<FunctionLibraryDefinition> optimized_flib; |
| 896 | |
| 897 | Status s = OptimizeGraph(options, &optimized_graph, &optimized_flib); |
| 898 | if (!s.ok()) { |
| 899 | VLOG(2) << "Grappler optimization failed. Error: " << s.error_message(); |
| 900 | // Simply copy the original graph and the function library if we couldn't |
| 901 | // optimize it. |
| 902 | optimized_graph.reset(new Graph(flib_def_.get())); |
| 903 | CopyGraph(*graph_, optimized_graph.get()); |
| 904 | optimized_flib.reset(new FunctionLibraryDefinition(*flib_def_)); |
| 905 | } |
| 906 | |
| 907 | subgraph::RewriteGraphMetadata rewrite_metadata; |
| 908 | if (session_options_ == nullptr || |
| 909 | !session_options_->config.graph_options().place_pruned_graph()) { |
| 910 | TF_RETURN_IF_ERROR( |
| 911 | PruneGraph(options, optimized_graph.get(), &rewrite_metadata)); |
| 912 | } else { |
| 913 | // This GraphExecutionState represents a graph that was |
| 914 | // pruned when this was constructed, so we copy the metadata from |
| 915 | // a member variable. |
| 916 | CHECK(rewrite_metadata_); |
| 917 | rewrite_metadata = *rewrite_metadata_; |
| 918 | } |
| 919 | |
| 920 | CHECK_EQ(options.callable_options.feed_size(), |
| 921 | rewrite_metadata.feed_types.size()); |
| 922 | CHECK_EQ(options.callable_options.fetch_size(), |
| 923 | rewrite_metadata.fetch_types.size()); |
| 924 | |
| 925 | // TODO(andydavis): Clarify optimization pass requirements around CostModel. |
| 926 | GraphOptimizationPassOptions optimization_options; |
| 927 | optimization_options.session_options = session_options_; |
| 928 | optimization_options.graph = &optimized_graph; |
| 929 | optimization_options.flib_def = optimized_flib.get(); |
| 930 | optimization_options.device_set = device_set_; |
| 931 | |
| 932 | TF_RETURN_IF_ERROR(OptimizationPassRegistry::Global()->RunGrouping( |
| 933 | OptimizationPassRegistry::POST_REWRITE_FOR_EXEC, optimization_options)); |
| 934 | |
| 935 | int64 collective_graph_key = options.collective_graph_key; |
| 936 | if (collective_graph_key == BuildGraphOptions::kNoCollectiveGraphKey) { |
| 937 | // BuildGraphOptions does not specify a collective_graph_key. Check all |
| 938 | // nodes in the Graph and FunctionLibraryDefinition for collective ops and |
no test coverage detected