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 #ifndef TENSORFLOW_CORE_COMMON_RUNTIME_ENTRY_H_ 16 #define TENSORFLOW_CORE_COMMON_RUNTIME_ENTRY_H_ 17 18 #include "tensorflow/core/framework/allocator.h" 19 #include "tensorflow/core/framework/tensor.h" 20 #include "tensorflow/core/lib/gtl/inlined_vector.h" 21 #include "tensorflow/core/lib/gtl/manual_constructor.h" 22 23 namespace tensorflow { 24 25 class mutex; 26 class Tensor; 27 28 // An Entry store a single input value for an individual kernel invocation in 29 // an executor. 30 // 31 // Either a tensor pointer (pass-by-reference) or a tensor (pass-by-value). 32 struct Entry { 33 enum class State { 34 NO_VALUE = 0, // The default state for a newly-created Entry. 35 HAS_VALUE, // `this->val` is valid. 36 HAS_CONST_TENSOR, // `this->const_tensor` is valid. 37 HAS_REF_TENSOR, // `this->ref_tensor` is valid. 38 }; 39 EntryEntry40 Entry() : state(State::NO_VALUE) {} EntryEntry41 Entry(const Entry& other) : state(other.state), alloc_attr(other.alloc_attr) { 42 switch (state) { 43 case State::NO_VALUE: 44 break; 45 case State::HAS_VALUE: 46 val.Init(*other.val); 47 break; 48 case State::HAS_CONST_TENSOR: 49 const_tensor = other.const_tensor; 50 break; 51 case State::HAS_REF_TENSOR: 52 ref_tensor = other.ref_tensor; 53 break; 54 } 55 } 56 ~EntryEntry57 ~Entry() { 58 if (state == State::HAS_VALUE) val.Destroy(); 59 } 60 61 Entry& operator=(const Entry& other) { 62 if (state == State::HAS_VALUE) { 63 val.Destroy(); 64 } 65 state = other.state; 66 alloc_attr = other.alloc_attr; 67 switch (state) { 68 case State::NO_VALUE: 69 break; 70 case State::HAS_VALUE: 71 val.Init(*other.val); 72 break; 73 case State::HAS_CONST_TENSOR: 74 const_tensor = other.const_tensor; 75 break; 76 case State::HAS_REF_TENSOR: 77 ref_tensor = other.ref_tensor; 78 break; 79 } 80 return *this; 81 } 82 83 Entry& operator=(Entry&& other) { 84 if (state == State::HAS_VALUE) { 85 val.Destroy(); 86 } 87 state = other.state; 88 alloc_attr = other.alloc_attr; 89 switch (state) { 90 case State::NO_VALUE: 91 break; 92 case State::HAS_VALUE: 93 val.Init(std::move(*other.val)); 94 break; 95 case State::HAS_CONST_TENSOR: 96 const_tensor = other.const_tensor; 97 break; 98 case State::HAS_REF_TENSOR: 99 ref_tensor = other.ref_tensor; 100 break; 101 } 102 return *this; 103 } 104 105 // Clears the <val> field, and sets this entry to the `NO_VALUE` state. ClearValEntry106 void ClearVal() { 107 if (state == State::HAS_VALUE) { 108 val.Destroy(); 109 } 110 state = State::NO_VALUE; 111 } 112 113 union { 114 // A tensor value. Valid iff `state_ == HAS_VALUE`. 115 ManualConstructor<Tensor> val; 116 117 // A pointer to a constant tensor value. Valid iff `state_ == 118 // HAS_CONST_TENSOR`. 119 const Tensor* const_tensor; 120 121 // A tensor reference and associated mutex. Valid iff `state_ == 122 // HAS_REF_TENSOR`. 123 struct { 124 Tensor* tensor; 125 mutex* mu; 126 } ref_tensor; 127 }; 128 129 // The current state of this entry, indicating which member of the above 130 // union is active. 131 State state; 132 133 // The attributes of the allocator that creates the tensor. 134 AllocatorAttributes alloc_attr; 135 }; 136 137 // TODO(b/152925936): Re-evaluate this constant with current usage patterns. 138 typedef gtl::InlinedVector<Entry, 4> EntryVector; 139 140 } // namespace tensorflow 141 142 #endif // TENSORFLOW_CORE_COMMON_RUNTIME_ENTRY_H_ 143