1 | /* Copyright 2015 The TensorFlow Authors. All Rights Reserved. |
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations under the License. |
14 | ==============================================================================*/ |
15 | #include "tensorflow/core/common_runtime/propagator_debug_utils.h" |
16 | |
17 | #include "tensorflow/core/common_runtime/entry.h" |
18 | #include "tensorflow/core/common_runtime/graph_view.h" |
19 | #include "tensorflow/core/framework/op_kernel.h" |
20 | #include "tensorflow/core/framework/tensor.h" |
21 | #include "tensorflow/core/platform/logging.h" |
22 | #include "tensorflow/core/platform/strcat.h" |
23 | |
24 | namespace tensorflow { |
25 | |
26 | // 1-D, 0 element tensor. |
27 | static const Tensor* const kEmptyTensor = new Tensor; |
28 | |
29 | |
30 | const Tensor* GetTensorValueForDump(const Entry& input) { |
31 | switch (input.state) { |
32 | case Entry::State::NO_VALUE: |
33 | return kEmptyTensor; |
34 | case Entry::State::HAS_VALUE: |
35 | return input.val.get(); |
36 | case Entry::State::HAS_CONST_TENSOR: |
37 | return input.const_tensor; |
38 | case Entry::State::HAS_REF_TENSOR: |
39 | return input.ref_tensor.tensor; |
40 | } |
41 | } |
42 | |
43 | void DumpPendingNodeState(const NodeItem& node_item, const Entry* input_vector, |
44 | const bool show_nodes_with_no_ready_inputs) { |
45 | const int input_base = node_item.input_start; |
46 | if (!show_nodes_with_no_ready_inputs) { |
47 | bool has_ready_input = false; |
48 | for (int i = 0; i < node_item.num_inputs; ++i) { |
49 | const Entry& input = input_vector[input_base + i]; |
50 | const Tensor* tensor = GetTensorValueForDump(input); |
51 | if (tensor && tensor->IsInitialized()) { |
52 | has_ready_input = true; |
53 | break; |
54 | } |
55 | } |
56 | if (!has_ready_input) { |
57 | return; |
58 | } |
59 | } |
60 | LOG(WARNING) << " Pending Node: " << node_item.DebugString(); |
61 | for (int i = 0; i < node_item.num_inputs; ++i) { |
62 | const Entry& input = input_vector[input_base + i]; |
63 | const Tensor* tensor = GetTensorValueForDump(input); |
64 | if (tensor->IsInitialized()) { |
65 | LOG(WARNING) << " Input " << i << ": " |
66 | << strings::StrCat( |
67 | "Tensor<type: " , DataTypeString(tensor->dtype()), |
68 | " shape: " , tensor->shape().DebugString(), ">" ); |
69 | } else { |
70 | LOG(WARNING) << " Input " << i << ": not present" ; |
71 | } |
72 | } |
73 | } |
74 | |
75 | void DumpActiveNodeState(const NodeItem& node_item, const Entry* input_vector) { |
76 | LOG(WARNING) << " Active Node: " << node_item.DebugString(); |
77 | const int input_base = node_item.input_start; |
78 | for (int i = 0; i < node_item.num_inputs; ++i) { |
79 | const Entry& input = input_vector[input_base + i]; |
80 | const Tensor* tensor = GetTensorValueForDump(input); |
81 | if (tensor->IsInitialized()) { |
82 | LOG(WARNING) << " Input " << i << ": " |
83 | << strings::StrCat( |
84 | "Tensor<type: " , DataTypeString(tensor->dtype()), |
85 | " shape: " , tensor->shape().DebugString(), ">" ); |
86 | } else { |
87 | LOG(WARNING) << " Input " << i << ": not present" ; |
88 | } |
89 | } |
90 | } |
91 | |
92 | } // namespace tensorflow |
93 | |