• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "tensorflow/lite/interpreter.h"
17 
18 #include <stddef.h>
19 #include <stdlib.h>
20 
21 #include <cstdint>
22 #include <functional>
23 #include <memory>
24 #include <utility>
25 #include <vector>
26 
27 #include "ruy/denormal.h"  // from @ruy
28 #include "tensorflow/lite/allocation.h"
29 #include "tensorflow/lite/core/api/error_reporter.h"
30 #include "tensorflow/lite/core/api/profiler.h"
31 #include "tensorflow/lite/core/subgraph.h"
32 #include "tensorflow/lite/external_cpu_backend_context.h"
33 #include "tensorflow/lite/minimal_logging.h"
34 #include "tensorflow/lite/stderr_reporter.h"
35 #include "tensorflow/lite/util.h"
36 
37 namespace tflite {
38 
SetCustomAllocationForTensor(int tensor_index,const TfLiteCustomAllocation & allocation,int64_t flags)39 TfLiteStatus Interpreter::SetCustomAllocationForTensor(
40     int tensor_index, const TfLiteCustomAllocation& allocation, int64_t flags) {
41   return primary_subgraph().SetCustomAllocationForTensor(tensor_index,
42                                                          allocation, flags);
43 }
44 
ReleaseNonPersistentMemory()45 TfLiteStatus Interpreter::ReleaseNonPersistentMemory() {
46   // TODO(b/138790287): We could do this for all subgraphs whose tensors have
47   // been allocated. However, AllocateTensors() relies on Control Flow ops to
48   // allocate tensors on 'children' subgraphs. Revisit this if required.
49   return primary_subgraph().ReleaseNonPersistentMemory();
50 }
51 
ResetVariableTensors()52 TfLiteStatus Interpreter::ResetVariableTensors() {
53   for (auto& subgraph : subgraphs_) {
54     TF_LITE_ENSURE_STATUS(subgraph->ResetVariableTensors());
55   }
56   return kTfLiteOk;
57 }
58 
SetAllowFp16PrecisionForFp32(bool allow)59 void Interpreter::SetAllowFp16PrecisionForFp32(bool allow) {
60   for (auto& subgraph : subgraphs_) {
61     subgraph->context()->allow_fp32_relax_to_fp16 = allow;
62   }
63 }
64 
65 // TODO(b/121264966): Subgraphs added after cancellation is set will not get the
66 // cancellation function added to their context.
SetCancellationFunction(void * data,bool (* check_cancelled_func)(void *))67 void Interpreter::SetCancellationFunction(void* data,
68                                           bool (*check_cancelled_func)(void*)) {
69   for (auto& subgraph : subgraphs_) {
70     subgraph->SetCancellationFunction(data, check_cancelled_func);
71   }
72 }
73 
IsCancelled()74 bool Interpreter::IsCancelled() { return primary_subgraph().IsCancelled(); }
75 
ModifyGraphWithDelegate(TfLiteDelegate * delegate)76 TfLiteStatus Interpreter::ModifyGraphWithDelegate(TfLiteDelegate* delegate) {
77   TfLiteStatus status = kTfLiteOk;
78   for (auto& subgraph : subgraphs_) {
79     if (IsValidationSubgraph(subgraph->GetName().c_str())) {
80       continue;
81     }
82     status = subgraph->ModifyGraphWithDelegate(delegate);
83     if (status != kTfLiteOk) {
84       break;
85     }
86   }
87   // Delegate-specific errors can be recovered from by restoring Interpreter to
88   // its original state.
89   if (status == kTfLiteDelegateError) {
90     TF_LITE_ENSURE_STATUS(RemoveAllDelegates());
91   }
92   return status;
93 }
94 
RemoveAllDelegates()95 TfLiteStatus Interpreter::RemoveAllDelegates() {
96   for (auto& subgraph : subgraphs_) {
97     TF_LITE_ENSURE_STATUS(subgraph->RemoveAllDelegates());
98   }
99   return kTfLiteOk;
100 }
101 
HasDelegates()102 bool Interpreter::HasDelegates() { return primary_subgraph().HasDelegates(); }
103 
SetBufferHandle(int tensor_index,TfLiteBufferHandle buffer_handle,TfLiteDelegate * delegate)104 TfLiteStatus Interpreter::SetBufferHandle(int tensor_index,
105                                           TfLiteBufferHandle buffer_handle,
106                                           TfLiteDelegate* delegate) {
107   TF_LITE_ENSURE(context_, tensor_index < tensors_size());
108   TfLiteTensor* tensor = primary_subgraph().tensor(tensor_index);
109 
110   TF_LITE_ENSURE(context_,
111                  tensor->delegate == nullptr || tensor->delegate == delegate);
112   tensor->delegate = delegate;
113   if (tensor->buffer_handle != kTfLiteNullBufferHandle) {
114     TF_LITE_ENSURE(context_, tensor->delegate->FreeBufferHandle != nullptr);
115     tensor->delegate->FreeBufferHandle(context_, tensor->delegate,
116                                        &tensor->buffer_handle);
117   }
118   tensor->buffer_handle = buffer_handle;
119 
120   return kTfLiteOk;
121 }
122 
GetBufferHandle(int tensor_index,TfLiteBufferHandle * buffer_handle,TfLiteDelegate ** delegate)123 TfLiteStatus Interpreter::GetBufferHandle(int tensor_index,
124                                           TfLiteBufferHandle* buffer_handle,
125                                           TfLiteDelegate** delegate) {
126   TF_LITE_ENSURE(context_, tensor_index < tensors_size());
127   TfLiteTensor* tensor = primary_subgraph().tensor(tensor_index);
128 
129   *delegate = tensor->delegate;
130   *buffer_handle = tensor->buffer_handle;
131 
132   return kTfLiteOk;
133 }
134 
SetProfiler(Profiler * profiler)135 void Interpreter::SetProfiler(Profiler* profiler) {
136   // Release resources occupied by owned_profiler_ which is replaced by
137   // caller-owned profiler.
138   owned_profiler_.reset(nullptr);
139   installed_profiler_ = profiler;
140   SetSubgraphProfiler();
141 }
142 
SetProfiler(std::unique_ptr<Profiler> profiler)143 void Interpreter::SetProfiler(std::unique_ptr<Profiler> profiler) {
144   owned_profiler_ = std::move(profiler);
145   installed_profiler_ = owned_profiler_.get();
146   SetSubgraphProfiler();
147 }
148 
SetSubgraphProfiler()149 void Interpreter::SetSubgraphProfiler() {
150   for (int subgraph_index = 0; subgraph_index < subgraphs_.size();
151        ++subgraph_index) {
152     subgraphs_[subgraph_index]->SetProfiler(installed_profiler_,
153                                             subgraph_index);
154   }
155 }
156 
GetProfiler()157 Profiler* Interpreter::GetProfiler() {
158   return primary_subgraph().GetProfiler();
159 }
160 
PreserveAllTensorsExperimental()161 TfLiteStatus Interpreter::PreserveAllTensorsExperimental() {
162   for (int subgraph_index = 0; subgraph_index < subgraphs_.size();
163        ++subgraph_index) {
164     TF_LITE_ENSURE_STATUS(
165         subgraphs_[subgraph_index]->PreserveAllTensorsExperimental());
166   }
167   return kTfLiteOk;
168 }
169 
170 }  // namespace tflite
171