TODO(josh11b,mrry): Change Session to be able to use a Graph directly, instead of requiring us to serialize to a GraphDef and call Session::Extend().
| 313 | // directly, instead of requiring us to serialize to a GraphDef and |
| 314 | // call Session::Extend(). |
| 315 | bool ExtendSessionGraphHelper(TF_Session* session, TF_Status* status) { |
| 316 | if (session->graph != nullptr) { |
| 317 | // Take the graph lock before the session lock to avoid deadlock. This is |
| 318 | // safe since session->graph does not change. |
| 319 | session->graph->mu.lock(); |
| 320 | mutex_lock session_lock(session->mu); |
| 321 | const Graph& graph = session->graph->graph; |
| 322 | |
| 323 | const string& mutation_warning = session->graph->sessions[session]; |
| 324 | if (!mutation_warning.empty()) { |
| 325 | // TODO(b/74949947): turn this back into an error status |
| 326 | LOG(WARNING) << mutation_warning; |
| 327 | session->graph->sessions[session].clear(); |
| 328 | } |
| 329 | |
| 330 | const auto num_nodes = graph.num_node_ids(); |
| 331 | if (session->last_num_graph_nodes < num_nodes) { |
| 332 | // TODO(nolivia): check this on a subset of the graph instead of all of |
| 333 | // it. |
| 334 | status->status = graph::ValidateGraphHasNoCycle(session->graph->graph); |
| 335 | if (TF_GetCode(status) != TF_OK) { |
| 336 | session->graph->mu.unlock(); |
| 337 | return false; |
| 338 | } |
| 339 | |
| 340 | GraphDef graph_def; |
| 341 | *graph_def.mutable_versions() = graph.versions(); |
| 342 | // Fill graph_def with nodes with ids in the range |
| 343 | // [session->last_num_graph_nodes, num_nodes), that is the nodes |
| 344 | // added since the last TF_SessionRun() call. |
| 345 | for (auto id = session->last_num_graph_nodes; id < num_nodes; ++id) { |
| 346 | Node* const node = graph.FindNodeId(id); |
| 347 | if (node != nullptr && node->IsOp()) { |
| 348 | NodeDef* const node_def = graph_def.add_node(); |
| 349 | *node_def = node->def(); |
| 350 | } |
| 351 | } |
| 352 | *graph_def.mutable_library() = graph.flib_def().ToProto(); |
| 353 | session->graph->mu.unlock(); |
| 354 | status->status = session->session->Extend(std::move(graph_def)); |
| 355 | if (TF_GetCode(status) != TF_OK) { |
| 356 | // Contract is we always delete input_values[i]. |
| 357 | return false; |
| 358 | } |
| 359 | // Note: session->session is not modified if Extend() fails, so |
| 360 | // we only set last_num_graph_nodes if it succeeds. |
| 361 | session->last_num_graph_nodes = num_nodes; |
| 362 | } else { |
| 363 | session->graph->mu.unlock(); |
| 364 | } |
| 365 | } |
| 366 | return true; |
| 367 | } |
| 368 | |
| 369 | } // namespace tensorflow |
| 370 |
no test coverage detected