Daniel Konegen / MNIST_example

Dependencies:   mbed-os

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers c_api_internal.h Source File

c_api_internal.h

00001 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
00002 
00003 Licensed under the Apache License, Version 2.0 (the "License");
00004 you may not use this file except in compliance with the License.
00005 You may obtain a copy of the License at
00006 
00007     http://www.apache.org/licenses/LICENSE-2.0
00008 
00009 Unless required by applicable law or agreed to in writing, software
00010 distributed under the License is distributed on an "AS IS" BASIS,
00011 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 See the License for the specific language governing permissions and
00013 limitations under the License.
00014 ==============================================================================*/
00015 // This file defines a C API for implementing operations in tflite.
00016 // These operations can be defined using c++ but the interface between
00017 // the interpreter and the operations are C.
00018 //
00019 // Summary of abstractions
00020 // TF_LITE_ENSURE - Self-sufficient error checking
00021 // TfLiteStatus - Status reporting
00022 // TfLiteIntArray - stores tensor shapes (dims),
00023 // TfLiteContext - allows an op to access the tensors
00024 // TfLiteTensor - tensor (a multidimensional array)
00025 // TfLiteNode - a single node or operation
00026 // TfLiteRegistration - the implementation of a conceptual operation.
00027 //
00028 // Some abstractions in this file are created and managed by Interpreter.
00029 #ifndef TENSORFLOW_LITE_C_C_API_INTERNAL_H_
00030 #define TENSORFLOW_LITE_C_C_API_INTERNAL_H_
00031 
00032 #include <stdbool.h>
00033 #include <stddef.h>
00034 #include <stdint.h>
00035 
00036 #ifdef __cplusplus
00037 extern "C" {
00038 #endif  // __cplusplus
00039 
00040 typedef enum { kTfLiteOk = 0, kTfLiteError = 1 } TfLiteStatus;
00041 
00042 // The list of external context types known to TF Lite. This list exists solely
00043 // to avoid conflicts and to ensure ops can share the external contexts they
00044 // need. Access to the external contexts is controled by one of the
00045 // corresponding support files.
00046 typedef enum {
00047   kTfLiteEigenContext = 0,       // include eigen_support.h to use.
00048   kTfLiteGemmLowpContext = 1,    // include gemm_support.h to use.
00049   kTfLiteEdgeTpuContext = 2,     // Placeholder for Edge TPU support.
00050   kTfLiteCpuBackendContext = 3,  // include cpu_backend_support.h to use.
00051   kTfLiteMaxExternalContexts = 4
00052 } TfLiteExternalContextType;
00053 
00054 // Forward declare so dependent structs and methods can reference these types
00055 // prior to the struct definitions.
00056 struct TfLiteContext;
00057 struct TfLiteDelegate;
00058 struct TfLiteRegistration;
00059 
00060 // An external context is a collection of information unrelated to the TF Lite
00061 // framework, but useful to a subset of the ops. TF Lite knows very little
00062 // about about the actual contexts, but it keeps a list of them, and is able to
00063 // refresh them if configurations like the number of recommended threads
00064 // change.
00065 typedef struct {
00066   TfLiteExternalContextType type;
00067   TfLiteStatus (*Refresh)(struct TfLiteContext* context);
00068 } TfLiteExternalContext;
00069 
00070 #define kOptionalTensor (-1)
00071 
00072 // Fixed size list of integers. Used for dimensions and inputs/outputs tensor
00073 // indices
00074 typedef struct {
00075   int size;
00076 // gcc 6.1+ have a bug where flexible members aren't properly handled
00077 // https://github.com/google/re2/commit/b94b7cd42e9f02673cd748c1ac1d16db4052514c
00078 #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && \
00079     __GNUC_MINOR__ >= 1
00080   int data[0];
00081 #else
00082   int data[];
00083 #endif
00084 } TfLiteIntArray;
00085 
00086 // Given the size (number of elements) in a TfLiteIntArray, calculate its size
00087 // in bytes.
00088 int TfLiteIntArrayGetSizeInBytes(int size);
00089 
00090 // Create a array of a given `size` (uninitialized entries).
00091 // This returns a pointer, that you must free using TfLiteIntArrayFree().
00092 TfLiteIntArray* TfLiteIntArrayCreate(int size);
00093 
00094 // Check if two intarrays are equal. Returns 1 if they are equal, 0 otherwise.
00095 int TfLiteIntArrayEqual(const TfLiteIntArray* a, const TfLiteIntArray* b);
00096 
00097 // Check if an intarray equals an array. Returns 1 if equals, 0 otherwise.
00098 int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size,
00099                               const int b_data[]);
00100 
00101 // Create a copy of an array passed as `src`.
00102 // You are expected to free memory with TfLiteIntArrayFree
00103 TfLiteIntArray* TfLiteIntArrayCopy(const TfLiteIntArray* src);
00104 
00105 // Free memory of array `a`.
00106 void TfLiteIntArrayFree(TfLiteIntArray* a);
00107 
00108 // Fixed size list of floats. Used for per-channel quantization.
00109 typedef struct {
00110   int size;
00111 // gcc 6.1+ have a bug where flexible members aren't properly handled
00112 // https://github.com/google/re2/commit/b94b7cd42e9f02673cd748c1ac1d16db4052514c
00113 #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && \
00114     __GNUC_MINOR__ >= 1
00115   float data[0];
00116 #else
00117   float data[];
00118 #endif
00119 } TfLiteFloatArray;
00120 
00121 // Given the size (number of elements) in a TfLiteFloatArray, calculate its size
00122 // in bytes.
00123 int TfLiteFloatArrayGetSizeInBytes(int size);
00124 
00125 // Create a array of a given `size` (uninitialized entries).
00126 // This returns a pointer, that you must free using TfLiteFloatArrayFree().
00127 TfLiteFloatArray* TfLiteFloatArrayCreate(int size);
00128 
00129 // Free memory of array `a`.
00130 void TfLiteFloatArrayFree(TfLiteFloatArray* a);
00131 
00132 // Since we must not depend on any libraries, define a minimal subset of
00133 // error macros while avoiding names that have pre-conceived meanings like
00134 // assert and check.
00135 
00136 // Check whether value is true, and if not return kTfLiteError from
00137 // the current function (and report the error string msg).
00138 #define TF_LITE_ENSURE_MSG(context, value, msg)            \
00139   do {                                                     \
00140     if (!(value)) {                                        \
00141       (context)->ReportError((context), __FILE__ " " msg); \
00142       return kTfLiteError;                                 \
00143     }                                                      \
00144   } while (0)
00145 
00146 // Check whether the value `a` is true, and if not return kTfLiteError from
00147 // the current function, while also reporting the location of the error.
00148 #define TF_LITE_ENSURE(context, a)                                          \
00149   do {                                                                      \
00150     if (!(a)) {                                                             \
00151       (context)->ReportError((context), "%s:%d %s was not true.", __FILE__, \
00152                              __LINE__, #a);                                 \
00153       return kTfLiteError;                                                  \
00154     }                                                                       \
00155   } while (0)
00156 
00157 #define TF_LITE_ENSURE_STATUS(a) \
00158   do {                           \
00159     if ((a) != kTfLiteOk) {      \
00160       return kTfLiteError;       \
00161     }                            \
00162   } while (0)
00163 
00164 // Check whether the value `a == b` is true, and if not return kTfLiteError from
00165 // the current function, while also reporting the location of the error.
00166 // `a` and `b` may be evaluated more than once, so no side effects or
00167 // extremely expensive computations should be done.
00168 #define TF_LITE_ENSURE_EQ(context, a, b)                                       \
00169   do {                                                                         \
00170     if ((a) != (b)) {                                                          \
00171       (context)->ReportError((context), "%s:%d %s != %s (%d != %d)", __FILE__, \
00172                              __LINE__, #a, #b, (a), (b));                      \
00173       return kTfLiteError;                                                     \
00174     }                                                                          \
00175   } while (0)
00176 
00177 #define TF_LITE_ENSURE_TYPES_EQ(context, a, b)                                 \
00178   do {                                                                         \
00179     if ((a) != (b)) {                                                          \
00180       (context)->ReportError((context), "%s:%d %s != %s (%s != %s)", __FILE__, \
00181                              __LINE__, #a, #b, TfLiteTypeGetName(a),           \
00182                              TfLiteTypeGetName(b));                            \
00183       return kTfLiteError;                                                     \
00184     }                                                                          \
00185   } while (0)
00186 
00187 #define TF_LITE_ENSURE_OK(context, status) \
00188   do {                                     \
00189     if ((status) != kTfLiteOk) {           \
00190       return kTfLiteError;                 \
00191     }                                      \
00192   } while (0)
00193 
00194 // Single-precision complex data type compatible with the C99 definition.
00195 typedef struct {
00196   float re, im;  // real and imaginary parts, respectively.
00197 } TfLiteComplex64;
00198 
00199 // Half precision data type compatible with the C99 definition.
00200 typedef struct {
00201   uint16_t data;
00202 } TfLiteFloat16;
00203 
00204 // Types supported by tensor
00205 typedef enum {
00206   kTfLiteNoType = 0,
00207   kTfLiteFloat32 = 1,
00208   kTfLiteInt32 = 2,
00209   kTfLiteUInt8 = 3,
00210   kTfLiteInt64 = 4,
00211   kTfLiteString = 5,
00212   kTfLiteBool = 6,
00213   kTfLiteInt16 = 7,
00214   kTfLiteComplex64 = 8,
00215   kTfLiteInt8 = 9,
00216   kTfLiteFloat16 = 10,
00217 } TfLiteType;
00218 
00219 // Return the name of a given type, for error reporting purposes.
00220 const char* TfLiteTypeGetName(TfLiteType type);
00221 
00222 // SupportedQuantizationTypes.
00223 typedef enum {
00224   // No quantization.
00225   kTfLiteNoQuantization = 0,
00226   // Affine quantization (with support for per-channel quantization).
00227   // Corresponds to TfLiteAffineQuantization.
00228   kTfLiteAffineQuantization = 1,
00229 } TfLiteQuantizationType;
00230 
00231 // Structure specifying the quantization used by the tensor, if-any.
00232 typedef struct {
00233   // The type of quantization held by params.
00234   TfLiteQuantizationType type;
00235   // Holds a reference to one of the quantization param structures specified
00236   // below.
00237   void* params;
00238 } TfLiteQuantization;
00239 
00240 // Legacy. Will be deprecated in favor of TfLiteAffineQuantization.
00241 // If per-layer quantization is specified this field will still be populated in
00242 // addition to TfLiteAffineQuantization.
00243 // Parameters for asymmetric quantization. Quantized values can be converted
00244 // back to float using:
00245 //     real_value = scale * (quantized_value - zero_point)
00246 typedef struct {
00247   float scale;
00248   int32_t zero_point;
00249 } TfLiteQuantizationParams;
00250 
00251 // Parameters for asymmetric quantization across a dimension (i.e per output
00252 // channel quantization).
00253 // quantized_dimension specifies which dimension the scales and zero_points
00254 // correspond to.
00255 // For a particular value in quantized_dimension, quantized values can be
00256 // converted back to float using:
00257 //     real_value = scale * (quantized_value - zero_point)
00258 typedef struct {
00259   TfLiteFloatArray* scale;
00260   TfLiteIntArray* zero_point;
00261   int32_t quantized_dimension;
00262 } TfLiteAffineQuantization;
00263 
00264 // A union of pointers that points to memory for a given tensor.
00265 typedef union {
00266   int32_t* i32;
00267   int64_t* i64;
00268   float* f;
00269   // Placeholder for 16b float type. Use uint16* in the pointer union for now.
00270   TfLiteFloat16* f16;
00271   char* raw;
00272   const char* raw_const;
00273   uint8_t* uint8;
00274   bool* b;
00275   int16_t* i16;
00276   TfLiteComplex64* c64;
00277   int8_t* int8;
00278 } TfLitePtrUnion;
00279 
00280 // Memory allocation strategies. kTfLiteMmapRo is for read-only memory-mapped
00281 // data (or data externally allocated). kTfLiteArenaRw is arena allocated
00282 // data. kTfLiteDynamic is for tensors that are allocated during evaluation.
00283 typedef enum {
00284   kTfLiteMemNone = 0,
00285   kTfLiteMmapRo,
00286   kTfLiteArenaRw,
00287   kTfLiteArenaRwPersistent,
00288   kTfLiteDynamic,
00289 } TfLiteAllocationType;
00290 
00291 // The delegates should use zero or positive integers to represent handles.
00292 // -1 is reserved from unallocated status.
00293 typedef int TfLiteBufferHandle;
00294 enum {
00295   kTfLiteNullBufferHandle = -1,
00296 };
00297 
00298 // An tensor in the interpreter system which is a wrapper around a buffer of
00299 // data including a dimensionality (or NULL if not currently defined).
00300 typedef struct {
00301   // The data type specification for data stored in `data`. This affects
00302   // what member of `data` union should be used.
00303   TfLiteType type;
00304   // A union of data pointers. The appropriate type should be used for a typed
00305   // tensor based on `type`.
00306   TfLitePtrUnion data;
00307   // A pointer to a structure representing the dimensionality interpretation
00308   // that the buffer should have. NOTE: the product of elements of `dims`
00309   // and the element datatype size should be equal to `bytes` below.
00310   TfLiteIntArray* dims;
00311   // Quantization information.
00312   TfLiteQuantizationParams params;
00313   // How memory is mapped
00314   //  kTfLiteMmapRo: Memory mapped read only.
00315   //  i.e. weights
00316   //  kTfLiteArenaRw: Arena allocated read write memory
00317   //  (i.e. temporaries, outputs).
00318   TfLiteAllocationType allocation_type;
00319   // The number of bytes required to store the data of this Tensor. I.e.
00320   // (bytes of each element) * dims[0] * ... * dims[n-1].  For example, if
00321   // type is kTfLiteFloat32 and dims = {3, 2} then
00322   // bytes = sizeof(float) * 3 * 2 = 4 * 3 * 2 = 24.
00323   size_t bytes;
00324 
00325   // An opaque pointer to a tflite::MMapAllocation
00326   const void* allocation;
00327 
00328   // Null-terminated name of this tensor.
00329   const char* name;
00330 
00331   // The delegate which knows how to handle `buffer_handle`.
00332   // WARNING: This is an experimental interface that is subject to change.
00333   struct TfLiteDelegate* delegate;
00334 
00335   // An integer buffer handle that can be handled by `delegate`.
00336   // The value is valid only when delegate is not null.
00337   // WARNING: This is an experimental interface that is subject to change.
00338   TfLiteBufferHandle buffer_handle;
00339 
00340   // If the delegate uses its own buffer (e.g. GPU memory), the delegate is
00341   // responsible to set data_is_stale to true.
00342   // `delegate->CopyFromBufferHandle` can be called to copy the data from
00343   // delegate buffer.
00344   // WARNING: This is an // experimental interface that is subject to change.
00345   bool data_is_stale;
00346 
00347   // True if the tensor is a variable.
00348   bool is_variable;
00349 
00350   // Quantization information. Replaces params field above.
00351   TfLiteQuantization quantization;
00352 } TfLiteTensor;
00353 
00354 // Free data memory of tensor `t`.
00355 void TfLiteTensorDataFree(TfLiteTensor* t);
00356 
00357 // Free quantization data.
00358 void TfLiteQuantizationFree(TfLiteQuantization* quantization);
00359 
00360 // Free memory of tensor `t`.
00361 void TfLiteTensorFree(TfLiteTensor* t);
00362 
00363 // Set all of a tensor's fields (and free any previously allocated data).
00364 void TfLiteTensorReset(TfLiteType type, const char* name, TfLiteIntArray* dims,
00365                        TfLiteQuantizationParams quantization, char* buffer,
00366                        size_t size, TfLiteAllocationType allocation_type,
00367                        const void* allocation, bool is_variable,
00368                        TfLiteTensor* tensor);
00369 
00370 // Resize the allocated data of a (dynamic) tensor. Tensors with allocation
00371 // types other than kTfLiteDynamic will be ignored.
00372 void TfLiteTensorRealloc(size_t num_bytes, TfLiteTensor* tensor);
00373 
00374 // A structure representing an instance of a node.
00375 // This structure only exhibits the inputs, outputs and user defined data, not
00376 // other features like the type.
00377 typedef struct {
00378   // Inputs to this node expressed as indices into the simulator's tensors.
00379   TfLiteIntArray* inputs;
00380 
00381   // Outputs to this node expressed as indices into the simulator's tensors.
00382   TfLiteIntArray* outputs;
00383 
00384   // intermediate tensors to this node expressed as indices into the simulator's
00385   // tensors.
00386   TfLiteIntArray* intermediates;
00387 
00388   // Temporary tensors uses during the computations. This usually contains no
00389   // tensors, but ops are allowed to change that if they need scratch space of
00390   // any sort.
00391   TfLiteIntArray* temporaries;
00392 
00393   // Opaque data provided by the node implementer through `Registration.init`.
00394   void* user_data;
00395 
00396   // Opaque data provided to the node if the node is a builtin. This is usually
00397   // a structure defined in builtin_op_data.h
00398   void* builtin_data;
00399 
00400   // Custom initial data. This is the opaque data provided in the flatbuffer.
00401   // WARNING: This is an experimental interface that is subject to change.
00402   const void* custom_initial_data;
00403   int custom_initial_data_size;
00404 
00405   // The pointer to the delegate. This is non-null only when the node is
00406   // created by calling `interpreter.ModifyGraphWithDelegate`.
00407   // WARNING: This is an experimental interface that is subject to change.
00408   struct TfLiteDelegate* delegate;
00409 } TfLiteNode;
00410 
00411 typedef struct TfLiteContext {
00412   // Number of tensors in the context.
00413   size_t tensors_size;
00414 
00415   // The execution plan contains a list of the node indices in execution
00416   // order. execution_plan->size is the current number of nodes. And,
00417   // execution_plan->data[0] is the first node that needs to be run.
00418   // TfLiteDelegates can traverse the current execution plan by iterating
00419   // through each member of this array and using GetNodeAndRegistration() to
00420   // access details about a node. i.e.
00421   // TfLiteIntArray* execution_plan;
00422   // TF_LITE_ENSURE_STATUS(context->GetExecutionPlan(context, &execution_plan));
00423   // for (int exec_index = 0; exec_index < execution_plan->size; exec_index++) {
00424   //    int node_index = execution_plan->data[exec_index];
00425   //    TfLiteNode* node;
00426   //    TfLiteRegistration* reg;
00427   //    context->GetNodeAndRegistration(context, node_index, &node, &reg);
00428   // }
00429   // WARNING: This is an experimental interface that is subject to change.
00430   TfLiteStatus (*GetExecutionPlan)(struct TfLiteContext* context,
00431                                    TfLiteIntArray** execution_plan);
00432 
00433   // An array of tensors in the interpreter context (of length `tensors_size`)
00434   TfLiteTensor* tensors;
00435 
00436   // opaque full context ptr (an opaque c++ data structure)
00437   void* impl_;
00438 
00439   // Request memory pointer be resized. Updates dimensions on the tensor.
00440   // NOTE: ResizeTensor takes ownership of newSize.
00441   TfLiteStatus (*ResizeTensor)(struct TfLiteContext*, TfLiteTensor* tensor,
00442                                TfLiteIntArray* new_size);
00443   // Request that an error be reported with format string msg.
00444   void (*ReportError)(struct TfLiteContext*, const char* msg, ...);
00445 
00446   // Add `tensors_to_add` tensors, preserving pre-existing Tensor entries.  If
00447   // non-null, the value pointed to by `first_new_tensor_index` will be set to
00448   // the index of the first new tensor.
00449   TfLiteStatus (*AddTensors)(struct TfLiteContext*, int tensors_to_add,
00450                              int* first_new_tensor_index);
00451 
00452   // Get a Tensor node by node_index.
00453   // WARNING: This is an experimental interface that is subject to change.
00454   TfLiteStatus (*GetNodeAndRegistration)(
00455       struct TfLiteContext*, int node_index, TfLiteNode** node,
00456       struct TfLiteRegistration** registration);
00457 
00458   // Replace ops with one or more stub delegate operations. This function
00459   // does not take ownership of `nodes_to_replace`.
00460   TfLiteStatus (*ReplaceNodeSubsetsWithDelegateKernels)(
00461       struct TfLiteContext*, struct TfLiteRegistration registration,
00462       const TfLiteIntArray* nodes_to_replace, struct TfLiteDelegate* delegate);
00463 
00464   // Number of threads that are recommended to subsystems like gemmlowp and
00465   // eigen.
00466   int recommended_num_threads;
00467 
00468   // Access external contexts by type.
00469   // WARNING: This is an experimental interface that is subject to change.
00470   TfLiteExternalContext* (*GetExternalContext)(struct TfLiteContext*,
00471                                                TfLiteExternalContextType);
00472   // Set the value of a external context. Does not take ownership of the
00473   // pointer.
00474   // WARNING: This is an experimental interface that is subject to change.
00475   void (*SetExternalContext)(struct TfLiteContext*, TfLiteExternalContextType,
00476                              TfLiteExternalContext*);
00477 
00478   // Flag for allowing float16 precision for FP32 calculation.
00479   // default: false.
00480   // WARNING: This is an experimental API and subject to change.
00481   bool allow_fp32_relax_to_fp16;
00482 
00483   // Pointer to the op-level profiler, if set; nullptr otherwise.
00484   void* profiler;
00485 } TfLiteContext;
00486 
00487 typedef struct TfLiteRegistration {
00488   // Initializes the op from serialized data.
00489   // If a built-in op:
00490   //   `buffer` is the op's params data (TfLiteLSTMParams*).
00491   //   `length` is zero.
00492   // If custom op:
00493   //   `buffer` is the op's `custom_options`.
00494   //   `length` is the size of the buffer.
00495   //
00496   // Returns a type-punned (i.e. void*) opaque data (e.g. a primitive pointer
00497   // or an instance of a struct).
00498   //
00499   // The returned pointer will be stored with the node in the `user_data` field,
00500   // accessible within prepare and invoke functions below.
00501   // NOTE: if the data is already in the desired format, simply implement this
00502   // function to return `nullptr` and implement the free function to be a no-op.
00503   void* (*init)(TfLiteContext* context, const char* buffer, size_t length);
00504 
00505   // The pointer `buffer` is the data previously returned by an init invocation.
00506   void (*free)(TfLiteContext* context, void* buffer);
00507 
00508   // prepare is called when the inputs this node depends on have been resized.
00509   // context->ResizeTensor() can be called to request output tensors to be
00510   // resized.
00511   //
00512   // Returns kTfLiteOk on success.
00513   TfLiteStatus (*prepare)(TfLiteContext* context, TfLiteNode* node);
00514 
00515   // Execute the node (should read node->inputs and output to node->outputs).
00516   // Returns kTfLiteOk on success.
00517   TfLiteStatus (*invoke)(TfLiteContext* context, TfLiteNode* node);
00518 
00519   // profiling_string is called during summarization of profiling information
00520   // in order to group executions together. Providing a value here will cause a
00521   // given op to appear multiple times is the profiling report. This is
00522   // particularly useful for custom ops that can perform significantly
00523   // different calculations depending on their `user-data`.
00524   const char* (*profiling_string)(const TfLiteContext* context,
00525                                   const TfLiteNode* node);
00526 
00527   // Builtin codes. If this kernel refers to a builtin this is the code
00528   // of the builtin. This is so we can do marshaling to other frameworks like
00529   // NN API.
00530   // Note: It is the responsibility of the registration binder to set this
00531   // properly.
00532   int32_t builtin_code;
00533 
00534   // Custom op name. If the op is a builtin, this will be null.
00535   // Note: It is the responsibility of the registration binder to set this
00536   // properly.
00537   // WARNING: This is an experimental interface that is subject to change.
00538   const char* custom_name;
00539 
00540   // The version of the op.
00541   // Note: It is the responsibility of the registration binder to set this
00542   // properly.
00543   int version;
00544 } TfLiteRegistration;
00545 
00546 // The flags used in `TfLiteDelegate`. Note that this is a bitmask, so the
00547 // values should be 1, 2, 4, 8, ...etc.
00548 typedef enum {
00549   kTfLiteDelegateFlagsNone = 0,
00550   // The flag is set if the delegate can handle dynamic sized tensors.
00551   // For example, the output shape of a `Resize` op with non-constant shape
00552   // can only be inferred when the op is invoked.
00553   // In this case, the Delegate is responsible for calling
00554   // `SetTensorToDynamic` to mark the tensor as a dynamic tensor, and calling
00555   // `ResizeTensor` when invoking the op.
00556   //
00557   // If the delegate isn't capable to handle dynamic tensors, this flag need
00558   // to be set to false.
00559   kTfLiteDelegateFlagsAllowDynamicTensors = 1
00560 } TfLiteDelegateFlags;
00561 
00562 // WARNING: This is an experimental interface that is subject to change.
00563 typedef struct TfLiteDelegate {
00564   // Data that delegate needs to identify itself. This data is owned by the
00565   // delegate. The delegate is owned in the user code, so the delegate is
00566   // responsible for doing this when it is destroyed.
00567   void* data_;
00568 
00569   // Invoked by ModifyGraphWithDelegate. This prepare is called, giving the
00570   // delegate a view of the current graph through TfLiteContext*. It typically
00571   // will look at the nodes and call ReplaceNodeSubsetsWithDelegateKernels()
00572   // to ask the TensorFlow lite runtime to create macro-nodes to represent
00573   // delegated subgraphs of the original graph.
00574   TfLiteStatus (*Prepare)(TfLiteContext* context,
00575                           struct TfLiteDelegate* delegate);
00576 
00577   // Copy the data from delegate buffer handle into raw memory of the given
00578   // 'tensor'. This cannot be null. The delegate is allowed to allocate the raw
00579   // bytes as long as it follows the rules for kTfLiteDynamic tensors.
00580   TfLiteStatus (*CopyFromBufferHandle)(TfLiteContext* context,
00581                                        struct TfLiteDelegate* delegate,
00582                                        TfLiteBufferHandle buffer_handle,
00583                                        TfLiteTensor* tensor);
00584 
00585   // Copy the data from raw memory of the given 'tensor' to delegate buffer
00586   // handle. This can be null if the delegate doesn't use its own buffer.
00587   TfLiteStatus (*CopyToBufferHandle)(TfLiteContext* context,
00588                                      struct TfLiteDelegate* delegate,
00589                                      TfLiteBufferHandle buffer_handle,
00590                                      TfLiteTensor* tensor);
00591 
00592   // Free the Delegate Buffer Handle. Note: This only frees the handle, but
00593   // this doesn't release the underlying resource (e.g. textures). The
00594   // resources are either owned by application layer or the delegate.
00595   // This can be null if the delegate doesn't use its own buffer.
00596   void (*FreeBufferHandle)(TfLiteContext* context,
00597                            struct TfLiteDelegate* delegate,
00598                            TfLiteBufferHandle* handle);
00599 
00600   // Bitmask flags. See the comments in `TfLiteDelegateFlags`.
00601   int64_t flags;
00602 } TfLiteDelegate;
00603 
00604 // Build a 'null' delegate, with all the fields properly set to their default
00605 // values.
00606 TfLiteDelegate TfLiteDelegateCreate();
00607 
00608 // WARNING: This is an experimental interface that is subject to change.
00609 //
00610 // Currently, TfLiteDelegateParams has to be allocated in a way that it's
00611 // trivially destructable. It will be stored as `builtin_data` field in
00612 // `TfLiteNode` of the delegate node.
00613 //
00614 // See also the `CreateDelegateParams` function in `interpreter.cc` details.
00615 typedef struct {
00616   TfLiteDelegate* delegate;
00617   TfLiteIntArray* nodes_to_replace;
00618   TfLiteIntArray* input_tensors;
00619   TfLiteIntArray* output_tensors;
00620 } TfLiteDelegateParams;
00621 
00622 #ifdef __cplusplus
00623 }  // extern "C"
00624 #endif  // __cplusplus
00625 #endif  // TENSORFLOW_LITE_C_C_API_INTERNAL_H_