From 4b6a394e951090e8ffb3770badfef3ab0b293d23 Mon Sep 17 00:00:00 2001 From: Elena Zhelezina Date: Thu, 9 Jul 2020 17:21:24 +0100 Subject: [PATCH 1/2] Added GATHER operator for 16x8. Implementation, tests, versioning are added. Change-Id: I87ffb816994b07770419979e45ce14a73b569bf9 --- .../delegates/nnapi/acceleration_test_list.cc | 1 + tensorflow/lite/kernels/gather.cc | 5 +++++ tensorflow/lite/kernels/gather_test.cc | 18 ++++++++++++++++++ tensorflow/lite/kernels/register.cc | 2 +- tensorflow/lite/toco/tflite/op_version.cc | 1 + .../lite/tools/optimize/operator_property.cc | 1 - tensorflow/lite/tools/versioning/op_version.cc | 3 +++ .../lite/tools/versioning/runtime_version.cc | 1 + 8 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tensorflow/lite/delegates/nnapi/acceleration_test_list.cc b/tensorflow/lite/delegates/nnapi/acceleration_test_list.cc index 56c1895ca4e..e08cdb763c0 100644 --- a/tensorflow/lite/delegates/nnapi/acceleration_test_list.cc +++ b/tensorflow/lite/delegates/nnapi/acceleration_test_list.cc @@ -214,6 +214,7 @@ TypesGatherOpTest/Float32Int32,29 TypesGatherOpTest/Int32Int32,29 TypesGatherOpTest/Uint8Int32,29 TypesGatherOpTest/Int8Int32,29 +-TypesGatherOpTest/.*Int16.* # hashtable_lookup_test # All test excepted the string one should be accelerated diff --git a/tensorflow/lite/kernels/gather.cc b/tensorflow/lite/kernels/gather.cc index 1de49f7c486..01a1e2a8a17 100644 --- a/tensorflow/lite/kernels/gather.cc +++ b/tensorflow/lite/kernels/gather.cc @@ -61,6 +61,7 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { case kTfLiteFloat32: case kTfLiteUInt8: case kTfLiteInt8: + case kTfLiteInt16: case kTfLiteInt64: case kTfLiteInt32: case kTfLiteBool: @@ -143,6 +144,8 @@ TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { return Gather(*params, input, positions, output); case kTfLiteInt8: return Gather(*params, input, positions, output); + case kTfLiteInt16: + return Gather(*params, input, positions, output); case kTfLiteInt32: return Gather(*params, input, positions, output); case kTfLiteInt64: @@ -165,6 +168,8 @@ TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { return Gather(*params, input, positions, output); case kTfLiteInt8: return Gather(*params, input, positions, output); + case kTfLiteInt16: + return Gather(*params, input, positions, output); case kTfLiteInt32: return Gather(*params, input, positions, output); case kTfLiteInt64: diff --git a/tensorflow/lite/kernels/gather_test.cc b/tensorflow/lite/kernels/gather_test.cc index 01be7f01935..3f987975856 100644 --- a/tensorflow/lite/kernels/gather_test.cc +++ b/tensorflow/lite/kernels/gather_test.cc @@ -272,6 +272,24 @@ TEST(TypesGatherOpTest, Int8Int64) { EXPECT_THAT(m.GetOutput(), ElementsAreArray({14, 15, -13, -120})); } +TEST(TypesGatherOpTest, Int16Int32) { + GatherOpModel m({TensorType_INT16, {2, 2}}, {TensorType_INT32, {2}}); + m.SetInput({-13, -32000, 0, 32500}); + m.SetPositions({1, 0}); + m.Invoke(); + + EXPECT_THAT(m.GetOutput(), ElementsAreArray({0, 32500, -13, -32000})); +} + +TEST(TypesGatherOpTest, Int16Int64) { + GatherOpModel m({TensorType_INT16, {2, 2}}, {TensorType_INT64, {2}}); + m.SetInput({-13, -32000, 0, 32500}); + m.SetPositions({1LL, 0LL}); + m.Invoke(); + + EXPECT_THAT(m.GetOutput(), ElementsAreArray({0, 32500, -13, -32000})); +} + TEST(TypesGatherOpTest, Int64Int32) { GatherOpModel m({TensorType_INT64, {2, 2}}, {TensorType_INT32, {2}}); m.SetInput({-(1LL << 34), 134LL, 14LL, 15LL}); diff --git a/tensorflow/lite/kernels/register.cc b/tensorflow/lite/kernels/register.cc index 333ffc12d7e..e735cb926f9 100644 --- a/tensorflow/lite/kernels/register.cc +++ b/tensorflow/lite/kernels/register.cc @@ -131,7 +131,7 @@ BuiltinOpResolver::BuiltinOpResolver() { AddBuiltin(BuiltinOperator_DEPTH_TO_SPACE, Register_DEPTH_TO_SPACE()); AddBuiltin(BuiltinOperator_GATHER, Register_GATHER(), /* min_version = */ 1, - /* max_version = */ 3); + /* max_version = */ 4); AddBuiltin(BuiltinOperator_TRANSPOSE, Register_TRANSPOSE(), /* min_version = */ 1, /* max_version = */ 4); diff --git a/tensorflow/lite/toco/tflite/op_version.cc b/tensorflow/lite/toco/tflite/op_version.cc index 02afc35de3b..d395dfb5a9b 100644 --- a/tensorflow/lite/toco/tflite/op_version.cc +++ b/tensorflow/lite/toco/tflite/op_version.cc @@ -80,6 +80,7 @@ std::string GetMinimumRuntimeVersionForModel(const Model& model) { {{OperatorType::kGather, 1}, "1.6.0"}, {{OperatorType::kGather, 2}, "1.14.0"}, {{OperatorType::kGather, 3}, "1.15.0"}, + {{OperatorType::kGather, 4}, kPendingReleaseOpVersion}, {{OperatorType::kGatherNd, 1}, "1.14.0"}, {{OperatorType::kGatherNd, 2}, kPendingReleaseOpVersion}, {{OperatorType::kSvdf, 1}, "1.5.0"}, diff --git a/tensorflow/lite/tools/optimize/operator_property.cc b/tensorflow/lite/tools/optimize/operator_property.cc index f2cb98ef31a..4c63929d588 100644 --- a/tensorflow/lite/tools/optimize/operator_property.cc +++ b/tensorflow/lite/tools/optimize/operator_property.cc @@ -191,7 +191,6 @@ OperatorProperty GetOperatorProperty(const ModelT* model, int subgraph_index, property.outputs = {{0, {}}}; property.restrict_same_input_output_scale = true; property.version = 2; - property.quantizable_int16 = false; break; case BuiltinOperator_HARD_SWISH: { property.inputs = {{0, {}}}; diff --git a/tensorflow/lite/tools/versioning/op_version.cc b/tensorflow/lite/tools/versioning/op_version.cc index 2f62230f334..79cced17509 100644 --- a/tensorflow/lite/tools/versioning/op_version.cc +++ b/tensorflow/lite/tools/versioning/op_version.cc @@ -176,6 +176,9 @@ int GetBuiltinOperatorVersion(const OpSignature& op_sig) { return 1; case BuiltinOperator_GATHER: + if (op_sig.input_types.at(0) == TensorType_INT16) { + return 4; + } // If the op takes bool input, it is version 3. if (op_sig.input_types.at(0) == TensorType_BOOL) { return 3; diff --git a/tensorflow/lite/tools/versioning/runtime_version.cc b/tensorflow/lite/tools/versioning/runtime_version.cc index d345164f7e6..a1ae430e13c 100644 --- a/tensorflow/lite/tools/versioning/runtime_version.cc +++ b/tensorflow/lite/tools/versioning/runtime_version.cc @@ -109,6 +109,7 @@ std::string FindMinimumRuntimeVersionForOp(tflite::BuiltinOperator op_code, {{BuiltinOperator_GATHER, 1}, "1.6.0"}, {{BuiltinOperator_GATHER, 2}, "1.14.0"}, {{BuiltinOperator_GATHER, 3}, "1.15.0"}, + {{BuiltinOperator_GATHER, 4}, kPendingReleaseVersion}, {{BuiltinOperator_GATHER_ND, 1}, "1.14.0"}, {{BuiltinOperator_GATHER_ND, 2}, "2.3.0"}, {{BuiltinOperator_HASHTABLE_LOOKUP, 1}, "1.5.0"}, From de482ff7038ed825af2a6da18adc07354a9f0590 Mon Sep 17 00:00:00 2001 From: Elena Zhelezina Date: Fri, 24 Jul 2020 11:03:21 +0100 Subject: [PATCH 2/2] Fix after quantization of the network. Change-Id: I109ab0e87e8c4b9c16be55e902142469545ea815 --- tensorflow/lite/tools/optimize/operator_property.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/tensorflow/lite/tools/optimize/operator_property.cc b/tensorflow/lite/tools/optimize/operator_property.cc index 4c63929d588..06015dacf12 100644 --- a/tensorflow/lite/tools/optimize/operator_property.cc +++ b/tensorflow/lite/tools/optimize/operator_property.cc @@ -190,6 +190,7 @@ OperatorProperty GetOperatorProperty(const ModelT* model, int subgraph_index, property.inputs = {{0, {}}}; property.outputs = {{0, {}}}; property.restrict_same_input_output_scale = true; + property.quantize_input_as_activations = true; property.version = 2; break; case BuiltinOperator_HARD_SWISH: {