xref: /aosp_15_r20/external/tensorflow/tensorflow/lite/delegates/gpu/cl/buffer.cc (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 #include "tensorflow/lite/delegates/gpu/cl/buffer.h"
17 
18 #include <string>
19 
20 #include "absl/status/status.h"
21 #include "tensorflow/lite/delegates/gpu/common/data_type.h"
22 #include "tensorflow/lite/delegates/gpu/common/status.h"
23 
24 namespace tflite {
25 namespace gpu {
26 namespace cl {
27 namespace {
28 
CreateBuffer(size_t size_in_bytes,bool gpu_read_only,const void * data,CLContext * context,Buffer * result)29 absl::Status CreateBuffer(size_t size_in_bytes, bool gpu_read_only,
30                           const void* data, CLContext* context,
31                           Buffer* result) {
32   cl_mem buffer;
33   RETURN_IF_ERROR(CreateCLBuffer(context->context(), size_in_bytes,
34                                  gpu_read_only, const_cast<void*>(data),
35                                  &buffer));
36   *result = Buffer(buffer, size_in_bytes);
37 
38   return absl::OkStatus();
39 }
40 
CreateSubBuffer(const Buffer & parent,size_t origin_in_bytes,size_t size_in_bytes,bool gpu_read_only,CLContext * context,Buffer * result)41 absl::Status CreateSubBuffer(const Buffer& parent, size_t origin_in_bytes,
42                              size_t size_in_bytes, bool gpu_read_only,
43                              CLContext* context, Buffer* result) {
44   cl_mem buffer;
45   if (parent.IsSubBuffer()) {
46     return absl::InvalidArgumentError(
47         "Cannot create a sub-buffer from a sub-buffer!");
48   }
49   RETURN_IF_ERROR(CreateCLSubBuffer(context->context(), parent.GetMemoryPtr(),
50                                     origin_in_bytes, size_in_bytes,
51                                     gpu_read_only, &buffer));
52   *result = Buffer(buffer, size_in_bytes, /*is_sub_buffer=*/true);
53 
54   return absl::OkStatus();
55 }
56 }  // namespace
57 
Buffer(cl_mem buffer,size_t size_in_bytes,bool is_sub_buffer)58 Buffer::Buffer(cl_mem buffer, size_t size_in_bytes, bool is_sub_buffer)
59     : buffer_(buffer), size_(size_in_bytes), is_sub_buffer_(is_sub_buffer) {}
60 
Buffer(Buffer && buffer)61 Buffer::Buffer(Buffer&& buffer)
62     : buffer_(buffer.buffer_),
63       size_(buffer.size_),
64       is_sub_buffer_(buffer.is_sub_buffer_) {
65   buffer.buffer_ = nullptr;
66   buffer.size_ = 0;
67   buffer.is_sub_buffer_ = false;
68 }
69 
operator =(Buffer && buffer)70 Buffer& Buffer::operator=(Buffer&& buffer) {
71   if (this != &buffer) {
72     Release();
73     std::swap(size_, buffer.size_);
74     std::swap(buffer_, buffer.buffer_);
75     std::swap(is_sub_buffer_, buffer.is_sub_buffer_);
76   }
77   return *this;
78 }
79 
Release()80 void Buffer::Release() {
81   if (buffer_) {
82     clReleaseMemObject(buffer_);
83     buffer_ = nullptr;
84     size_ = 0;
85     is_sub_buffer_ = false;
86   }
87 }
88 
GetGPUResources(const GPUObjectDescriptor * obj_ptr,GPUResourcesWithValue * resources) const89 absl::Status Buffer::GetGPUResources(const GPUObjectDescriptor* obj_ptr,
90                                      GPUResourcesWithValue* resources) const {
91   const auto* buffer_desc = dynamic_cast<const BufferDescriptor*>(obj_ptr);
92   if (!buffer_desc) {
93     return absl::InvalidArgumentError("Expected BufferDescriptor on input.");
94   }
95 
96   resources->buffers.push_back({"buffer", buffer_});
97   return absl::OkStatus();
98 }
99 
CreateFromBufferDescriptor(const BufferDescriptor & desc,CLContext * context)100 absl::Status Buffer::CreateFromBufferDescriptor(const BufferDescriptor& desc,
101                                                 CLContext* context) {
102   bool read_only = desc.memory_type == MemoryType::CONSTANT;
103   uint8_t* data_ptr = desc.data.empty()
104                           ? nullptr
105                           : const_cast<unsigned char*>(desc.data.data());
106   size_ = desc.size;
107   return CreateCLBuffer(context->context(), desc.size, read_only, data_ptr,
108                         &buffer_);
109 }
110 
CreateReadOnlyBuffer(size_t size_in_bytes,CLContext * context,Buffer * result)111 absl::Status CreateReadOnlyBuffer(size_t size_in_bytes, CLContext* context,
112                                   Buffer* result) {
113   return CreateBuffer(size_in_bytes, true, nullptr, context, result);
114 }
115 
CreateReadOnlyBuffer(size_t size_in_bytes,const void * data,CLContext * context,Buffer * result)116 absl::Status CreateReadOnlyBuffer(size_t size_in_bytes, const void* data,
117                                   CLContext* context, Buffer* result) {
118   return CreateBuffer(size_in_bytes, true, data, context, result);
119 }
120 
CreateReadWriteBuffer(size_t size_in_bytes,CLContext * context,Buffer * result)121 absl::Status CreateReadWriteBuffer(size_t size_in_bytes, CLContext* context,
122                                    Buffer* result) {
123   return CreateBuffer(size_in_bytes, false, nullptr, context, result);
124 }
125 
CreateReadWriteSubBuffer(const Buffer & parent,size_t origin_in_bytes,size_t size_in_bytes,CLContext * context,Buffer * result)126 absl::Status CreateReadWriteSubBuffer(const Buffer& parent,
127                                       size_t origin_in_bytes,
128                                       size_t size_in_bytes, CLContext* context,
129                                       Buffer* result) {
130   return CreateSubBuffer(parent, origin_in_bytes, size_in_bytes,
131                          /*gpu_read_only=*/false, context, result);
132 }
133 
134 }  // namespace cl
135 }  // namespace gpu
136 }  // namespace tflite
137