|
|
@@ -1,4 +1,4 @@
|
|
|
-/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.
|
|
|
+/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
you may not use this file except in compliance with the License.
|
|
|
@@ -131,6 +131,17 @@ TfLitePadding ConvertPadding(Padding padding) {
|
|
|
return kTfLitePaddingUnknown;
|
|
|
}
|
|
|
|
|
|
+// Converts the flatbuffer mirror padding enum to what is used at runtime.
|
|
|
+TfLiteMirrorPaddingMode ConvertMirrorPadding(MirrorPadMode padding) {
|
|
|
+ switch (padding) {
|
|
|
+ case MirrorPadMode_REFLECT:
|
|
|
+ return kTfLiteMirrorPaddingReflect;
|
|
|
+ case MirrorPadMode_SYMMETRIC:
|
|
|
+ return kTfLiteMirrorPaddingSymmetric;
|
|
|
+ }
|
|
|
+ return kTfLiteMirrorPaddingUnknown;
|
|
|
+}
|
|
|
+
|
|
|
#ifndef TF_LITE_STATIC_MEMORY
|
|
|
TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
ErrorReporter* error_reporter,
|
|
|
@@ -181,6 +192,10 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
return ParseArgMin(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
|
|
|
+ case BuiltinOperator_ASSIGN_VARIABLE: {
|
|
|
+ return ParseAssignVariable(op, error_reporter, allocator, builtin_data);
|
|
|
+ }
|
|
|
+
|
|
|
case BuiltinOperator_AVERAGE_POOL_2D: {
|
|
|
return ParsePool(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
@@ -193,6 +208,10 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
return ParseBatchToSpaceNd(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
|
|
|
+ case BuiltinOperator_CALL_ONCE: {
|
|
|
+ return ParseCallOnce(op, error_reporter, allocator, builtin_data);
|
|
|
+ }
|
|
|
+
|
|
|
case BuiltinOperator_CEIL: {
|
|
|
return ParseCeil(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
@@ -325,6 +344,10 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
return ParsePool(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
|
|
|
+ case BuiltinOperator_MIRROR_PAD: {
|
|
|
+ return ParseMirrorPad(op, error_reporter, allocator, builtin_data);
|
|
|
+ }
|
|
|
+
|
|
|
case BuiltinOperator_MEAN: {
|
|
|
return ParseReducer(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
@@ -369,6 +392,10 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
return ParseQuantize(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
|
|
|
+ case BuiltinOperator_READ_VARIABLE: {
|
|
|
+ return ParseReadVariable(op, error_reporter, allocator, builtin_data);
|
|
|
+ }
|
|
|
+
|
|
|
case BuiltinOperator_REDUCE_ANY: {
|
|
|
return ParseReducer(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
@@ -486,6 +513,10 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
return ParseUnpack(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
|
|
|
+ case BuiltinOperator_VAR_HANDLE: {
|
|
|
+ return ParseVarHandle(op, error_reporter, allocator, builtin_data);
|
|
|
+ }
|
|
|
+
|
|
|
case BuiltinOperator_ZEROS_LIKE: {
|
|
|
return ParseZerosLike(op, error_reporter, allocator, builtin_data);
|
|
|
}
|
|
|
@@ -606,21 +637,8 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
case BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM: {
|
|
|
- auto params =
|
|
|
- safe_allocator.Allocate<TfLiteUnidirectionalSequenceLSTMParams>();
|
|
|
- TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
- if (const auto* seq_lstm_params =
|
|
|
- op->builtin_options_as_UnidirectionalSequenceLSTMOptions()) {
|
|
|
- params->activation =
|
|
|
- ConvertActivation(seq_lstm_params->fused_activation_function());
|
|
|
- params->cell_clip = seq_lstm_params->cell_clip();
|
|
|
- params->proj_clip = seq_lstm_params->proj_clip();
|
|
|
- params->time_major = seq_lstm_params->time_major();
|
|
|
- params->asymmetric_quantize_inputs =
|
|
|
- seq_lstm_params->asymmetric_quantize_inputs();
|
|
|
- }
|
|
|
- *builtin_data = params.release();
|
|
|
- return kTfLiteOk;
|
|
|
+ return ParseUnidirectionalSequenceLSTM(op, error_reporter, allocator,
|
|
|
+ builtin_data);
|
|
|
}
|
|
|
case BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM: {
|
|
|
auto params =
|
|
|
@@ -693,19 +711,6 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
*builtin_data = params.release();
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
- case BuiltinOperator_MIRROR_PAD: {
|
|
|
- auto params = safe_allocator.Allocate<TfLiteMirrorPaddingParams>();
|
|
|
- TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
- const auto* mirror_pad_params = op->builtin_options_as_MirrorPadOptions();
|
|
|
- if (mirror_pad_params != nullptr) {
|
|
|
- params->mode =
|
|
|
- mirror_pad_params->mode() == tflite::MirrorPadMode_REFLECT
|
|
|
- ? TfLiteMirrorPaddingMode::kTfLiteMirrorPaddingReflect
|
|
|
- : TfLiteMirrorPaddingMode::kTfLiteMirrorPaddingSymmetric;
|
|
|
- }
|
|
|
- *builtin_data = params.release();
|
|
|
- return kTfLiteOk;
|
|
|
- }
|
|
|
case BuiltinOperator_UNIQUE: {
|
|
|
auto params = safe_allocator.Allocate<TfLiteUniqueParams>();
|
|
|
TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
@@ -750,16 +755,6 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
*builtin_data = params.release();
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
- case BuiltinOperator_CALL_ONCE: {
|
|
|
- auto params = safe_allocator.Allocate<TfLiteCallOnceParams>();
|
|
|
- TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
- if (const auto* call_once_params =
|
|
|
- op->builtin_options_as_CallOnceOptions()) {
|
|
|
- params->init_subgraph_index = call_once_params->init_subgraph_index();
|
|
|
- }
|
|
|
- *builtin_data = params.release();
|
|
|
- return kTfLiteOk;
|
|
|
- }
|
|
|
case BuiltinOperator_CONV_3D:
|
|
|
case BuiltinOperator_CONV_3D_TRANSPOSE: {
|
|
|
auto params = safe_allocator.Allocate<TfLiteConv3DParams>();
|
|
|
@@ -793,17 +788,69 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
*builtin_data = params.release();
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
- case BuiltinOperator_VAR_HANDLE: {
|
|
|
- auto params = safe_allocator.Allocate<TfLiteVarHandleParams>();
|
|
|
+ case BuiltinOperator_MULTINOMIAL: {
|
|
|
+ auto params = safe_allocator.Allocate<TfLiteRandomParams>();
|
|
|
+ TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
+ if (const auto* multinomial_params =
|
|
|
+ op->builtin_options_as_RandomOptions()) {
|
|
|
+ params->seed = multinomial_params->seed();
|
|
|
+ params->seed2 = multinomial_params->seed2();
|
|
|
+ }
|
|
|
+ *builtin_data = params.release();
|
|
|
+ return kTfLiteOk;
|
|
|
+ }
|
|
|
+ case BuiltinOperator_RANDOM_STANDARD_NORMAL: {
|
|
|
+ auto params = safe_allocator.Allocate<TfLiteRandomParams>();
|
|
|
+ TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
+ if (const auto* random_std_normal_params =
|
|
|
+ op->builtin_options_as_RandomOptions()) {
|
|
|
+ params->seed = random_std_normal_params->seed();
|
|
|
+ params->seed2 = random_std_normal_params->seed2();
|
|
|
+ }
|
|
|
+ *builtin_data = params.release();
|
|
|
+ return kTfLiteOk;
|
|
|
+ }
|
|
|
+ case BuiltinOperator_BUCKETIZE: {
|
|
|
+ auto params = safe_allocator.Allocate<TfLiteBucketizeParams>();
|
|
|
+ TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
+ if (const auto* bucketize_params =
|
|
|
+ op->builtin_options_as_BucketizeOptions()) {
|
|
|
+ const flatbuffers::Vector<float>* boundaries =
|
|
|
+ bucketize_params->boundaries();
|
|
|
+ if (boundaries == nullptr) {
|
|
|
+ TF_LITE_REPORT_ERROR(
|
|
|
+ error_reporter,
|
|
|
+ "boundaries array not provided for operation 'bucketize'.\n");
|
|
|
+ return kTfLiteError;
|
|
|
+ }
|
|
|
+ params->num_boundaries = boundaries->size();
|
|
|
+ if (boundaries->data() == nullptr) {
|
|
|
+ TF_LITE_REPORT_ERROR(error_reporter,
|
|
|
+ "boundaries.data() returned nullptr for "
|
|
|
+ "operation 'bucketize'.\n");
|
|
|
+ return kTfLiteError;
|
|
|
+ }
|
|
|
+ params->boundaries = boundaries->data();
|
|
|
+ }
|
|
|
+ *builtin_data = params.release();
|
|
|
+ return kTfLiteOk;
|
|
|
+ }
|
|
|
+ case BuiltinOperator_RANDOM_UNIFORM: {
|
|
|
+ auto params = safe_allocator.Allocate<TfLiteRandomParams>();
|
|
|
+ TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
+ if (const auto* random_uniform_params =
|
|
|
+ op->builtin_options_as_RandomOptions()) {
|
|
|
+ params->seed = random_uniform_params->seed();
|
|
|
+ params->seed2 = random_uniform_params->seed2();
|
|
|
+ }
|
|
|
+ *builtin_data = params.release();
|
|
|
+ return kTfLiteOk;
|
|
|
+ }
|
|
|
+ case BuiltinOperator_GELU: {
|
|
|
+ auto params = safe_allocator.Allocate<TfLiteGeluParams>();
|
|
|
TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
- params->container = nullptr;
|
|
|
- params->shared_name = nullptr;
|
|
|
- if (const auto* var_handle_params =
|
|
|
- op->builtin_options_as_VarHandleOptions()) {
|
|
|
- if (var_handle_params->container())
|
|
|
- params->container = var_handle_params->container()->c_str();
|
|
|
- if (var_handle_params->shared_name())
|
|
|
- params->shared_name = var_handle_params->shared_name()->c_str();
|
|
|
+ if (const auto* gelu_params = op->builtin_options_as_GeluOptions()) {
|
|
|
+ params->approximate = gelu_params->approximate();
|
|
|
}
|
|
|
*builtin_data = params.release();
|
|
|
return kTfLiteOk;
|
|
|
@@ -844,8 +891,6 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
|
|
|
case BuiltinOperator_HASHTABLE_FIND:
|
|
|
case BuiltinOperator_HASHTABLE_IMPORT:
|
|
|
case BuiltinOperator_HASHTABLE_SIZE:
|
|
|
- case BuiltinOperator_READ_VARIABLE:
|
|
|
- case BuiltinOperator_ASSIGN_VARIABLE:
|
|
|
case BuiltinOperator_BROADCAST_ARGS:
|
|
|
return kTfLiteOk;
|
|
|
case BuiltinOperator_PLACEHOLDER_FOR_GREATER_OP_CODES:
|
|
|
@@ -1003,6 +1048,14 @@ TfLiteStatus ParseArgMin(const Operator* op, ErrorReporter* error_reporter,
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
|
|
|
+// We have this parse function instead of directly returning kTfLiteOk from the
|
|
|
+// switch-case in ParseOpData because this function is used as part of the
|
|
|
+// selective registration for the OpResolver implementation in micro.
|
|
|
+TfLiteStatus ParseAssignVariable(const Operator*, ErrorReporter*,
|
|
|
+ BuiltinDataAllocator*, void**) {
|
|
|
+ return kTfLiteOk;
|
|
|
+}
|
|
|
+
|
|
|
// We have this parse function instead of directly returning kTfLiteOk from the
|
|
|
// switch-case in ParseOpData because this function is used as part of the
|
|
|
// selective registration for the OpResolver implementation in micro.
|
|
|
@@ -1032,6 +1085,33 @@ TfLiteStatus ParseBatchToSpaceNd(const Operator*, ErrorReporter*,
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
|
|
|
+TfLiteStatus ParseCallOnce(const Operator* op, ErrorReporter* error_reporter,
|
|
|
+ BuiltinDataAllocator* allocator,
|
|
|
+ void** builtin_data) {
|
|
|
+ CheckParsePointerParams(op, error_reporter, allocator, builtin_data);
|
|
|
+
|
|
|
+ SafeBuiltinDataAllocator safe_allocator(allocator);
|
|
|
+ std::unique_ptr<TfLiteCallOnceParams,
|
|
|
+ SafeBuiltinDataAllocator::BuiltinDataDeleter>
|
|
|
+ params = safe_allocator.Allocate<TfLiteCallOnceParams>();
|
|
|
+ TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
+
|
|
|
+ const CallOnceOptions* schema_params =
|
|
|
+ op->builtin_options_as_CallOnceOptions();
|
|
|
+
|
|
|
+ if (schema_params != nullptr) {
|
|
|
+ params->init_subgraph_index = schema_params->init_subgraph_index();
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // TODO(b/157480169): We should either return kTfLiteError or fill in some
|
|
|
+ // reasonable defaults in the params struct. We are not doing so until we
|
|
|
+ // better undertand the ramifications of changing the legacy behavior.
|
|
|
+ }
|
|
|
+
|
|
|
+ *builtin_data = params.release();
|
|
|
+ return kTfLiteOk;
|
|
|
+}
|
|
|
+
|
|
|
// We have this parse function instead of directly returning kTfLiteOk from the
|
|
|
// switch-case in ParseOpData because this function is used as part of the
|
|
|
// selective registration for the OpResolver implementation in micro.
|
|
|
@@ -1541,6 +1621,32 @@ TfLiteStatus ParseMinimum(const Operator*, ErrorReporter*,
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
|
|
|
+TfLiteStatus ParseMirrorPad(const Operator* op, ErrorReporter* error_reporter,
|
|
|
+ BuiltinDataAllocator* allocator,
|
|
|
+ void** builtin_data) {
|
|
|
+ CheckParsePointerParams(op, error_reporter, allocator, builtin_data);
|
|
|
+
|
|
|
+ SafeBuiltinDataAllocator safe_allocator(allocator);
|
|
|
+ std::unique_ptr<TfLiteMirrorPaddingParams,
|
|
|
+ SafeBuiltinDataAllocator::BuiltinDataDeleter>
|
|
|
+ params = safe_allocator.Allocate<TfLiteMirrorPaddingParams>();
|
|
|
+ TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
+
|
|
|
+ const MirrorPadOptions* schema_params =
|
|
|
+ op->builtin_options_as_MirrorPadOptions();
|
|
|
+
|
|
|
+ if (schema_params != nullptr) {
|
|
|
+ params->mode = ConvertMirrorPadding(schema_params->mode());
|
|
|
+ } else {
|
|
|
+ // TODO(b/157480169): We should either return kTfLiteError or fill in some
|
|
|
+ // reasonable defaults in the params struct. We are not doing so until we
|
|
|
+ // better undertand the ramifications of changing the legacy behavior.
|
|
|
+ }
|
|
|
+
|
|
|
+ *builtin_data = params.release();
|
|
|
+ return kTfLiteOk;
|
|
|
+}
|
|
|
+
|
|
|
TfLiteStatus ParseMul(const Operator* op, ErrorReporter* error_reporter,
|
|
|
BuiltinDataAllocator* allocator, void** builtin_data) {
|
|
|
CheckParsePointerParams(op, error_reporter, allocator, builtin_data);
|
|
|
@@ -1676,6 +1782,14 @@ TfLiteStatus ParseQuantize(const Operator*, ErrorReporter*,
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
|
|
|
+// We have this parse function instead of directly returning kTfLiteOk from the
|
|
|
+// switch-case in ParseOpData because this function is used as part of the
|
|
|
+// selective registration for the OpResolver implementation in micro.
|
|
|
+TfLiteStatus ParseReadVariable(const Operator*, ErrorReporter*,
|
|
|
+ BuiltinDataAllocator*, void**) {
|
|
|
+ return kTfLiteOk;
|
|
|
+}
|
|
|
+
|
|
|
TfLiteStatus ParseReducer(const Operator* op, ErrorReporter* error_reporter,
|
|
|
BuiltinDataAllocator* allocator,
|
|
|
void** builtin_data) {
|
|
|
@@ -1856,6 +1970,14 @@ TfLiteStatus ParseSin(const Operator*, ErrorReporter*, BuiltinDataAllocator*,
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
|
|
|
+// We have this parse function instead of directly returning kTfLiteOk from the
|
|
|
+// switch-case in ParseOpData because this function is used as part of the
|
|
|
+// selective registration for the OpResolver implementation in micro.
|
|
|
+TfLiteStatus ParseSlice(const Operator*, ErrorReporter*, BuiltinDataAllocator*,
|
|
|
+ void**) {
|
|
|
+ return kTfLiteOk;
|
|
|
+}
|
|
|
+
|
|
|
TfLiteStatus ParseSoftmax(const Operator* op, ErrorReporter* error_reporter,
|
|
|
BuiltinDataAllocator* allocator,
|
|
|
void** builtin_data) {
|
|
|
@@ -1962,6 +2084,29 @@ TfLiteStatus ParseSplitV(const Operator* op, ErrorReporter* error_reporter,
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
|
|
|
+TfLiteStatus ParseUnidirectionalSequenceLSTM(const Operator* op,
|
|
|
+ ErrorReporter* error_reporter,
|
|
|
+ BuiltinDataAllocator* allocator,
|
|
|
+ void** builtin_data) {
|
|
|
+ CheckParsePointerParams(op, error_reporter, allocator, builtin_data);
|
|
|
+ SafeBuiltinDataAllocator safe_allocator(allocator);
|
|
|
+ auto params =
|
|
|
+ safe_allocator.Allocate<TfLiteUnidirectionalSequenceLSTMParams>();
|
|
|
+ TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
+ if (const auto* seq_lstm_params =
|
|
|
+ op->builtin_options_as_UnidirectionalSequenceLSTMOptions()) {
|
|
|
+ params->activation =
|
|
|
+ ConvertActivation(seq_lstm_params->fused_activation_function());
|
|
|
+ params->cell_clip = seq_lstm_params->cell_clip();
|
|
|
+ params->proj_clip = seq_lstm_params->proj_clip();
|
|
|
+ params->time_major = seq_lstm_params->time_major();
|
|
|
+ params->asymmetric_quantize_inputs =
|
|
|
+ seq_lstm_params->asymmetric_quantize_inputs();
|
|
|
+ }
|
|
|
+ *builtin_data = params.release();
|
|
|
+ return kTfLiteOk;
|
|
|
+}
|
|
|
+
|
|
|
TfLiteStatus ParseSqueeze(const Operator* op, ErrorReporter* error_reporter,
|
|
|
BuiltinDataAllocator* allocator,
|
|
|
void** builtin_data) {
|
|
|
@@ -2161,6 +2306,37 @@ TfLiteStatus ParseUnpack(const Operator* op, ErrorReporter* error_reporter,
|
|
|
return kTfLiteOk;
|
|
|
}
|
|
|
|
|
|
+TfLiteStatus ParseVarHandle(const Operator* op, ErrorReporter* error_reporter,
|
|
|
+ BuiltinDataAllocator* allocator,
|
|
|
+ void** builtin_data) {
|
|
|
+ CheckParsePointerParams(op, error_reporter, allocator, builtin_data);
|
|
|
+
|
|
|
+ SafeBuiltinDataAllocator safe_allocator(allocator);
|
|
|
+ std::unique_ptr<TfLiteVarHandleParams,
|
|
|
+ SafeBuiltinDataAllocator::BuiltinDataDeleter>
|
|
|
+ params = safe_allocator.Allocate<TfLiteVarHandleParams>();
|
|
|
+ TF_LITE_ENSURE(error_reporter, params != nullptr);
|
|
|
+
|
|
|
+ const VarHandleOptions* schema_params =
|
|
|
+ op->builtin_options_as_VarHandleOptions();
|
|
|
+
|
|
|
+ if (schema_params != nullptr) {
|
|
|
+ if (schema_params->container()) {
|
|
|
+ params->container = schema_params->container()->c_str();
|
|
|
+ }
|
|
|
+ if (schema_params->shared_name()) {
|
|
|
+ params->shared_name = schema_params->shared_name()->c_str();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // TODO(b/157480169): We should either return kTfLiteError or fill in some
|
|
|
+ // reasonable defaults in the params struct. We are not doing so until we
|
|
|
+ // better undertand the ramifications of changing the legacy behavior.
|
|
|
+ }
|
|
|
+
|
|
|
+ *builtin_data = params.release();
|
|
|
+ return kTfLiteOk;
|
|
|
+}
|
|
|
+
|
|
|
// We have this parse function instead of directly returning kTfLiteOk from the
|
|
|
// switch-case in ParseOpData because this function is used as part of the
|
|
|
// selective registration for the OpResolver implementation in micro.
|