xref: /aosp_15_r20/external/tensorflow/tensorflow/lite/experimental/resource/resource_variable.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/experimental/resource/resource_variable.h"
17 
18 #include <cstdlib>
19 #include <cstring>
20 #include <map>
21 #include <memory>
22 
23 #include "tensorflow/lite/c/c_api_types.h"
24 
25 namespace tflite {
26 namespace resource {
27 
ResourceVariable()28 ResourceVariable::ResourceVariable() {
29   memset(&tensor_, 0, sizeof(TfLiteTensor));
30 }
31 
ResourceVariable(ResourceVariable && other)32 ResourceVariable::ResourceVariable(ResourceVariable&& other) {
33   tensor_ = other.tensor_;
34   is_initialized_ = other.is_initialized_;
35 
36   memset(&other.tensor_, 0, sizeof(TfLiteTensor));
37   other.is_initialized_ = false;
38 }
39 
~ResourceVariable()40 ResourceVariable::~ResourceVariable() {
41   if (is_initialized_) {
42     free(tensor_.data.raw);
43     if (tensor_.dims) {
44       TfLiteIntArrayFree(tensor_.dims);
45     }
46   }
47 }
48 
AssignFrom(const TfLiteTensor * tensor)49 TfLiteStatus ResourceVariable::AssignFrom(const TfLiteTensor* tensor) {
50   // Save the old allocated resources and attributes that we might use.
51   char* old_raw = tensor_.data.raw;
52   size_t old_bytes = tensor_.bytes;
53   TfLiteIntArray* old_dims = tensor_.dims;
54 
55   // Copy primitive parameters.
56   memset(&tensor_, 0, sizeof(tensor_));
57   tensor_.name = "ResourceVariable";
58   tensor_.allocation_type = kTfLiteDynamic;
59   tensor_.type = tensor->type;
60   tensor_.params = tensor->params;
61   tensor_.quantization = tensor->quantization;
62 
63   // Copy old shape if possible otherwise create a new one.
64   if (TfLiteIntArrayEqual(old_dims, tensor->dims)) {
65     tensor_.dims = old_dims;
66   } else {
67     TfLiteIntArrayFree(old_dims);
68     tensor_.dims = TfLiteIntArrayCopy(tensor->dims);
69   }
70 
71   // Reuse the same buffer if possible otherwise allocate a new one.
72   tensor_.data.raw = old_raw;
73   if (old_bytes != tensor->bytes) {
74     TfLiteTensorRealloc(tensor->bytes, &tensor_);
75   } else {
76     tensor_.bytes = old_bytes;
77   }
78 
79   memcpy(tensor_.data.raw, tensor->data.raw, tensor_.bytes);
80   is_initialized_ = true;
81 
82   return kTfLiteOk;
83 }
84 
CreateResourceVariableIfNotAvailable(ResourceMap * resources,int resource_id)85 void CreateResourceVariableIfNotAvailable(ResourceMap* resources,
86                                           int resource_id) {
87   if (resources->count(resource_id) != 0) {
88     return;
89   }
90   resources->emplace(resource_id, std::make_unique<ResourceVariable>());
91 }
92 
GetResourceVariable(ResourceMap * resources,int resource_id)93 ResourceVariable* GetResourceVariable(ResourceMap* resources, int resource_id) {
94   auto it = resources->find(resource_id);
95   if (it != resources->end()) {
96     return static_cast<ResourceVariable*>(it->second.get());
97   }
98   return nullptr;
99 }
100 
IsBuiltinResource(const TfLiteTensor * tensor)101 bool IsBuiltinResource(const TfLiteTensor* tensor) {
102   return tensor && tensor->type == kTfLiteResource &&
103          tensor->delegate == nullptr;
104 }
105 
106 }  // namespace resource
107 }  // namespace tflite
108