1 /* Copyright 2020 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 #include "tensorflow/lite/experimental/resource/resource_variable.h"
16
17 #include <vector>
18
19 #include <gtest/gtest.h>
20 #include "tensorflow/lite/c/common.h"
21 #include "tensorflow/lite/util.h"
22
23 namespace tflite {
24 namespace resource {
25 // Helper util that initialize 'tensor'.
InitTensor(const std::vector<int> & shape,TfLiteAllocationType alloc_type,float default_value,TfLiteTensor * tensor)26 void InitTensor(const std::vector<int>& shape, TfLiteAllocationType alloc_type,
27 float default_value, TfLiteTensor* tensor) {
28 memset(tensor, 0, sizeof(TfLiteTensor));
29 int num_elements = 1;
30 for (auto dim : shape) num_elements *= dim;
31 if (shape.empty()) num_elements = 0;
32 float* buf = static_cast<float*>(malloc(sizeof(float) * num_elements));
33 for (int i = 0; i < num_elements; ++i) buf[i] = default_value;
34 const int bytes = num_elements * sizeof(buf[0]);
35 auto* dims = ConvertArrayToTfLiteIntArray(shape.size(), shape.data());
36 TfLiteTensorReset(TfLiteType::kTfLiteFloat32, nullptr, dims, {},
37 reinterpret_cast<char*>(buf), bytes, alloc_type, nullptr,
38 false, tensor);
39 }
40
TEST(ResourceTest,NonDynamicTensorAssign)41 TEST(ResourceTest, NonDynamicTensorAssign) {
42 ResourceVariable var;
43 EXPECT_FALSE(var.IsInitialized());
44
45 TfLiteTensor tensor;
46 std::vector<int> shape = {1};
47 InitTensor(shape, kTfLiteArenaRw, 1.0f, &tensor);
48
49 EXPECT_EQ(kTfLiteOk, var.AssignFrom(&tensor));
50 EXPECT_TRUE(var.IsInitialized());
51 auto* value = var.GetTensor();
52
53 // Variables are always dynamic type.
54 EXPECT_EQ(kTfLiteDynamic, value->allocation_type);
55 EXPECT_EQ(kTfLiteFloat32, value->type);
56 EXPECT_EQ(sizeof(float), value->bytes);
57 EXPECT_EQ(1, value->dims->size);
58 EXPECT_EQ(1, value->dims->data[0]);
59 EXPECT_EQ(1.0f, value->data.f[0]);
60
61 // Cleanup
62 // For non dynamic tensors we need to delete the buffers manually.
63 free(tensor.data.raw);
64 TfLiteTensorFree(&tensor);
65 }
66
TEST(ResourceTest,DynamicTensorAssign)67 TEST(ResourceTest, DynamicTensorAssign) {
68 ResourceVariable var;
69 EXPECT_FALSE(var.IsInitialized());
70
71 TfLiteTensor tensor;
72 std::vector<int> shape = {1};
73 InitTensor(shape, kTfLiteDynamic, 1.0f, &tensor);
74
75 EXPECT_EQ(kTfLiteOk, var.AssignFrom(&tensor));
76 EXPECT_TRUE(var.IsInitialized());
77 auto* value = var.GetTensor();
78
79 // Variables are always dynamic type.
80 EXPECT_EQ(kTfLiteDynamic, value->allocation_type);
81 EXPECT_EQ(kTfLiteFloat32, value->type);
82 EXPECT_EQ(sizeof(float), value->bytes);
83 EXPECT_EQ(1, value->dims->size);
84 EXPECT_EQ(1, value->dims->data[0]);
85 EXPECT_EQ(1.0f, value->data.f[0]);
86
87 // Cleanup
88 TfLiteTensorFree(&tensor);
89 }
90
TEST(ResourceTest,AssignSameSizeTensor)91 TEST(ResourceTest, AssignSameSizeTensor) {
92 ResourceVariable var;
93 EXPECT_FALSE(var.IsInitialized());
94
95 // We create 2 tensors and make 2 calls for Assign.
96 // The second Assign call should trigger the case of assign with same size.
97 TfLiteTensor tensor_a, tensor_b;
98 std::vector<int> shape_a = {1};
99 std::vector<int> shape_b = {1};
100 InitTensor(shape_a, kTfLiteDynamic, 1.0, &tensor_a);
101 InitTensor(shape_b, kTfLiteDynamic, 4.0, &tensor_b);
102
103 EXPECT_EQ(kTfLiteOk, var.AssignFrom(&tensor_a));
104 EXPECT_TRUE(var.IsInitialized());
105 auto* value = var.GetTensor();
106 // Variables are always dynamic type.
107 EXPECT_EQ(kTfLiteDynamic, value->allocation_type);
108 EXPECT_EQ(kTfLiteFloat32, value->type);
109 EXPECT_EQ(sizeof(float), value->bytes);
110 EXPECT_EQ(1, value->dims->size);
111 EXPECT_EQ(1, value->dims->data[0]);
112 EXPECT_EQ(1.0f, value->data.f[0]);
113
114 // Second AssignFrom but now tensor_b has same size as the variable.
115 EXPECT_EQ(kTfLiteOk, var.AssignFrom(&tensor_b));
116 EXPECT_TRUE(var.IsInitialized());
117 value = var.GetTensor();
118 // Variables are always dynamic type.
119 EXPECT_EQ(kTfLiteDynamic, value->allocation_type);
120 EXPECT_EQ(kTfLiteFloat32, value->type);
121 EXPECT_EQ(sizeof(float), value->bytes);
122 EXPECT_EQ(1, value->dims->size);
123 EXPECT_EQ(1, value->dims->data[0]);
124 EXPECT_EQ(4.0f, value->data.f[0]);
125
126 // Cleanup
127 TfLiteTensorFree(&tensor_a);
128 TfLiteTensorFree(&tensor_b);
129 }
130
TEST(ResourceTest,AssignDifferentSizeTensor)131 TEST(ResourceTest, AssignDifferentSizeTensor) {
132 ResourceVariable var;
133 EXPECT_FALSE(var.IsInitialized());
134
135 // We create 2 tensors and make 2 calls for Assign.
136 // The second Assign call should trigger the case of assign with different
137 // size.
138 TfLiteTensor tensor_a, tensor_b;
139 std::vector<int> shape_a = {1};
140 std::vector<int> shape_b = {2};
141 InitTensor(shape_a, kTfLiteDynamic, 1.0, &tensor_a);
142 InitTensor(shape_b, kTfLiteDynamic, 4.0, &tensor_b);
143
144 EXPECT_EQ(kTfLiteOk, var.AssignFrom(&tensor_a));
145 EXPECT_TRUE(var.IsInitialized());
146 auto* value = var.GetTensor();
147 // Variables are always dynamic type.
148 EXPECT_EQ(kTfLiteDynamic, value->allocation_type);
149 EXPECT_EQ(kTfLiteFloat32, value->type);
150 EXPECT_EQ(sizeof(float), value->bytes);
151 EXPECT_EQ(1, value->dims->size);
152 EXPECT_EQ(1, value->dims->data[0]);
153 EXPECT_EQ(1.0f, value->data.f[0]);
154
155 // Second AssignFrom but now tensor_b has different size from the variable.
156 EXPECT_EQ(kTfLiteOk, var.AssignFrom(&tensor_b));
157 EXPECT_TRUE(var.IsInitialized());
158 value = var.GetTensor();
159 // Variables are always dynamic type.
160 EXPECT_EQ(kTfLiteDynamic, value->allocation_type);
161 EXPECT_EQ(kTfLiteFloat32, value->type);
162 EXPECT_EQ(sizeof(float) * 2, value->bytes);
163 EXPECT_EQ(1, value->dims->size);
164 EXPECT_EQ(2, value->dims->data[0]);
165 EXPECT_EQ(4.0f, value->data.f[0]);
166
167 // Cleanup
168 TfLiteTensorFree(&tensor_a);
169 TfLiteTensorFree(&tensor_b);
170 }
171
172 } // namespace resource
173 } // namespace tflite
174