aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/contrib/lite/interpreter.cc
diff options
context:
space:
mode:
authorGravatar Gunhan Gulsoy <gunan@google.com>2018-03-08 00:32:17 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-03-08 00:36:30 -0800
commite52f916b87557d6b6d28f27f570462debb5ee262 (patch)
tree79657f4d3f9c6978e008b7125ffaf07d6bb7f3ea /tensorflow/contrib/lite/interpreter.cc
parent6ff54600831b0af86855b492da938c0ba0e4d910 (diff)
Automated g4 rollback of changelist 188263046
PiperOrigin-RevId: 188293315
Diffstat (limited to 'tensorflow/contrib/lite/interpreter.cc')
-rw-r--r--tensorflow/contrib/lite/interpreter.cc154
1 files changed, 32 insertions, 122 deletions
diff --git a/tensorflow/contrib/lite/interpreter.cc b/tensorflow/contrib/lite/interpreter.cc
index 733c47852e..0f5e17f0de 100644
--- a/tensorflow/contrib/lite/interpreter.cc
+++ b/tensorflow/contrib/lite/interpreter.cc
@@ -26,7 +26,6 @@ limitations under the License.
#include "tensorflow/contrib/lite/memory_planner.h"
#include "tensorflow/contrib/lite/nnapi_delegate.h"
#include "tensorflow/contrib/lite/schema/schema_generated.h"
-#include "tensorflow/contrib/lite/util.h"
namespace tflite {
@@ -97,57 +96,19 @@ Interpreter::~Interpreter() {
}
for (int i = 0; i < context_.tensors_size; i++) {
- TfLiteTensor* tensor = &context_.tensors[i];
- if (tensor->delegate_buffer_handle != kTfLiteNullBufferHandle) {
- tensor->delegate->FreeBufferHandle(tensor->delegate,
- &tensor->delegate_buffer_handle);
- }
- TfLiteTensorFree(tensor);
+ TfLiteTensorFree(&context_.tensors[i]);
}
}
TfLiteStatus Interpreter::ReplaceSubgraphsWithDelegateKernels(
TfLiteContext* context, TfLiteRegistration registration,
- const TfLiteIntArray* nodes_to_replace, TfLiteDelegate* delegate) {
+ const TfLiteIntArray* nodes_to_replace) {
return static_cast<Interpreter*>(context->impl_)
- ->ReplaceSubgraphsWithDelegateKernels(registration, nodes_to_replace,
- delegate);
-}
-
-namespace {
-
-// This function allocates a continuous memory space that contains a
-// TfLiteDelegateParams followed by a TfLiteIntArray. The pointer will be
-// deallocated by C `free` function later.
-TfLiteDelegateParams* CreateDelegateParams(
- TfLiteDelegate* delegate, const std::vector<int>& nodes_to_replace) {
- int nodes_to_replace_size_in_bytes =
- TfLiteIntArrayGetSizeInBytes(nodes_to_replace.size());
- void* allocation =
- malloc(sizeof(TfLiteDelegateParams) + nodes_to_replace_size_in_bytes);
- TfLiteDelegateParams* params =
- reinterpret_cast<TfLiteDelegateParams*>(allocation);
- TfLiteIntArray* nodes_to_replace_arr = reinterpret_cast<TfLiteIntArray*>(
- static_cast<char*>(allocation) + sizeof(TfLiteDelegateParams));
-
- nodes_to_replace_arr->size = nodes_to_replace.size();
- for (int i = 0; i < nodes_to_replace.size(); ++i) {
- nodes_to_replace_arr->data[i] = nodes_to_replace[i];
- }
-
- params->delegate = delegate;
- params->nodes_to_replace = nodes_to_replace_arr;
- return params;
+ ->ReplaceSubgraphsWithDelegateKernels(registration, nodes_to_replace);
}
-} // Anonymous namespace
-
TfLiteStatus Interpreter::ReplaceSubgraphsWithDelegateKernels(
- TfLiteRegistration registration, const TfLiteIntArray* nodes_to_replace,
- TfLiteDelegate* delegate) {
- // Annotate the registration as DELEGATE op.
- registration.builtin_code = BuiltinOperator_DELEGATE;
-
+ TfLiteRegistration registration, const TfLiteIntArray* nodes_to_replace) {
// Annotate the registration as DELEGATE op.
registration.builtin_code = BuiltinOperator_DELEGATE;
@@ -159,38 +120,30 @@ TfLiteStatus Interpreter::ReplaceSubgraphsWithDelegateKernels(
execution_plan_.clear();
for (auto& subgraph : subgraphs) {
+ // Turn subgraph.nodes into a TfLiteIntArray compatible data structure.
+ // TODO(aselle): Avoid this copy by constructing subgraph.nodes that way
+ // in the first place
+ subgraph.nodes.insert(subgraph.nodes.begin(),
+ static_cast<int>(subgraph.nodes.size()));
// Subgraphs calimed by the delegate should have a "macro" op created, the
// other subgraphs (kTfNonPartition) just have their nodes added back to
// the execution plan.
switch (subgraph.type) {
case Subgraph::kTfNonPartition:
- for (auto it = subgraph.nodes.begin(); it != subgraph.nodes.end();
+ for (auto it = subgraph.nodes.begin() + 1; it != subgraph.nodes.end();
++it) {
execution_plan_.push_back(*it);
}
break;
case Subgraph::kTfPartition: {
+ void* builtin_data = nullptr;
int node_index;
-
- TfLiteDelegateParams* params =
- CreateDelegateParams(delegate, subgraph.nodes);
- AddNodeWithParameters(subgraph.input_tensors, subgraph.output_tensors,
- nullptr, 0, params, &registration, &node_index);
-
- // Initialize the output tensors's delegate-related fields.
- for (int tensor_index : subgraph.output_tensors) {
- TfLiteTensor* tensor = &tensors_[tensor_index];
- TF_LITE_ENSURE_EQ(&context_, tensor->delegate, nullptr);
- TF_LITE_ENSURE_EQ(&context_, tensor->delegate_buffer_handle,
- kTfLiteNullBufferHandle);
- // delegate_buffer_handle will be filled in delegate's `Prepare`
- // function.
- tensor->delegate = delegate;
- }
-
- // Associate the node with the delegate.
- TfLiteNode* node = &nodes_and_registration_[node_index].first;
- node->delegate = delegate;
+ // Create a node that represents computation of this subgraph.
+ AddNodeWithParameters(
+ subgraph.input_tensors, subgraph.output_tensors,
+ reinterpret_cast<const char*>(subgraph.nodes.data()),
+ subgraph.nodes.size() * sizeof(subgraph.nodes[0]), builtin_data,
+ &registration, &node_index);
} break;
case Subgraph::kTfUnexplored:
return kTfLiteError;
@@ -280,6 +233,14 @@ TfLiteStatus Interpreter::BytesRequired(TfLiteType type, const int* dims,
return kTfLiteOk;
}
+namespace {
+TfLiteIntArray* convertVectorToTfLiteIntArray(const std::vector<int>& x) {
+ TfLiteIntArray* lite = TfLiteIntArrayCreate(x.size());
+ for (size_t i = 0; i < x.size(); i++) lite->data[i] = x[i];
+ return lite;
+}
+} // namespace
+
TfLiteStatus Interpreter::AllocateTensors() {
next_execution_plan_index_to_prepare_ = 0;
if (memory_planner_) {
@@ -314,6 +275,7 @@ TfLiteStatus Interpreter::AddNodeWithParameters(
int new_node_index = nodes_and_registration_.size();
if (node_index) *node_index = new_node_index;
nodes_and_registration_.resize(nodes_and_registration_.size() + 1);
+
auto& node_and_reg = nodes_and_registration_.back();
TfLiteNode& node = node_and_reg.first;
if (node.inputs) TfLiteIntArrayFree(node.inputs);
@@ -323,8 +285,8 @@ TfLiteStatus Interpreter::AddNodeWithParameters(
// NOTE, here we are not using move semantics yet, since our internal
// representation isn't std::vector, but in the future we would like to avoid
// copies, so we want the interface to take r-value references now.
- node.inputs = ConvertVectorToTfLiteIntArray(inputs);
- node.outputs = ConvertVectorToTfLiteIntArray(outputs);
+ node.inputs = convertVectorToTfLiteIntArray(inputs);
+ node.outputs = convertVectorToTfLiteIntArray(outputs);
node.temporaries = TfLiteIntArrayCreate(0);
if (init_data) {
node.user_data = OpInit(*registration, init_data, init_data_size);
@@ -337,7 +299,6 @@ TfLiteStatus Interpreter::AddNodeWithParameters(
node.builtin_data = builtin_data_deleter.release();
// TODO(ycling): Filling `custom_initial_data` and `custom_initial_data_size`
// properly for nodes generated by ReplaceSubgraphsWithDelegateKernels.
-
if (registration->builtin_code == BuiltinOperator_CUSTOM) {
// When it's a CUSTOM op, the `custom_options` field in the Flatbuffer
// `Operator` table is passed in.
@@ -348,7 +309,6 @@ TfLiteStatus Interpreter::AddNodeWithParameters(
node.custom_initial_data_size = 0;
}
- node.delegate = nullptr;
node_and_reg.second = *registration;
execution_plan_.push_back(new_node_index);
return kTfLiteOk;
@@ -362,7 +322,7 @@ TfLiteStatus Interpreter::ResizeInputTensor(int tensor_index,
TF_LITE_ENSURE(&context_,
tensor_index < context_.tensors_size && tensor_index >= 0);
invokable_ = false;
- TfLiteIntArray* dims_lite = ConvertVectorToTfLiteIntArray(dims);
+ TfLiteIntArray* dims_lite = convertVectorToTfLiteIntArray(dims);
return ResizeTensorImpl(&context_.tensors[tensor_index], dims_lite);
}
@@ -464,29 +424,11 @@ TfLiteStatus Interpreter::Invoke() {
TfLiteNode& node = nodes_and_registration_[node_index].first;
const TfLiteRegistration& registration =
nodes_and_registration_[node_index].second;
-
- // TODO(ycling): This is an extra loop through inputs to check if the data
- // need to be copied from Delegate buffer to raw memory, which is often not
- // needed. We may want to cache this in prepare to know if this needs to be
- // done for a node or not.
- for (int i = 0; i < node.inputs->size; ++i) {
- int tensor_index = node.inputs->data[i];
- if (tensor_index == kOptionalTensor) {
- continue;
- }
- TfLiteTensor* tensor = &tensors_[tensor_index];
- if (tensor->delegate && tensor->delegate != node.delegate &&
- tensor->data_is_stale) {
- EnsureTensorDataIsReadable(tensor_index);
- }
- }
-
EnsureTensorsVectorCapacity();
if (OpInvoke(registration, &node) == kTfLiteError) {
status = kTfLiteError;
}
}
-
return status;
}
@@ -522,7 +464,6 @@ TfLiteStatus Interpreter::AddTensors(int tensors_to_add,
tensors_.resize(tensors_.size() + tensors_to_add);
for (int i = base_index; i < tensors_.size(); i++) {
memset(&tensors_[i], 0, sizeof(tensors_[i]));
- tensors_[i].delegate_buffer_handle = kTfLiteNullBufferHandle;
}
context_.tensors = tensors_.data();
context_.tensors_size = tensors_.size();
@@ -570,7 +511,7 @@ TfLiteStatus Interpreter::SetTensorParametersReadOnly(
TF_LITE_ENSURE_EQ(&context_, required_bytes, bytes);
}
invokable_ = false;
- TfLiteTensorReset(type, name, ConvertVectorToTfLiteIntArray(dims),
+ TfLiteTensorReset(type, name, convertVectorToTfLiteIntArray(dims),
quantization, const_cast<char*>(buffer), bytes,
kTfLiteMmapRo, allocation, &context_.tensors[tensor_index]);
return kTfLiteOk;
@@ -595,7 +536,7 @@ TfLiteStatus Interpreter::SetTensorParametersReadWrite(
TF_LITE_ENSURE_OK(&context_, BytesRequired(type, dims.data(), dims.size(),
&required_bytes));
}
- TfLiteTensorReset(type, name, ConvertVectorToTfLiteIntArray(dims),
+ TfLiteTensorReset(type, name, convertVectorToTfLiteIntArray(dims),
quantization,
/*buffer=*/nullptr, required_bytes,
type == kTfLiteString ? kTfLiteDynamic : kTfLiteArenaRw,
@@ -672,7 +613,7 @@ TfLiteStatus Interpreter::ModifyGraphWithDelegate(TfLiteDelegate* delegate) {
ReplaceSubgraphsWithDelegateKernels;
context_.GetExecutionPlan = GetExecutionPlan;
- TfLiteStatus status = delegate->Prepare(&context_, delegate);
+ TfLiteStatus status = delegate->Prepare(&context_, delegate->data_);
// Remove additional context info.
context_.GetNodeAndRegistration = nullptr;
context_.ReplaceSubgraphsWithDelegateKernels = nullptr;
@@ -680,35 +621,4 @@ TfLiteStatus Interpreter::ModifyGraphWithDelegate(TfLiteDelegate* delegate) {
return status;
}
-TfLiteStatus Interpreter::SetDelegateBufferHandle(
- int tensor_index, TfLiteDelegateBufferHandle delegate_buffer_handle,
- TfLiteDelegate* delegate) {
- TF_LITE_ENSURE(&context_, tensor_index < tensors_size());
- TfLiteTensor* tensor = &tensors_[tensor_index];
-
- TF_LITE_ENSURE(&context_,
- tensor->delegate == nullptr || tensor->delegate == delegate);
- tensor->delegate = delegate;
- if (tensor->delegate_buffer_handle != kTfLiteNullBufferHandle) {
- TF_LITE_ENSURE(&context_, tensor->delegate->FreeBufferHandle != nullptr);
- tensor->delegate->FreeBufferHandle(tensor->delegate,
- &tensor->delegate_buffer_handle);
- }
- tensor->delegate_buffer_handle = delegate_buffer_handle;
-
- return kTfLiteOk;
-}
-
-TfLiteStatus Interpreter::GetDelegateBufferHandle(
- int tensor_index, TfLiteDelegateBufferHandle* delegate_buffer_handle,
- TfLiteDelegate** delegate) {
- TF_LITE_ENSURE(&context_, tensor_index < tensors_size());
- TfLiteTensor* tensor = &tensors_[tensor_index];
-
- *delegate = tensor->delegate;
- *delegate_buffer_handle = tensor->delegate_buffer_handle;
-
- return kTfLiteOk;
-}
-
} // namespace tflite