Runs a Tensorflow graph defined by the root scope, and fetches the result of 'fetch' node into the output Tensor. Optional `fetch_node` parameter allows to define a fetch node directly using a NodeDef for the ops that are not supported by the C++ Api.
| 550 | // allows to define a fetch node directly using a NodeDef for the ops that are |
| 551 | // not supported by the C++ Api. |
| 552 | void RunAndFetch(const tensorflow::Scope& root, const string& fetch, |
| 553 | Tensor* output, bool allow_gpu_device, |
| 554 | const NodeDef* fetch_node = nullptr) { |
| 555 | tensorflow::GraphDef graph; |
| 556 | TF_ASSERT_OK(root.ToGraphDef(&graph)); |
| 557 | |
| 558 | if (fetch_node) { |
| 559 | *graph.add_node() = *fetch_node; |
| 560 | } |
| 561 | |
| 562 | // We really want to make sure that graph executed exactly as we passed it |
| 563 | // to the session, so we disable various optimizations. |
| 564 | tensorflow::SessionOptions session_options; |
| 565 | |
| 566 | // Disable common runtime constant folding. |
| 567 | session_options.config.mutable_graph_options() |
| 568 | ->mutable_optimizer_options() |
| 569 | ->set_opt_level(OptimizerOptions::L0); |
| 570 | |
| 571 | // Disable Grappler optimizations for tests. |
| 572 | tensorflow::RewriterConfig* cfg = |
| 573 | session_options.config.mutable_graph_options() |
| 574 | ->mutable_rewrite_options(); |
| 575 | cfg->set_constant_folding(tensorflow::RewriterConfig::OFF); |
| 576 | cfg->set_layout_optimizer(tensorflow::RewriterConfig::OFF); |
| 577 | cfg->set_remapping(tensorflow::RewriterConfig::OFF); |
| 578 | |
| 579 | std::unique_ptr<tensorflow::Session> session( |
| 580 | tensorflow::NewSession(session_options)); |
| 581 | |
| 582 | std::vector<DeviceAttributes> available_devices; |
| 583 | TF_ASSERT_OK(session->ListDevices(&available_devices)) |
| 584 | << "Failed to get available session devices"; |
| 585 | |
| 586 | // Check if session has an available GPU device. |
| 587 | const bool has_gpu_device = |
| 588 | absl::c_any_of(available_devices, [](const DeviceAttributes& device) { |
| 589 | return device.device_type() == DEVICE_GPU; |
| 590 | }); |
| 591 | |
| 592 | // Some of the `FusedConv2D` fusion types are implemented only for CPU, and |
| 593 | // in this test we don't want to compare GPU vs CPU numbers, so place all |
| 594 | // nodes on CPU in this case. |
| 595 | const bool place_all_on_gpu = allow_gpu_device && has_gpu_device; |
| 596 | |
| 597 | const string device = place_all_on_gpu ? "/device:GPU:0" : "/device:CPU:0"; |
| 598 | for (NodeDef& mutable_node : *graph.mutable_node()) { |
| 599 | mutable_node.set_device(device); |
| 600 | } |
| 601 | |
| 602 | TF_ASSERT_OK(session->Create(graph)); |
| 603 | |
| 604 | std::vector<Tensor> unfused_tensors; |
| 605 | TF_ASSERT_OK(session->Run({}, {fetch}, {}, &unfused_tensors)); |
| 606 | |
| 607 | *output = unfused_tensors[0]; |
| 608 | } |
| 609 |
nothing calls this directly
no test coverage detected