Skip to content

Commit 9943c39

Browse files
TFLM-botmysterywolf
authored andcommitted
cherry-pick tflite-micro from 2023-02-27 to 2023-05-13
tflite-micro cherry-pick info: start commit id: 48b6cffeb2c6f07b887e227f57de00da7783d736 end commit id: d5f70ceb5202f72efc856901c3418fff92b76f9e Since e344f4b6bbc1a3d6a62fd31555ba6715a4504c1e add new feature and remove "tensorflow/lite/micro/all_ops_resolver.h" caused compile error, this commit cherry-pick end at d5f70ceb5202f72efc856901c3418fff92b76f9e of tflite-micro.
1 parent aebe203 commit 9943c39

File tree

256 files changed

+7881
-5279
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

256 files changed

+7881
-5279
lines changed

src/tensorflow/lite/builtin_ops.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ typedef enum {
186186
kTfLiteBuiltinAtan2 = 156,
187187
kTfLiteBuiltinUnsortedSegmentMin = 157,
188188
kTfLiteBuiltinSign = 158,
189+
kTfLiteBuiltinBitcast = 159,
190+
kTfLiteBuiltinBitwiseXor = 160,
191+
kTfLiteBuiltinRightShift = 161,
189192
} TfLiteBuiltinOperator;
190193

191194
#ifdef __cplusplus

src/tensorflow/lite/c/common.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,4 @@ limitations under the License.
3838

3939
#include "tensorflow/lite/core/c/common.h"
4040

41-
// TfLiteOpaqueDelegate: allows delegation of nodes to alternative backends.
42-
// TfLiteOpaqueDelegate is an abstract type that is intended to have the same
43-
// role as TfLiteDelegate, but without necessarily exposing the implementation
44-
// details of how delegates are implemented.
45-
typedef TfLiteDelegate TfLiteOpaqueDelegate;
46-
4741
#endif // TENSORFLOW_LITE_C_COMMON_H_

src/tensorflow/lite/core/api/flatbuffer_conversions.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
256256
return ParseElu(op, error_reporter, allocator, builtin_data);
257257
}
258258

259+
case BuiltinOperator_EMBEDDING_LOOKUP: {
260+
return ParseEmbeddingLookup(op, error_reporter, allocator, builtin_data);
261+
}
262+
259263
case BuiltinOperator_EXP: {
260264
return ParseExp(op, error_reporter, allocator, builtin_data);
261265
}
@@ -542,6 +546,14 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
542546
return ParseZerosLike(op, error_reporter, allocator, builtin_data);
543547
}
544548

549+
case BuiltinOperator_BITWISE_XOR: {
550+
return ParseBitwiseXor(op, error_reporter, allocator, builtin_data);
551+
}
552+
553+
case BuiltinOperator_RIGHT_SHIFT: {
554+
return ParseRightShift(op, error_reporter, allocator, builtin_data);
555+
}
556+
545557
case BuiltinOperator_CAST: {
546558
return ParseCast(op, error_reporter, allocator, builtin_data);
547559
}
@@ -845,6 +857,7 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
845857
*builtin_data = params.release();
846858
return kTfLiteOk;
847859
}
860+
848861
// Below are the ops with no builtin_data structure.
849862
// TODO(aselle): Implement call in BuiltinOptions, but nullptrs are
850863
// ok for now, since there is no call implementation either.
@@ -855,7 +868,6 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
855868
case BuiltinOperator_CUSTOM:
856869
case BuiltinOperator_DENSIFY:
857870
case BuiltinOperator_DYNAMIC_UPDATE_SLICE:
858-
case BuiltinOperator_EMBEDDING_LOOKUP:
859871
case BuiltinOperator_EQUAL:
860872
case BuiltinOperator_HASHTABLE_FIND:
861873
case BuiltinOperator_HASHTABLE_IMPORT:
@@ -885,6 +897,7 @@ TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type,
885897
case BuiltinOperator_UNSORTED_SEGMENT_SUM:
886898
case BuiltinOperator_ATAN2:
887899
case BuiltinOperator_SIGN:
900+
case BuiltinOperator_BITCAST:
888901
case BuiltinOperator_WHERE:
889902
return kTfLiteOk;
890903
case BuiltinOperator_PLACEHOLDER_FOR_GREATER_OP_CODES:
@@ -1335,6 +1348,14 @@ TfLiteStatus ParseElu(const Operator*, ErrorReporter*, BuiltinDataAllocator*,
13351348
return kTfLiteOk;
13361349
}
13371350

1351+
// We have this parse function instead of directly returning kTfLiteOk from the
1352+
// switch-case in ParseOpData because this function is used as part of the
1353+
// selective registration for the OpResolver implementation in micro.
1354+
TfLiteStatus ParseEmbeddingLookup(const Operator*, ErrorReporter*,
1355+
BuiltinDataAllocator*, void**) {
1356+
return kTfLiteOk;
1357+
}
1358+
13381359
// We have this parse function instead of directly returning kTfLiteOk from the
13391360
// switch-case in ParseOpData because this function is used as part of the
13401361
// selective registration for the OpResolver implementation in micro.
@@ -2441,6 +2462,22 @@ TfLiteStatus ParseZerosLike(const Operator*, ErrorReporter*,
24412462
return kTfLiteOk;
24422463
}
24432464

2465+
// We have this parse function instead of directly returning kTfLiteOk from the
2466+
// switch-case in ParseOpData because this function is used as part of the
2467+
// selective registration for the OpResolver implementation in micro.
2468+
TfLiteStatus ParseBitwiseXor(const Operator*, ErrorReporter*,
2469+
BuiltinDataAllocator*, void**) {
2470+
return kTfLiteOk;
2471+
}
2472+
2473+
// We have this parse function instead of directly returning kTfLiteOk from the
2474+
// switch-case in ParseOpData because this function is used as part of the
2475+
// selective registration for the OpResolver implementation in micro.
2476+
TfLiteStatus ParseRightShift(const Operator*, ErrorReporter*,
2477+
BuiltinDataAllocator*, void**) {
2478+
return kTfLiteOk;
2479+
}
2480+
24442481
TfLiteStatus ParseOpData(const Operator* op, BuiltinOperator op_type,
24452482
ErrorReporter* error_reporter,
24462483
BuiltinDataAllocator* allocator, void** builtin_data) {

src/tensorflow/lite/core/api/flatbuffer_conversions.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ TfLiteStatus ParseDiv(const Operator* op, ErrorReporter* error_reporter,
151151
TfLiteStatus ParseElu(const Operator* op, ErrorReporter* error_reporter,
152152
BuiltinDataAllocator* allocator, void** builtin_data);
153153

154+
TfLiteStatus ParseEmbeddingLookup(const Operator* op,
155+
ErrorReporter* error_reporter,
156+
BuiltinDataAllocator* allocator,
157+
void** builtin_data);
158+
154159
TfLiteStatus ParseEqual(const Operator* op, ErrorReporter* error_reporter,
155160
BuiltinDataAllocator* allocator, void** builtin_data);
156161

@@ -407,6 +412,14 @@ TfLiteStatus ParseZerosLike(const Operator* op, ErrorReporter* error_reporter,
407412
BuiltinDataAllocator* allocator,
408413
void** builtin_data);
409414

415+
TfLiteStatus ParseBitwiseXor(const Operator* op, ErrorReporter* error_reporter,
416+
BuiltinDataAllocator* allocator,
417+
void** builtin_data);
418+
419+
TfLiteStatus ParseRightShift(const Operator* op, ErrorReporter* error_reporter,
420+
BuiltinDataAllocator* allocator,
421+
void** builtin_data);
422+
410423
} // namespace tflite
411424

412425
#endif // TENSORFLOW_LITE_CORE_API_FLATBUFFER_CONVERSIONS_H_

src/tensorflow/lite/core/c/c_api_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ limitations under the License.
2121
/// "third_party/tensorflow/lite/c/c_api_types.h".
2222
/// Only the TensorFlow Lite implementation itself should include this
2323
/// file directly.
24+
// IWYU pragma: private, include "third_party/tensorflow/lite/c/c_api_types.h"
2425

2526
#ifndef TENSORFLOW_LITE_CORE_C_C_API_TYPES_H_
2627
#define TENSORFLOW_LITE_CORE_C_C_API_TYPES_H_

src/tensorflow/lite/core/c/common.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,22 @@ TfLiteFloatArray* TfLiteFloatArrayCreate(int size) {
9898
return ret;
9999
}
100100

101+
TfLiteFloatArray* TfLiteFloatArrayCopy(const TfLiteFloatArray* src) {
102+
if (!src) return nullptr;
103+
TfLiteFloatArray* ret = TfLiteFloatArrayCreate(src->size);
104+
if (ret) {
105+
memcpy(ret->data, src->data, src->size * sizeof(float));
106+
}
107+
return ret;
108+
}
109+
101110
void TfLiteFloatArrayFree(TfLiteFloatArray* a) { free(a); }
102111

103112
void TfLiteTensorDataFree(TfLiteTensor* t) {
104-
if (t->allocation_type == kTfLiteDynamic ||
105-
t->allocation_type == kTfLitePersistentRo) {
113+
if (t->allocation_type == kTfLiteVariantObject) {
114+
delete reinterpret_cast<VariantData*>(t->data.data);
115+
} else if (t->allocation_type == kTfLiteDynamic ||
116+
t->allocation_type == kTfLitePersistentRo) {
106117
if (t->data.raw) {
107118
#ifdef TF_LITE_TENSORFLOW_PROFILER
108119
tflite::PauseHeapMonitoring(/*pause=*/true);
@@ -207,11 +218,16 @@ TfLiteStatus TfLiteTensorCopy(const TfLiteTensor* src, TfLiteTensor* dst) {
207218
if (!src || !dst) return kTfLiteOk;
208219
if (src->bytes != dst->bytes) return kTfLiteError;
209220
if (src == dst) return kTfLiteOk;
210-
211221
dst->type = src->type;
212222
if (dst->dims) TfLiteIntArrayFree(dst->dims);
213223
dst->dims = TfLiteIntArrayCopy(src->dims);
214-
memcpy(dst->data.raw, src->data.raw, src->bytes);
224+
if (src->allocation_type == kTfLiteVariantObject) {
225+
if (dst->allocation_type != kTfLiteVariantObject) return kTfLiteError;
226+
dst->data.data =
227+
reinterpret_cast<VariantData*>(src->data.data)->Clone(dst->data.raw);
228+
} else {
229+
memcpy(dst->data.raw, src->data.raw, src->bytes);
230+
}
215231
dst->buffer_handle = src->buffer_handle;
216232
dst->data_is_stale = src->data_is_stale;
217233
dst->delegate = src->delegate;

src/tensorflow/lite/core/c/common.h

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ limitations under the License.
3838
/// "third_party/tensorflow/lite/c/common.h".
3939
/// Only the TensorFlow Lite implementation itself should include this
4040
/// file directly.
41+
// IWYU pragma: private, include "third_party/tensorflow/lite/c/common.h"
4142

4243
#ifndef TENSORFLOW_LITE_CORE_C_COMMON_H_
4344
#define TENSORFLOW_LITE_CORE_C_COMMON_H_
@@ -157,6 +158,10 @@ int TfLiteFloatArrayGetSizeInBytes(int size);
157158
// This returns a pointer, that you must free using TfLiteFloatArrayFree().
158159
TfLiteFloatArray* TfLiteFloatArrayCreate(int size);
159160

161+
// Create a copy of an array passed as `src`.
162+
// You are expected to free memory with TfLiteFloatArrayFree.
163+
TfLiteFloatArray* TfLiteFloatArrayCopy(const TfLiteFloatArray* src);
164+
160165
// Free memory of array `a`.
161166
void TfLiteFloatArrayFree(TfLiteFloatArray* a);
162167
#endif // TF_LITE_STATIC_MEMORY
@@ -345,6 +350,8 @@ typedef union TfLitePtrUnion {
345350
// as constant inputs for downstream ops (also in prepare).
346351
// * kTfLiteCustom: Custom memory allocation provided by the user. See
347352
// TfLiteCustomAllocation below.
353+
// * kTfLiteVariantObject: Allocation is an arbitrary type-erased C++ object.
354+
// Allocation and deallocation are done through `new` and `delete`.
348355
typedef enum TfLiteAllocationType {
349356
kTfLiteMemNone = 0,
350357
kTfLiteMmapRo,
@@ -353,6 +360,7 @@ typedef enum TfLiteAllocationType {
353360
kTfLiteDynamic,
354361
kTfLitePersistentRo,
355362
kTfLiteCustom,
363+
kTfLiteVariantObject,
356364
} TfLiteAllocationType;
357365

358366
// The delegates should use zero or positive integers to represent handles.
@@ -959,12 +967,53 @@ typedef struct TfLiteRegistration {
959967
// ops. We keep it inside of `TfLiteRegistration` and use it to route
960968
// callbacks properly.
961969
TfLiteRegistrationExternal* registration_external;
970+
971+
// Retrieves asynchronous kernel.
972+
//
973+
// If the `async_kernel` field is nullptr, it means the operation described by
974+
// this TfLiteRegistration object does not support asynchronous execution.
975+
// Otherwise, the function that the field points to should only be called for
976+
// delegate kernel nodes, i.e. `node` should be a delegate kernel node created
977+
// by applying a delegate.
978+
// If the function returns nullptr, that means that the underlying delegate
979+
// does not support asynchronous execution for this `node`.
980+
struct TfLiteAsyncKernel* (*async_kernel)(TfLiteContext* context,
981+
TfLiteNode* node);
962982
} TfLiteRegistration;
963983

984+
/// \private
964985
// Old version of `TfLiteRegistration` to maintain binary backward
965986
// compatibility.
966-
// WARNING: This structure is deprecated / not an official part of the API.
967-
// It should be only used for binary backward compatibility.
987+
// The legacy registration type must be a POD struct type whose field types must
988+
// be a prefix of the field types in TfLiteRegistration, and offset of the first
989+
// field in TfLiteRegistration that is not present in the legacy registration
990+
// type must be greater than or equal to the size of the legacy registration
991+
// type.
992+
// WARNING: This structure is deprecated / not an official part of the
993+
// API. It should be only used for binary backward compatibility.
994+
typedef struct TfLiteRegistration_V2 {
995+
void* (*init)(TfLiteContext* context, const char* buffer, size_t length);
996+
void (*free)(TfLiteContext* context, void* buffer);
997+
TfLiteStatus (*prepare)(TfLiteContext* context, TfLiteNode* node);
998+
TfLiteStatus (*invoke)(TfLiteContext* context, TfLiteNode* node);
999+
const char* (*profiling_string)(const TfLiteContext* context,
1000+
const TfLiteNode* node);
1001+
int32_t builtin_code;
1002+
const char* custom_name;
1003+
int version;
1004+
TfLiteRegistrationExternal* registration_external;
1005+
} TfLiteRegistration_V2;
1006+
1007+
/// \private
1008+
// Old version of `TfLiteRegistration` to maintain binary backward
1009+
// compatibility.
1010+
// The legacy registration type must be a POD struct type whose field types must
1011+
// be a prefix of the field types in TfLiteRegistration, and offset of the first
1012+
// field in TfLiteRegistration that is not present in the legacy registration
1013+
// type must be greater than or equal to the size of the legacy registration
1014+
// type.
1015+
// WARNING: This structure is deprecated / not an official part of the
1016+
// API. It should be only used for binary backward compatibility.
9681017
typedef struct TfLiteRegistration_V1 {
9691018
void* (*init)(TfLiteContext* context, const char* buffer, size_t length);
9701019
void (*free)(TfLiteContext* context, void* buffer);
@@ -1155,5 +1204,74 @@ void* TfLiteOpaqueDelegateGetData(const TfLiteOpaqueDelegate* delegate);
11551204

11561205
#ifdef __cplusplus
11571206
} // extern "C"
1207+
1208+
#include <utility>
1209+
1210+
// `kTfLiteVariant` type tensors encode arbitrary C++ objects behind their
1211+
// `data.data : void*` member. This is the type-erased interface for interacting
1212+
// with such objects at runtime. Deleting or Cloning any `VariantData`
1213+
// will call the destructor and copy constructor of the erased type
1214+
// automatically. For example usage, see `common_test.cc`.
1215+
class VariantData {
1216+
public:
1217+
// All variant objects must be able to be destroyed and copied.
1218+
virtual ~VariantData() = default;
1219+
// This allows for a "virtual copy-constructor" like pattern.
1220+
// In most cases, we will be copying from an input to an output tensor.
1221+
// Often, the output tensor is already allocated so we can pass
1222+
// a pointer to its buffer for reuse.
1223+
virtual VariantData* Clone(char* maybe_alloc) const = 0;
1224+
};
1225+
1226+
// An abstract base class for variant objects. The template parameter
1227+
// is the type we are erasing.
1228+
template <typename ErasedDerived>
1229+
class AbstractVariantData : public VariantData {
1230+
public:
1231+
VariantData* Clone(char* maybe_alloc) const override {
1232+
if (maybe_alloc) {
1233+
// We assume that the output tensor is already a variant of the same
1234+
// derived type. If the output is still allocated, then it still may have
1235+
// state that was not destroyed, so we must call the destructor before
1236+
// using the buffer.
1237+
// This may actual have a non-negligle effect on perfomance if the
1238+
// destructor is complex. In a future optimization we would want to
1239+
// introduce something like "move to" semantics, allowing for the
1240+
// underlying implementation to optimize for this case.
1241+
reinterpret_cast<VariantData*>(maybe_alloc)->~VariantData();
1242+
return new (maybe_alloc)
1243+
ErasedDerived(static_cast<ErasedDerived const&>(*this));
1244+
}
1245+
return new ErasedDerived(static_cast<ErasedDerived const&>(*this));
1246+
}
1247+
1248+
protected:
1249+
AbstractVariantData() = default;
1250+
AbstractVariantData(const AbstractVariantData&) = default;
1251+
AbstractVariantData(AbstractVariantData&&) = delete;
1252+
};
1253+
1254+
// Analogous to `TfLiteTensorRealloc` for allocation of tensors whose
1255+
// data member points to an arbitrary C++ object. `VariantType` refers
1256+
// to the erased type of said object and `VariantArgs` refers to
1257+
// a list of argument types with which to construct a new `VariantType`
1258+
// `VariantArgs` must match constructor in `VariantType`.
1259+
template <class VariantType, class... VariantArgs>
1260+
TfLiteStatus TfLiteTensorVariantRealloc(TfLiteTensor* t,
1261+
VariantArgs&&... args) {
1262+
if (t->type != kTfLiteVariant) return kTfLiteError;
1263+
if (t->data.raw) {
1264+
reinterpret_cast<VariantData*>(t->data.data)->~VariantData();
1265+
// For now we assume if `t` is already allocated then it was allocated
1266+
// with the same `VariantType` as templated.
1267+
t->data.data =
1268+
new (t->data.raw) VariantType(std::forward<VariantArgs...>(args...));
1269+
} else {
1270+
t->data.data = new VariantType(std::forward<VariantArgs...>(args...));
1271+
}
1272+
t->allocation_type = kTfLiteVariantObject;
1273+
return kTfLiteOk;
1274+
}
1275+
11581276
#endif // __cplusplus
11591277
#endif // TENSORFLOW_LITE_CORE_C_COMMON_H_

0 commit comments

Comments
 (0)