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/micro/memory_helpers.h"
17
18 #include "tensorflow/lite/micro/micro_error_reporter.h"
19 #include "tensorflow/lite/micro/test_helpers.h"
20 #include "tensorflow/lite/micro/testing/micro_test.h"
21
22 namespace {
23
24 // This just needs to be big enough to handle the array of 5 ints allocated
25 // in TestAllocateOutputDimensionsFromInput below.
26 const int kGlobalPersistentBufferLength = 100;
27 char global_persistent_buffer[kGlobalPersistentBufferLength];
28
29 // Only need to handle a single allocation at a time for output dimensions
30 // in TestAllocateOutputDimensionsFromInput.
FakeAllocatePersistentBuffer(TfLiteContext * context,size_t bytes)31 void* FakeAllocatePersistentBuffer(TfLiteContext* context, size_t bytes) {
32 return reinterpret_cast<void*>(global_persistent_buffer);
33 }
34
35 } // namespace
36
37 TF_LITE_MICRO_TESTS_BEGIN
38
TF_LITE_MICRO_TEST(TestAlignPointerUp)39 TF_LITE_MICRO_TEST(TestAlignPointerUp) {
40 uint8_t* input0 = reinterpret_cast<uint8_t*>(0);
41
42 uint8_t* input0_aligned1 = tflite::AlignPointerUp(input0, 1);
43 TF_LITE_MICRO_EXPECT(input0 == input0_aligned1);
44
45 uint8_t* input0_aligned2 = tflite::AlignPointerUp(input0, 2);
46 TF_LITE_MICRO_EXPECT(input0 == input0_aligned2);
47
48 uint8_t* input0_aligned3 = tflite::AlignPointerUp(input0, 3);
49 TF_LITE_MICRO_EXPECT(input0 == input0_aligned3);
50
51 uint8_t* input0_aligned16 = tflite::AlignPointerUp(input0, 16);
52 TF_LITE_MICRO_EXPECT(input0 == input0_aligned16);
53
54 uint8_t* input23 = reinterpret_cast<uint8_t*>(23);
55
56 uint8_t* input23_aligned1 = tflite::AlignPointerUp(input23, 1);
57 TF_LITE_MICRO_EXPECT(input23 == input23_aligned1);
58
59 uint8_t* input23_aligned2 = tflite::AlignPointerUp(input23, 2);
60 uint8_t* expected23_aligned2 = reinterpret_cast<uint8_t*>(24);
61 TF_LITE_MICRO_EXPECT(expected23_aligned2 == input23_aligned2);
62
63 uint8_t* input23_aligned3 = tflite::AlignPointerUp(input23, 3);
64 uint8_t* expected23_aligned3 = reinterpret_cast<uint8_t*>(24);
65 TF_LITE_MICRO_EXPECT(expected23_aligned3 == input23_aligned3);
66
67 uint8_t* input23_aligned16 = tflite::AlignPointerUp(input23, 16);
68 uint8_t* expected23_aligned16 = reinterpret_cast<uint8_t*>(32);
69 TF_LITE_MICRO_EXPECT(expected23_aligned16 == input23_aligned16);
70 }
71
TF_LITE_MICRO_TEST(TestAlignPointerDown)72 TF_LITE_MICRO_TEST(TestAlignPointerDown) {
73 uint8_t* input0 = reinterpret_cast<uint8_t*>(0);
74
75 uint8_t* input0_aligned1 = tflite::AlignPointerDown(input0, 1);
76 TF_LITE_MICRO_EXPECT(input0 == input0_aligned1);
77
78 uint8_t* input0_aligned2 = tflite::AlignPointerDown(input0, 2);
79 TF_LITE_MICRO_EXPECT(input0 == input0_aligned2);
80
81 uint8_t* input0_aligned3 = tflite::AlignPointerDown(input0, 3);
82 TF_LITE_MICRO_EXPECT(input0 == input0_aligned3);
83
84 uint8_t* input0_aligned16 = tflite::AlignPointerDown(input0, 16);
85 TF_LITE_MICRO_EXPECT(input0 == input0_aligned16);
86
87 uint8_t* input23 = reinterpret_cast<uint8_t*>(23);
88
89 uint8_t* input23_aligned1 = tflite::AlignPointerDown(input23, 1);
90 TF_LITE_MICRO_EXPECT(input23 == input23_aligned1);
91
92 uint8_t* input23_aligned2 = tflite::AlignPointerDown(input23, 2);
93 uint8_t* expected23_aligned2 = reinterpret_cast<uint8_t*>(22);
94 TF_LITE_MICRO_EXPECT(expected23_aligned2 == input23_aligned2);
95
96 uint8_t* input23_aligned3 = tflite::AlignPointerDown(input23, 3);
97 uint8_t* expected23_aligned3 = reinterpret_cast<uint8_t*>(21);
98 TF_LITE_MICRO_EXPECT(expected23_aligned3 == input23_aligned3);
99
100 uint8_t* input23_aligned16 = tflite::AlignPointerDown(input23, 16);
101 uint8_t* expected23_aligned16 = reinterpret_cast<uint8_t*>(16);
102 TF_LITE_MICRO_EXPECT(expected23_aligned16 == input23_aligned16);
103 }
104
TF_LITE_MICRO_TEST(TestAlignSizeUp)105 TF_LITE_MICRO_TEST(TestAlignSizeUp) {
106 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(1), tflite::AlignSizeUp(1, 1));
107 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(2), tflite::AlignSizeUp(1, 2));
108 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(3), tflite::AlignSizeUp(1, 3));
109 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(16), tflite::AlignSizeUp(1, 16));
110
111 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(23), tflite::AlignSizeUp(23, 1));
112 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(24), tflite::AlignSizeUp(23, 2));
113 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(24), tflite::AlignSizeUp(23, 3));
114 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(32), tflite::AlignSizeUp(23, 16));
115 }
116
TF_LITE_MICRO_TEST(TestTypeSizeOf)117 TF_LITE_MICRO_TEST(TestTypeSizeOf) {
118 size_t size;
119 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
120 tflite::TfLiteTypeSizeOf(kTfLiteFloat16, &size));
121 TF_LITE_MICRO_EXPECT_EQ(sizeof(int16_t), size);
122
123 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
124 tflite::TfLiteTypeSizeOf(kTfLiteFloat32, &size));
125 TF_LITE_MICRO_EXPECT_EQ(sizeof(float), size);
126
127 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
128 tflite::TfLiteTypeSizeOf(kTfLiteFloat64, &size));
129 TF_LITE_MICRO_EXPECT_EQ(sizeof(double), size);
130
131 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
132 tflite::TfLiteTypeSizeOf(kTfLiteInt16, &size));
133 TF_LITE_MICRO_EXPECT_EQ(sizeof(int16_t), size);
134
135 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
136 tflite::TfLiteTypeSizeOf(kTfLiteInt32, &size));
137 TF_LITE_MICRO_EXPECT_EQ(sizeof(int32_t), size);
138
139 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
140 tflite::TfLiteTypeSizeOf(kTfLiteUInt32, &size));
141 TF_LITE_MICRO_EXPECT_EQ(sizeof(uint32_t), size);
142
143 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
144 tflite::TfLiteTypeSizeOf(kTfLiteUInt8, &size));
145 TF_LITE_MICRO_EXPECT_EQ(sizeof(uint8_t), size);
146
147 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
148 tflite::TfLiteTypeSizeOf(kTfLiteInt8, &size));
149 TF_LITE_MICRO_EXPECT_EQ(sizeof(int8_t), size);
150
151 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
152 tflite::TfLiteTypeSizeOf(kTfLiteInt64, &size));
153 TF_LITE_MICRO_EXPECT_EQ(sizeof(int64_t), size);
154
155 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
156 tflite::TfLiteTypeSizeOf(kTfLiteUInt64, &size));
157 TF_LITE_MICRO_EXPECT_EQ(sizeof(uint64_t), size);
158
159 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
160 tflite::TfLiteTypeSizeOf(kTfLiteBool, &size));
161 TF_LITE_MICRO_EXPECT_EQ(sizeof(bool), size);
162
163 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
164 tflite::TfLiteTypeSizeOf(kTfLiteComplex64, &size));
165 TF_LITE_MICRO_EXPECT_EQ(sizeof(float) * 2, size);
166
167 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk,
168 tflite::TfLiteTypeSizeOf(kTfLiteComplex128, &size));
169 TF_LITE_MICRO_EXPECT_EQ(sizeof(double) * 2, size);
170
171 TF_LITE_MICRO_EXPECT_NE(
172 kTfLiteOk, tflite::TfLiteTypeSizeOf(static_cast<TfLiteType>(-1), &size));
173 }
174
TF_LITE_MICRO_TEST(TestBytesRequiredForTensor)175 TF_LITE_MICRO_TEST(TestBytesRequiredForTensor) {
176 const tflite::Tensor* tensor100 =
177 tflite::testing::Create1dFlatbufferTensor(100);
178 size_t bytes;
179 size_t type_size;
180 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, tflite::BytesRequiredForTensor(
181 *tensor100, &bytes, &type_size,
182 tflite::GetMicroErrorReporter()));
183 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(400), bytes);
184 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(4), type_size);
185
186 const tflite::Tensor* tensor200 =
187 tflite::testing::Create1dFlatbufferTensor(200);
188 TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, tflite::BytesRequiredForTensor(
189 *tensor200, &bytes, &type_size,
190 tflite::GetMicroErrorReporter()));
191 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(800), bytes);
192 TF_LITE_MICRO_EXPECT_EQ(static_cast<size_t>(4), type_size);
193 }
194
TF_LITE_MICRO_TEST(TestAllocateOutputDimensionsFromInput)195 TF_LITE_MICRO_TEST(TestAllocateOutputDimensionsFromInput) {
196 constexpr int kDimsLen = 4;
197 const int input1_dims[] = {1, 1};
198 const int input2_dims[] = {kDimsLen, 5, 5, 5, 5};
199 int output_dims[] = {0, 0, 0, 0, 0};
200 TfLiteTensor input_tensor1 = tflite::testing::CreateTensor<int32_t>(
201 nullptr, tflite::testing::IntArrayFromInts(input1_dims));
202 TfLiteTensor input_tensor2 = tflite::testing::CreateTensor<int32_t>(
203 nullptr, tflite::testing::IntArrayFromInts(input2_dims));
204 TfLiteTensor output_tensor = tflite::testing::CreateTensor<int32_t>(
205 nullptr, tflite::testing::IntArrayFromInts(output_dims));
206 TfLiteContext context;
207 // Only need to allocate space for output_tensor.dims. Use a simple
208 // fake allocator.
209 context.AllocatePersistentBuffer = FakeAllocatePersistentBuffer;
210
211 TF_LITE_MICRO_EXPECT_EQ(
212 kTfLiteOk, tflite::AllocateOutputDimensionsFromInput(
213 &context, &input_tensor1, &input_tensor2, &output_tensor));
214
215 TF_LITE_MICRO_EXPECT_EQ(output_tensor.bytes, input_tensor2.bytes);
216 for (int i = 0; i < kDimsLen; i++) {
217 TF_LITE_MICRO_EXPECT_EQ(input_tensor2.dims->data[i],
218 output_tensor.dims->data[i]);
219 // Reset output dims for next iteration.
220 output_tensor.dims->data[i] = 0;
221 }
222 // Output tensor size must be 0 to allocate output dimensions from input.
223 output_tensor.dims->size = 0;
224 TF_LITE_MICRO_EXPECT_EQ(
225 kTfLiteOk, tflite::AllocateOutputDimensionsFromInput(
226 &context, &input_tensor2, &input_tensor1, &output_tensor));
227 for (int i = 0; i < kDimsLen; i++) {
228 TF_LITE_MICRO_EXPECT_EQ(input_tensor2.dims->data[i],
229 output_tensor.dims->data[i]);
230 }
231 TF_LITE_MICRO_EXPECT_EQ(output_tensor.bytes, input_tensor2.bytes);
232 }
233 TF_LITE_MICRO_TESTS_END
234