tflite-micro/tensorflow/lite/micro/kernels/conv_test_common.cc
Esun Kim 63d4dbd332
[T2] Refactor Group 9z: Compression (#3393)
* Refactor t2-9z

Refactor t2-11z

Refactor t2-19z

Refactor t2-7z

* Fix

* Review
2026-02-03 17:50:04 +00:00

198 lines
9.6 KiB
C++

/* Copyright 2024 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/micro/kernels/conv_test.h"
namespace tflite {
namespace testing {
void ValidateConvFailsDuringPrepare(TfLiteTensor* tensors, int tensors_size,
const TfLiteConvParams* conv_params,
TFLMRegistration registration,
void* output_data) {
// TODO(b/358165875): support optional bias tensor
int inputs_array_data[] = {3, 0, 1, 2};
TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
int outputs_array_data[] = {1, 3};
TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
outputs_array, conv_params);
const char* init_data = reinterpret_cast<const char*>(conv_params);
EXPECT_NE(runner.InitAndPrepare(init_data), kTfLiteOk);
}
void TestConvFloat(int* input_dims_data, const float* input_data,
int* filter_dims_data, const float* filter_data,
int* bias_dims_data, const float* bias_data,
int* output_dims_data, const float* expected_output_data,
TfLiteConvParams* conv_params, TFLMRegistration registration,
float* output_data
#ifdef USE_TFLM_COMPRESSION
,
const TestCompressionInfo<const float>* filter_comp_info,
const TestCompressionInfo<const float>* bias_comp_info
#endif // USE_TFLM_COMPRESSION
) {
TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
TfLiteIntArray* filter_dims = IntArrayFromInts(filter_dims_data);
TfLiteIntArray* bias_dims = IntArrayFromInts(bias_dims_data);
TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
const int output_dims_count = ElementCount(*output_dims);
constexpr int inputs_size = 3;
constexpr int outputs_size = 1;
constexpr int tensors_size = inputs_size + outputs_size;
TfLiteTensor tensors[tensors_size] = {
CreateTensor(input_data, input_dims),
CreateTensor(filter_data, filter_dims),
CreateTensor(bias_data, bias_dims),
CreateTensor(output_data, output_dims),
};
ValidateConvGoldens(tensors, tensors_size, expected_output_data,
output_dims_count, conv_params, registration, output_data
#ifdef USE_TFLM_COMPRESSION
,
1e-5f, filter_comp_info, bias_comp_info
#endif // USE_TFLM_COMPRESSION
);
}
template <typename T, typename BiasT>
void TestConvQuantizedPerChannel(
int* input_dims_data, const float* input_data, T* input_quantized,
float input_scale, int input_zero_point, int* filter_dims_data,
const float* filter_data, int8_t* filter_data_quantized,
int* bias_dims_data, const float* bias_data, BiasT* bias_data_quantized,
float* bias_scales, int* bias_zero_points, int* output_dims_data,
const float* expected_output_data, T* expected_output_data_quantized,
float output_scale, int output_zero_point, TfLiteConvParams* conv_params,
TFLMRegistration registration, T* output_data,
TfLiteType tensor_weight_type = kTfLiteNoType) {
TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
TfLiteIntArray* filter_dims = IntArrayFromInts(filter_dims_data);
TfLiteIntArray* bias_dims = IntArrayFromInts(bias_dims_data);
TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
const int output_dims_count = ElementCount(*output_dims);
int filter_zero_points[5];
float filter_scales[5];
TfLiteAffineQuantization filter_quant;
TfLiteAffineQuantization bias_quant;
TfLiteTensor input_tensor = CreateQuantizedTensor(
input_data, input_quantized, input_dims, input_scale, input_zero_point);
TfLiteTensor filter_tensor = CreateSymmetricPerChannelQuantizedTensor(
filter_data, filter_data_quantized, filter_dims, filter_scales,
filter_zero_points, &filter_quant, 0 /* quantized dimension */, false,
tensor_weight_type);
TfLiteTensor bias_tensor = CreatePerChannelQuantizedBiasTensor(
bias_data, bias_data_quantized, bias_dims, input_scale, &filter_scales[1],
bias_scales, bias_zero_points, &bias_quant, 0 /* quantized dimension */);
TfLiteTensor output_tensor = CreateQuantizedTensor(
output_data, output_dims, output_scale, output_zero_point);
float input_scales[] = {1, input_scale};
int input_zero_points[] = {1, input_zero_point};
TfLiteAffineQuantization input_quant = {FloatArrayFromFloats(input_scales),
IntArrayFromInts(input_zero_points),
0};
input_tensor.quantization = {kTfLiteAffineQuantization, &input_quant};
float output_scales[] = {1, output_scale};
int output_zero_points[] = {1, output_zero_point};
TfLiteAffineQuantization output_quant = {FloatArrayFromFloats(output_scales),
IntArrayFromInts(output_zero_points),
0};
output_tensor.quantization = {kTfLiteAffineQuantization, &output_quant};
constexpr int inputs_size = 3;
constexpr int outputs_size = 1;
constexpr int tensors_size = inputs_size + outputs_size;
TfLiteTensor tensors[tensors_size] = {
input_tensor,
filter_tensor,
bias_tensor,
output_tensor,
};
tflite::Quantize(expected_output_data, expected_output_data_quantized,
output_dims_count, output_scale, output_zero_point);
return ValidateConvGoldens(
tensors, tensors_size, expected_output_data_quantized, output_dims_count,
conv_params, registration, output_data, 1.0 /* tolerance */);
}
// Test conv with int8 input, int8 weight, int32 bias, int32 accumulator
void TestConvQuantizedPerChannel(
int* input_dims_data, const float* input_data, int8_t* input_quantized,
float input_scale, int input_zero_point, int* filter_dims_data,
const float* filter_data, int8_t* filter_data_quantized,
int* bias_dims_data, const float* bias_data, int32_t* bias_data_quantized,
float* bias_scales, int* bias_zero_points, int* output_dims_data,
const float* expected_output_data, int8_t* expected_output_data_quantized,
float output_scale, int output_zero_point, TfLiteConvParams* conv_params,
TFLMRegistration registration, int8_t* output_data,
TfLiteType tensor_weight_type) {
TestConvQuantizedPerChannel<int8_t, int32_t>(
input_dims_data, input_data, input_quantized, input_scale,
input_zero_point, filter_dims_data, filter_data, filter_data_quantized,
bias_dims_data, bias_data, bias_data_quantized, bias_scales,
bias_zero_points, output_dims_data, expected_output_data,
expected_output_data_quantized, output_scale, output_zero_point,
conv_params, registration, output_data, tensor_weight_type);
}
// Test conv with int16 input, int8 weight, int64 bias, int64 accumulator
void TestConvQuantizedPerChannel(
int* input_dims_data, const float* input_data, int16_t* input_quantized,
float input_scale, int input_zero_point, int* filter_dims_data,
const float* filter_data, int8_t* filter_data_quantized,
int* bias_dims_data, const float* bias_data,
std::int64_t* bias_data_quantized, float* bias_scales,
int* bias_zero_points, int* output_dims_data,
const float* expected_output_data, int16_t* expected_output_data_quantized,
float output_scale, int output_zero_point, TfLiteConvParams* conv_params,
TFLMRegistration registration, int16_t* output_data) {
return TestConvQuantizedPerChannel<int16_t, std::int64_t>(
input_dims_data, input_data, input_quantized, input_scale,
input_zero_point, filter_dims_data, filter_data, filter_data_quantized,
bias_dims_data, bias_data, bias_data_quantized, bias_scales,
bias_zero_points, output_dims_data, expected_output_data,
expected_output_data_quantized, output_scale, output_zero_point,
conv_params, registration, output_data);
}
// Test conv with int16 input, int8 weight, int32 bias, int32 accumulator
void TestConvQuantizedPerChannel(
int* input_dims_data, const float* input_data, int16_t* input_quantized,
float input_scale, int input_zero_point, int* filter_dims_data,
const float* filter_data, int8_t* filter_data_quantized,
int* bias_dims_data, const float* bias_data, int32_t* bias_data_quantized,
float* bias_scales, int* bias_zero_points, int* output_dims_data,
const float* expected_output_data, int16_t* expected_output_data_quantized,
float output_scale, int output_zero_point, TfLiteConvParams* conv_params,
TFLMRegistration registration, int16_t* output_data) {
TestConvQuantizedPerChannel<int16_t, int32_t>(
input_dims_data, input_data, input_quantized, input_scale,
input_zero_point, filter_dims_data, filter_data, filter_data_quantized,
bias_dims_data, bias_data, bias_data_quantized, bias_scales,
bias_zero_points, output_dims_data, expected_output_data,
expected_output_data_quantized, output_scale, output_zero_point,
conv_params, registration, output_data);
}
} // namespace testing
} // namespace tflite