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