1 /* Copyright 2018 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 /// WARNING: Users of TensorFlow Lite should not include this file directly, 16 /// but should instead include 17 /// "third_party/tensorflow/lite/c/c_api_experimental.h". 18 /// Only the TensorFlow Lite implementation itself should include this 19 /// file directly. 20 #ifndef TENSORFLOW_LITE_CORE_C_C_API_EXPERIMENTAL_H_ 21 #define TENSORFLOW_LITE_CORE_C_C_API_EXPERIMENTAL_H_ 22 23 #include "tensorflow/lite/builtin_ops.h" 24 #include "tensorflow/lite/core/c/c_api.h" 25 #include "tensorflow/lite/core/c/common.h" 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif // __cplusplus 30 31 // -------------------------------------------------------------------------- 32 // Opaque types used by the C API. 33 34 /// TfLiteSignatureRunner is used to run inference on a signature. 35 /// 36 /// Note: A signature is used to define a computation in a TF model. A model can 37 /// have multiple signatures. Each signature contains three components: 38 /// * Signature Key: A unique string to identify a signature 39 /// * Inputs: A list of names, each mapped to an input tensor of a signature 40 /// * Outputs: A list of names, each mapped to an output tensor of a signature 41 /// 42 /// To learn more about signatures in TFLite, refer to: 43 /// https://www.tensorflow.org/lite/guide/signatures 44 /// 45 /// Using the TfLiteSignatureRunner, for a particular signature, you can set its 46 /// inputs, invoke (i.e. execute) the computation, and retrieve its outputs. 47 typedef struct TfLiteSignatureRunner TfLiteSignatureRunner; 48 49 // -------------------------------------------------------------------------- 50 /// Resets all variable tensors to zero. 51 /// 52 /// WARNING: This is an experimental API and subject to change. 53 TFL_CAPI_EXPORT extern TfLiteStatus TfLiteInterpreterResetVariableTensors( 54 TfLiteInterpreter* interpreter); 55 56 /// Adds an op registration for a builtin operator. 57 /// 58 /// Op registrations are used to map ops referenced in the flatbuffer model 59 /// to executable function pointers (`TfLiteRegistration`s). 60 /// 61 /// NOTE: The interpreter will make a shallow copy of `registration` internally, 62 /// so the caller should ensure that its contents (function pointers, etc...) 63 /// remain valid for the duration of the interpreter's lifetime. A common 64 /// practice is making the provided `TfLiteRegistration` instance static. 65 /// 66 /// Code that uses this function should NOT call 67 /// `TfLiteInterpreterOptionsSetOpResolver` (or related functions) on the same 68 /// options object. 69 /// 70 /// WARNING: This is an experimental API and subject to change. 71 TFL_CAPI_EXPORT void TfLiteInterpreterOptionsAddBuiltinOp( 72 TfLiteInterpreterOptions* options, TfLiteBuiltinOperator op, 73 const TfLiteRegistration* registration, int32_t min_version, 74 int32_t max_version); 75 76 /// Adds an op registration for a custom operator. 77 /// 78 /// Op registrations are used to map ops referenced in the flatbuffer model 79 /// to executable function pointers (`TfLiteRegistration`s). 80 /// 81 /// NOTE: The interpreter will make a shallow copy of `registration` internally, 82 /// so the caller should ensure that its contents (function pointers, etc...) 83 /// remain valid for the duration of any created interpreter's lifetime. A 84 /// common practice is making the provided `TfLiteRegistration` instance static. 85 /// 86 /// The lifetime of the string pointed to by `name` must be at least as long 87 /// as the lifetime of the `TfLiteInterpreterOptions`. 88 /// 89 /// Code that uses this function should NOT call 90 /// `TfLiteInterpreterOptionsSetOpResolver` (or related functions) on the same 91 /// options object. 92 /// 93 /// WARNING: This is an experimental API and subject to change. 94 TFL_CAPI_EXPORT void TfLiteInterpreterOptionsAddCustomOp( 95 TfLiteInterpreterOptions* options, const char* name, 96 const TfLiteRegistration* registration, int32_t min_version, 97 int32_t max_version); 98 99 /// Registers callbacks for resolving builtin or custom operators. 100 /// 101 /// The `TfLiteInterpreterOptionsSetOpResolverExternal` function provides an 102 /// alternative method for registering builtin ops and/or custom ops, by 103 /// providing operator resolver callbacks. Unlike using 104 /// `TfLiteInterpreterOptionsAddBuiltinOp` and/or 105 /// `TfLiteInterpreterOptionsAddAddCustomOp`, these let you register all the 106 /// operators in a single call. 107 /// 108 /// Code that uses this function should NOT call 109 /// `TfLiteInterpreterOptionsAddBuiltin` or 110 /// `TfLiteInterpreterOptionsAddCustomOp` on the same options object. 111 /// 112 /// If `op_resolver_user_data` is non-null, its lifetime must be at least as 113 /// long as the lifetime of the `TfLiteInterpreterOptions`. 114 /// 115 /// WARNING: This is an experimental API and subject to change. 116 void TfLiteInterpreterOptionsSetOpResolverExternal( 117 TfLiteInterpreterOptions* options, 118 const TfLiteRegistrationExternal* (*find_builtin_op)(void* user_data, 119 int op, int version), 120 const TfLiteRegistrationExternal* (*find_custom_op)(void* user_data, 121 const char* custom_op, 122 int version), 123 void* op_resolver_user_data); 124 125 /// Registers callbacks for resolving builtin or custom operators. 126 /// 127 /// The `TfLiteInterpreterOptionsSetOpResolver` function provides an alternative 128 /// method for registering builtin ops and/or custom ops, by providing operator 129 /// resolver callbacks. Unlike using `TfLiteInterpreterOptionsAddBuiltinOp` 130 /// and/or `TfLiteInterpreterOptionsAddAddCustomOp`, these let you register all 131 /// the operators in a single call. 132 /// 133 /// Code that uses this function should NOT call 134 /// `TfLiteInterpreterOptionsAddBuiltin` or 135 /// `TfLiteInterpreterOptionsAddCustomOp` on the same options object. 136 /// 137 /// If `op_resolver_user_data` is non-null, its lifetime must be at least as 138 /// long as the lifetime of the `TfLiteInterpreterOptions`. 139 /// 140 /// WARNING: This is an experimental API and subject to change. 141 /// 142 /// DEPRECATED: use TfLiteInterpreterOptionsSetOpResolverExternal instead. 143 void TfLiteInterpreterOptionsSetOpResolver( 144 TfLiteInterpreterOptions* options, 145 const TfLiteRegistration* (*find_builtin_op)(void* user_data, 146 TfLiteBuiltinOperator op, 147 int version), 148 const TfLiteRegistration* (*find_custom_op)(void* user_data, 149 const char* custom_op, 150 int version), 151 void* op_resolver_user_data); 152 153 /// \private 154 /// Backward-compat version of TfLiteInterpreterOptionsSetOpResolver. 155 /// 156 /// WARNING: This function is deprecated / not an official part of the API, is 157 /// only for binary backwards compatibility, and should not be called. 158 void TfLiteInterpreterOptionsSetOpResolverV2( 159 TfLiteInterpreterOptions* options, 160 const TfLiteRegistration_V2* (*find_builtin_op_v2)(void* user_data, 161 TfLiteBuiltinOperator op, 162 int version), 163 const TfLiteRegistration_V2* (*find_custom_op_v2)(void* user_data, 164 const char* op, 165 int version), 166 void* op_resolver_user_data); 167 168 /// \private 169 /// Backward-compat version of TfLiteInterpreterOptionsSetOpResolver. 170 /// 171 /// WARNING: This function is deprecated / not an official part of the API, is 172 /// only for binary backwards compatibility, and should not be called. 173 void TfLiteInterpreterOptionsSetOpResolverV1( 174 TfLiteInterpreterOptions* options, 175 const TfLiteRegistration_V1* (*find_builtin_op_v1)(void* user_data, 176 TfLiteBuiltinOperator op, 177 int version), 178 const TfLiteRegistration_V1* (*find_custom_op_v1)(void* user_data, 179 const char* op, 180 int version), 181 void* op_resolver_user_data); 182 183 /// Returns a new interpreter using the provided model and options, or null on 184 /// failure, where the model uses only the operators explicitly added to the 185 /// options. This is the same as `TFLiteInterpreterCreate` from `c_api.h`, 186 /// except that the only operators that are supported are the ones registered 187 /// in `options` via calls to `TfLiteInterpreterOptionsSetOpResolver`, 188 /// `TfLiteInterpreterOptionsAddBuiltinOp`, and/or 189 /// `TfLiteInterpreterOptionsAddCustomOp`. 190 /// 191 /// * `model` must be a valid model instance. The caller retains ownership of 192 /// the object, and can destroy it immediately after creating the interpreter; 193 /// the interpreter will maintain its own reference to the underlying model 194 /// data. 195 /// * `options` should not be null. The caller retains ownership of the object, 196 /// and can safely destroy it immediately after creating the interpreter. 197 /// 198 /// NOTE: The client *must* explicitly allocate tensors before attempting to 199 /// access input tensor data or invoke the interpreter. 200 /// 201 /// WARNING: This is an experimental API and subject to change. 202 TFL_CAPI_EXPORT extern TfLiteInterpreter* 203 TfLiteInterpreterCreateWithSelectedOps(const TfLiteModel* model, 204 const TfLiteInterpreterOptions* options); 205 206 /// Enable or disable the NN API delegate for the interpreter (true to enable). 207 /// 208 /// WARNING: This is an experimental API and subject to change. 209 TFL_CAPI_EXPORT extern void TfLiteInterpreterOptionsSetUseNNAPI( 210 TfLiteInterpreterOptions* options, bool enable); 211 212 /// Enable or disable CPU fallback for the interpreter (true to enable). 213 /// If enabled, TfLiteInterpreterInvoke will do automatic fallback from 214 /// executing with delegate(s) to regular execution without delegates 215 /// (i.e. on CPU). 216 /// 217 /// Allowing the fallback is suitable only if both of the following hold: 218 /// - The caller is known not to cache pointers to tensor data across 219 /// TfLiteInterpreterInvoke calls. 220 /// - The model is not stateful (no variables, no LSTMs) or the state isn't 221 /// needed between batches. 222 /// 223 /// When delegate fallback is enabled, TfLiteInterpreterInvoke will 224 /// behave as follows: 225 /// If one or more delegates were set in the interpreter options 226 /// (see TfLiteInterpreterOptionsAddDelegate), 227 /// AND inference fails, 228 /// then the interpreter will fall back to not using any delegates. 229 /// In that case, the previously applied delegate(s) will be automatically 230 /// undone, and an attempt will be made to return the interpreter to an 231 /// invokable state, which may invalidate previous tensor addresses, 232 /// and the inference will be attempted again, using input tensors with 233 /// the same value as previously set. 234 /// 235 /// WARNING: This is an experimental API and subject to change. 236 TFL_CAPI_EXPORT extern void TfLiteInterpreterOptionsSetEnableDelegateFallback( 237 TfLiteInterpreterOptions* options, bool enable); 238 239 // Set if buffer handle output is allowed. 240 // 241 /// When using hardware delegation, Interpreter will make the data of output 242 /// tensors available in `tensor->data` by default. If the application can 243 /// consume the buffer handle directly (e.g. reading output from OpenGL 244 /// texture), it can set this flag to false, so Interpreter won't copy the 245 /// data from buffer handle to CPU memory. WARNING: This is an experimental 246 /// API and subject to change. 247 TFL_CAPI_EXPORT extern void TfLiteSetAllowBufferHandleOutput( 248 const TfLiteInterpreter* interpreter, bool allow_buffer_handle_output); 249 250 /// Allow a delegate to look at the graph and modify the graph to handle 251 /// parts of the graph themselves. After this is called, the graph may 252 /// contain new nodes that replace 1 more nodes. 253 /// 'delegate' must outlive the interpreter. 254 /// Use `TfLiteInterpreterOptionsAddDelegate` instead of this unless 255 /// absolutely required. 256 /// Returns one of the following three status codes: 257 /// 1. kTfLiteOk: Success. 258 /// 2. kTfLiteDelegateError: Delegation failed due to an error in the 259 /// delegate. The Interpreter has been restored to its pre-delegation state. 260 /// NOTE: This undoes all delegates previously applied to the Interpreter. 261 /// 3. kTfLiteError: Unexpected/runtime failure. 262 /// WARNING: This is an experimental API and subject to change. 263 TFL_CAPI_EXPORT extern TfLiteStatus TfLiteInterpreterModifyGraphWithDelegate( 264 const TfLiteInterpreter* interpreter, TfLiteDelegate* delegate); 265 266 /// Returns the tensor index corresponding to the input tensor 267 /// 268 /// WARNING: This is an experimental API and subject to change. 269 TFL_CAPI_EXPORT extern int32_t TfLiteInterpreterGetInputTensorIndex( 270 const TfLiteInterpreter* interpreter, int32_t input_index); 271 272 /// Returns the tensor index corresponding to the output tensor 273 /// 274 /// WARNING: This is an experimental API and subject to change. 275 TFL_CAPI_EXPORT extern int32_t TfLiteInterpreterGetOutputTensorIndex( 276 const TfLiteInterpreter* interpreter, int32_t output_index); 277 278 /// -------------------------------------------------------------------------- 279 /// SignatureRunner APIs 280 /// 281 /// You can run inference by either: 282 /// 283 /// (i) (recommended) using the Interpreter to initialize SignatureRunner(s) and 284 /// then only using SignatureRunner APIs. 285 /// 286 /// (ii) only using Interpreter APIs. 287 /// 288 /// NOTE: 289 /// * Only use one of the above options to run inference, i.e. avoid mixing both 290 /// SignatureRunner APIs and Interpreter APIs to run inference as they share 291 /// the same underlying data (e.g. updating an input tensor “A” retrieved 292 /// using the Interpreter APIs will update the state of the input tensor “B” 293 /// retrieved using SignatureRunner APIs, if they point to the same underlying 294 /// tensor in the model; as it is not possible for a user to debug this by 295 /// analyzing the code, it can lead to undesirable behavior). 296 /// * The TfLiteSignatureRunner type is conditionally thread-safe, provided that 297 /// no two threads attempt to simultaneously access two TfLiteSignatureRunner 298 /// instances that point to the same underlying signature, or access a 299 /// TfLiteSignatureRunner and its underlying TfLiteInterpreter, unless all 300 /// such simultaneous accesses are reads (rather than writes). 301 /// * The lifetime of a TfLiteSignatureRunner object ends when 302 /// TfLiteSignatureRunnerDelete() is called on it (or when the lifetime of the 303 /// underlying TfLiteInterpreter ends -- but you should call 304 /// TfLiteSignatureRunnerDelete() before that happens in order to avoid 305 /// resource leaks). 306 /// * You can only apply delegates to the interpreter (via 307 /// TfLiteInterpreterOptions) and not to a signature. 308 309 /// Returns the number of signatures defined in the model. 310 /// 311 /// WARNING: This is an experimental API and subject to change. 312 TFL_CAPI_EXPORT extern int32_t TfLiteInterpreterGetSignatureCount( 313 const TfLiteInterpreter* interpreter); 314 315 /// Returns the key of the Nth signature in the model, where N is specified as 316 /// `signature_index`. 317 /// 318 /// NOTE: The lifetime of the returned key is the same as (and depends on) the 319 /// lifetime of `interpreter`. 320 /// 321 /// WARNING: This is an experimental API and subject to change. 322 TFL_CAPI_EXPORT extern const char* TfLiteInterpreterGetSignatureKey( 323 const TfLiteInterpreter* interpreter, int32_t signature_index); 324 325 /// Returns a new signature runner using the provided interpreter and signature 326 /// key, or nullptr on failure. 327 /// 328 /// NOTE: `signature_key` is a null-terminated C string that must match the 329 /// key of a signature in the interpreter's model. 330 /// 331 /// NOTE: The returned signature runner should be destroyed, by calling 332 /// TfLiteSignatureRunnerDelete(), before the interpreter is destroyed. 333 /// 334 /// WARNING: This is an experimental API and subject to change. 335 TFL_CAPI_EXPORT extern TfLiteSignatureRunner* 336 TfLiteInterpreterGetSignatureRunner(const TfLiteInterpreter* interpreter, 337 const char* signature_key); 338 339 /// Returns the number of inputs associated with a signature. 340 /// 341 /// WARNING: This is an experimental API and subject to change. 342 TFL_CAPI_EXPORT extern size_t TfLiteSignatureRunnerGetInputCount( 343 const TfLiteSignatureRunner* signature_runner); 344 345 /// Returns the (null-terminated) name of the Nth input in a signature, where N 346 /// is specified as `input_index`. 347 /// 348 /// NOTE: The lifetime of the returned name is the same as (and depends on) the 349 /// lifetime of `signature_runner`. 350 /// 351 /// WARNING: This is an experimental API and subject to change. 352 TFL_CAPI_EXPORT extern const char* TfLiteSignatureRunnerGetInputName( 353 const TfLiteSignatureRunner* signature_runner, const int32_t input_index); 354 355 /// Resizes the input tensor identified as `input_name` to be the dimensions 356 /// specified by `input_dims` and `input_dims_size`. Only unknown dimensions can 357 /// be resized with this function. Unknown dimensions are indicated as `-1` in 358 /// the `dims_signature` attribute of a TfLiteTensor. 359 /// 360 /// Returns status of failure or success. Note that this doesn't actually resize 361 /// any existing buffers. A call to TfLiteSignatureRunnerAllocateTensors() is 362 /// required to change the tensor input buffer. 363 /// 364 /// NOTE: This function is similar to TfLiteInterpreterResizeInputTensorStrict() 365 /// and not TfLiteInterpreterResizeInputTensor(). 366 /// 367 /// NOTE: `input_name` must match the name of an input in the signature. 368 /// 369 /// NOTE: This function makes a copy of the input dimensions, so the caller can 370 /// safely deallocate `input_dims` immediately after this function returns. 371 /// 372 /// WARNING: This is an experimental API and subject to change. 373 TFL_CAPI_EXPORT extern TfLiteStatus TfLiteSignatureRunnerResizeInputTensor( 374 TfLiteSignatureRunner* signature_runner, const char* input_name, 375 const int* input_dims, int32_t input_dims_size); 376 377 /// Updates allocations for tensors associated with a signature and resizes 378 /// dependent tensors using the specified input tensor dimensionality. 379 /// This is a relatively expensive operation and hence should only be called 380 /// after initializing the signature runner object and/or resizing any inputs. 381 /// 382 /// WARNING: This is an experimental API and subject to change. 383 TFL_CAPI_EXPORT extern TfLiteStatus TfLiteSignatureRunnerAllocateTensors( 384 TfLiteSignatureRunner* signature_runner); 385 386 /// Returns the input tensor identified by `input_name` in the given signature. 387 /// Returns nullptr if the given name is not valid. 388 /// 389 /// NOTE: The lifetime of the returned tensor is the same as (and depends on) 390 /// the lifetime of `signature_runner`. 391 /// 392 /// WARNING: This is an experimental API and subject to change. 393 TFL_CAPI_EXPORT extern TfLiteTensor* TfLiteSignatureRunnerGetInputTensor( 394 TfLiteSignatureRunner* signature_runner, const char* input_name); 395 396 /// Runs inference on a given signature. 397 /// 398 /// Before calling this function, the caller should first invoke 399 /// TfLiteSignatureRunnerAllocateTensors() and should also set the values for 400 /// the input tensors. After successfully calling this function, the values for 401 /// the output tensors will be set. 402 /// 403 /// WARNING: This is an experimental API and subject to change. 404 TFL_CAPI_EXPORT extern TfLiteStatus TfLiteSignatureRunnerInvoke( 405 TfLiteSignatureRunner* signature_runner); 406 407 /// Returns the number of output tensors associated with the signature. 408 /// 409 /// WARNING: This is an experimental API and subject to change. 410 TFL_CAPI_EXPORT extern size_t TfLiteSignatureRunnerGetOutputCount( 411 const TfLiteSignatureRunner* signature_runner); 412 413 /// Returns the (null-terminated) name of the Nth output in a signature, where 414 /// N is specified as `output_index`. 415 /// 416 /// NOTE: The lifetime of the returned name is the same as (and depends on) the 417 /// lifetime of `signature_runner`. 418 /// 419 /// WARNING: This is an experimental API and subject to change. 420 TFL_CAPI_EXPORT extern const char* TfLiteSignatureRunnerGetOutputName( 421 const TfLiteSignatureRunner* signature_runner, int32_t output_index); 422 423 /// Returns the output tensor identified by `output_name` in the given 424 /// signature. Returns nullptr if the given name is not valid. 425 /// 426 /// NOTE: The lifetime of the returned tensor is the same as (and depends on) 427 /// the lifetime of `signature_runner`. 428 /// 429 /// WARNING: This is an experimental API and subject to change. 430 TFL_CAPI_EXPORT extern const TfLiteTensor* TfLiteSignatureRunnerGetOutputTensor( 431 const TfLiteSignatureRunner* signature_runner, const char* output_name); 432 433 /// Attempts to cancel in flight invocation if any. 434 /// This will not affect calls to `Invoke` that happend after this. 435 /// Non blocking and thread safe. 436 /// Returns kTfLiteError if cancellation is not enabled, otherwise returns 437 /// kTfLiteOk. 438 /// NOTE: Calling this function will cancel in-flight invocations 439 /// in all SignatureRunners built from the same interpreter. 440 /// 441 /// WARNING: This is an experimental API and subject to change. 442 TFL_CAPI_EXPORT extern TfLiteStatus TfLiteSignatureRunnerCancel( 443 TfLiteSignatureRunner* signature_runner); 444 445 /// Destroys the signature runner. 446 /// 447 /// WARNING: This is an experimental API and subject to change. 448 TFL_CAPI_EXPORT extern void TfLiteSignatureRunnerDelete( 449 TfLiteSignatureRunner* signature_runner); 450 451 // Forward declaration, to avoid need for dependency on 452 // tensorflow/lite/profiling/telemetry/profiler.h. 453 struct TfLiteTelemetryProfilerStruct; 454 455 /// Registers the telemetry profiler to the interpreter. 456 /// Note: The interpreter does not take the ownership of profiler, but callers 457 /// must ensure profiler->data outlives the lifespan of the interpreter. 458 /// 459 /// WARNING: This is an experimental API and subject to change. 460 TFL_CAPI_EXPORT extern void TfLiteInterpreterOptionsSetTelemetryProfiler( 461 TfLiteInterpreterOptions* options, 462 struct TfLiteTelemetryProfilerStruct* profiler); 463 464 #ifdef __cplusplus 465 } // extern "C" 466 #endif // __cplusplus 467 468 #endif // TENSORFLOW_LITE_CORE_C_C_API_EXPERIMENTAL_H_ 469