1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #include "tensorflow/lite/c/builtin_op_data.h"
17 #include "tensorflow/lite/c/common.h"
18 #include "tensorflow/lite/micro/kernels/kernel_runner.h"
19 #include "tensorflow/lite/micro/test_helpers.h"
20 #include "tensorflow/lite/micro/testing/micro_test.h"
21
22 namespace tflite {
23 namespace testing {
24 namespace {
25
26 template <typename T>
ValidatePreluGoldens(TfLiteTensor * tensors,int tensors_size,const T * golden,const int output_length,T * output_data)27 void ValidatePreluGoldens(TfLiteTensor* tensors, int tensors_size,
28 const T* golden, const int output_length,
29 T* output_data) {
30 int inputs_array_data[] = {2, 0, 1};
31 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
32 int outputs_array_data[] = {1, 2};
33 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
34
35 const TfLiteRegistration registration = tflite::ops::micro::Register_PRELU();
36 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
37 outputs_array,
38 /*builtin_data=*/nullptr);
39
40 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
41 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
42
43 for (int i = 0; i < output_length; ++i) {
44 TF_LITE_MICRO_EXPECT_NEAR(golden[i], output_data[i], 1e-5f);
45 }
46 }
47
TestPreluFloat(int * input_dims_data,const float * input_data,int * alpha_dims_data,const float * alpha_data,const float * expected_output_data,int * output_dims_data,float * output_data)48 void TestPreluFloat(int* input_dims_data, const float* input_data,
49 int* alpha_dims_data, const float* alpha_data,
50 const float* expected_output_data, int* output_dims_data,
51 float* output_data) {
52 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
53 TfLiteIntArray* alpha_dims = IntArrayFromInts(alpha_dims_data);
54 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
55 const int output_dims_count = ElementCount(*output_dims);
56 constexpr int inputs_size = 2;
57 constexpr int outputs_size = 1;
58 constexpr int tensors_size = inputs_size + outputs_size;
59 TfLiteTensor tensors[tensors_size] = {
60 CreateTensor(input_data, input_dims),
61 CreateTensor(alpha_data, alpha_dims),
62 CreateTensor(output_data, output_dims),
63 };
64
65 ValidatePreluGoldens(tensors, tensors_size, expected_output_data,
66 output_dims_count, output_data);
67 }
68
69 // Template argument T can be either uint8_t or int8_t depending on which type
70 // of quantization required to be tested.
71 template <typename T>
TestPreluQuantized(int * input_dims_data,const float * input_data,T * input_quantized,const float input_scale,const int input_zero_point,int * alpha_dims_data,const float * alpha_data,T * alpha_quantized,const float alpha_scale,const int alpha_zero_point,const float * golden,T * golden_quantized,const float output_scale,const int output_zero_point,int * output_dims_data,T * output_data)72 void TestPreluQuantized(int* input_dims_data, const float* input_data,
73 T* input_quantized, const float input_scale,
74 const int input_zero_point, int* alpha_dims_data,
75 const float* alpha_data, T* alpha_quantized,
76 const float alpha_scale, const int alpha_zero_point,
77 const float* golden, T* golden_quantized,
78 const float output_scale, const int output_zero_point,
79 int* output_dims_data, T* output_data) {
80 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
81 TfLiteIntArray* alpha_dims = IntArrayFromInts(alpha_dims_data);
82 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
83 const int output_dims_count = ElementCount(*output_dims);
84 constexpr int inputs_size = 2;
85 constexpr int outputs_size = 1;
86 constexpr int tensors_size = inputs_size + outputs_size;
87 TfLiteTensor tensors[tensors_size] = {
88 CreateQuantizedTensor(input_data, input_quantized, input_dims,
89 input_scale, input_zero_point),
90 CreateQuantizedTensor(alpha_data, alpha_quantized, alpha_dims,
91 alpha_scale, alpha_zero_point),
92 CreateQuantizedTensor(output_data, output_dims, output_scale,
93 output_zero_point),
94 };
95
96 Quantize(golden, golden_quantized, output_dims_count, output_scale,
97 output_zero_point);
98
99 ValidatePreluGoldens(tensors, tensors_size, golden_quantized,
100 output_dims_count, output_data);
101 }
102 } // namespace
103 } // namespace testing
104 } // namespace tflite
105
106 TF_LITE_MICRO_TESTS_BEGIN
107
TF_LITE_MICRO_TEST(FloatPreluActivationsOpTest)108 TF_LITE_MICRO_TEST(FloatPreluActivationsOpTest) {
109 int input_shape[] = {3, 2, 2, 3};
110 const float input_values[] = {
111 0.0f, 0.0f, 0.0f, // Row 1, Column 1
112 1.0f, 1.0f, 1.0f, // Row 1, Column 2
113 -1.0f, -1.0f, -1.0f, // Row 2, Column 1
114 -2.0f, -2.0f, -2.0f, // Row 1, Column 2
115 };
116 int alpha_shape[] = {3, 1, 1, 3};
117 const float alpha_values[] = {0.0f, 1.0f, 2.0f};
118 int output_shape[] = {3, 2, 2, 3};
119 const float golden[] = {
120 0.0f, 0.0f, 0.0f, // Row 1, Column 1
121 1.0f, 1.0f, 1.0f, // Row 1, Column 2
122 0.0f, -1.0f, -2.0f, // Row 2, Column 1
123 0.0f, -2.0f, -4.0f, // Row 1, Column 2
124 };
125 const int output_dims_count = 12;
126 float output_data[output_dims_count];
127 tflite::testing::TestPreluFloat(input_shape, input_values, alpha_shape,
128 alpha_values, golden, output_shape,
129 output_data);
130 }
131
TF_LITE_MICRO_TEST(QuantizedUint8PreluActivationsOpTest)132 TF_LITE_MICRO_TEST(QuantizedUint8PreluActivationsOpTest) {
133 int input_shape[] = {3, 2, 2, 3};
134 const float input_values[] = {
135 0.0f, 0.0f, 0.0f, // Row 1, Column 1
136 0.5f, 0.5f, 0.5f, // Row 1, Column 2
137 -1.0f, -1.0f, -1.0f, // Row 2, Column 1
138 -0.25f, -0.25f, -0.25f, // Row 1, Column 2
139 };
140 int alpha_shape[] = {3, 1, 1, 3};
141 const float alpha_values[] = {0.0f, 0.5f, -0.5f};
142 int output_shape[] = {3, 2, 2, 3};
143 const float golden[] = {
144 0.0f, 0.0f, 0.0f, // Row 1, Column 1
145 0.5f, 0.5f, 0.5f, // Row 1, Column 2
146 0.0f, -0.5f, 0.5f, // Row 2, Column 1
147 0.0f, -0.125f, 0.125f, // Row 1, Column 2
148 };
149
150 const int dims_count = 12;
151
152 uint8_t input_quantized[dims_count];
153 uint8_t alpha_quantized[3];
154 uint8_t golden_quantized[dims_count];
155 float scale = 0.125;
156 int zero_point = 127;
157 uint8_t output_data[dims_count];
158
159 tflite::testing::TestPreluQuantized(
160 input_shape, input_values, input_quantized, scale, zero_point,
161 alpha_shape, alpha_values, alpha_quantized, scale, zero_point, golden,
162 golden_quantized, scale, zero_point, output_shape, output_data);
163 }
164
TF_LITE_MICRO_TEST(QuantizedInt8PreluActivationsOpTest)165 TF_LITE_MICRO_TEST(QuantizedInt8PreluActivationsOpTest) {
166 int input_shape[] = {3, 2, 2, 3};
167 const float input_values[] = {
168 0.0f, 0.0f, 0.0f, // Row 1, Column 1
169 0.5f, 0.5f, 0.5f, // Row 1, Column 2
170 -1.0f, -1.0f, -1.0f, // Row 2, Column 1
171 -0.25f, -0.25f, -0.25f, // Row 1, Column 2
172 };
173 int alpha_shape[] = {3, 1, 1, 3};
174 const float alpha_values[] = {0.0f, 0.5f, -0.5f};
175 int output_shape[] = {3, 2, 2, 3};
176 const float golden[] = {
177 0.0f, 0.0f, 0.0f, // Row 1, Column 1
178 0.5f, 0.5f, 0.5f, // Row 1, Column 2
179 0.0f, -0.5f, 0.5f, // Row 2, Column 1
180 0.0f, -0.125f, 0.125f, // Row 1, Column 2
181 };
182 const int dims_count = 12;
183 int8_t input_quantized[dims_count];
184 int8_t alpha_quantized[3];
185 int8_t golden_quantized[dims_count];
186 float scale = 2.0 / 255.0;
187 int zero_point = 0;
188 int8_t output_data[dims_count];
189 tflite::testing::TestPreluQuantized(
190 input_shape, input_values, input_quantized, scale, zero_point,
191 alpha_shape, alpha_values, alpha_quantized, scale, zero_point, golden,
192 golden_quantized, scale, zero_point, output_shape, output_data);
193 }
194 TF_LITE_MICRO_TESTS_END
195