add resize_nearest_neighbor op to micro
PiperOrigin-RevId: 307135856
Change-Id: If9fc8ed20a83c2563d1dd577152888b2df988191
diff --git a/tensorflow/lite/micro/kernels/BUILD b/tensorflow/lite/micro/kernels/BUILD
index 31e566f..b83154b 100644
--- a/tensorflow/lite/micro/kernels/BUILD
+++ b/tensorflow/lite/micro/kernels/BUILD
@@ -45,6 +45,7 @@
"prelu.cc",
"reduce.cc",
"reshape.cc",
+ "resize_nearest_neighbor.cc",
"round.cc",
"split.cc",
"strided_slice.cc",
@@ -144,6 +145,7 @@
"quantize.cc",
"reduce.cc",
"reshape.cc",
+ "resize_nearest_neighbor.cc",
"round.cc",
"softmax.cc",
"split.cc",
@@ -654,3 +656,16 @@
"//tensorflow/lite/micro/testing:micro_test",
],
)
+
+tflite_micro_cc_test(
+ name = "resize_nearest_neighbor_test",
+ srcs = [
+ "resize_nearest_neighbor_test.cc",
+ ],
+ deps = [
+ ":all_ops_resolver",
+ ":micro_ops",
+ "//tensorflow/lite/c:common",
+ "//tensorflow/lite/micro/testing:micro_test",
+ ],
+)
diff --git a/tensorflow/lite/micro/kernels/all_ops_resolver.cc b/tensorflow/lite/micro/kernels/all_ops_resolver.cc
index 8834d1d..4863382 100644
--- a/tensorflow/lite/micro/kernels/all_ops_resolver.cc
+++ b/tensorflow/lite/micro/kernels/all_ops_resolver.cc
@@ -71,6 +71,10 @@
AddBuiltin(BuiltinOperator_RELU, Register_RELU());
AddBuiltin(BuiltinOperator_RELU6, Register_RELU6());
AddBuiltin(BuiltinOperator_MEAN, Register_MEAN());
+ AddBuiltin(BuiltinOperator_RESIZE_NEAREST_NEIGHBOR,
+ Register_RESIZE_NEAREST_NEIGHBOR(),
+ /* min_version = */ 1,
+ /* max_version = */ 2);
}
} // namespace micro
diff --git a/tensorflow/lite/micro/kernels/micro_ops.h b/tensorflow/lite/micro/kernels/micro_ops.h
index 1433c25..650f4e8 100644
--- a/tensorflow/lite/micro/kernels/micro_ops.h
+++ b/tensorflow/lite/micro/kernels/micro_ops.h
@@ -35,6 +35,7 @@
TfLiteRegistration* Register_ARG_MIN();
TfLiteRegistration* Register_AVERAGE_POOL_2D();
TfLiteRegistration* Register_CEIL();
+TfLiteRegistration* Register_CIRCULAR_BUFFER();
TfLiteRegistration* Register_CONV_2D();
TfLiteRegistration* Register_CONCATENATION();
TfLiteRegistration* Register_COS();
@@ -67,6 +68,7 @@
TfLiteRegistration* Register_RELU();
TfLiteRegistration* Register_RELU6();
TfLiteRegistration* Register_RESHAPE();
+TfLiteRegistration* Register_RESIZE_NEAREST_NEIGHBOR();
TfLiteRegistration* Register_ROUND();
TfLiteRegistration* Register_RSQRT();
TfLiteRegistration* Register_SIN();
@@ -78,7 +80,6 @@
TfLiteRegistration* Register_SUB();
TfLiteRegistration* Register_SVDF();
TfLiteRegistration* Register_UNPACK();
-TfLiteRegistration* Register_CIRCULAR_BUFFER();
} // namespace micro
} // namespace ops
diff --git a/tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc b/tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc
new file mode 100644
index 0000000..2bce21e
--- /dev/null
+++ b/tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc
@@ -0,0 +1,111 @@
+/* Copyright 2017 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.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "tensorflow/lite/kernels/internal/reference/resize_nearest_neighbor.h"
+
+#include "tensorflow/lite/c/builtin_op_data.h"
+#include "tensorflow/lite/c/common.h"
+#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
+#include "tensorflow/lite/kernels/kernel_util.h"
+#include "tensorflow/lite/kernels/op_macros.h"
+
+namespace tflite {
+namespace ops {
+namespace micro {
+namespace resize_nearest_neighbor {
+
+constexpr int kInputTensor = 0;
+constexpr int kSizeTensor = 1;
+constexpr int kOutputTensor = 0;
+
+TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) {
+#if defined(DEBUG)
+ TF_LITE_ENSURE_EQ(context, NumInputs(node), 2);
+ TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1);
+
+ const TfLiteTensor* input = GetInput(context, node, kInputTensor);
+ const TfLiteTensor* size = GetInput(context, node, kSizeTensor);
+ TfLiteTensor* output = GetOutput(context, node, kOutputTensor);
+
+ // Our current implementations rely on the input being 4D,
+ // and the size being 1D tensor with exactly 2 elements.
+ TF_LITE_ENSURE_EQ(context, NumDimensions(input), 4);
+ TF_LITE_ENSURE_EQ(context, NumDimensions(size), 1);
+ TF_LITE_ENSURE_EQ(context, size->type, kTfLiteInt32);
+ TF_LITE_ENSURE_EQ(context, size->dims->data[0], 2);
+
+ output->type = input->type;
+
+ if (!IsConstantTensor(size)) {
+ TF_LITE_KERNEL_LOG(context,
+ "Dynamic tensors are unsupported in tfmicro.");
+ return kTfLiteError;
+ }
+#endif
+ return kTfLiteOk;
+}
+
+TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) {
+ auto* params =
+ reinterpret_cast<TfLiteResizeNearestNeighborParams*>(node->builtin_data);
+
+ const TfLiteTensor* input = GetInput(context, node, kInputTensor);
+ const TfLiteTensor* size = GetInput(context, node, kSizeTensor);
+ TfLiteTensor* output = GetOutput(context, node, kOutputTensor);
+
+ tflite::ResizeNearestNeighborParams op_params;
+ op_params.align_corners = params->align_corners;
+
+ if (output->type == kTfLiteFloat32) {
+ reference_ops::ResizeNearestNeighbor(
+ op_params, GetTensorShape(input), GetTensorData<int32>(input),
+ GetTensorShape(size), GetTensorData<int32>(size),
+ GetTensorShape(output), GetTensorData<int32>(output));
+ } else if (output->type == kTfLiteUInt8) {
+ reference_ops::ResizeNearestNeighbor(
+ op_params, GetTensorShape(input), GetTensorData<uint8_t>(input),
+ GetTensorShape(size), GetTensorData<int32>(size),
+ GetTensorShape(output), GetTensorData<uint8_t>(output));
+ } else if (output->type == kTfLiteInt8) {
+ reference_ops::ResizeNearestNeighbor(
+ op_params, GetTensorShape(input), GetTensorData<int8_t>(input),
+ GetTensorShape(size), GetTensorData<int32>(size),
+ GetTensorShape(output), GetTensorData<int8_t>(output));
+ } else {
+ TF_LITE_KERNEL_LOG(context,
+ "Output type is %d, requires float, uint8 or int8.",
+ output->type);
+ return kTfLiteError;
+ }
+
+ return kTfLiteOk;
+}
+} // namespace resize_nearest_neighbor
+
+TfLiteRegistration* Register_RESIZE_NEAREST_NEIGHBOR() {
+ static TfLiteRegistration r = {/*init=*/nullptr,
+ /*free=*/nullptr,
+ /*prepare=*/resize_nearest_neighbor::Prepare,
+ /*invoke=*/resize_nearest_neighbor::Eval,
+ /*profiling_string=*/nullptr,
+ /*builtin_code=*/0,
+ /*custom_name=*/nullptr,
+ /*version=*/0};
+ return &r;
+}
+
+} // namespace micro
+} // namespace ops
+} // namespace tflite
diff --git a/tensorflow/lite/micro/kernels/resize_nearest_neighbor_test.cc b/tensorflow/lite/micro/kernels/resize_nearest_neighbor_test.cc
new file mode 100644
index 0000000..b38c7b6
--- /dev/null
+++ b/tensorflow/lite/micro/kernels/resize_nearest_neighbor_test.cc
@@ -0,0 +1,342 @@
+/* Copyright 2017 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.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "tensorflow/lite/c/builtin_op_data.h"
+#include "tensorflow/lite/micro/kernels/all_ops_resolver.h"
+#include "tensorflow/lite/micro/testing/micro_test.h"
+#include "tensorflow/lite/micro/testing/test_utils.h"
+
+
+namespace tflite {
+namespace testing {
+namespace {
+
+using uint8 = std::uint8_t;
+using int32 = std::int32_t;
+
+TfLiteTensor TestCreateTensor(const float* data, TfLiteIntArray* dims,
+ const char* name) {
+ return CreateFloatTensor(data, dims, name);
+}
+
+TfLiteTensor TestCreateTensor(const uint8* data, TfLiteIntArray* dims,
+ const char* name) {
+ return CreateQuantizedTensor(data, dims, name, 0, 255);
+}
+
+TfLiteTensor TestCreateTensor(const int8* data, TfLiteIntArray* dims,
+ const char* name) {
+ return CreateQuantizedTensor(data, dims, name, -128, 127);
+}
+
+
+// Input data expects a 4-D tensor of [batch, height, width, channels]
+// Output data should match input datas batch and channels
+// Expected sizes should be a 1-D tensor with 2 elements: new_height & new_width
+template<typename T>
+void TestResizeNearestNeighbor(const int32* input_dims_data,
+ const T* input_data,
+ const int32* expected_size_data,
+ const T* expected_output_data,
+ const int32 *output_dims_data,
+ T* output_data) {
+ TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
+
+ int expected_size_dims_data[] = {2, 1, 2};
+ TfLiteIntArray* expected_size_dims =
+ IntArrayFromInts(expected_size_dims_data);
+
+ TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
+
+ const int output_dims_count = ElementCount(*output_dims);
+
+ constexpr int tensors_size = 3;
+ TfLiteTensor tensors[tensors_size] = {
+ TestCreateTensor(input_data, input_dims, "input_tensor"),
+ CreateInt32Tensor(expected_size_data, expected_size_dims, "size_tensor"),
+ TestCreateTensor(output_data, output_dims, "output_tensor"),
+ };
+
+ TfLiteContext context;
+ PopulateContext(tensors, tensors_size, micro_test::reporter, &context);
+ ::tflite::ops::micro::AllOpsResolver resolver;
+ const TfLiteRegistration* registration =
+ resolver.FindOp(tflite::BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, 1);
+ TF_LITE_MICRO_EXPECT_NE(nullptr, registration);
+
+ TfLiteResizeNearestNeighborParams builtin_data = {
+ .align_corners = false
+ };
+
+ int inputs_array_data[] = {2, 0, 1};
+ TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
+ int outputs_array_data[] = {1, 2};
+ TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
+ int temporaries_array_data[] = {0};
+ TfLiteIntArray* temporaries_array = IntArrayFromInts(temporaries_array_data);
+
+ TfLiteNode node;
+ node.inputs = inputs_array;
+ node.outputs = outputs_array;
+ node.temporaries = temporaries_array;
+ node.user_data = nullptr;
+ node.builtin_data = reinterpret_cast<void*>(&builtin_data);
+ node.custom_initial_data = nullptr;
+ node.custom_initial_data_size = 0;
+ node.delegate = nullptr;
+ TF_LITE_MICRO_EXPECT_NE(nullptr, registration->invoke);
+ TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, registration->invoke(&context, &node));
+
+ // compare results
+ for (int i = 0; i < output_dims_count; ++i) {
+ TF_LITE_MICRO_EXPECT_EQ(expected_output_data[i], output_data[i]);
+ }
+}
+
+} // namespace
+} // namespace testing
+} // namespace tflite
+
+
+TF_LITE_MICRO_TESTS_BEGIN
+
+TF_LITE_MICRO_TEST(HorizontalResize) {
+ const int32 input_dims[] = {4, 1, 1, 2, 1};
+ const float input_data[] = {3, 6};
+ const int32 expected_size_data[] = {1, 3};
+ const float expected_output_data[] = {3, 3, 6};
+ const int32 output_dims[] = {4, 1, 1, 3, 1};
+ float output_data[3];
+
+ tflite::testing::TestResizeNearestNeighbor<float>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(HorizontalResizeUInt8) {
+ const int32 input_dims[] = {4, 1, 1, 2, 1};
+ const uint8 input_data[] = {3, 6};
+ const int32 expected_size_data[] = {1, 3};
+ const uint8 expected_output_data[] = {3, 3, 6};
+ const int32 output_dims[] = {4, 1, 1, 3, 1};
+ uint8 output_data[3];
+
+ tflite::testing::TestResizeNearestNeighbor<uint8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(HorizontalResizeInt8) {
+ const int32 input_dims[] = {4, 1, 1, 2, 1};
+ const int8 input_data[] = {-3, 6};
+ const int32 expected_size_data[] = {1, 3};
+ const int8 expected_output_data[] = {-3, -3, 6};
+ const int32 output_dims[] = {4, 1, 1, 3, 1};
+ int8 output_data[3];
+
+ tflite::testing::TestResizeNearestNeighbor<int8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(VerticalResize) {
+ const int32 input_dims[] = {4, 1, 2, 1, 1};
+ const float input_data[] = {3, 9};
+ const int32 expected_size_data[] = {3, 1};
+ const float expected_output_data[] = {3, 3, 9};
+ const int32 output_dims[] = {4, 1, 3, 1, 1};
+ float output_data[3];
+
+ tflite::testing::TestResizeNearestNeighbor<float>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(VerticalResizeUInt8) {
+ const int32 input_dims[] = {4, 1, 2, 1, 1};
+ const uint8 input_data[] = {3, 9};
+ const int32 expected_size_data[] = {3, 1};
+ const uint8 expected_output_data[] = {3, 3, 9};
+ const int32 output_dims[] = {4, 1, 3, 1, 1};
+ uint8 output_data[3];
+
+ tflite::testing::TestResizeNearestNeighbor<uint8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(VerticalResizeInt8) {
+ const int32 input_dims[] = {4, 1, 2, 1, 1};
+ const int8 input_data[] = {3, -9};
+ const int32 expected_size_data[] = {3, 1};
+ const int8 expected_output_data[] = {3, 3, -9};
+ const int32 output_dims[] = {4, 1, 3, 1, 1};
+ int8 output_data[3];
+
+ tflite::testing::TestResizeNearestNeighbor<int8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(TwoDimensionalResize) {
+ const int32 input_dims[] = {4, 1, 2, 2, 1};
+ const float input_data[] = {3, 6, //
+ 9, 12, //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const float expected_output_data[] = {3, 3, 6, //
+ 3, 3, 6, //
+ 9, 9, 12 //
+ };
+
+ const int32 output_dims[] = {4, 1, 3, 3, 1};
+ float output_data[9];
+
+ tflite::testing::TestResizeNearestNeighbor<float>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(TwoDimensionalResizeUInt8) {
+ const int input_dims[] = {4, 1, 2, 2, 1};
+ const uint8 input_data[] = {3, 6, //
+ 9, 12 //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const uint8 expected_output_data[] = {3, 3, 6, //
+ 3, 3, 6, //
+ 9, 9, 12 //
+ };
+ const int32 output_dims[] = {4, 1, 3, 3, 1};
+ uint8 output_data[9];
+
+ tflite::testing::TestResizeNearestNeighbor<uint8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(TwoDimensionalResizeInt8) {
+ const int32 input_dims[] = {4, 1, 2, 2, 1};
+ const int8 input_data[] = {3, -6, //
+ 9, 12, //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const int8 expected_output_data[] = {3, 3, -6, //
+ 3, 3, -6, //
+ 9, 9, 12, //
+ };
+ const int32 output_dims[] = {4, 1, 3, 3, 1};
+ int8 output_data[9];
+
+ tflite::testing::TestResizeNearestNeighbor<int8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatches) {
+ const int32 input_dims[] = {4, 2, 2, 2, 1};
+ const float input_data[] = {3, 6, //
+ 9, 12, //
+ 4, 10, //
+ 10, 16 //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const float expected_output_data[] = {3, 3, 6, //
+ 3, 3, 6, //
+ 9, 9, 12, //
+ 4, 4, 10, //
+ 4, 4, 10, //
+ 10, 10, 16, //
+ };
+ const int32 output_dims[] = {4, 2, 3, 3, 1};
+ float output_data[18];
+
+ tflite::testing::TestResizeNearestNeighbor<float>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatchesUInt8) {
+ const int32 input_dims[] = {4, 2, 2, 2, 1};
+ const uint8 input_data[] = {3, 6, //
+ 9, 12, //
+ 4, 10, //
+ 10, 16 //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const uint8 expected_output_data[] = {3, 3, 6, //
+ 3, 3, 6, //
+ 9, 9, 12, //
+ 4, 4, 10, //
+ 4, 4, 10, //
+ 10, 10, 16, //
+ };
+ const int32 output_dims[] = {4, 2, 3, 3, 1};
+ uint8 output_data[18];
+
+ tflite::testing::TestResizeNearestNeighbor<uint8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(TwoDimensionalResizeWithTwoBatchesInt8) {
+ const int32 input_dims[] = {4, 2, 2, 2, 1};
+ const int8 input_data[] = {3, 6, //
+ 9, -12, //
+ -4, 10, //
+ 10, 16 //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const int8 expected_output_data[] = {3, 3, 6, //
+ 3, 3, 6, //
+ 9, 9, -12, //
+ -4, -4, 10, //
+ -4, -4, 10, //
+ 10, 10, 16, //
+ };
+ const int32 output_dims[] = {4, 2, 3, 3, 1};
+ int8 output_data[18];
+
+ tflite::testing::TestResizeNearestNeighbor<int8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(ThreeDimensionalResize) {
+ const int input_dims[] = {4, 1, 2, 2, 2};
+ const float input_data[] = {3, 4, 6, 10, //
+ 9, 10, 12, 16, //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const float expected_output_data[] = {3, 4, 3, 4, 6, 10, //
+ 3, 4, 3, 4, 6, 10, //
+ 9, 10, 9, 10, 12, 16, //
+ };
+ const int32 output_dims[] = {4, 1, 3, 3, 2};
+ float output_data[18];
+
+ tflite::testing::TestResizeNearestNeighbor<float>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(ThreeDimensionalResizeUInt8) {
+ const int32 input_dims[] = {4, 1, 2, 2, 2};
+ const uint8 input_data[] = {3, 4, 6, 10, //
+ 10, 12, 14, 16, //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const uint8 expected_output_data[] = {3, 4, 3, 4, 6, 10, //
+ 3, 4, 3, 4, 6, 10, //
+ 10, 12, 10, 12, 14, 16, //
+ };
+ const int32 output_dims[] = {4, 1, 3, 3, 2};
+ uint8 output_data[18];
+
+ tflite::testing::TestResizeNearestNeighbor<uint8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+TF_LITE_MICRO_TEST(ThreeDimensionalResizeInt8) {
+ const int32 input_dims[] = {4, 1, 2, 2, 2};
+ const int8 input_data[] = {3, 4, -6, 10, //
+ 10, 12, -14, 16, //
+ };
+ const int32 expected_size_data[] = {3, 3};
+ const int8 expected_output_data[] = {3, 4, 3, 4, -6, 10, //
+ 3, 4, 3, 4, -6, 10, //
+ 10, 12, 10, 12, -14, 16, //
+ };
+ const int32 output_dims[] = {4, 1, 3, 3, 2};
+ int8 output_data[18];
+
+ tflite::testing::TestResizeNearestNeighbor<int8>(input_dims, input_data,
+ expected_size_data, expected_output_data, output_dims, output_data);
+}
+
+TF_LITE_MICRO_TESTS_END
diff --git a/tensorflow/lite/micro/tools/make/Makefile b/tensorflow/lite/micro/tools/make/Makefile
index 078748a..8d717ae 100644
--- a/tensorflow/lite/micro/tools/make/Makefile
+++ b/tensorflow/lite/micro/tools/make/Makefile
@@ -170,6 +170,7 @@
tensorflow/lite/kernels/internal/reference/quantize.h \
tensorflow/lite/kernels/internal/reference/reduce.h \
tensorflow/lite/kernels/internal/reference/requantize.h \
+tensorflow/lite/kernels/internal/reference/resize_nearest_neighbor.h \
tensorflow/lite/kernels/internal/reference/round.h \
tensorflow/lite/kernels/internal/reference/softmax.h \
tensorflow/lite/kernels/internal/reference/sub.h \