• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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