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/common.h"
17 #include "tensorflow/lite/micro/all_ops_resolver.h"
18 #include "tensorflow/lite/micro/debug_log.h"
19 #include "tensorflow/lite/micro/kernels/kernel_runner.h"
20 #include "tensorflow/lite/micro/test_helpers.h"
21 #include "tensorflow/lite/micro/testing/micro_test.h"
22
23 namespace tflite {
24 namespace testing {
25
TestElementwiseFloat(const TfLiteRegistration & registration,const int * input_dims_data,const float * input_data,const int * output_dims_data,const float * expected_output_data,float * output_data)26 void TestElementwiseFloat(const TfLiteRegistration& registration,
27 const int* input_dims_data, const float* input_data,
28 const int* output_dims_data,
29 const float* expected_output_data,
30 float* output_data) {
31 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
32 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
33 const int output_dims_count = ElementCount(*output_dims);
34
35 constexpr int input_size = 1;
36 constexpr int output_size = 1;
37 constexpr int tensors_size = input_size + output_size;
38 TfLiteTensor tensors[tensors_size] = {CreateTensor(input_data, input_dims),
39 CreateTensor(output_data, output_dims)};
40
41 // Place a unique value in the uninitialized output buffer.
42 for (int i = 0; i < output_dims_count; ++i) {
43 output_data[i] = 23;
44 }
45
46 static int inputs_array_data[] = {1, 0};
47 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
48 static int outputs_array_data[] = {1, 1};
49 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
50
51 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
52 outputs_array,
53 /*builtin_data=*/nullptr);
54
55 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
56 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
57
58 for (int i = 0; i < output_dims_count; ++i) {
59 TF_LITE_MICRO_EXPECT_NEAR(expected_output_data[i], output_data[i], 1e-5f);
60 }
61 }
62
TestElementwiseBool(const TfLiteRegistration & registration,const int * input_dims_data,const bool * input_data,const int * output_dims_data,const bool * expected_output_data,bool * output_data)63 void TestElementwiseBool(const TfLiteRegistration& registration,
64 const int* input_dims_data, const bool* input_data,
65 const int* output_dims_data,
66 const bool* expected_output_data, bool* output_data) {
67 TfLiteIntArray* input_dims = IntArrayFromInts(input_dims_data);
68 TfLiteIntArray* output_dims = IntArrayFromInts(output_dims_data);
69 const int output_dims_count = ElementCount(*output_dims);
70
71 constexpr int input_size = 1;
72 constexpr int output_size = 1;
73 constexpr int tensors_size = input_size + output_size;
74 TfLiteTensor tensors[tensors_size] = {CreateTensor(input_data, input_dims),
75 CreateTensor(output_data, output_dims)};
76
77 // Place false in the uninitialized output buffer.
78 for (int i = 0; i < output_dims_count; ++i) {
79 output_data[i] = false;
80 }
81
82 const int inputs_array_data[] = {1, 0};
83 TfLiteIntArray* inputs_array = IntArrayFromInts(inputs_array_data);
84 const int outputs_array_data[] = {1, 1};
85 TfLiteIntArray* outputs_array = IntArrayFromInts(outputs_array_data);
86
87 micro::KernelRunner runner(registration, tensors, tensors_size, inputs_array,
88 outputs_array,
89 /*builtin_data=*/nullptr);
90
91 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.InitAndPrepare());
92 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, runner.Invoke());
93
94 for (int i = 0; i < output_dims_count; ++i) {
95 TF_LITE_MICRO_EXPECT_EQ(expected_output_data[i], output_data[i]);
96 }
97 }
98
99 } // namespace testing
100 } // namespace tflite
101
102 TF_LITE_MICRO_TESTS_BEGIN
103
TF_LITE_MICRO_TEST(Abs)104 TF_LITE_MICRO_TEST(Abs) {
105 constexpr int output_dims_count = 4;
106 const int shape[] = {2, 2, 2};
107 const float input[] = {0.01, -0.01, 10, -10};
108 const float golden[] = {0.01, 0.01, 10, 10};
109 float output_data[output_dims_count];
110 tflite::testing::TestElementwiseFloat(tflite::ops::micro::Register_ABS(),
111 shape, input, shape, golden,
112 output_data);
113 }
114
TF_LITE_MICRO_TEST(Sin)115 TF_LITE_MICRO_TEST(Sin) {
116 constexpr int output_dims_count = 4;
117 const int shape[] = {2, 2, 2};
118 const float input[] = {0, 3.1415926, -3.1415926, 1};
119 const float golden[] = {0, 0, 0, 0.84147};
120 float output_data[output_dims_count];
121 tflite::testing::TestElementwiseFloat(tflite::ops::micro::Register_SIN(),
122 shape, input, shape, golden,
123 output_data);
124 }
125
TF_LITE_MICRO_TEST(Cos)126 TF_LITE_MICRO_TEST(Cos) {
127 constexpr int output_dims_count = 4;
128 const int shape[] = {2, 2, 2};
129 const float input[] = {0, 3.1415926, -3.1415926, 1};
130 const float golden[] = {1, -1, -1, 0.54030};
131 float output_data[output_dims_count];
132 tflite::testing::TestElementwiseFloat(tflite::ops::micro::Register_COS(),
133 shape, input, shape, golden,
134 output_data);
135 }
136
TF_LITE_MICRO_TEST(Log)137 TF_LITE_MICRO_TEST(Log) {
138 constexpr int output_dims_count = 4;
139 const int shape[] = {2, 2, 2};
140 const float input[] = {1, 2.7182818, 0.5, 2};
141 const float golden[] = {0, 1, -0.6931472, 0.6931472};
142 float output_data[output_dims_count];
143 tflite::testing::TestElementwiseFloat(tflite::ops::micro::Register_LOG(),
144 shape, input, shape, golden,
145 output_data);
146 }
147
TF_LITE_MICRO_TEST(Sqrt)148 TF_LITE_MICRO_TEST(Sqrt) {
149 constexpr int output_dims_count = 4;
150 const int shape[] = {2, 2, 2};
151 const float input[] = {0, 1, 2, 4};
152 const float golden[] = {0, 1, 1.41421, 2};
153 float output_data[output_dims_count];
154 tflite::testing::TestElementwiseFloat(tflite::ops::micro::Register_SQRT(),
155 shape, input, shape, golden,
156 output_data);
157 }
158
TF_LITE_MICRO_TEST(Rsqrt)159 TF_LITE_MICRO_TEST(Rsqrt) {
160 constexpr int output_dims_count = 4;
161 const int shape[] = {2, 2, 2};
162 const float input[] = {1, 2, 4, 9};
163 const float golden[] = {1, 0.7071, 0.5, 0.33333};
164 float output_data[output_dims_count];
165 tflite::testing::TestElementwiseFloat(tflite::ops::micro::Register_RSQRT(),
166 shape, input, shape, golden,
167 output_data);
168 }
169
TF_LITE_MICRO_TEST(Square)170 TF_LITE_MICRO_TEST(Square) {
171 constexpr int output_dims_count = 4;
172 const int shape[] = {2, 2, 2};
173 const float input[] = {1, 2, 0.5, -3.0};
174 const float golden[] = {1, 4.0, 0.25, 9.0};
175 float output_data[output_dims_count];
176 tflite::testing::TestElementwiseFloat(tflite::ops::micro::Register_SQUARE(),
177 shape, input, shape, golden,
178 output_data);
179 }
180
TF_LITE_MICRO_TEST(LogicalNot)181 TF_LITE_MICRO_TEST(LogicalNot) {
182 constexpr int output_dims_count = 4;
183 const int shape[] = {2, 2, 2};
184 const bool input[] = {true, false, false, true};
185 const bool golden[] = {false, true, true, false};
186 bool output_data[output_dims_count];
187 tflite::testing::TestElementwiseBool(
188 tflite::ops::micro::Register_LOGICAL_NOT(), shape, input, shape, golden,
189 output_data);
190 }
191
192 TF_LITE_MICRO_TESTS_END
193