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 #ifndef TF_LITE_STATIC_MEMORY
18 #include <stdlib.h>
19 #include <string.h>
20 #endif // TF_LITE_STATIC_MEMORY
21
TfLiteIntArrayGetSizeInBytes(int size)22 int TfLiteIntArrayGetSizeInBytes(int size) {
23 static TfLiteIntArray dummy;
24 return sizeof(dummy) + sizeof(dummy.data[0]) * size;
25 }
26
TfLiteIntArrayEqual(const TfLiteIntArray * a,const TfLiteIntArray * b)27 int TfLiteIntArrayEqual(const TfLiteIntArray* a, const TfLiteIntArray* b) {
28 if (a == b) return 1;
29 if (a == NULL || b == NULL) return 0;
30 return TfLiteIntArrayEqualsArray(a, b->size, b->data);
31 }
32
TfLiteIntArrayEqualsArray(const TfLiteIntArray * a,int b_size,const int b_data[])33 int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size,
34 const int b_data[]) {
35 if (a == NULL) return (b_size == 0);
36 if (a->size != b_size) return 0;
37 int i = 0;
38 for (; i < a->size; i++)
39 if (a->data[i] != b_data[i]) return 0;
40 return 1;
41 }
42
43 #ifndef TF_LITE_STATIC_MEMORY
44
TfLiteIntArrayCreate(int size)45 TfLiteIntArray* TfLiteIntArrayCreate(int size) {
46 TfLiteIntArray* ret =
47 (TfLiteIntArray*)malloc(TfLiteIntArrayGetSizeInBytes(size));
48 ret->size = size;
49 return ret;
50 }
51
TfLiteIntArrayCopy(const TfLiteIntArray * src)52 TfLiteIntArray* TfLiteIntArrayCopy(const TfLiteIntArray* src) {
53 if (!src) return NULL;
54 TfLiteIntArray* ret = TfLiteIntArrayCreate(src->size);
55 if (ret) {
56 memcpy(ret->data, src->data, src->size * sizeof(int));
57 }
58 return ret;
59 }
60
TfLiteIntArrayFree(TfLiteIntArray * a)61 void TfLiteIntArrayFree(TfLiteIntArray* a) { free(a); }
62
63 #endif // TF_LITE_STATIC_MEMORY
64
TfLiteFloatArrayGetSizeInBytes(int size)65 int TfLiteFloatArrayGetSizeInBytes(int size) {
66 static TfLiteFloatArray dummy;
67 return sizeof(dummy) + sizeof(dummy.data[0]) * size;
68 }
69
70 #ifndef TF_LITE_STATIC_MEMORY
71
TfLiteFloatArrayCreate(int size)72 TfLiteFloatArray* TfLiteFloatArrayCreate(int size) {
73 TfLiteFloatArray* ret =
74 (TfLiteFloatArray*)malloc(TfLiteFloatArrayGetSizeInBytes(size));
75 ret->size = size;
76 return ret;
77 }
78
TfLiteFloatArrayFree(TfLiteFloatArray * a)79 void TfLiteFloatArrayFree(TfLiteFloatArray* a) { free(a); }
80
TfLiteTensorDataFree(TfLiteTensor * t)81 void TfLiteTensorDataFree(TfLiteTensor* t) {
82 if (t->allocation_type == kTfLiteDynamic) {
83 free(t->data.raw);
84 }
85 t->data.raw = NULL;
86 }
87
TfLiteQuantizationFree(TfLiteQuantization * quantization)88 void TfLiteQuantizationFree(TfLiteQuantization* quantization) {
89 if (quantization->type == kTfLiteAffineQuantization) {
90 TfLiteAffineQuantization* q_params =
91 (TfLiteAffineQuantization*)(quantization->params);
92 if (q_params->scale) {
93 TfLiteFloatArrayFree(q_params->scale);
94 q_params->scale = NULL;
95 }
96 if (q_params->zero_point) {
97 TfLiteIntArrayFree(q_params->zero_point);
98 q_params->zero_point = NULL;
99 }
100 free(q_params);
101 }
102 quantization->params = NULL;
103 quantization->type = kTfLiteNoQuantization;
104 }
105
TfLiteSparsityFree(TfLiteSparsity * sparsity)106 void TfLiteSparsityFree(TfLiteSparsity* sparsity) {
107 if (sparsity == NULL) {
108 return;
109 }
110
111 if (sparsity->traversal_order) {
112 TfLiteIntArrayFree(sparsity->traversal_order);
113 sparsity->traversal_order = NULL;
114 }
115
116 if (sparsity->block_map) {
117 TfLiteIntArrayFree(sparsity->block_map);
118 sparsity->block_map = NULL;
119 }
120
121 if (sparsity->dim_metadata) {
122 for (int i = 0; i < sparsity->dim_metadata_size; i++) {
123 TfLiteDimensionMetadata metadata = sparsity->dim_metadata[i];
124 if (metadata.format == kTfLiteDimSparseCSR) {
125 TfLiteIntArrayFree(metadata.array_segments);
126 metadata.array_segments = NULL;
127 TfLiteIntArrayFree(metadata.array_indices);
128 metadata.array_indices = NULL;
129 }
130 }
131 free(sparsity->dim_metadata);
132 sparsity->dim_metadata = NULL;
133 }
134
135 free(sparsity);
136 }
137
TfLiteTensorFree(TfLiteTensor * t)138 void TfLiteTensorFree(TfLiteTensor* t) {
139 TfLiteTensorDataFree(t);
140 if (t->dims) TfLiteIntArrayFree(t->dims);
141 t->dims = NULL;
142
143 if (t->dims_signature) {
144 TfLiteIntArrayFree((TfLiteIntArray *) t->dims_signature);
145 }
146 t->dims_signature = NULL;
147
148 TfLiteQuantizationFree(&t->quantization);
149 TfLiteSparsityFree(t->sparsity);
150 t->sparsity = NULL;
151 }
152
TfLiteTensorReset(TfLiteType type,const char * name,TfLiteIntArray * dims,TfLiteQuantizationParams quantization,char * buffer,size_t size,TfLiteAllocationType allocation_type,const void * allocation,bool is_variable,TfLiteTensor * tensor)153 void TfLiteTensorReset(TfLiteType type, const char* name, TfLiteIntArray* dims,
154 TfLiteQuantizationParams quantization, char* buffer,
155 size_t size, TfLiteAllocationType allocation_type,
156 const void* allocation, bool is_variable,
157 TfLiteTensor* tensor) {
158 TfLiteTensorFree(tensor);
159 tensor->type = type;
160 tensor->name = name;
161 tensor->dims = dims;
162 tensor->params = quantization;
163 tensor->data.raw = buffer;
164 tensor->bytes = size;
165 tensor->allocation_type = allocation_type;
166 tensor->allocation = allocation;
167 tensor->is_variable = is_variable;
168
169 tensor->quantization.type = kTfLiteNoQuantization;
170 tensor->quantization.params = NULL;
171 }
172
TfLiteTensorRealloc(size_t num_bytes,TfLiteTensor * tensor)173 void TfLiteTensorRealloc(size_t num_bytes, TfLiteTensor* tensor) {
174 if (tensor->allocation_type != kTfLiteDynamic) {
175 return;
176 }
177 // TODO(b/145340303): Tensor data should be aligned.
178 if (!tensor->data.raw) {
179 tensor->data.raw = malloc(num_bytes);
180 } else if (num_bytes > tensor->bytes) {
181 tensor->data.raw = realloc(tensor->data.raw, num_bytes);
182 }
183 tensor->bytes = num_bytes;
184 }
185 #endif // TF_LITE_STATIC_MEMORY
186
TfLiteTypeGetName(TfLiteType type)187 const char* TfLiteTypeGetName(TfLiteType type) {
188 switch (type) {
189 case kTfLiteNoType:
190 return "NOTYPE";
191 case kTfLiteFloat32:
192 return "FLOAT32";
193 case kTfLiteInt16:
194 return "INT16";
195 case kTfLiteInt32:
196 return "INT32";
197 case kTfLiteUInt8:
198 return "UINT8";
199 case kTfLiteInt8:
200 return "INT8";
201 case kTfLiteInt64:
202 return "INT64";
203 case kTfLiteBool:
204 return "BOOL";
205 case kTfLiteComplex64:
206 return "COMPLEX64";
207 case kTfLiteString:
208 return "STRING";
209 case kTfLiteFloat16:
210 return "FLOAT16";
211 }
212 return "Unknown type";
213 }
214
TfLiteDelegateCreate()215 TfLiteDelegate TfLiteDelegateCreate() {
216 TfLiteDelegate d = {
217 .data_ = NULL,
218 .Prepare = NULL,
219 .CopyFromBufferHandle = NULL,
220 .CopyToBufferHandle = NULL,
221 .FreeBufferHandle = NULL,
222 .flags = kTfLiteDelegateFlagsNone,
223 };
224 return d;
225 }
226