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 <stddef.h>
17 #include <stdlib.h>
18
19 #include <cstdint>
20 #include <functional>
21 #include <memory>
22 #include <utility>
23 #include <vector>
24
25 #include "ruy/denormal.h" // from @ruy
26 #include "tensorflow/lite/allocation.h"
27 #include "tensorflow/lite/core/api/error_reporter.h"
28 #include "tensorflow/lite/core/api/profiler.h"
29 #include "tensorflow/lite/core/subgraph.h"
30 #include "tensorflow/lite/external_cpu_backend_context.h"
31 #include "tensorflow/lite/interpreter.h"
32 #include "tensorflow/lite/minimal_logging.h"
33 #include "tensorflow/lite/stderr_reporter.h"
34 #include "tensorflow/lite/util.h"
35
36 namespace tflite {
37
SetCustomAllocationForTensor(int tensor_index,const TfLiteCustomAllocation & allocation,int64_t flags)38 TfLiteStatus Interpreter::SetCustomAllocationForTensor(
39 int tensor_index, const TfLiteCustomAllocation& allocation, int64_t flags) {
40 return primary_subgraph().SetCustomAllocationForTensor(tensor_index,
41 allocation, flags);
42 }
43
ReleaseNonPersistentMemory()44 TfLiteStatus Interpreter::ReleaseNonPersistentMemory() {
45 // TODO(b/138790287): We could do this for all subgraphs whose tensors have
46 // been allocated. However, AllocateTensors() relies on Control Flow ops to
47 // allocate tensors on 'children' subgraphs. Revisit this if required.
48 return primary_subgraph().ReleaseNonPersistentMemory();
49 }
50
ResetVariableTensors()51 TfLiteStatus Interpreter::ResetVariableTensors() {
52 for (auto& subgraph : subgraphs_) {
53 TF_LITE_ENSURE_STATUS(subgraph->ResetVariableTensors());
54 }
55 return kTfLiteOk;
56 }
57
SetAllowFp16PrecisionForFp32(bool allow)58 void Interpreter::SetAllowFp16PrecisionForFp32(bool allow) {
59 for (auto& subgraph : subgraphs_) {
60 subgraph->context()->allow_fp32_relax_to_fp16 = allow;
61 }
62 }
63
64 // TODO(b/121264966): Subgraphs added after cancellation is set will not get the
65 // cancellation function added to their context.
SetCancellationFunction(void * data,bool (* check_cancelled_func)(void *))66 void Interpreter::SetCancellationFunction(void* data,
67 bool (*check_cancelled_func)(void*)) {
68 for (auto& subgraph : subgraphs_) {
69 subgraph->SetCancellationFunction(data, check_cancelled_func);
70 }
71 }
72
IsCancelled()73 bool Interpreter::IsCancelled() { return primary_subgraph().IsCancelled(); }
74
ModifyGraphWithDelegate(TfLiteDelegate * delegate)75 TfLiteStatus Interpreter::ModifyGraphWithDelegate(TfLiteDelegate* delegate) {
76 return ModifyGraphWithDelegateImpl(delegate);
77 }
78
HasDelegates()79 bool Interpreter::HasDelegates() { return primary_subgraph().HasDelegates(); }
80
SetBufferHandle(int tensor_index,TfLiteBufferHandle buffer_handle,TfLiteDelegate * delegate)81 TfLiteStatus Interpreter::SetBufferHandle(int tensor_index,
82 TfLiteBufferHandle buffer_handle,
83 TfLiteDelegate* delegate) {
84 TF_LITE_ENSURE(context_, tensor_index < tensors_size());
85 TfLiteTensor* tensor = primary_subgraph().tensor(tensor_index);
86
87 TF_LITE_ENSURE(context_,
88 tensor->delegate == nullptr || tensor->delegate == delegate);
89 tensor->delegate = delegate;
90 if (tensor->buffer_handle != kTfLiteNullBufferHandle) {
91 TF_LITE_ENSURE(context_, tensor->delegate->FreeBufferHandle != nullptr);
92 tensor->delegate->FreeBufferHandle(context_, tensor->delegate,
93 &tensor->buffer_handle);
94 }
95 tensor->buffer_handle = buffer_handle;
96
97 return kTfLiteOk;
98 }
99
GetBufferHandle(int tensor_index,TfLiteBufferHandle * buffer_handle,TfLiteDelegate ** delegate)100 TfLiteStatus Interpreter::GetBufferHandle(int tensor_index,
101 TfLiteBufferHandle* buffer_handle,
102 TfLiteDelegate** delegate) {
103 TF_LITE_ENSURE(context_, tensor_index < tensors_size());
104 TfLiteTensor* tensor = primary_subgraph().tensor(tensor_index);
105
106 *delegate = tensor->delegate;
107 *buffer_handle = tensor->buffer_handle;
108
109 return kTfLiteOk;
110 }
111
SetProfiler(Profiler * profiler)112 void Interpreter::SetProfiler(Profiler* profiler) {
113 if (profiler == nullptr) {
114 root_profiler_ = nullptr;
115 return;
116 }
117 if (root_profiler_ != nullptr) root_profiler_->RemoveChildProfilers();
118 AddProfiler(profiler);
119 }
120
SetProfiler(std::unique_ptr<Profiler> profiler)121 void Interpreter::SetProfiler(std::unique_ptr<Profiler> profiler) {
122 SetProfilerImpl(std::move(profiler));
123 }
124
AddProfiler(Profiler * profiler)125 void Interpreter::AddProfiler(Profiler* profiler) {
126 if (profiler == nullptr) return;
127 if (root_profiler_ == nullptr) {
128 root_profiler_ = std::make_unique<profiling::RootProfiler>();
129 }
130 root_profiler_->AddProfiler(profiler);
131 SetSubgraphProfiler();
132 }
133
GetProfiler()134 Profiler* Interpreter::GetProfiler() {
135 return primary_subgraph().GetProfiler();
136 }
137
ApplyOptions(InterpreterOptions * options)138 TfLiteStatus Interpreter::ApplyOptions(InterpreterOptions* options) {
139 return ApplyOptionsImpl(options);
140 }
141
GetSignatureRunner(const char * signature_key)142 SignatureRunner* Interpreter::GetSignatureRunner(const char* signature_key) {
143 auto iter = signature_runner_map_.find(signature_key);
144 if (iter != signature_runner_map_.end()) {
145 return &(iter->second);
146 }
147
148 // Default delegates are applied once for all subgraphs. Only returns error
149 // when the status is kTfLiteError. For other statuses, it will fall back to
150 // the default implementation.
151 if (ApplyLazyDelegateProviders() == kTfLiteError) {
152 return nullptr;
153 }
154
155 for (const auto& signature : signature_defs_) {
156 if (signature.signature_key == signature_key) {
157 auto status = signature_runner_map_.insert(
158 {signature_key,
159 SignatureRunner(&signature, subgraph(signature.subgraph_index))});
160 return &(status.first->second);
161 }
162 }
163 return nullptr;
164 }
165
166 } // namespace tflite
167