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