mirror of
https://github.com/vee1e/tflite-micro.git
synced 2026-09-03 18:58:00 +00:00
464 lines
16 KiB
C++
464 lines
16 KiB
C++
/* Copyright 2023 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/c/common.h"
|
|
#include "tensorflow/lite/micro/debug_log.h"
|
|
#include "tensorflow/lite/micro/kernels/kernel_runner.h"
|
|
#include "tensorflow/lite/micro/test_helpers.h"
|
|
#include "tensorflow/lite/micro/testing/micro_test_v2.h"
|
|
|
|
namespace tflite {
|
|
namespace testing {
|
|
|
|
template <int N>
|
|
struct OutputTensors {
|
|
float* data[N];
|
|
int* dims[N];
|
|
float* expected_output_data[N];
|
|
};
|
|
template <int N>
|
|
void TestSplitVFloat(int* input_dims_data, const float* input_data,
|
|
int* axis_dims_data, const int32_t* axis_data,
|
|
int* split_dims_data, const int32_t* split_data,
|
|
const OutputTensors<N>& output_tensors) {
|
|
TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
|
|
TfLiteIntArray* axis_dims = IntArrayFromInts(axis_dims_data);
|
|
TfLiteIntArray* split_dims = IntArrayFromInts(split_dims_data);
|
|
TfLiteIntArray* output_dims[N];
|
|
for (int i = 0; i < N; i++)
|
|
output_dims[i] = IntArrayFromInts(output_tensors.dims[i]);
|
|
|
|
// Place a unique value in the uninitialized output buffer.
|
|
for (int i = 0; i < N; i++) {
|
|
int dim_count = ElementCount(*output_dims[i]);
|
|
for (int j = 0; j < dim_count; j++) {
|
|
(output_tensors.data[i])[j] = 23;
|
|
}
|
|
}
|
|
constexpr int input_size = 1;
|
|
constexpr int axis_size = 1;
|
|
constexpr int split_size = 1;
|
|
constexpr int output_size = N;
|
|
|
|
constexpr int tensors_size =
|
|
input_size + output_size + axis_size + split_size;
|
|
|
|
// first input tensor is data
|
|
// second is size_splits
|
|
// third is axis
|
|
// then come outputs
|
|
|
|
TfLiteTensor tensors[tensors_size];
|
|
tensors[0] = CreateTensor(input_data, input_dims);
|
|
tensors[1] = CreateTensor(split_data, split_dims);
|
|
tensors[2] = CreateTensor(axis_data, axis_dims);
|
|
|
|
// add output tensors
|
|
for (int i = 0; i < N; i++)
|
|
tensors[3 + i] = CreateTensor(output_tensors.data[i], output_dims[i]);
|
|
|
|
tensors[2].allocation_type = kTfLiteMmapRo;
|
|
tensors[1].allocation_type = kTfLiteMmapRo;
|
|
|
|
int inputs_array_data[] = {3, 0, 1, 2};
|
|
TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
|
|
int outputs_array_data[N + 1];
|
|
outputs_array_data[0] = N;
|
|
for (int i = 0; i < N; i++) outputs_array_data[i + 1] = i + 3;
|
|
TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
|
|
|
|
const TFLMRegistration registration = Register_SPLIT_V();
|
|
micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
|
|
outputs_array, nullptr);
|
|
|
|
EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
|
|
EXPECT_EQ(kTfLiteOk, runner.Invoke());
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
int dim_count = ElementCount(*output_dims[i]);
|
|
for (int j = 0; j < dim_count; j++) {
|
|
EXPECT_NEAR((output_tensors.expected_output_data[i])[j],
|
|
(output_tensors.data[i])[j], 1e-5f);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace testing
|
|
} // namespace tflite
|
|
|
|
TEST(SplitVTest, SPLIT_V_ThreeOutputs) {
|
|
constexpr int output1_dims_count = 3;
|
|
constexpr int output2_dims_count = 3;
|
|
constexpr int output3_dims_count = 6;
|
|
float output1_data[output1_dims_count];
|
|
float output2_data[output2_dims_count];
|
|
float output3_data[output3_dims_count];
|
|
int input_shape[] = {2, 4, 3};
|
|
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
|
int axis_shape[] = {1, 1};
|
|
int32_t axis_values[] = {0};
|
|
int split_shape[] = {1, 3};
|
|
int32_t split_values[] = {1, 1, 2};
|
|
int output1_shape[] = {2, 1, 3};
|
|
float output1_values[] = {1, 2, 3};
|
|
int output2_shape[] = {2, 1, 3};
|
|
float output2_values[] = {4, 5, 6};
|
|
int output3_shape[] = {2, 2, 3};
|
|
float output3_values[] = {7, 8, 9, 10, 11, 12};
|
|
|
|
tflite::testing::OutputTensors<3> output_tensors;
|
|
output_tensors.data[0] = output1_data;
|
|
output_tensors.data[1] = output2_data;
|
|
output_tensors.data[2] = output3_data;
|
|
|
|
output_tensors.dims[0] = output1_shape;
|
|
output_tensors.dims[1] = output2_shape;
|
|
output_tensors.dims[2] = output3_shape;
|
|
|
|
output_tensors.expected_output_data[0] = output1_values;
|
|
output_tensors.expected_output_data[1] = output2_values;
|
|
output_tensors.expected_output_data[2] = output3_values;
|
|
|
|
tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
|
|
axis_values, split_shape, split_values,
|
|
output_tensors);
|
|
}
|
|
|
|
TEST(SplitVTest, SPLIT_V_FourDimensionalFloatAxis0) {
|
|
constexpr int output1_dims_count = 8;
|
|
constexpr int output2_dims_count = 8;
|
|
float output1_data[output1_dims_count];
|
|
float output2_data[output2_dims_count];
|
|
|
|
int input_shape[] = {4, 2, 2, 2, 2};
|
|
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
|
|
9, 10, 11, 12, 13, 14, 15, 16};
|
|
int axis_shape[] = {1, 1};
|
|
int32_t axis_values[] = {0};
|
|
int split_shape[] = {1, 2};
|
|
int32_t split_values[] = {1, 1};
|
|
int output1_shape[] = {4, 1, 2, 2, 2};
|
|
float output1_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
int output2_shape[] = {4, 1, 2, 2, 2};
|
|
float output2_values[] = {9, 10, 11, 12, 13, 14, 15, 16};
|
|
|
|
tflite::testing::OutputTensors<2> output_tensors;
|
|
|
|
output_tensors.data[0] = output1_data;
|
|
output_tensors.data[1] = output2_data;
|
|
|
|
output_tensors.dims[0] = output1_shape;
|
|
output_tensors.dims[1] = output2_shape;
|
|
|
|
output_tensors.expected_output_data[0] = output1_values;
|
|
output_tensors.expected_output_data[1] = output2_values;
|
|
|
|
tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
|
|
axis_values, split_shape, split_values,
|
|
output_tensors);
|
|
}
|
|
|
|
TEST(SplitVTest, SPLIT_V_FourDimensionalFloatAxis1) {
|
|
constexpr int output1_dims_count = 8;
|
|
constexpr int output2_dims_count = 8;
|
|
float output1_data[output1_dims_count];
|
|
float output2_data[output2_dims_count];
|
|
|
|
int input_shape[] = {4, 2, 2, 2, 2};
|
|
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
|
|
9, 10, 11, 12, 13, 14, 15, 16};
|
|
int axis_shape[] = {1, 1};
|
|
int32_t axis_values[] = {1};
|
|
int split_shape[] = {1, 2};
|
|
int32_t split_values[] = {1, 1};
|
|
int output1_shape[] = {4, 2, 1, 2, 2};
|
|
float output1_values[] = {1, 2, 3, 4, 9, 10, 11, 12};
|
|
int output2_shape[] = {4, 2, 1, 2, 2};
|
|
float output2_values[] = {5, 6, 7, 8, 13, 14, 15, 16};
|
|
|
|
tflite::testing::OutputTensors<2> output_tensors;
|
|
|
|
output_tensors.data[0] = output1_data;
|
|
output_tensors.data[1] = output2_data;
|
|
|
|
output_tensors.dims[0] = output1_shape;
|
|
output_tensors.dims[1] = output2_shape;
|
|
|
|
output_tensors.expected_output_data[0] = output1_values;
|
|
output_tensors.expected_output_data[1] = output2_values;
|
|
|
|
tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
|
|
axis_values, split_shape, split_values,
|
|
output_tensors);
|
|
}
|
|
|
|
TEST(SplitVTest, SPLIT_VFourDimensionalFloatAxis2) {
|
|
constexpr int output1_dims_count = 8;
|
|
constexpr int output2_dims_count = 8;
|
|
float output1_data[output1_dims_count];
|
|
float output2_data[output2_dims_count];
|
|
|
|
int input_shape[] = {4, 2, 2, 2, 2};
|
|
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
|
|
9, 10, 11, 12, 13, 14, 15, 16};
|
|
int axis_shape[] = {1, 1};
|
|
int32_t axis_values[] = {2};
|
|
int split_shape[] = {1, 2};
|
|
int32_t split_values[] = {1, 1};
|
|
int output1_shape[] = {4, 2, 2, 1, 2};
|
|
float output1_values[] = {1, 2, 5, 6, 9, 10, 13, 14};
|
|
int output2_shape[] = {4, 2, 2, 1, 2};
|
|
float output2_values[] = {3, 4, 7, 8, 11, 12, 15, 16};
|
|
|
|
tflite::testing::OutputTensors<2> output_tensors;
|
|
|
|
output_tensors.data[0] = output1_data;
|
|
output_tensors.data[1] = output2_data;
|
|
|
|
output_tensors.dims[0] = output1_shape;
|
|
output_tensors.dims[1] = output2_shape;
|
|
|
|
output_tensors.expected_output_data[0] = output1_values;
|
|
output_tensors.expected_output_data[1] = output2_values;
|
|
|
|
tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
|
|
axis_values, split_shape, split_values,
|
|
output_tensors);
|
|
}
|
|
|
|
TEST(SplitVTest, SPLIT_V_FourDimensionalFloatAxis3) {
|
|
constexpr int output1_dims_count = 8;
|
|
constexpr int output2_dims_count = 8;
|
|
float output1_data[output1_dims_count];
|
|
float output2_data[output2_dims_count];
|
|
int input_shape[] = {4, 2, 2, 2, 2};
|
|
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
|
|
9, 10, 11, 12, 13, 14, 15, 16};
|
|
int axis_shape[] = {1, 1};
|
|
int32_t axis_values[] = {3};
|
|
int split_shape[] = {1, 2};
|
|
int32_t split_values[] = {1, 1};
|
|
int output1_shape[] = {4, 2, 2, 2, 1};
|
|
float output1_values[] = {1, 3, 5, 7, 9, 11, 13, 15};
|
|
int output2_shape[] = {4, 2, 2, 2, 1};
|
|
float output2_values[] = {2, 4, 6, 8, 10, 12, 14, 16};
|
|
|
|
tflite::testing::OutputTensors<2> output_tensors;
|
|
|
|
output_tensors.data[0] = output1_data;
|
|
output_tensors.data[1] = output2_data;
|
|
|
|
output_tensors.dims[0] = output1_shape;
|
|
output_tensors.dims[1] = output2_shape;
|
|
|
|
output_tensors.expected_output_data[0] = output1_values;
|
|
output_tensors.expected_output_data[1] = output2_values;
|
|
|
|
tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
|
|
axis_values, split_shape, split_values,
|
|
output_tensors);
|
|
}
|
|
|
|
TEST(SplitVTest, SPLIT_V_FourDimensionalFloatNegativeAxis) {
|
|
constexpr int output1_dims_count = 8;
|
|
constexpr int output2_dims_count = 8;
|
|
float output1_data[output1_dims_count];
|
|
float output2_data[output2_dims_count];
|
|
|
|
int input_shape[] = {4, 2, 2, 2, 2};
|
|
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
|
|
9, 10, 11, 12, 13, 14, 15, 16};
|
|
int axis_shape[] = {1, 1};
|
|
int32_t axis_values[] = {-4};
|
|
int split_shape[] = {1, 2};
|
|
int32_t split_values[] = {1, 1};
|
|
int output1_shape[] = {4, 1, 2, 2, 2};
|
|
float output1_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
int output2_shape[] = {4, 1, 2, 2, 2};
|
|
float output2_values[] = {9, 10, 11, 12, 13, 14, 15, 16};
|
|
|
|
tflite::testing::OutputTensors<2> output_tensors;
|
|
|
|
output_tensors.data[0] = output1_data;
|
|
output_tensors.data[1] = output2_data;
|
|
|
|
output_tensors.dims[0] = output1_shape;
|
|
output_tensors.dims[1] = output2_shape;
|
|
|
|
output_tensors.expected_output_data[0] = output1_values;
|
|
output_tensors.expected_output_data[1] = output2_values;
|
|
|
|
tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
|
|
axis_values, split_shape, split_values,
|
|
output_tensors);
|
|
}
|
|
|
|
TEST(SplitVTest, SPLIT_V_OneDimensionalFloatAxis0) {
|
|
constexpr int output1_dims_count = 1;
|
|
constexpr int output2_dims_count = 1;
|
|
constexpr int output3_dims_count = 1;
|
|
constexpr int output4_dims_count = 1;
|
|
constexpr int output5_dims_count = 1;
|
|
constexpr int output6_dims_count = 1;
|
|
constexpr int output7_dims_count = 1;
|
|
constexpr int output8_dims_count = 1;
|
|
|
|
float output1_data[output1_dims_count];
|
|
float output2_data[output2_dims_count];
|
|
float output3_data[output3_dims_count];
|
|
float output4_data[output4_dims_count];
|
|
float output5_data[output5_dims_count];
|
|
float output6_data[output6_dims_count];
|
|
float output7_data[output7_dims_count];
|
|
float output8_data[output8_dims_count];
|
|
int input_shape[] = {1, 8};
|
|
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
int axis_shape[] = {1, 1};
|
|
int32_t axis_value[] = {0};
|
|
int split_size_shape[] = {1, 8};
|
|
int32_t split[] = {1, 1, 1, 1, 1, 1, 1, 1};
|
|
int output1_shape[] = {1, 1};
|
|
float output1_values[] = {1};
|
|
int output2_shape[] = {1, 1};
|
|
float output2_values[] = {2};
|
|
|
|
int output3_shape[] = {1, 1};
|
|
float output3_values[] = {3};
|
|
int output4_shape[] = {1, 1};
|
|
float output4_values[] = {4};
|
|
|
|
int output5_shape[] = {1, 1};
|
|
float output5_values[] = {5};
|
|
int output6_shape[] = {1, 1};
|
|
float output6_values[] = {6};
|
|
|
|
int output7_shape[] = {1, 1};
|
|
float output7_values[] = {7};
|
|
int output8_shape[] = {1, 1};
|
|
float output8_values[] = {8};
|
|
|
|
tflite::testing::OutputTensors<8> output_tensors;
|
|
|
|
output_tensors.data[0] = output1_data;
|
|
output_tensors.data[1] = output2_data;
|
|
output_tensors.data[2] = output3_data;
|
|
output_tensors.data[3] = output4_data;
|
|
output_tensors.data[4] = output5_data;
|
|
output_tensors.data[5] = output6_data;
|
|
output_tensors.data[6] = output7_data;
|
|
output_tensors.data[7] = output8_data;
|
|
|
|
output_tensors.dims[0] = output1_shape;
|
|
output_tensors.dims[1] = output2_shape;
|
|
output_tensors.dims[2] = output3_shape;
|
|
output_tensors.dims[3] = output4_shape;
|
|
output_tensors.dims[4] = output5_shape;
|
|
output_tensors.dims[5] = output6_shape;
|
|
output_tensors.dims[6] = output7_shape;
|
|
output_tensors.dims[7] = output8_shape;
|
|
|
|
output_tensors.expected_output_data[0] = output1_values;
|
|
output_tensors.expected_output_data[1] = output2_values;
|
|
output_tensors.expected_output_data[2] = output3_values;
|
|
output_tensors.expected_output_data[3] = output4_values;
|
|
output_tensors.expected_output_data[4] = output5_values;
|
|
output_tensors.expected_output_data[5] = output6_values;
|
|
output_tensors.expected_output_data[6] = output7_values;
|
|
output_tensors.expected_output_data[7] = output8_values;
|
|
|
|
tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
|
|
axis_value, split_size_shape, split,
|
|
output_tensors);
|
|
}
|
|
|
|
TEST(SplitVTest, SPLIT_V_OneDimensionalFloatTest2) {
|
|
constexpr int output1_dims_count = 1;
|
|
constexpr int output2_dims_count = 1;
|
|
constexpr int output3_dims_count = 1;
|
|
constexpr int output4_dims_count = 1;
|
|
constexpr int output5_dims_count = 1;
|
|
constexpr int output6_dims_count = 1;
|
|
constexpr int output7_dims_count = 2;
|
|
|
|
float output1_data[output1_dims_count];
|
|
float output2_data[output2_dims_count];
|
|
float output3_data[output3_dims_count];
|
|
float output4_data[output4_dims_count];
|
|
float output5_data[output5_dims_count];
|
|
float output6_data[output6_dims_count];
|
|
float output7_data[output7_dims_count];
|
|
|
|
int input_shape[] = {1, 8};
|
|
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
int axis_shape[] = {1, 1};
|
|
int32_t axis_value[] = {0};
|
|
int split_size_shape[] = {1, 8};
|
|
int32_t split[] = {1, 1, 1, 1, 1, 1, 2, -1};
|
|
int output1_shape[] = {1, 1};
|
|
float output1_values[] = {1};
|
|
int output2_shape[] = {1, 1};
|
|
float output2_values[] = {2};
|
|
|
|
int output3_shape[] = {1, 1};
|
|
float output3_values[] = {3};
|
|
int output4_shape[] = {1, 1};
|
|
float output4_values[] = {4};
|
|
|
|
int output5_shape[] = {1, 1};
|
|
float output5_values[] = {5};
|
|
int output6_shape[] = {1, 1};
|
|
float output6_values[] = {6};
|
|
|
|
int output7_shape[] = {1, 2};
|
|
float output7_values[] = {7, 8};
|
|
int output8_shape[] = {1, 0};
|
|
float output8_values[1] = {};
|
|
|
|
tflite::testing::OutputTensors<8> output_tensors;
|
|
|
|
output_tensors.data[0] = output1_data;
|
|
output_tensors.data[1] = output2_data;
|
|
output_tensors.data[2] = output3_data;
|
|
output_tensors.data[3] = output4_data;
|
|
output_tensors.data[4] = output5_data;
|
|
output_tensors.data[5] = output6_data;
|
|
output_tensors.data[6] = output7_data;
|
|
output_tensors.data[7] = NULL;
|
|
|
|
output_tensors.dims[0] = output1_shape;
|
|
output_tensors.dims[1] = output2_shape;
|
|
output_tensors.dims[2] = output3_shape;
|
|
output_tensors.dims[3] = output4_shape;
|
|
output_tensors.dims[4] = output5_shape;
|
|
output_tensors.dims[5] = output6_shape;
|
|
output_tensors.dims[6] = output7_shape;
|
|
output_tensors.dims[7] = output8_shape;
|
|
|
|
output_tensors.expected_output_data[0] = output1_values;
|
|
output_tensors.expected_output_data[1] = output2_values;
|
|
output_tensors.expected_output_data[2] = output3_values;
|
|
output_tensors.expected_output_data[3] = output4_values;
|
|
output_tensors.expected_output_data[4] = output5_values;
|
|
output_tensors.expected_output_data[5] = output6_values;
|
|
output_tensors.expected_output_data[6] = output7_values;
|
|
output_tensors.expected_output_data[7] = output8_values;
|
|
|
|
tflite::testing::TestSplitVFloat(input_shape, input_values, axis_shape,
|
|
axis_value, split_size_shape, split,
|
|
output_tensors);
|
|
}
|
|
|
|
TF_LITE_MICRO_TESTS_MAIN
|