xref: /aosp_15_r20/external/tensorflow/tensorflow/lite/delegates/gpu/gl/object.h (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1 /* Copyright 2019 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_LITE_DELEGATES_GPU_GL_OBJECT_H_
17 #define TENSORFLOW_LITE_DELEGATES_GPU_GL_OBJECT_H_
18 
19 #include <array>
20 #include <cstdint>
21 #include <cstring>
22 #include <string>
23 #include <variant>
24 #include <vector>
25 
26 #include "absl/types/variant.h"
27 #include "tensorflow/lite/delegates/gpu/common/access_type.h"
28 #include "tensorflow/lite/delegates/gpu/common/data_type.h"
29 #include "tensorflow/lite/delegates/gpu/common/shape.h"
30 #include "tensorflow/lite/delegates/gpu/common/types.h"
31 #include "tensorflow/lite/delegates/gpu/common/util.h"
32 
33 namespace tflite {
34 namespace gpu {
35 namespace gl {
36 
37 using ObjectData = std::vector<uint8_t>;
38 
39 // Generic identifier to be used to lookup an object.
40 using ObjectRef = uint32_t;
41 
42 constexpr ObjectRef kInvalidObjectRef = ~0;
43 
44 enum class ObjectType : int {
45   UNKNOWN = 0,
46   TEXTURE = 1,
47   BUFFER = 2,
48 };
49 
50 using ObjectSize = std::variant<size_t, uint2, uint3>;
51 
52 // An object represents a reference to or pre-defined constant OpenGL Buffer or
53 // Texture. NodeShader is supposed to set all fields but leave binding = 0
54 // that will be set later by a compiler.
55 struct Object {
56   AccessType access;
57 
58   DataType data_type;
59 
60   ObjectType object_type;
61 
62   // OpenGL-specific binding information
63   uint32_t binding;
64 
65   // Indicates size of 1D, 2D or 3D object in elements, where single element
66   // consists of 4 values.
67   ObjectSize size;
68 
69   std::variant<ObjectData, ObjectRef> object;
70 };
71 
72 // @return true if object is a reference.
IsRef(const Object & object)73 inline bool IsRef(const Object& object) {
74   return !std::holds_alternative<ObjectData>(object.object);
75 }
76 
GetRef(const Object & object)77 inline ObjectRef GetRef(const Object& object) {
78   auto ref = std::get_if<ObjectRef>(&object.object);
79   return ref ? *ref : kInvalidObjectRef;
80 }
81 
GetData(const Object & object)82 inline const ObjectData* GetData(const Object& object) {
83   return std::get_if<ObjectData>(&object.object);
84 }
85 
86 inline size_t ByteSizeOf(const Object& object);
87 
88 // @return object that references an object created externally.
MakeObjectRef(ObjectRef unique_id,const ObjectSize & size,AccessType access_type)89 inline Object MakeObjectRef(ObjectRef unique_id, const ObjectSize& size,
90                             AccessType access_type) {
91   return Object{access_type, DataType::FLOAT32, ObjectType::UNKNOWN, 0,
92                 size,        unique_id};
93 }
94 
95 namespace internal_object {
96 
97 template <typename T>
ToBytesVector(const std::vector<T> & data,size_t alignment)98 std::vector<uint8_t> ToBytesVector(const std::vector<T>& data,
99                                    size_t alignment) {
100   std::vector<uint8_t> t(AlignByN(data.size() * sizeof(T), alignment));
101   std::memcpy(t.data(), data.data(), data.size() * sizeof(T));
102   return t;
103 }
104 
105 struct ObjectSizer {
operatorObjectSizer106   size_t operator()(const uint3& size) const {
107     return size.x * size.y * size.z;
108   }
109 
operatorObjectSizer110   size_t operator()(const uint2& size) const { return size.x * size.y; }
111 
operatorObjectSizer112   size_t operator()(uint32_t size) const { return size; }
113 };
114 
115 }  // namespace internal_object
116 
NumElements(const ObjectSize & size)117 inline size_t NumElements(const ObjectSize& size) {
118   return std::visit(internal_object::ObjectSizer{}, size);
119 }
120 
ByteSizeOf(const Object & object)121 inline size_t ByteSizeOf(const Object& object) {
122   return SizeOf(object.data_type) * /* vec4 */ 4 * NumElements(object.size);
123 }
124 
MakeReadonlyObject(const ObjectSize & size,const std::vector<float> & data)125 inline Object MakeReadonlyObject(const ObjectSize& size,
126                                  const std::vector<float>& data) {
127   return Object{AccessType::READ,
128                 DataType::FLOAT32,
129                 ObjectType::UNKNOWN,
130                 0,
131                 size,
132                 internal_object::ToBytesVector(data, 16)};
133 }
134 
MakeReadonlyTexture(const ObjectSize & size,const std::vector<float> & data)135 inline Object MakeReadonlyTexture(const ObjectSize& size,
136                                   const std::vector<float>& data) {
137   return Object{AccessType::READ,
138                 DataType::FLOAT32,
139                 ObjectType::TEXTURE,
140                 0,
141                 size,
142                 internal_object::ToBytesVector(data, 16)};
143 }
144 
MakeReadonlyBuffer(const ObjectSize & size,const std::vector<float> & data)145 inline Object MakeReadonlyBuffer(const ObjectSize& size,
146                                  const std::vector<float>& data) {
147   return Object{AccessType::READ,
148                 DataType::FLOAT32,
149                 ObjectType::BUFFER,
150                 0,
151                 size,
152                 internal_object::ToBytesVector(data, 16)};
153 }
154 
MakeReadonlyObject(const std::vector<float> & data)155 inline Object MakeReadonlyObject(const std::vector<float>& data) {
156   return MakeReadonlyObject(
157       DivideRoundUp(static_cast<uint32_t>(data.size()), 4U), data);
158 }
159 
MakeReadonlyTexture(const std::vector<float> & data)160 inline Object MakeReadonlyTexture(const std::vector<float>& data) {
161   return MakeReadonlyTexture(
162       DivideRoundUp(static_cast<uint32_t>(data.size()), 4U), data);
163 }
164 
MakeReadonlyBuffer(const std::vector<float> & data)165 inline Object MakeReadonlyBuffer(const std::vector<float>& data) {
166   return MakeReadonlyBuffer(
167       DivideRoundUp(static_cast<uint32_t>(data.size()), 4U), data);
168 }
169 
170 // TODO(akulik): find better place for functions below.
171 
GetPHWC4Size(const BHWC & shape)172 inline uint3 GetPHWC4Size(const BHWC& shape) {
173   uint3 size;
174   size.x = shape.w;
175   size.y = shape.h;
176   size.z = shape.b * DivideRoundUp(shape.c, 4);
177   return size;
178 }
179 
MakePHWC4Ref(uint32_t global_id,const BHWC & shape)180 inline Object MakePHWC4Ref(uint32_t global_id, const BHWC& shape) {
181   return MakeObjectRef(global_id, GetPHWC4Size(shape), AccessType::READ_WRITE);
182 }
183 
184 }  // namespace gl
185 }  // namespace gpu
186 }  // namespace tflite
187 
188 #endif  // TENSORFLOW_LITE_DELEGATES_GPU_GL_OBJECT_H_
189