chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
load("@rules_cc//cc:cc_library.bzl", "cc_library")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:LICENSE"],
default_visibility = [
"//visibility:public",
],
licenses = ["notice"],
)
cc_library(
name = "external_delegate_interface",
hdrs = ["external_delegate_interface.h"],
deps = [
"//tensorflow/lite/c:common",
],
)
cc_library(
name = "external_delegate",
srcs = ["external_delegate.cc"],
hdrs = ["external_delegate.h"],
deps = [
":external_delegate_interface",
"//tensorflow/lite:minimal_logging",
"//tensorflow/lite:shared_library",
"//tensorflow/lite/c:c_api_types",
"//tensorflow/lite/c:common",
"//tensorflow/lite/core/c:common",
],
)
exports_files([
"external_delegate.h",
])
+33
View File
@@ -0,0 +1,33 @@
# What is an External Delegate?
An external delegate is a special Tensorflow Lite delegate that is simply
initialized from loading a dynamic library which encapsulates an actual
Tensorflow Lite delegate implementation. The actual delegate exposes the
following two creation and deletion C APIs:
* __tflite_plugin_create_delegate__ (declaration seen below) creates a delegate
object based on provided key-value options. It may return NULL to indicate an
error with the detailed information reported by calling `report_error` if
provided. Each option key and value should be null-terminated.
```
TfLiteDelegate* tflite_plugin_create_delegate(
char** options_keys, char** options_values, size_t num_options,
void (*report_error)(const char *))
```
* __tflite_plugin_destroy_delegate__ (declaration seen below) destroys the
delegate object that is created by the previous API. NULL as an argument value
is allowed.
```
void tflite_plugin_destroy_delegate(TfLiteDelegate* delegate)
```
The external delegate provides an opaque and transparent way to utilize a
Tensorflow Lite delegate when performing inference. In other words, one may
replace the actual Tensorflow Lite delegate by simply updating the dynamic
library without changing the application code. We developed this mainly for
delegate evaluation.
Note, this delegate is the corresponding C++ implementation to the one for
Tensorflow Lite Python binding as shown [here](https://github.com/tensorflow/tensorflow/blob/7145fc0e49be01ef6943f4df386ce38567e37797/tensorflow/lite/python/interpreter.py#L42).
+227
View File
@@ -0,0 +1,227 @@
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/lite/delegates/external/external_delegate.h"
#include <locale>
#include <memory>
#include <string>
#include <vector>
#include "tensorflow/lite/c/c_api_types.h"
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/delegates/external/external_delegate_interface.h"
#include "tensorflow/lite/logger.h"
#include "tensorflow/lite/minimal_logging.h"
#include "tensorflow/lite/shared_library.h"
namespace tflite {
namespace {
// TODO(b/245168068): Add support for `TfLiteOpaqueDelegateBuilder`.
// External delegate library construct
struct ExternalLib {
struct wchar_codecvt : public std::codecvt<wchar_t, char, std::mbstate_t> {};
// Open a given delegate library and load the create/destroy symbols
bool load(const std::string library) {
#if defined(_WIN32)
std::wstring_convert<wchar_codecvt> converter;
void* handle = SharedLibrary::LoadLibrary(
converter.from_bytes(library.c_str()).c_str());
#else
void* handle = SharedLibrary::LoadLibrary(library.c_str());
#endif // defined(_WIN32)
if (handle == nullptr) {
TFLITE_LOG(TFLITE_LOG_INFO,
"Unable to load external delegate from : %s (%s)",
library.c_str(), SharedLibrary::GetError());
} else {
create = reinterpret_cast<decltype(&tflite_plugin_create_delegate)>(
SharedLibrary::GetLibrarySymbol(handle,
"tflite_plugin_create_delegate"));
destroy = reinterpret_cast<decltype(&tflite_plugin_destroy_delegate)>(
SharedLibrary::GetLibrarySymbol(handle,
"tflite_plugin_destroy_delegate"));
return create && destroy;
}
return false;
}
decltype(&tflite_plugin_create_delegate) create{nullptr};
decltype(&tflite_plugin_destroy_delegate) destroy{nullptr};
};
// An ExternalDelegateWrapper is responsibile to manage a TFLite delegate
// initialized from a shared library. It creates a delegate from the given
// option and storages it to external_delegate_ member variable. On the
// destruction, it conducts necessary clean up process.
class ExternalDelegateWrapper {
public:
explicit ExternalDelegateWrapper(
const TfLiteExternalDelegateOptions* options);
~ExternalDelegateWrapper();
// Return a TfLiteDelegate which is created from
// tflite_plugin_create_delegate() of an external delegate logic.
TfLiteDelegate* tflite_external_delegate() { return external_delegate_; }
// Return a TfLiteDelegate which is convertibile to this class.
TfLiteDelegate* tflite_wrapper_delegate() { return &wrapper_delegate_; }
private:
ExternalLib external_lib_;
// external delegate instance owned by external delegate logic.
// It's created by "tflite_plugin_destroy_delegate()" function in the external
// delegate logic And it should be released by
// "tflite_plugin_destroy_delegate()" function.
TfLiteDelegate* external_delegate_;
// TfLiteDelegate representation of this ExternalDelegateWrapper object.
TfLiteDelegate wrapper_delegate_ = {};
};
// Converts the given TfLiteDelegate to an ExternalDelegateWrapper instance.
inline ExternalDelegateWrapper* GetExternalDelegateWrapper(
TfLiteDelegate* delegate) {
return reinterpret_cast<ExternalDelegateWrapper*>(delegate->data_);
}
// Relay Prepare() call to the associated external TfLiteDelegate object.
TfLiteStatus DelegatePrepare(TfLiteContext* context, TfLiteDelegate* delegate) {
auto external_delegate_wrapper = GetExternalDelegateWrapper(delegate);
TfLiteDelegate* external_delegate =
external_delegate_wrapper->tflite_external_delegate();
return external_delegate->Prepare(context, external_delegate);
}
// Relay CopyFromBufferHandle() call to the associated external TfLiteDelegate
// object.
TfLiteStatus DelegateCopyFromBufferHandle(TfLiteContext* context,
struct TfLiteDelegate* delegate,
TfLiteBufferHandle buffer_handle,
TfLiteTensor* tensor) {
auto external_delegate_wrapper = GetExternalDelegateWrapper(delegate);
TfLiteDelegate* external_delegate =
external_delegate_wrapper->tflite_external_delegate();
return external_delegate->CopyFromBufferHandle(context, delegate,
buffer_handle, tensor);
}
// Relay CopyToBufferHandle() call to the associated external TfLiteDelegate
// object.
TfLiteStatus DelegateCopyToBufferHandle(TfLiteContext* context,
struct TfLiteDelegate* delegate,
TfLiteBufferHandle buffer_handle,
TfLiteTensor* tensor) {
auto external_delegate_wrapper = GetExternalDelegateWrapper(delegate);
TfLiteDelegate* external_delegate =
external_delegate_wrapper->tflite_external_delegate();
return external_delegate->CopyToBufferHandle(context, delegate, buffer_handle,
tensor);
}
// Relay FreeBufferHandle() call to the associated external TfLiteDelegate
// object.
void DelegateFreeBufferHandle(TfLiteContext* context,
struct TfLiteDelegate* delegate,
TfLiteBufferHandle* handle) {
auto external_delegate_wrapper = GetExternalDelegateWrapper(delegate);
TfLiteDelegate* external_delegate =
external_delegate_wrapper->tflite_external_delegate();
return external_delegate->FreeBufferHandle(context, delegate, handle);
}
ExternalDelegateWrapper::ExternalDelegateWrapper(
const TfLiteExternalDelegateOptions* options) {
external_delegate_ = nullptr;
if (external_lib_.load(options->lib_path)) {
std::vector<const char*> ckeys, cvalues;
for (int i = 0; i < options->count; i++) {
ckeys.push_back(options->keys[i]);
cvalues.push_back(options->values[i]);
}
external_delegate_ = external_lib_.create(ckeys.data(), cvalues.data(),
ckeys.size(), nullptr);
if (external_delegate_) {
wrapper_delegate_.data_ = reinterpret_cast<void*>(this);
wrapper_delegate_.Prepare = DelegatePrepare;
wrapper_delegate_.CopyFromBufferHandle = nullptr;
wrapper_delegate_.CopyToBufferHandle = nullptr;
wrapper_delegate_.FreeBufferHandle = nullptr;
wrapper_delegate_.flags = external_delegate_->flags;
if (external_delegate_->CopyFromBufferHandle) {
wrapper_delegate_.CopyFromBufferHandle = DelegateCopyFromBufferHandle;
}
if (external_delegate_->CopyToBufferHandle) {
wrapper_delegate_.CopyToBufferHandle = DelegateCopyToBufferHandle;
}
if (external_delegate_->FreeBufferHandle) {
wrapper_delegate_.FreeBufferHandle = DelegateFreeBufferHandle;
}
}
}
}
ExternalDelegateWrapper::~ExternalDelegateWrapper() {
if (external_delegate_ != nullptr) {
external_lib_.destroy(external_delegate_);
}
}
} // namespace
} // namespace tflite
// TfLiteExternalDelegateOptionsInsert adds key/value to the given
// TfLiteExternalDelegateOptions instance.
TfLiteStatus TfLiteExternalDelegateOptionsInsert(
TfLiteExternalDelegateOptions* options, const char* key,
const char* value) {
if (options->count >= kExternalDelegateMaxOptions) {
return kTfLiteError;
}
options->keys[options->count] = key;
options->values[options->count] = value;
options->count++;
return kTfLiteOk;
}
TfLiteExternalDelegateOptions TfLiteExternalDelegateOptionsDefault(
const char* lib_path) {
// As 'keys' and 'values' don't need to be set here, using designated
// initializers may cause a compiling error as "non-trivial designated
// initializers not supported" by some compiler.
TfLiteExternalDelegateOptions options;
options.lib_path = lib_path;
options.count = 0;
options.insert = TfLiteExternalDelegateOptionsInsert;
return options;
}
TfLiteDelegate* TfLiteExternalDelegateCreate(
const TfLiteExternalDelegateOptions* options) {
auto external_delegate_wrapper =
std::make_unique<tflite::ExternalDelegateWrapper>(options);
if (external_delegate_wrapper->tflite_external_delegate() != nullptr) {
return external_delegate_wrapper.release()->tflite_wrapper_delegate();
}
return nullptr;
}
void TfLiteExternalDelegateDelete(TfLiteDelegate* delegate) {
delete tflite::GetExternalDelegateWrapper(delegate);
}
+57
View File
@@ -0,0 +1,57 @@
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_LITE_DELEGATES_EXTERNAL_EXTERNAL_DELEGATE_H_
#define TENSORFLOW_LITE_DELEGATES_EXTERNAL_EXTERNAL_DELEGATE_H_
#include "tensorflow/lite/core/c/common.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// TfLiteExternalDelegateOptions is a structure of key/value options to create
// an external delegate.
#define kExternalDelegateMaxOptions 256
typedef struct TfLiteExternalDelegateOptions {
const char* lib_path;
int count;
const char* keys[kExternalDelegateMaxOptions];
const char* values[kExternalDelegateMaxOptions];
TfLiteStatus (*insert)(struct TfLiteExternalDelegateOptions* options,
const char* key, const char* value);
} TfLiteExternalDelegateOptions;
// Insert key/value to the options.
TfLiteStatus TfLiteExternalDelegateOptionsInsert(
TfLiteExternalDelegateOptions* options, const char* key, const char* value);
// Populates TfLiteExternalDelegateOptions with the given shared library path.
TfLiteExternalDelegateOptions TfLiteExternalDelegateOptionsDefault(
const char* lib_path);
// Creates a new delegate instance that need to be destroyed with
// `TfLiteExternalDelegateDelete` when delegate is no longer used by TFLite.
TfLiteDelegate* TfLiteExternalDelegateCreate(
const TfLiteExternalDelegateOptions* options);
// Destroys a delegate created with `TfLiteExternalDelegateCreate` call.
void TfLiteExternalDelegateDelete(TfLiteDelegate* delegate);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // TENSORFLOW_LITE_DELEGATES_EXTERNAL_EXTERNAL_DELEGATE_H_
@@ -0,0 +1,79 @@
/* Copyright 2022 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_LITE_DELEGATES_EXTERNAL_EXTERNAL_DELEGATE_INTERFACE_H_
#define TENSORFLOW_LITE_DELEGATES_EXTERNAL_EXTERNAL_DELEGATE_INTERFACE_H_
#include "tensorflow/lite/c/common.h"
// This header file declares the interface that external delegate shared
// libraries need to implement. The functions declared here are not defined
// in TF Lite itself -- this just declares the interface to functions that
// are defined elsewhere, in a shared library that TfLiteExternalDelegate will
// dynamically load.
#ifdef __cplusplus
extern "C" {
#endif
// Define TFL_EXTERNAL_DELEGATE_EXPORT macro to export an external delegate API
// function properly with a shared library.
#ifdef SWIG
#define TFL_EXTERNAL_DELEGATE_EXPORT
#else // !defined SWIG
#ifdef _WIN32
// On Windows, the TFL_EXTERNAL_DELEGATE_COMPILE_LIBRARY macro should be
// defined when _building_ an external delegate shared library, but should not
// be defined when _using_ an external delegate shared library.
#ifdef TFL_EXTERNAL_DELEGATE_COMPILE_LIBRARY
#define TFL_EXTERNAL_DELEGATE_EXPORT __declspec(dllexport)
#else // !defined TFL_EXTERNAL_DELEGATE_COMPILE_LIBRARY
// We may not actually need dllimport,
// since the symbols will looked up dynamically?
#define TFL_EXTERNAL_DELEGATE_EXPORT __declspec(dllimport)
#endif // !defined TFL_EXTERNAL_DELEGATE_COMPILE_LIBRARY
#else // !defined _WIN32
#define TFL_EXTERNAL_DELEGATE_EXPORT __attribute__((visibility("default")))
#endif // !defined _WIN32
#endif // !defined SWIG
// Creates a delegate object based on provided key-value options.
//
// The delegate is initialized using the option settings specified by the
// names in `options_keys` and the corresponding values in `options_values`,
// which are both arrays of length `num_options` of NUL-terminated C strings.
// This function *should not* modify those arrays, but the caller must not rely
// on that. `options_keys` and `options_values` may be null if `num_options` is
// zero.
//
// On success, returns a non-null value that should be deallocated with
// tflite_plugin_destroy_delegate when no longer needed.
// On failure, returns NULL to indicate an error, with the detailed information
// reported by calling `report_error` if provided.
extern TFL_EXTERNAL_DELEGATE_EXPORT TfLiteDelegate*
tflite_plugin_create_delegate(const char* const* options_keys,
const char* const* options_values,
size_t num_options,
void (*report_error)(const char*));
// Destroys a delegate object that was created by tflite_plugin_create_delegate.
// Calling this with nullptr as the argument value is allowed and has no effect.
extern TFL_EXTERNAL_DELEGATE_EXPORT void tflite_plugin_destroy_delegate(
TfLiteDelegate* delegate);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // TENSORFLOW_LITE_DELEGATES_EXTERNAL_EXTERNAL_DELEGATE_INTERFACE_H_