xref: /aosp_15_r20/external/tensorflow/tensorflow/core/framework/variant_tensor_data.h (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1 /* Copyright 2017 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 
16 #ifndef TENSORFLOW_CORE_FRAMEWORK_VARIANT_TENSOR_DATA_H_
17 #define TENSORFLOW_CORE_FRAMEWORK_VARIANT_TENSOR_DATA_H_
18 
19 #include <algorithm>
20 #include <vector>
21 
22 #include "tensorflow/core/framework/tensor.h"
23 #include "tensorflow/core/lib/core/stringpiece.h"
24 #include "tensorflow/core/platform/types.h"
25 
26 namespace tensorflow {
27 
28 class VariantTensorDataProto;
29 
30 // The serialization format for Variant objects. Objects with references to
31 // other Tensors can simply store those tensors in the `tensors` field, and
32 // serialize other metadata content in to the `metadata` field. Objects can
33 // optionally set the `type_name` for type-checking before deserializing an
34 // object.
35 //
36 // This is the native C++ class equivalent of VariantTensorDataProto. They are
37 // separate so that kernels do not need to depend on protos.
38 class VariantTensorData {
39  public:
40   VariantTensorData() = default;
41 
42   // TODO(b/118823936): This silently returns if the proto is invalid.
43   // Consider calling FromProto explicitly instead.
44   VariantTensorData(VariantTensorDataProto proto);
45 
46   // Name of the type of objects being serialized.
type_name()47   const std::string& type_name() const { return type_name_; }
set_type_name(const std::string & type_name)48   void set_type_name(const std::string& type_name) { type_name_ = type_name; }
49 
50   template <typename T, bool = std::is_pod<typename std::decay<T>::type>::value>
51   struct PODResolver {};
52 
53   // Portions of the object that are not Tensors.
54   // Directly supported types include string POD types.
55   template <typename T>
set_metadata(const T & value)56   void set_metadata(const T& value) {
57     SetMetadata<T>(value, PODResolver<T>());
58   }
59 
60   template <typename T>
get_metadata(T * value)61   bool get_metadata(T* value) const {
62     return GetMetadata<T>(value, PODResolver<T>());
63   }
64 
metadata_string()65   std::string& metadata_string() { return metadata_; }
66 
metadata_string()67   const std::string& metadata_string() const { return metadata_; }
68 
69   // Tensors contained within objects being serialized.
70   int tensors_size() const;
71   const Tensor& tensors(int index) const;
72   const std::vector<Tensor>& tensors() const;
73   Tensor* add_tensors();
74 
75   // A more general version of add_tensors. Parameters are perfectly forwarded
76   // to the constructor of the tensor added here.
77   template <typename... TensorConstructorArgs>
78   Tensor* add_tensor(TensorConstructorArgs&&... args);
79 
80   // Conversion to and from VariantTensorDataProto
81   void ToProto(VariantTensorDataProto* proto) const;
82   // This allows optimizations via std::move.
83   bool FromProto(VariantTensorDataProto proto);
84   bool FromConstProto(const VariantTensorDataProto& proto);
85 
86   // Serialization via VariantTensorDataProto
87   std::string SerializeAsString() const;
88   bool SerializeToString(std::string* buf);
89   bool ParseFromString(std::string s);
90 
91   std::string DebugString() const;
92 
93  public:
94   std::string type_name_;
95   std::string metadata_;
96   std::vector<Tensor> tensors_;
97 
98  private:
99   template <typename T>
SetMetadata(const std::string & value,PODResolver<T,false>)100   void SetMetadata(const std::string& value,
101                    PODResolver<T, false /* is_pod */>) {
102     metadata_ = value;
103   }
104 
105   template <typename T>
GetMetadata(std::string * value,PODResolver<T,false>)106   bool GetMetadata(std::string* value,
107                    PODResolver<T, false /* is_pod */>) const {
108     *value = metadata_;
109     return true;
110   }
111 
112   template <typename T>
SetMetadata(const T & value,PODResolver<T,true>)113   void SetMetadata(const T& value, PODResolver<T, true /* is_pod */>) {
114     metadata_.assign(reinterpret_cast<const char*>(&value), sizeof(T));
115   }
116 
117   template <typename T>
GetMetadata(T * value,PODResolver<T,true>)118   bool GetMetadata(T* value, PODResolver<T, true /* is_pod */>) const {
119     if (metadata_.size() != sizeof(T)) return false;
120     std::copy_n(metadata_.data(), sizeof(T), reinterpret_cast<char*>(value));
121     return true;
122   }
123 };
124 
125 // For backwards compatibility for when this was a proto
126 std::string ProtoDebugString(const VariantTensorData& object);
127 
128 template <typename... TensorConstructorArgs>
add_tensor(TensorConstructorArgs &&...args)129 Tensor* VariantTensorData::add_tensor(TensorConstructorArgs&&... args) {
130   tensors_.emplace_back(std::forward<TensorConstructorArgs>(args)...);
131   return &tensors_.back();
132 }
133 
134 }  // namespace tensorflow
135 
136 #endif  // TENSORFLOW_CORE_FRAMEWORK_VARIANT_TENSOR_DATA_H_
137