Some style changes to splitV. Changed tests to use a single function template.

This commit is contained in:
yair_ehrenwald 2020-09-04 11:48:33 +03:00 committed by GitHub
parent f3d22549ff
commit 340a16ac54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 345 additions and 469 deletions

View File

@ -1,135 +1,135 @@
/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. /* Copyright 2018 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "tensorflow/lite/c/builtin_op_data.h" #include "tensorflow/lite/c/builtin_op_data.h"
#include "tensorflow/lite/c/common.h" #include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" #include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
#include "tensorflow/lite/kernels/kernel_util.h" #include "tensorflow/lite/kernels/kernel_util.h"
#include "tensorflow/lite/kernels/op_macros.h" #include "tensorflow/lite/kernels/op_macros.h"
#include "tensorflow/lite/micro/kernels/kernel_util.h" #include "tensorflow/lite/micro/kernels/kernel_util.h"
namespace tflite { namespace tflite {
namespace ops { namespace ops {
namespace micro { namespace micro {
namespace split_v { namespace split_v {
template <typename T> template <typename T>
TfLiteStatus SplitImpl(TfLiteContext* context, TfLiteNode* node, TfLiteStatus SplitImpl(TfLiteContext* context, TfLiteNode* node,
const TfLiteEvalTensor* input, int axis_value) { const TfLiteEvalTensor* input, int axis_value) {
const int output_count = NumOutputs(node); const TfLiteIntArray* input_dims = input->dims;
const TfLiteIntArray* input_dims = input->dims; const TfLiteEvalTensor* output0 =
const TfLiteEvalTensor* output0 = tflite::micro::GetEvalOutput(context, node, 0);
tflite::micro::GetEvalOutput(context, node, 0);
const TfLiteIntArray* output_dims = output0->dims; const int split_dimensions = input_dims->size;
const int split_dimensions = input_dims->size; TFLITE_DCHECK_LT(axis_value, split_dimensions);
TFLITE_DCHECK_EQ(output0->dims->size, split_dimensions);
TFLITE_DCHECK_LT(axis_value, split_dimensions);
TFLITE_DCHECK_EQ(output_dims->size, split_dimensions); int64_t split_size = 0;
const int output_count = NumOutputs(node);
int64_t split_size = 0; for (int i = 0; i < output_count; i++) {
for (int i = 0; i < output_count; i++) { split_size +=
split_size += tflite::micro::GetEvalOutput(context, node, i)->dims->data[axis_value];
tflite::micro::GetEvalOutput(context, node, i)->dims->data[axis_value]; }
} TFLITE_DCHECK_EQ(split_size, input_dims->data[axis_value]);
TFLITE_DCHECK_EQ(split_size, input_dims->data[axis_value]); int64_t outer_size = 1;
int64_t outer_size = 1; for (int i = 0; i < axis_value; ++i) {
for (int i = 0; i < axis_value; ++i) { outer_size *= input_dims->data[i];
outer_size *= input_dims->data[i]; }
}
int64_t base_inner_size = 1;
int64_t base_inner_size = 1; for (int i = axis_value + 1; i < split_dimensions; ++i) {
for (int i = axis_value + 1; i < split_dimensions; ++i) { base_inner_size *= input_dims->data[i];
base_inner_size *= input_dims->data[i]; }
}
const T* input_ptr = tflite::micro::GetTensorData<T>(input);
const T* input_ptr = tflite::micro::GetTensorData<T>(input); for (int k = 0; k < outer_size; ++k) {
for (int k = 0; k < outer_size; ++k) { for (int i = 0; i < output_count; ++i) {
for (int i = 0; i < output_count; ++i) { TfLiteEvalTensor* output_tensor =
TfLiteEvalTensor* t = tflite::micro::GetEvalOutput(context, node, i); tflite::micro::GetEvalOutput(context, node, i);
T* output_data = tflite::micro::GetTensorData<T>(t); T* output_data = tflite::micro::GetTensorData<T>(output_tensor);
output_dims = t->dims; const int copy_size =
const int copy_size = output_dims->data[axis_value] * base_inner_size; output_tensor->dims->data[axis_value] * base_inner_size;
T* output_ptr = output_data + k * copy_size; T* output_ptr = output_data + k * copy_size;
for (int j = 0; j < copy_size; ++j) output_ptr[j] = input_ptr[j]; for (int j = 0; j < copy_size; ++j) output_ptr[j] = input_ptr[j];
input_ptr += copy_size; input_ptr += copy_size;
} }
} }
return kTfLiteOk; return kTfLiteOk;
} }
TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) {
TF_LITE_ENSURE_EQ(context, NumInputs(node), 3); TF_LITE_ENSURE_EQ(context, NumInputs(node), 3);
// Dynamic output tensors are needed if axis tensor is not constant. // Dynamic output tensors are needed if axis tensor is not constant.
// But Micro doesn't support dynamic memory allocation, so we only support // But Micro doesn't support dynamic memory allocation, so we only support
// constant axis tensor for now. // constant axis tensor for now.
const TfLiteTensor* axis = GetInput(context, node, 2); const TfLiteTensor* axis = GetInput(context, node, 2);
TF_LITE_ENSURE_MSG(context, IsConstantTensor(axis), TF_LITE_ENSURE_MSG(context, IsConstantTensor(axis),
"Non constant axis tensor not supported"); "Non constant axis tensor not supported");
return kTfLiteOk; return kTfLiteOk;
} }
TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) {
const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0);
const TfLiteEvalTensor* axis = tflite::micro::GetEvalInput(context, node, 2); const TfLiteEvalTensor* axis = tflite::micro::GetEvalInput(context, node, 2);
int axis_value = tflite::micro::GetTensorData<int32_t>(axis)[0]; int axis_value = tflite::micro::GetTensorData<int32_t>(axis)[0];
if (axis_value < 0) { if (axis_value < 0) {
axis_value += input->dims->size; axis_value += input->dims->size;
} }
TF_LITE_ENSURE(context, axis_value >= 0); TF_LITE_ENSURE(context, axis_value >= 0);
TF_LITE_ENSURE(context, axis_value < input->dims->size); TF_LITE_ENSURE(context, axis_value < input->dims->size);
switch (input->type) { switch (input->type) {
case kTfLiteFloat32: { case kTfLiteFloat32: {
return SplitImpl<float>(context, node, input, axis_value); return SplitImpl<float>(context, node, input, axis_value);
} }
case kTfLiteInt8: { case kTfLiteInt8: {
return SplitImpl<int8_t>(context, node, input, axis_value); return SplitImpl<int8_t>(context, node, input, axis_value);
} }
case kTfLiteInt16: { case kTfLiteInt16: {
return SplitImpl<int16_t>(context, node, input, axis_value); return SplitImpl<int16_t>(context, node, input, axis_value);
} }
case kTfLiteInt32: { case kTfLiteInt32: {
return SplitImpl<int32_t>(context, node, input, axis_value); return SplitImpl<int32_t>(context, node, input, axis_value);
} }
default: default:
TF_LITE_KERNEL_LOG(context, "Type %s currently not supported.", TF_LITE_KERNEL_LOG(context, "Type %s currently not supported.",
TfLiteTypeGetName(input->type)); TfLiteTypeGetName(input->type));
return kTfLiteError; return kTfLiteError;
} }
return kTfLiteOk; return kTfLiteOk;
} }
} // namespace split_v } // namespace split_v
TfLiteRegistration Register_SPLIT_V() { TfLiteRegistration Register_SPLIT_V() {
return {/*init=*/nullptr, return {/*init=*/nullptr,
/*free=*/nullptr, /*free=*/nullptr,
/*prepare=*/split_v::Prepare, /*prepare=*/split_v::Prepare,
/*invoke=*/split_v::Eval, /*invoke=*/split_v::Eval,
/*profiling_string=*/nullptr, /*profiling_string=*/nullptr,
/*builtin_code=*/0, /*builtin_code=*/0,
/*custom_name=*/nullptr, /*custom_name=*/nullptr,
/*version=*/0}; /*version=*/0};
} }
} // namespace micro } // namespace micro
} // namespace ops } // namespace ops
} // namespace tflite } // namespace tflite

View File

@ -24,42 +24,36 @@ limitations under the License.
namespace tflite { namespace tflite {
namespace testing { namespace testing {
void TestSplitVThreeOutputsFloat( template <int N>
const int* input_dims_data, const float* input_data, struct OutputTensors {
const int* axis_dims_data, const int* axis_data, const int* split_dims_data, float* data[N];
const int* split_data, const int* output1_dims_data, int* dims[N];
const float* expected_output1_data, const int* output2_dims_data, float* expected_output_data[N];
const float* expected_output2_data, const int* output3_dims_data, };
const float* expected_output3_data, float* output1_data, template <int N>
float* output2_data, float* output3_data) { void TestSplitVFloat(const int* input_dims_data, const float* input_data,
const int* axis_dims_data, const int* axis_data,
const int* split_dims_data, const int* split_data,
const OutputTensors<N>& output_tensors) {
TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data); TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
TfLiteIntArray* axis_dims = IntArrayFromInts(axis_dims_data); TfLiteIntArray* axis_dims = IntArrayFromInts(axis_dims_data);
TfLiteIntArray* split_dims = IntArrayFromInts(split_dims_data); TfLiteIntArray* split_dims = IntArrayFromInts(split_dims_data);
TfLiteIntArray* output1_dims = IntArrayFromInts(output1_dims_data); TfLiteIntArray* output_dims[N];
TfLiteIntArray* output2_dims = IntArrayFromInts(output2_dims_data); for (int i = 0; i < N; i++)
TfLiteIntArray* output3_dims = IntArrayFromInts(output3_dims_data); output_dims[i] = IntArrayFromInts(output_tensors.dims[i]);
const int output1_dims_count = ElementCount(*output1_dims);
const int output2_dims_count = ElementCount(*output2_dims);
const int output3_dims_count = ElementCount(*output3_dims);
// Place a unique value in the uninitialized output buffer. // Place a unique value in the uninitialized output buffer.
for (int i = 0; i < output1_dims_count; ++i) { for (int i = 0; i < N; i++) {
output1_data[i] = 23; int dim_count = ElementCount(*output_dims[i]);
for (int j = 0; j < dim_count; j++) {
(output_tensors.data[i])[j] = 23;
}
} }
for (int i = 0; i < output2_dims_count; ++i) {
output2_data[i] = 23;
}
for (int i = 0; i < output3_dims_count; ++i) {
output3_data[i] = 23;
}
constexpr int input_size = 1; constexpr int input_size = 1;
constexpr int axis_size = 1; constexpr int axis_size = 1;
constexpr int split_size = 1; constexpr int split_size = 1;
constexpr int output_size = 3; constexpr int output_size = N;
TfLiteContext context;
constexpr int tensors_size = constexpr int tensors_size =
input_size + output_size + axis_size + split_size; input_size + output_size + axis_size + split_size;
@ -68,27 +62,26 @@ void TestSplitVThreeOutputsFloat(
// third is axis // third is axis
// then come outputs // then come outputs
TfLiteTensor tensors[tensors_size] = { TfLiteTensor tensors[tensors_size];
tensors[0] = CreateFloatTensor(input_data, input_dims);
tensors[1] = CreateQuantized32Tensor(split_data, split_dims, 1.0);
tensors[2] = CreateQuantized32Tensor(axis_data, axis_dims, 1.0);
CreateFloatTensor(input_data, input_dims), // add output tensors
CreateQuantized32Tensor(split_data, split_dims, 1.0), for (int i = 0; i < N; i++)
CreateQuantized32Tensor(axis_data, axis_dims, 1.0), tensors[3 + i] = CreateFloatTensor(output_tensors.data[i], output_dims[i]);
// outputs
CreateFloatTensor(output1_data, output1_dims),
CreateFloatTensor(output2_data, output2_dims),
CreateFloatTensor(output3_data, output3_dims)
};
tensors[2].allocation_type = kTfLiteMmapRo; tensors[2].allocation_type = kTfLiteMmapRo;
tensors[1].allocation_type = kTfLiteMmapRo; tensors[1].allocation_type = kTfLiteMmapRo;
void* user_data = nullptr; void* user_data = nullptr;
TfLiteSplitVParams builtin; TfLiteSplitVParams builtin;
builtin.num_splits = 3; builtin.num_splits = N;
int inputs_array_data[] = {3, 0, 1, 2}; int inputs_array_data[] = {3, 0, 1, 2};
TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data); TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
int outputs_array_data[] = {3, 3, 4, 5}; 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); TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
TfLiteIntArray* temporaries_array = IntArrayFromInts({0}); TfLiteIntArray* temporaries_array = IntArrayFromInts({0});
@ -109,242 +102,12 @@ void TestSplitVThreeOutputsFloat(
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare()); TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke()); TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
for (int i = 0; i < output1_dims_count; ++i) { for (int i = 0; i < N; i++) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output1_data[i], output1_data[i], 1e-5f); int dim_count = ElementCount(*output_dims[i]);
} for (int j = 0; j < dim_count; j++) {
for (int i = 0; i < output2_dims_count; ++i) { TF_LITE_MICRO_EXPECT_NEAR((output_tensors.expected_output_data[i])[j],
TF_LITE_MICRO_EXPECT_NEAR(expected_output2_data[i], output2_data[i], 1e-5f); (output_tensors.data[i])[j], 1e-5f);
} }
for (int i = 0; i < output3_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output3_data[i], output3_data[i], 1e-5f);
}
}
void TestSplitVTwoOutputsFloat(
const int* input_dims_data, const float* input_data,
const int* axis_dims_data, const int* axis_data, const int* split_dims_data,
const int* size_splits_data, const int* output1_dims_data,
const float* expected_output1_data, const int* output2_dims_data,
const float* expected_output2_data, float* output1_data,
float* output2_data) {
TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
TfLiteIntArray* axis_dims = IntArrayFromInts(axis_dims_data);
TfLiteIntArray* output1_dims = IntArrayFromInts(output1_dims_data);
TfLiteIntArray* output2_dims = IntArrayFromInts(output2_dims_data);
TfLiteIntArray* size_splits_dims = IntArrayFromInts(split_dims_data);
const int output1_dims_count = ElementCount(*output1_dims);
const int output2_dims_count = ElementCount(*output2_dims);
constexpr int input_size = 1;
constexpr int output_size = 2;
constexpr int axis_size = 1;
constexpr int split_size = 1;
constexpr int tensors_size =
input_size + output_size + axis_size + split_size;
TfLiteTensor tensors[tensors_size] = {
CreateFloatTensor(input_data, input_dims),
CreateQuantized32Tensor(size_splits_data, size_splits_dims, 1.0),
CreateQuantized32Tensor(axis_data, axis_dims, 1.0),
CreateFloatTensor(output1_data, output1_dims),
CreateFloatTensor(output2_data, output2_dims)};
// Currently only support constant axis tensor.
tensors[1].allocation_type = kTfLiteMmapRo;
tensors[2].allocation_type = kTfLiteMmapRo;
// Place a unique value in the uninitialized output buffer.
for (int i = 0; i < output1_dims_count; ++i) {
output1_data[i] = 23;
}
for (int i = 0; i < output2_dims_count; ++i) {
output2_data[i] = 23;
}
TfLiteSplitVParams builtin_data;
builtin_data.num_splits = 2;
void* user_data = nullptr;
int inputs_array_data[] = {3, 0, 1, 2};
TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
int outputs_array_data[] = {2, 3, 4};
TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
TfLiteIntArray* temporaries_array = IntArrayFromInts({0});
TfLiteNode node;
node.inputs = inputs_array;
node.outputs = outputs_array;
// node.temporaries = temporaries_array;
node.user_data = user_data;
node.builtin_data = reinterpret_cast<void*>(&builtin_data);
node.custom_initial_data = nullptr;
node.custom_initial_data_size = 0;
const TfLiteRegistration registration =
tflite::ops::micro::Register_SPLIT_V();
micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
outputs_array, nullptr, micro_test::reporter);
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
for (int i = 0; i < output1_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output1_data[i], output1_data[i], 1e-5f);
}
for (int i = 0; i < output2_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output2_data[i], output2_data[i], 1e-5f);
}
}
void TestSplitVEightOutputsFloat(
const int* input_dims_data, const float* input_data,
const int* axis_dims_data, const int* axis_data, const int* split_dims_data,
const int* size_splits_data, const int* output1_dims_data,
const float* expected_output1_data, const int* output2_dims_data,
const float* expected_output2_data, const int* output3_dims_data,
const float* expected_output3_data, const int* output4_dims_data,
const float* expected_output4_data, const int* output5_dims_data,
const float* expected_output5_data, const int* output6_dims_data,
const float* expected_output6_data, const int* output7_dims_data,
const float* expected_output7_data, const int* output8_dims_data,
const float* expected_output8_data,
float* output1_data, float* output2_data, float* output3_data,
float* output4_data, float* output5_data, float* output6_data,
float* output7_data, float* output8_data) {
TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
TfLiteIntArray* axis_dims = IntArrayFromInts(axis_dims_data);
TfLiteIntArray* output1_dims = IntArrayFromInts(output1_dims_data);
TfLiteIntArray* output2_dims = IntArrayFromInts(output2_dims_data);
TfLiteIntArray* output3_dims = IntArrayFromInts(output3_dims_data);
TfLiteIntArray* output4_dims = IntArrayFromInts(output4_dims_data);
TfLiteIntArray* output5_dims = IntArrayFromInts(output5_dims_data);
TfLiteIntArray* output6_dims = IntArrayFromInts(output6_dims_data);
TfLiteIntArray* output7_dims = IntArrayFromInts(output7_dims_data);
TfLiteIntArray* output8_dims = IntArrayFromInts(output8_dims_data);
TfLiteIntArray* size_splits_dims = IntArrayFromInts(split_dims_data);
const int output1_dims_count = ElementCount(*output1_dims);
const int output2_dims_count = ElementCount(*output2_dims);
const int output3_dims_count = ElementCount(*output3_dims);
const int output4_dims_count = ElementCount(*output4_dims);
const int output5_dims_count = ElementCount(*output5_dims);
const int output6_dims_count = ElementCount(*output6_dims);
const int output7_dims_count = ElementCount(*output7_dims);
const int output8_dims_count = ElementCount(*output8_dims);
constexpr int input_size = 1;
constexpr int output_size = 8;
constexpr int axis_size = 1;
constexpr int split_size = 1;
constexpr int tensors_size =
input_size + output_size + axis_size + split_size;
TfLiteTensor tensors[tensors_size] = {
CreateFloatTensor(input_data, input_dims),
CreateQuantized32Tensor(size_splits_data, size_splits_dims, 1.0),
CreateQuantized32Tensor(axis_data, axis_dims, 1.0),
CreateFloatTensor(output1_data, output1_dims),
CreateFloatTensor(output2_data, output2_dims),
CreateFloatTensor(output3_data, output3_dims),
CreateFloatTensor(output4_data, output4_dims),
CreateFloatTensor(output5_data, output5_dims),
CreateFloatTensor(output6_data, output6_dims),
CreateFloatTensor(output7_data, output7_dims),
CreateFloatTensor(output8_data, output8_dims)};
// Currently only support constant axis tensor.
tensors[1].allocation_type = kTfLiteMmapRo;
tensors[2].allocation_type = kTfLiteMmapRo;
// Place a unique value in the uninitialized output buffer.
for (int i = 0; i < output1_dims_count; ++i) {
output1_data[i] = 23;
}
for (int i = 0; i < output2_dims_count; ++i) {
output2_data[i] = 23;
}
for (int i = 0; i < output3_dims_count; ++i) {
output3_data[i] = 23;
}
for (int i = 0; i < output4_dims_count; ++i) {
output4_data[i] = 23;
}
for (int i = 0; i < output5_dims_count; ++i) {
output5_data[i] = 23;
}
for (int i = 0; i < output6_dims_count; ++i) {
output6_data[i] = 23;
}
for (int i = 0; i < output7_dims_count; ++i) {
output7_data[i] = 23;
}
for (int i = 0; i < output8_dims_count; ++i) {
output8_data[i] = 23;
}
TfLiteSplitVParams builtin_data;
builtin_data.num_splits = 8;
int inputs_array_data[] = {3, 0, 1, 2};
TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
int outputs_array_data[] = {8, 3, 4, 5, 6, 7, 8, 9, 10};
TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
TfLiteIntArray* temporaries_array = IntArrayFromInts({0});
void* user_data = nullptr;
TfLiteNode node;
node.inputs = inputs_array;
node.outputs = outputs_array;
node.user_data = user_data;
node.builtin_data = reinterpret_cast<void*>(&builtin_data);
node.custom_initial_data = nullptr;
node.custom_initial_data_size = 0;
const TfLiteRegistration registration =
tflite::ops::micro::Register_SPLIT_V();
micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
outputs_array, nullptr, micro_test::reporter);
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
for (int i = 0; i < output1_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output1_data[i], output1_data[i], 1e-5f);
}
for (int i = 0; i < output2_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output2_data[i], output2_data[i], 1e-5f);
}
for (int i = 0; i < output3_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output3_data[i], output3_data[i], 1e-5f);
}
for (int i = 0; i < output4_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output4_data[i], output4_data[i], 1e-5f);
}
for (int i = 0; i < output5_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output5_data[i], output5_data[i], 1e-5f);
}
for (int i = 0; i < output6_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output6_data[i], output6_data[i], 1e-5f);
}
for (int i = 0; i < output7_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output7_data[i], output7_data[i], 1e-5f);
}
for (int i = 0; i < output8_dims_count; ++i) {
TF_LITE_MICRO_EXPECT_NEAR(expected_output8_data[i], output8_data[i], 1e-5f);
} }
} }
@ -372,11 +135,23 @@ TF_LITE_MICRO_TEST(SPLIT_V_ThreeOutputs) {
float output2_values[] = {4, 5, 6}; float output2_values[] = {4, 5, 6};
int output3_shape[] = {2, 2, 3}; int output3_shape[] = {2, 2, 3};
float output3_values[] = {7, 8, 9, 10, 11, 12}; float output3_values[] = {7, 8, 9, 10, 11, 12};
tflite::testing::TestSplitVThreeOutputsFloat(
input_shape, input_values, axis_shape, axis_values, split_shape, tflite::testing::OutputTensors<3> output_tensors;
split_values, output1_shape, output1_values, output2_shape, output_tensors.data[0] = output1_data;
output2_values, output3_shape, output3_values, output1_data, output2_data, output_tensors.data[1] = output2_data;
output3_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);
} }
TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis0) { TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis0) {
@ -389,17 +164,28 @@ TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis0) {
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16}; 9, 10, 11, 12, 13, 14, 15, 16};
int axis_shape[] = {1, 1}; int axis_shape[] = {1, 1};
int axis_value[] = {0}; int axis_values[] = {0};
int split_size_shape[] = {1, 2}; int split_shape[] = {1, 2};
int split_data[] = {1, 1}; int split_values[] = {1, 1};
int output1_shape[] = {4, 1, 2, 2, 2}; int output1_shape[] = {4, 1, 2, 2, 2};
float output1_values[] = {1, 2, 3, 4, 5, 6, 7, 8}; float output1_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
int output2_shape[] = {4, 1, 2, 2, 2}; int output2_shape[] = {4, 1, 2, 2, 2};
float output2_values[] = {9, 10, 11, 12, 13, 14, 15, 16}; float output2_values[] = {9, 10, 11, 12, 13, 14, 15, 16};
tflite::testing::TestSplitVTwoOutputsFloat(
input_shape, input_values, axis_shape, axis_value, split_size_shape, tflite::testing::OutputTensors<2> output_tensors;
split_data, output1_shape, output1_values, output2_shape, output2_values,
output1_data, output2_data); 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);
} }
TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis1) { TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis1) {
@ -412,17 +198,28 @@ TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis1) {
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16}; 9, 10, 11, 12, 13, 14, 15, 16};
int axis_shape[] = {1, 1}; int axis_shape[] = {1, 1};
int axis_value[] = {1}; int axis_values[] = {1};
int split_size_shape[] = {1, 2}; int split_shape[] = {1, 2};
int split_data[] = {1, 1}; int split_values[] = {1, 1};
int output1_shape[] = {4, 2, 1, 2, 2}; int output1_shape[] = {4, 2, 1, 2, 2};
float output1_values[] = {1, 2, 3, 4, 9, 10, 11, 12}; float output1_values[] = {1, 2, 3, 4, 9, 10, 11, 12};
int output2_shape[] = {4, 2, 1, 2, 2}; int output2_shape[] = {4, 2, 1, 2, 2};
float output2_values[] = {5, 6, 7, 8, 13, 14, 15, 16}; float output2_values[] = {5, 6, 7, 8, 13, 14, 15, 16};
tflite::testing::TestSplitVTwoOutputsFloat(
input_shape, input_values, axis_shape, axis_value, split_size_shape, tflite::testing::OutputTensors<2> output_tensors;
split_data, output1_shape, output1_values, output2_shape, output2_values,
output1_data, output2_data); 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);
} }
TF_LITE_MICRO_TEST(SPLIT_VFourDimensionalFloatAxis2) { TF_LITE_MICRO_TEST(SPLIT_VFourDimensionalFloatAxis2) {
@ -435,17 +232,28 @@ TF_LITE_MICRO_TEST(SPLIT_VFourDimensionalFloatAxis2) {
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16}; 9, 10, 11, 12, 13, 14, 15, 16};
int axis_shape[] = {1, 1}; int axis_shape[] = {1, 1};
int axis_value[] = {2}; int axis_values[] = {2};
int split_size_shape[] = {1, 2}; int split_shape[] = {1, 2};
int split_data[] = {1, 1}; int split_values[] = {1, 1};
int output1_shape[] = {4, 2, 2, 1, 2}; int output1_shape[] = {4, 2, 2, 1, 2};
float output1_values[] = {1, 2, 5, 6, 9, 10, 13, 14}; float output1_values[] = {1, 2, 5, 6, 9, 10, 13, 14};
int output2_shape[] = {4, 2, 2, 1, 2}; int output2_shape[] = {4, 2, 2, 1, 2};
float output2_values[] = {3, 4, 7, 8, 11, 12, 15, 16}; float output2_values[] = {3, 4, 7, 8, 11, 12, 15, 16};
tflite::testing::TestSplitVTwoOutputsFloat(
input_shape, input_values, axis_shape, axis_value, split_size_shape, tflite::testing::OutputTensors<2> output_tensors;
split_data, output1_shape, output1_values, output2_shape, output2_values,
output1_data, output2_data); 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);
} }
TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis3) { TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis3) {
@ -457,17 +265,28 @@ TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatAxis3) {
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16}; 9, 10, 11, 12, 13, 14, 15, 16};
int axis_shape[] = {1, 1}; int axis_shape[] = {1, 1};
int axis_value[] = {3}; int axis_values[] = {3};
int split_size_shape[] = {1, 2}; int split_shape[] = {1, 2};
int split_data[] = {1, 1}; int split_values[] = {1, 1};
int output1_shape[] = {4, 2, 2, 2, 1}; int output1_shape[] = {4, 2, 2, 2, 1};
float output1_values[] = {1, 3, 5, 7, 9, 11, 13, 15}; float output1_values[] = {1, 3, 5, 7, 9, 11, 13, 15};
int output2_shape[] = {4, 2, 2, 2, 1}; int output2_shape[] = {4, 2, 2, 2, 1};
float output2_values[] = {2, 4, 6, 8, 10, 12, 14, 16}; float output2_values[] = {2, 4, 6, 8, 10, 12, 14, 16};
tflite::testing::TestSplitVTwoOutputsFloat(
input_shape, input_values, axis_shape, axis_value, split_size_shape, tflite::testing::OutputTensors<2> output_tensors;
split_data, output1_shape, output1_values, output2_shape, output2_values,
output1_data, output2_data); 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);
} }
TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatNegativeAxis) { TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatNegativeAxis) {
@ -480,17 +299,28 @@ TF_LITE_MICRO_TEST(SPLIT_V_FourDimensionalFloatNegativeAxis) {
float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8, float input_values[] = {1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16}; 9, 10, 11, 12, 13, 14, 15, 16};
int axis_shape[] = {1, 1}; int axis_shape[] = {1, 1};
int axis_value[] = {-4}; int axis_values[] = {-4};
int split_size_shape[] = {1, 2}; int split_shape[] = {1, 2};
int split_data[] = {1, 1}; int split_values[] = {1, 1};
int output1_shape[] = {4, 1, 2, 2, 2}; int output1_shape[] = {4, 1, 2, 2, 2};
float output1_values[] = {1, 2, 3, 4, 5, 6, 7, 8}; float output1_values[] = {1, 2, 3, 4, 5, 6, 7, 8};
int output2_shape[] = {4, 1, 2, 2, 2}; int output2_shape[] = {4, 1, 2, 2, 2};
float output2_values[] = {9, 10, 11, 12, 13, 14, 15, 16}; float output2_values[] = {9, 10, 11, 12, 13, 14, 15, 16};
tflite::testing::TestSplitVTwoOutputsFloat(
input_shape, input_values, axis_shape, axis_value, split_size_shape, tflite::testing::OutputTensors<2> output_tensors;
split_data, output1_shape, output1_values, output2_shape, output2_values,
output1_data, output2_data); 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);
} }
TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatAxis0) { TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatAxis0) {
@ -536,16 +366,39 @@ TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatAxis0) {
float output7_values[] = {7}; float output7_values[] = {7};
int output8_shape[] = {1, 1}; int output8_shape[] = {1, 1};
float output8_values[] = {8}; float output8_values[] = {8};
tflite::testing::TestSplitVEightOutputsFloat(
input_shape, input_values, axis_shape, axis_value, split_size_shape, tflite::testing::OutputTensors<8> output_tensors;
split, output1_shape, output1_values, output2_shape, output2_values,
output3_shape, output3_values, output4_shape, output4_values, output_tensors.data[0] = output1_data;
output5_shape, output5_values, output6_shape, output6_values, output_tensors.data[1] = output2_data;
output7_shape, output7_values, output8_shape, output8_values, output_tensors.data[2] = output3_data;
output1_data, output_tensors.data[3] = output4_data;
output2_data, // locally allocated output buffers output_tensors.data[4] = output5_data;
output3_data, output4_data, output5_data, output6_data, output7_data, output_tensors.data[5] = output6_data;
output8_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);
} }
TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatTest2) { TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatTest2) {
@ -591,16 +444,39 @@ TF_LITE_MICRO_TEST(SPLIT_V_OneDimensionalFloatTest2) {
float output7_values[] = {7, 8}; float output7_values[] = {7, 8};
int output8_shape[] = {1, 0}; int output8_shape[] = {1, 0};
float output8_values[1] = {}; float output8_values[1] = {};
tflite::testing::TestSplitVEightOutputsFloat(
input_shape, input_values, axis_shape, axis_value, split_size_shape, tflite::testing::OutputTensors<8> output_tensors;
split, output1_shape, output1_values, output2_shape, output2_values,
output3_shape, output3_values, output4_shape, output4_values, output_tensors.data[0] = output1_data;
output5_shape, output5_values, output6_shape, output6_values, output_tensors.data[1] = output2_data;
output7_shape, output7_values, output8_shape, output8_values, output_tensors.data[2] = output3_data;
output1_data, output_tensors.data[3] = output4_data;
output2_data, // locally allocated output buffers output_tensors.data[4] = output5_data;
output3_data, output4_data, output5_data, output6_data, output7_data, output_tensors.data[5] = output6_data;
nullptr); 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_END TF_LITE_MICRO_TESTS_END