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
@@ -0,0 +1,436 @@
# Copyright 2019 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.
# ==============================================================================
# buildifier: disable=out-of-order-load
load("@rules_cc//cc:cc_test.bzl", "cc_test")
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
load("@com_google_protobuf//bazel:java_lite_proto_library.bzl", "java_lite_proto_library")
load("@flatbuffers//:build_defs.bzl", "DEFAULT_FLATC_ARGS", "flatbuffer_android_library", "flatbuffer_cc_library", "flatbuffer_java_library", "flatc_path")
load("//tensorflow:tensorflow.default.bzl", "get_compatible_with_portable")
load("//tensorflow/lite:build_def.bzl", "tflite_copts", "tflite_copts_warnings")
load("//tensorflow/lite:special_rules.bzl", "tflite_portable_test_suite")
load("//tensorflow/lite/core/shims:cc_library_with_tflite.bzl", "cc_library_with_tflite", "cc_test_with_tflite")
# copybara:uncomment load("//tools/build_defs/proto/cpp:cc_proto_library.bzl", "cc_proto_library")
load(":build_defs.bzl", "flatbuffer_schema_compat_test")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:LICENSE"],
default_visibility = [
"//visibility:public",
],
licenses = ["notice"],
)
# We generate a FlatBuffer schema from the Protobuf schema.
genrule(
name = "configuration_schema",
srcs = ["configuration.proto"],
outs = ["configuration.fbs"],
# We rename the namespace since otherwise the proto classes and flatbuffer
# classes would have the same names.
cmd = """
$(location {}) --proto -o $(@D) $(location :configuration.proto)
perl -p -i -e 's/tflite.proto/tflite/' $@
""".format(flatc_path),
compatible_with = get_compatible_with_portable(),
tools = [flatc_path],
)
# We also do the same transformation for the _previous_
# version of the schema -- this is used to test that changes
# to the schema preserve binary backwards compatibility.
genrule(
name = "configuration_prev_schema",
srcs = ["testdata/configuration.proto_prev"], # Must NOT end in '.proto'.
outs = ["configuration.prev.fbs"], # MUST end in '.fbs'.
# We rename the namespace since otherwise the proto classes and flatbuffer
# classes would have the same names.
cmd = """
cp $(location :testdata/configuration.proto_prev) $(@D)/configuration.prev.proto
$(location {}) --proto -o $(@D) $(@D)/configuration.prev.proto
perl -p -i -e 's/tflite.proto/tflite/' $@
""".format(flatc_path),
compatible_with = get_compatible_with_portable(),
tools = [flatc_path],
)
# Test that changes to the proto file preserve binary backwards compatibility
# of the generated FlatBuffer schema, relative to the one generated from the
# previous proto file.
flatbuffer_schema_compat_test(
name = "configuration_abi_stability_test",
ref_schema = ":configuration.prev.fbs",
schema = ":configuration.fbs",
)
# Test that changes to the proto file OR to the FlatBuffer proto-to-flatbuffer
# schema conversion itself will preserve binary backwards compatibility of the
# generated FlatBuffer schema, relative to an older snapshot of the
# generated FlatBuffer schema.
flatbuffer_schema_compat_test(
name = "configuration_flatbuffer_abi_stability_test",
ref_schema = "testdata/configuration.old.fbs",
schema = ":configuration.fbs",
)
# Test that the previous version of the proto is different than the current version.
sh_test(
name = "prev_is_different_than_current_test",
srcs = ["prev_is_different_than_current_test.sh"],
data = [
"configuration.proto",
"testdata/configuration.proto_prev",
],
)
# Generate a C++ header containing the contents of the FlatBuffer schema
# as a char array literal. This is potentially useful for embedding in programs
# (e.g. for JSON parsing using that schema).
genrule(
name = "configuration_fbs_contents_cc",
srcs = ["configuration.fbs"],
outs = ["configuration_fbs_contents-inl.h"],
cmd = """
echo 'constexpr char configuration_fbs_contents[] = R"Delimiter(' > $(@)
cat < $(<) >> $(@)
echo ')Delimiter";' >> $(@)
""",
)
exports_files(["configuration.proto"])
proto_library(
name = "configuration_proto",
srcs = [
"configuration.proto",
],
compatible_with = get_compatible_with_portable(),
)
cc_proto_library(
name = "configuration_cc_proto",
compatible_with = get_compatible_with_portable(),
deps = [":configuration_proto"],
)
java_lite_proto_library(
name = "configuration_java_proto_lite",
deps = [":configuration_proto"],
)
flatbuffer_cc_library(
name = "configuration_fbs",
srcs = [":configuration.fbs"],
compatible_with = get_compatible_with_portable(),
flatc_args = DEFAULT_FLATC_ARGS + ["--gen-compare"],
)
flatbuffer_java_library(
name = "configuration_fbs_java",
srcs = [":configuration.fbs"],
)
flatbuffer_android_library(
name = "configuration_fbs_android",
srcs = [":configuration.fbs"],
)
cc_library(
name = "proto_to_flatbuffer",
srcs = [
"proto_to_flatbuffer.cc",
],
hdrs = ["proto_to_flatbuffer.h"],
deps = [
":configuration_cc_proto",
":configuration_fbs",
"//tensorflow/lite:minimal_logging",
"@flatbuffers",
],
)
cc_test(
name = "proto_to_flatbuffer_test",
srcs = ["proto_to_flatbuffer_test.cc"],
deps = [
":configuration_cc_proto",
":proto_to_flatbuffer",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "flatbuffer_to_proto",
srcs = [
"flatbuffer_to_proto.cc",
],
hdrs = ["flatbuffer_to_proto.h"],
compatible_with = get_compatible_with_portable(),
deps = [
":configuration_cc_proto",
":configuration_fbs",
"//tensorflow/lite:minimal_logging",
"@flatbuffers",
],
)
cc_test(
name = "flatbuffer_to_proto_test",
srcs = ["flatbuffer_to_proto_test.cc"],
deps = [
":configuration_cc_proto",
":configuration_fbs",
":flatbuffer_to_proto",
"@com_google_googletest//:gtest_main",
],
)
cc_library_with_tflite(
name = "delegate_registry",
hdrs = ["delegate_registry.h"],
compatible_with = get_compatible_with_portable(),
copts = tflite_copts_warnings(),
deps = [
":configuration_fbs",
"//tensorflow/lite/core/acceleration/configuration:delegate_registry",
"//tensorflow/lite/core/c:common",
"@com_google_absl//absl/synchronization",
],
)
cc_library_with_tflite(
name = "delegate_plugin_converter",
srcs = ["delegate_plugin_converter.cc"],
hdrs = ["delegate_plugin_converter.h"],
tflite_deps = [
"//tensorflow/lite/acceleration/configuration/c:delegate_plugin",
"//tensorflow/lite/acceleration/configuration:delegate_registry",
"//tensorflow/lite/c:common",
],
deps = ["@com_google_absl//absl/memory"],
)
cc_library_with_tflite(
name = "nnapi_plugin",
compatible_with = get_compatible_with_portable(),
deps = ["//tensorflow/lite/core/acceleration/configuration:nnapi_plugin"],
)
# Commented under b/279852433 because caused an error in the OSS
# TODO(zhurakovskyi): Uncomment when fixed.
# copybara:uncomment_begin
# cc_library(
# name = "hexagon_plugin",
# srcs = ["hexagon_plugin.cc"],
# deps = [
# ":configuration_fbs",
# "@com_google_absl//absl/memory",
# "//tensorflow/lite/core/acceleration/configuration:delegate_registry",
# ] + select({
# "//third_party/bazel_platforms/cpu:aarch64": [
# "//tensorflow/lite/delegates/hexagon:hexagon_delegate",
# ],
# "//third_party/bazel_platforms/cpu:armv7": [
# "//tensorflow/lite/delegates/hexagon:hexagon_delegate",
# ],
# "//conditions:default": [],
# }),
# alwayslink = 1, # For registration to always run.
# )
# copybara:uncomment_end
cc_library(
name = "gpu_plugin",
deps = [
":gpu_plugin_impl",
],
)
common_copts = tflite_copts() + tflite_copts_warnings()
cc_library(
name = "gpu_plugin_impl",
srcs = ["gpu_plugin.cc"],
hdrs = ["gpu_plugin.h"],
copts = common_copts + select({
"//tensorflow:ios": [
"-xobjective-c++",
],
"//tensorflow:macos_arm64": [
"-xobjective-c++",
],
"//conditions:default": [],
}),
visibility = [
"//tensorflow/lite/core/acceleration/configuration/c:__pkg__",
"//tensorflow/lite/experimental/acceleration/configuration:__pkg__",
],
deps = [
":configuration_fbs",
"//tensorflow/lite/core/acceleration/configuration:delegate_registry",
"@com_google_absl//absl/memory",
] + select({
"//tensorflow/lite/delegates/gpu:supports_gpu_delegate": [
"//tensorflow/lite/delegates/gpu:delegate",
],
"//conditions:default": [],
}) + select({
"//tensorflow:ios": [
"//tensorflow/lite/delegates/gpu:metal_delegate",
],
"//tensorflow:macos_arm64": [
"//tensorflow/lite/delegates/gpu:metal_delegate",
],
"//conditions:default": [],
}),
alwayslink = 1, # For registration to always run.
)
cc_test(
name = "gpu_plugin_test",
srcs = ["gpu_plugin_test.cc"],
tags = [
# TODO(b/214492180): Enable the tests for mac/ios too. This most likely
# needs TAP to recognize the xobjective-c++ flag.
"no_mac",
"tflite_not_portable_ios",
],
deps = [
":configuration_cc_proto",
":configuration_fbs",
":gpu_plugin_impl",
":proto_to_flatbuffer",
"//tensorflow/lite/core/acceleration/configuration:delegate_registry",
"@com_google_googletest//:gtest_main",
"@flatbuffers//:runtime_cc",
],
)
cc_library_with_tflite(
name = "xnnpack_plugin",
compatible_with = get_compatible_with_portable(),
visibility = ["//visibility:public"],
deps = ["//tensorflow/lite/core/acceleration/configuration:xnnpack_plugin"],
)
cc_test_with_tflite(
name = "xnnpack_plugin_with_tflite_test",
srcs = ["xnnpack_plugin_test.cc"],
# The variant of this test that links against TF Lite in Play services
# isn't portable to iOS / Mac or Android, because it relies on a separate
# shared library that isn't included in the executable, and the testing
# infrastructure for iOS and Android doesn't propagate data dependencies
# to the test device. So we disable this test on those devices.
# TODO(b/306161304): ideally we ought to apply these tags only to the
# variant for TF Lite in Play services. In the mean time, we apply those
# tags to the whole test, but also duplicate the test below using cc_test
# without the tags.
tags = [
"no_mac",
"tflite_not_portable_android",
"tflite_not_portable_ios",
],
tflite_deps = [
":xnnpack_plugin",
"//tensorflow/lite:test_util",
"//tensorflow/lite/acceleration/configuration:delegate_registry",
],
deps = [
":configuration_fbs",
"@com_google_googletest//:gtest_main",
"@flatbuffers//:runtime_cc",
"@pthreadpool",
],
)
# This duplicates xnnnpack_plugin_with_tflite_test above, but without the tags,
# to ensure that this test does get run on iOS and Android.
cc_test(
name = "xnnpack_plugin_test",
srcs = ["xnnpack_plugin_test.cc"],
deps = [
":configuration_fbs",
":xnnpack_plugin",
"//tensorflow/lite:test_util",
"//tensorflow/lite/acceleration/configuration:delegate_registry",
"@com_google_googletest//:gtest_main",
"@flatbuffers//:runtime_cc",
"@pthreadpool",
],
)
cc_library(
name = "coreml_plugin",
srcs = ["coreml_plugin.cc"],
deps = [
":configuration_fbs",
"//tensorflow/lite:minimal_logging",
"//tensorflow/lite/core/acceleration/configuration:delegate_registry",
"@com_google_absl//absl/memory",
] + select({
"//tensorflow:macos": [
"//tensorflow/lite/delegates/coreml:coreml_delegate",
],
"//tensorflow:ios": [
"//tensorflow/lite/delegates/coreml:coreml_delegate",
],
"//conditions:default": [],
}),
alwayslink = 1, # For registration to always run.
)
# TODO(b/260582614): Add support for TF Lite in Play Services.
cc_library(
name = "stable_delegate_plugin",
srcs = ["stable_delegate_plugin.cc"],
hdrs = ["stable_delegate_plugin.h"],
deps = [
":configuration_fbs",
"//tensorflow/lite/acceleration/configuration/c:delegate_plugin",
"//tensorflow/lite/acceleration/configuration/c:stable_delegate",
"//tensorflow/lite/c:common",
"//tensorflow/lite/core/acceleration/configuration:delegate_registry",
"//tensorflow/lite/delegates/utils/experimental/stable_delegate:delegate_loader",
"//tensorflow/lite/tools:logging",
"@com_google_absl//absl/memory",
"@flatbuffers//:runtime_cc",
],
alwayslink = 1, # For registration to always run.
)
cc_test(
name = "stable_delegate_plugin_test",
srcs = ["stable_delegate_plugin_test.cc"],
data = ["//tensorflow/lite/delegates/utils/experimental/stable_delegate:libtensorflowlite_stable_xnnpack_delegate.so"],
tags = [
# TODO(b/259303511): Propagate build config to data correctly to enable the test on x86 platforms.
"no_test_android_x86",
],
deps = [
":configuration_fbs",
":stable_delegate_plugin",
"//tensorflow/lite/core/acceleration/configuration:delegate_registry",
"//tensorflow/lite/delegates/xnnpack:xnnpack_delegate",
"@com_google_googletest//:gtest_main",
"@flatbuffers//:runtime_cc",
"@pthreadpool",
],
)
tflite_portable_test_suite()
@@ -0,0 +1,43 @@
# 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.
# ==============================================================================
"""Build macros for checking ABI compatibility."""
load("@flatbuffers//:build_defs.bzl", "flatc_path")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
def flatbuffer_schema_compat_test(name, ref_schema, schema):
"""Generates a test for schema binary compatibility.
Generates a test that the specified schema file is binary backwards
compatible with a reference schema (e.g. a previous version of the
schema).
Note: currently this build macro requires that the schema be a single
fully self-contained .fbs file; it does not yet support includes.
"""
native.genrule(
name = name + "_gen",
srcs = [ref_schema, schema],
outs = [name + "_test.sh"],
tools = [flatc_path],
cmd = ("echo $(rootpath {}) --conform $(rootpath {}) $(rootpath {}) > $@"
.format(flatc_path, ref_schema, schema)),
)
sh_test(
name = name,
srcs = [name + "_test.sh"],
data = [flatc_path, ref_schema, schema],
)
@@ -0,0 +1,107 @@
# Copyright 2021 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.
# ==============================================================================
# C API for delegate plugins.
load("//tensorflow:tensorflow.default.bzl", "get_compatible_with_portable")
load("//tensorflow/lite:build_def.bzl", "tflite_copts", "tflite_copts_warnings")
load(
"//tensorflow/lite/core/shims:cc_library_with_tflite.bzl",
"cc_library_with_tflite_with_c_headers_test",
)
# LINT.IfChange(tflite_acceleration_exported_headers)
exports_files([
"delegate_plugin.h",
"gpu_plugin.h",
"xnnpack_plugin.h",
])
# LINT.ThenChange(
# ../../../core/acceleration/configuration/c/BUILD:tflite_acceleration_exported_headers,
# ../../../java/BUILD:tflite_acceleration_exported_headers
# )
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:LICENSE"],
default_visibility = ["//visibility:private"],
licenses = ["notice"],
)
cc_library_with_tflite_with_c_headers_test(
name = "delegate_plugin",
hdrs = ["delegate_plugin.h"],
compatible_with = get_compatible_with_portable(),
copts = tflite_copts() + tflite_copts_warnings(),
generate_opaque_delegate_target = True,
visibility = ["//visibility:public"],
deps = ["//tensorflow/lite/core/acceleration/configuration/c:delegate_plugin"],
)
cc_library_with_tflite_with_c_headers_test(
name = "nnapi_plugin",
hdrs = ["nnapi_plugin.h"],
copts = tflite_copts() + tflite_copts_warnings(),
visibility = ["//visibility:public"],
deps = ["//tensorflow/lite/core/acceleration/configuration/c:nnapi_plugin"],
)
test_suite(
name = "nnapi_plugin_test",
tests = [
"//tensorflow/lite/core/acceleration/configuration/c:nnapi_plugin_test",
],
)
cc_library_with_tflite_with_c_headers_test(
name = "gpu_plugin",
hdrs = ["gpu_plugin.h"],
copts = tflite_copts() + tflite_copts_warnings(),
visibility = ["//visibility:public"],
deps = ["//tensorflow/lite/core/acceleration/configuration/c:gpu_plugin"],
)
# For non-Android platforms, this should be built with '--copt=-DCL_DELEGATE_NO_GL'.
# On non-supported platforms (i.e. non-Android platforms if -DCL_DELEGATE_NO_GL wasn't specified),
# the test srcs are set to the empty list, so the test will succeed without testing anything.
test_suite(
name = "gpu_plugin_test",
tests = [
"//tensorflow/lite/core/acceleration/configuration/c:gpu_plugin_test",
],
)
cc_library_with_tflite_with_c_headers_test(
name = "xnnpack_plugin",
hdrs = ["xnnpack_plugin.h"],
compatible_with = get_compatible_with_portable(),
copts = tflite_copts() + tflite_copts_warnings(),
visibility = ["//visibility:public"],
deps = ["//tensorflow/lite/core/acceleration/configuration/c:xnnpack_plugin"],
)
test_suite(
name = "xnnpack_plugin_test",
tests = [
"//tensorflow/lite/core/acceleration/configuration/c:xnnpack_plugin_test",
],
)
cc_library_with_tflite_with_c_headers_test(
name = "stable_delegate",
hdrs = ["stable_delegate.h"],
generate_opaque_delegate_target = True,
visibility = ["//visibility:public"],
deps = ["//tensorflow/lite/core/acceleration/configuration/c:stable_delegate"],
)
@@ -0,0 +1,23 @@
/* Copyright 2021 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_ACCELERATION_CONFIGURATION_C_DELEGATE_PLUGIN_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_DELEGATE_PLUGIN_H_
/// For documentation, see
/// third_party/tensorflow/lite/core/acceleration/configuration/c/delegate_plugin.h
#include "tensorflow/lite/core/acceleration/configuration/c/delegate_plugin.h"
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_DELEGATE_PLUGIN_H_
@@ -0,0 +1,23 @@
/* 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_ACCELERATION_CONFIGURATION_C_GPU_PLUGIN_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_GPU_PLUGIN_H_
/// For documentation, see
/// third_party/tensorflow/lite/core/acceleration/configuration/c/gpu_plugin.h
#include "tensorflow/lite/core/acceleration/configuration/c/gpu_plugin.h"
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_GPU_PLUGIN_H_
@@ -0,0 +1,26 @@
/* 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_ACCELERATION_CONFIGURATION_C_NNAPI_PLUGIN_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_NNAPI_PLUGIN_H_
/// WARNING: this header file is DEPRECATED.
/// See https://developer.android.com/ndk/guides/neuralnetworks/migration-guide.
/// For documentation, see
/// third_party/tensorflow/lite/core/acceleration/configuration/c/nnapi_plugin.h
#include "tensorflow/lite/core/acceleration/configuration/c/nnapi_plugin.h"
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_NNAPI_PLUGIN_H_
@@ -0,0 +1,23 @@
/* 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_ACCELERATION_CONFIGURATION_C_STABLE_DELEGATE_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_STABLE_DELEGATE_H_
/// For documentation, see
/// third_party/tensorflow/lite/core/acceleration/configuration/c/stable_delegate.h
#include "tensorflow/lite/core/acceleration/configuration/c/stable_delegate.h"
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_STABLE_DELEGATE_H_
@@ -0,0 +1,23 @@
/* 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_ACCELERATION_CONFIGURATION_C_XNNPACK_PLUGIN_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_XNNPACK_PLUGIN_H_
/// For documentation, see
/// third_party/tensorflow/lite/core/acceleration/configuration/c/xnnpack_plugin.h
#include "tensorflow/lite/core/acceleration/configuration/c/xnnpack_plugin.h"
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_C_XNNPACK_PLUGIN_H_
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,73 @@
/* 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 <memory>
#include "absl/memory/memory.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/core/acceleration/configuration/delegate_registry.h"
#include "tensorflow/lite/minimal_logging.h"
// Guarding anyway although this file not expected to be compiled for non-Apple.
#if defined(__APPLE__)
#include "tensorflow/lite/delegates/coreml/coreml_delegate.h"
namespace tflite {
namespace delegates {
class CoreMLPlugin : public DelegatePluginInterface {
public:
TfLiteDelegatePtr Create() override {
TfLiteDelegate* delegate_ptr = TfLiteCoreMlDelegateCreate(&options_);
TfLiteDelegatePtr delegate(delegate_ptr, [](TfLiteDelegate* delegate) {
TfLiteCoreMlDelegateDelete(delegate);
});
return delegate;
}
int GetDelegateErrno(TfLiteDelegate* /* from_delegate */) override {
return 0;
}
static std::unique_ptr<CoreMLPlugin> New(
const TFLiteSettings& tflite_settings) {
return absl::make_unique<CoreMLPlugin>(tflite_settings);
}
explicit CoreMLPlugin(const TFLiteSettings& tflite_settings) {
const CoreMLSettings* settings = tflite_settings.coreml_settings();
options_ = TfLiteCoreMlDelegateOptions({});
// Using the proto defaults if the settings were not set.
switch (settings->enabled_devices()) {
case tflite::CoreMLSettings_::EnabledDevices_DEVICES_ALL:
options_.enabled_devices = TfLiteCoreMlDelegateAllDevices;
break;
case tflite::CoreMLSettings_::EnabledDevices_DEVICES_WITH_NEURAL_ENGINE:
options_.enabled_devices = TfLiteCoreMlDelegateDevicesWithNeuralEngine;
break;
default:
TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Invalid devices enum: %d",
settings->enabled_devices());
}
options_.coreml_version = settings->coreml_version();
options_.max_delegated_partitions = settings->max_delegated_partitions();
options_.min_nodes_per_partition = settings->min_nodes_per_partition();
}
private:
TfLiteCoreMlDelegateOptions options_;
};
TFLITE_REGISTER_DELEGATE_FACTORY_FUNCTION(CoreMLPlugin, CoreMLPlugin::New);
} // namespace delegates
} // namespace tflite
#endif // __APPLE__
@@ -0,0 +1,59 @@
/* Copyright 2021 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/acceleration/configuration/delegate_plugin_converter.h"
#include <functional>
#include <memory>
#include "tensorflow/lite/c/common.h"
namespace tflite {
namespace delegates {
using ::tflite::delegates::DelegatePluginInterface;
using ::tflite::delegates::TfLiteOpaqueDelegatePtr;
// This class implements the C++ DelegatePluginInterface using
// the equivalent C API, which is the TfLiteDelegatePlugin struct.
class DelegatePluginViaCApi : public DelegatePluginInterface {
public:
explicit DelegatePluginViaCApi(const TfLiteOpaqueDelegatePlugin& plugin_c_api,
const ::tflite::TFLiteSettings& settings)
: plugin_c_api_(plugin_c_api), tflite_settings_(settings) {}
TfLiteOpaqueDelegatePtr Create() override {
return TfLiteOpaqueDelegatePtr(plugin_c_api_.create(&tflite_settings_),
plugin_c_api_.destroy);
}
int GetDelegateErrno(TfLiteOpaqueDelegate* from_delegate) override {
return plugin_c_api_.get_delegate_errno(from_delegate);
}
private:
TfLiteOpaqueDelegatePlugin plugin_c_api_;
const ::tflite::TFLiteSettings& tflite_settings_;
};
std::function<
std::unique_ptr<DelegatePluginInterface>(const ::tflite::TFLiteSettings&)>
DelegatePluginConverter(const TfLiteOpaqueDelegatePlugin& plugin_c_api) {
return [plugin_c_api](const ::tflite::TFLiteSettings& settings)
-> std::unique_ptr<DelegatePluginInterface> {
return std::make_unique<DelegatePluginViaCApi>(plugin_c_api, settings);
};
}
} // namespace delegates
} // namespace tflite
@@ -0,0 +1,38 @@
/* Copyright 2021 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_ACCELERATION_CONFIGURATION_DELEGATE_PLUGIN_CONVERTER_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_DELEGATE_PLUGIN_CONVERTER_H_
#include <functional>
#include <memory>
#include "tensorflow/lite/acceleration/configuration/c/delegate_plugin.h"
#include "tensorflow/lite/acceleration/configuration/delegate_registry.h"
namespace tflite {
namespace delegates {
// Converts from the C delegate plugin API to the C++ delegate plugin API.
// Given an instance of the (C) TfLiteOpaqueDelegatePlugin struct, this returns
// a function that takes a TFLiteSettings FlatBuffer and returns a unique_ptr to
// an instance of the (C++) DelegatePluginInterface abstract class.
std::function<std::unique_ptr<tflite::delegates::DelegatePluginInterface>(
const ::tflite::TFLiteSettings&)>
DelegatePluginConverter(const TfLiteOpaqueDelegatePlugin& plugin_c_api);
} // namespace delegates
} // namespace tflite
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_DELEGATE_PLUGIN_CONVERTER_H_
@@ -0,0 +1,33 @@
/* Copyright 2021 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_ACCELERATION_CONFIGURATION_DELEGATE_REGISTRY_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_DELEGATE_REGISTRY_H_
/// For documentation, see
/// third_party/tensorflow/lite/core/acceleration/configuration/delegate_registry.h
#include "tensorflow/lite/core/acceleration/configuration/delegate_registry.h" // IWYU pragma: export
namespace tflite {
namespace delegates {
using TfLiteOpaqueDelegatePtr = ::tflite::delegates::TfLiteDelegatePtr;
using DelegatePluginInterface = ::tflite::delegates::DelegatePluginInterface;
using DelegatePluginRegistry = ::tflite::delegates::DelegatePluginRegistry;
} // namespace delegates
} // namespace tflite
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_DELEGATE_REGISTRY_H_
@@ -0,0 +1,805 @@
/* Copyright 2021 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/acceleration/configuration/flatbuffer_to_proto.h"
#include "tensorflow/lite/acceleration/configuration/configuration.pb.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/minimal_logging.h"
namespace tflite {
namespace {
proto::ExecutionPreference ConvertExecutionPreference(
ExecutionPreference preference) {
switch (preference) {
case ExecutionPreference_ANY:
return proto::ExecutionPreference::ANY;
case ExecutionPreference_LOW_LATENCY:
return proto::ExecutionPreference::LOW_LATENCY;
case ExecutionPreference_LOW_POWER:
return proto::ExecutionPreference::LOW_POWER;
case ExecutionPreference_FORCE_CPU:
return proto::ExecutionPreference::FORCE_CPU;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for ExecutionPreference: %d", preference);
return proto::ExecutionPreference::ANY;
}
proto::Delegate ConvertDelegate(Delegate delegate) {
switch (delegate) {
case Delegate_NONE:
return proto::Delegate::NONE;
case Delegate_NNAPI:
return proto::Delegate::NNAPI;
case Delegate_GPU:
return proto::Delegate::GPU;
case Delegate_HEXAGON:
return proto::Delegate::HEXAGON;
case Delegate_XNNPACK:
return proto::Delegate::XNNPACK;
case Delegate_EDGETPU:
return proto::Delegate::EDGETPU;
case Delegate_EDGETPU_CORAL:
return proto::Delegate::EDGETPU_CORAL;
case Delegate_CORE_ML:
return proto::Delegate::CORE_ML;
case Delegate_ARMNN:
return proto::Delegate::ARMNN;
case Delegate_MTK_NEURON:
return proto::Delegate::MTK_NEURON;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Unexpected value for Delegate: %d",
delegate);
return proto::Delegate::NONE;
}
proto::NNAPIExecutionPreference ConvertNNAPIExecutionPreference(
NNAPIExecutionPreference preference) {
switch (preference) {
case NNAPIExecutionPreference_UNDEFINED:
return proto::NNAPIExecutionPreference::UNDEFINED;
case NNAPIExecutionPreference_NNAPI_LOW_POWER:
return proto::NNAPIExecutionPreference::NNAPI_LOW_POWER;
case NNAPIExecutionPreference_NNAPI_FAST_SINGLE_ANSWER:
return proto::NNAPIExecutionPreference::NNAPI_FAST_SINGLE_ANSWER;
case NNAPIExecutionPreference_NNAPI_SUSTAINED_SPEED:
return proto::NNAPIExecutionPreference::NNAPI_SUSTAINED_SPEED;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for NNAPIExecutionPreference: %d",
preference);
return proto::NNAPIExecutionPreference::UNDEFINED;
}
proto::NNAPIExecutionPriority ConvertNNAPIExecutionPriority(
NNAPIExecutionPriority priority) {
switch (priority) {
case NNAPIExecutionPriority_NNAPI_PRIORITY_UNDEFINED:
return proto::NNAPIExecutionPriority::NNAPI_PRIORITY_UNDEFINED;
case NNAPIExecutionPriority_NNAPI_PRIORITY_LOW:
return proto::NNAPIExecutionPriority::NNAPI_PRIORITY_LOW;
case NNAPIExecutionPriority_NNAPI_PRIORITY_MEDIUM:
return proto::NNAPIExecutionPriority::NNAPI_PRIORITY_MEDIUM;
case NNAPIExecutionPriority_NNAPI_PRIORITY_HIGH:
return proto::NNAPIExecutionPriority::NNAPI_PRIORITY_HIGH;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for NNAPIExecutionPriority: %d", priority);
return proto::NNAPIExecutionPriority::NNAPI_PRIORITY_UNDEFINED;
}
proto::GPUBackend ConvertGPUBackend(GPUBackend backend) {
switch (backend) {
case GPUBackend_UNSET:
return proto::GPUBackend::UNSET;
case GPUBackend_OPENCL:
return proto::GPUBackend::OPENCL;
case GPUBackend_OPENGL:
return proto::GPUBackend::OPENGL;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Unexpected value for GPUBackend: %d",
backend);
return proto::GPUBackend::UNSET;
}
proto::GPUInferenceUsage ConvertGPUInferenceUsage(
GPUInferenceUsage preference) {
switch (preference) {
case GPUInferenceUsage_GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER:
return proto::GPUInferenceUsage::
GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER;
case GPUInferenceUsage_GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED:
return proto::GPUInferenceUsage::GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for GPUInferenceUsage: %d", preference);
return proto::GPUInferenceUsage::GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER;
}
proto::GPUInferencePriority ConvertGPUInferencePriority(
GPUInferencePriority priority) {
switch (priority) {
case GPUInferencePriority_GPU_PRIORITY_AUTO:
return proto::GPUInferencePriority::GPU_PRIORITY_AUTO;
case GPUInferencePriority_GPU_PRIORITY_MAX_PRECISION:
return proto::GPUInferencePriority::GPU_PRIORITY_MAX_PRECISION;
case GPUInferencePriority_GPU_PRIORITY_MIN_LATENCY:
return proto::GPUInferencePriority::GPU_PRIORITY_MIN_LATENCY;
case GPUInferencePriority_GPU_PRIORITY_MIN_MEMORY_USAGE:
return proto::GPUInferencePriority::GPU_PRIORITY_MIN_MEMORY_USAGE;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for GPUInferencePriority: %d", priority);
return proto::GPUInferencePriority::GPU_PRIORITY_AUTO;
}
proto::EdgeTpuPowerState ConvertEdgeTpuPowerState(EdgeTpuPowerState state) {
switch (state) {
case EdgeTpuPowerState_UNDEFINED_POWERSTATE:
return proto::EdgeTpuPowerState::UNDEFINED_POWERSTATE;
case EdgeTpuPowerState_TPU_CORE_OFF:
return proto::EdgeTpuPowerState::TPU_CORE_OFF;
case EdgeTpuPowerState_READY:
return proto::EdgeTpuPowerState::READY;
case EdgeTpuPowerState_ACTIVE_MIN_POWER:
return proto::EdgeTpuPowerState::ACTIVE_MIN_POWER;
case EdgeTpuPowerState_ACTIVE_VERY_LOW_POWER:
return proto::EdgeTpuPowerState::ACTIVE_VERY_LOW_POWER;
case EdgeTpuPowerState_ACTIVE_LOW_POWER:
return proto::EdgeTpuPowerState::ACTIVE_LOW_POWER;
case EdgeTpuPowerState_ACTIVE:
return proto::EdgeTpuPowerState::ACTIVE;
case EdgeTpuPowerState_OVER_DRIVE:
return proto::EdgeTpuPowerState::OVER_DRIVE;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for EdgeTpuSettings::PowerState: %d",
state);
return proto::EdgeTpuPowerState::UNDEFINED_POWERSTATE;
}
proto::FallbackSettings ConvertFallbackSettings(
const FallbackSettings& settings) {
proto::FallbackSettings proto_settings;
proto_settings.set_allow_automatic_fallback_on_compilation_error(
settings.allow_automatic_fallback_on_compilation_error());
proto_settings.set_allow_automatic_fallback_on_execution_error(
settings.allow_automatic_fallback_on_execution_error());
return proto_settings;
}
proto::NNAPISettings ConvertNNAPISettings(const NNAPISettings& settings) {
proto::NNAPISettings proto_settings;
if (settings.accelerator_name() != nullptr) {
proto_settings.set_accelerator_name(settings.accelerator_name()->str());
}
if (settings.cache_directory() != nullptr) {
proto_settings.set_cache_directory(settings.cache_directory()->str());
}
if (settings.model_token() != nullptr) {
proto_settings.set_model_token(settings.model_token()->str());
}
proto_settings.set_execution_preference(
ConvertNNAPIExecutionPreference(settings.execution_preference()));
proto_settings.set_no_of_nnapi_instances_to_cache(
settings.no_of_nnapi_instances_to_cache());
if (settings.fallback_settings() != nullptr) {
*(proto_settings.mutable_fallback_settings()) =
ConvertFallbackSettings(*settings.fallback_settings());
}
proto_settings.set_allow_nnapi_cpu_on_android_10_plus(
settings.allow_nnapi_cpu_on_android_10_plus());
proto_settings.set_execution_priority(
ConvertNNAPIExecutionPriority(settings.execution_priority()));
proto_settings.set_allow_dynamic_dimensions(
settings.allow_dynamic_dimensions());
proto_settings.set_allow_fp16_precision_for_fp32(
settings.allow_fp16_precision_for_fp32());
proto_settings.set_use_burst_computation(settings.use_burst_computation());
proto_settings.set_support_library_handle(settings.support_library_handle());
return proto_settings;
}
proto::GPUSettings ConvertGPUSettings(const GPUSettings& settings) {
proto::GPUSettings proto_settings;
proto_settings.set_is_precision_loss_allowed(
settings.is_precision_loss_allowed());
proto_settings.set_enable_quantized_inference(
settings.enable_quantized_inference());
proto_settings.set_force_backend(ConvertGPUBackend(settings.force_backend()));
proto_settings.set_inference_priority1(
ConvertGPUInferencePriority(settings.inference_priority1()));
proto_settings.set_inference_priority2(
ConvertGPUInferencePriority(settings.inference_priority2()));
proto_settings.set_inference_priority3(
ConvertGPUInferencePriority(settings.inference_priority3()));
proto_settings.set_inference_preference(
ConvertGPUInferenceUsage(settings.inference_preference()));
if (settings.cache_directory() != nullptr) {
proto_settings.set_cache_directory(settings.cache_directory()->str());
}
if (settings.model_token() != nullptr) {
proto_settings.set_model_token(settings.model_token()->str());
}
return proto_settings;
}
proto::HexagonSettings ConvertHexagonSettings(const HexagonSettings& settings) {
proto::HexagonSettings proto_settings;
proto_settings.set_debug_level(settings.debug_level());
proto_settings.set_powersave_level(settings.powersave_level());
proto_settings.set_print_graph_profile(settings.print_graph_profile());
proto_settings.set_print_graph_debug(settings.print_graph_debug());
return proto_settings;
}
proto::XNNPackSettings ConvertXNNPackSettings(const XNNPackSettings& settings) {
proto::XNNPackSettings proto_settings;
proto_settings.set_num_threads(settings.num_threads());
proto_settings.set_flags(::tflite::proto::XNNPackFlags(settings.flags()));
return proto_settings;
}
proto::CoreMLSettings ConvertCoreMLSettings(const CoreMLSettings& settings) {
proto::CoreMLSettings proto_settings;
switch (settings.enabled_devices()) {
case CoreMLSettings_::EnabledDevices_DEVICES_ALL:
proto_settings.set_enabled_devices(proto::CoreMLSettings::DEVICES_ALL);
break;
case CoreMLSettings_::EnabledDevices_DEVICES_WITH_NEURAL_ENGINE:
proto_settings.set_enabled_devices(
proto::CoreMLSettings::DEVICES_WITH_NEURAL_ENGINE);
break;
default:
TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Invalid devices enum: %d",
settings.enabled_devices());
}
proto_settings.set_coreml_version(settings.coreml_version());
proto_settings.set_max_delegated_partitions(
settings.max_delegated_partitions());
proto_settings.set_min_nodes_per_partition(
settings.min_nodes_per_partition());
return proto_settings;
}
proto::CPUSettings ConvertCPUSettings(const CPUSettings& settings) {
proto::CPUSettings proto_settings;
proto_settings.set_num_threads(settings.num_threads());
return proto_settings;
}
proto::EdgeTpuDeviceSpec ConvertEdgeTpuDeviceSpec(
const EdgeTpuDeviceSpec& device_spec) {
proto::EdgeTpuDeviceSpec proto_settings;
if (device_spec.device_paths() != nullptr) {
for (int i = 0; i < device_spec.device_paths()->size(); ++i) {
auto device_path = device_spec.device_paths()->Get(i);
proto_settings.add_device_paths(device_path->str());
}
}
proto_settings.set_platform_type(
static_cast<proto::EdgeTpuDeviceSpec::PlatformType>(
device_spec.platform_type()));
proto_settings.set_num_chips(device_spec.num_chips());
proto_settings.set_chip_family(device_spec.chip_family());
return proto_settings;
}
proto::EdgeTpuSettings ConvertEdgeTpuSettings(const EdgeTpuSettings& settings) {
proto::EdgeTpuSettings proto_settings;
proto_settings.set_inference_power_state(
ConvertEdgeTpuPowerState(settings.inference_power_state()));
proto_settings.set_inference_priority(settings.inference_priority());
if (settings.model_token() != nullptr) {
proto_settings.set_model_token(settings.model_token()->str());
}
if (settings.edgetpu_device_spec() != nullptr) {
*(proto_settings.mutable_edgetpu_device_spec()) =
ConvertEdgeTpuDeviceSpec(*settings.edgetpu_device_spec());
}
proto_settings.set_float_truncation_type(
static_cast<proto::EdgeTpuSettings::FloatTruncationType>(
settings.float_truncation_type()));
auto inactive_powre_configs = settings.inactive_power_configs();
if (inactive_powre_configs != nullptr) {
for (int i = 0; i < inactive_powre_configs->size(); ++i) {
auto config = inactive_powre_configs->Get(i);
auto proto_config = proto_settings.add_inactive_power_configs();
proto_config->set_inactive_power_state(
ConvertEdgeTpuPowerState(config->inactive_power_state()));
proto_config->set_inactive_timeout_us(config->inactive_timeout_us());
}
}
proto_settings.set_use_tpu_server(settings.use_tpu_server());
return proto_settings;
}
proto::StableDelegateLoaderSettings ConvertStableDelegateLoaderSettings(
const StableDelegateLoaderSettings& settings) {
proto::StableDelegateLoaderSettings proto_settings;
if (settings.delegate_path() != nullptr) {
proto_settings.set_delegate_path(settings.delegate_path()->str());
}
if (settings.delegate_name() != nullptr) {
proto_settings.set_delegate_name(settings.delegate_name()->str());
}
return proto_settings;
}
proto::CoralSettings ConvertCoralSettings(const CoralSettings& settings) {
proto::CoralSettings proto_settings;
if (settings.device() != nullptr) {
proto_settings.set_device(settings.device()->str());
}
proto_settings.set_performance(
static_cast<proto::CoralSettings::Performance>(settings.performance()));
proto_settings.set_usb_always_dfu(settings.usb_always_dfu());
proto_settings.set_usb_max_bulk_in_queue_length(
settings.usb_max_bulk_in_queue_length());
return proto_settings;
}
proto::GoogleEdgeTpuSettings::Priority ConvertGoogleEdgeTpuPriority(
GoogleEdgeTpuSettings_::Priority priority) {
switch (priority) {
case GoogleEdgeTpuSettings_::Priority_PRIORITY_UNDEFINED:
return proto::GoogleEdgeTpuSettings::PRIORITY_UNDEFINED;
case GoogleEdgeTpuSettings_::Priority_PRIORITY_LOW:
return proto::GoogleEdgeTpuSettings::PRIORITY_LOW;
case GoogleEdgeTpuSettings_::Priority_PRIORITY_MEDIUM:
return proto::GoogleEdgeTpuSettings::PRIORITY_MEDIUM;
case GoogleEdgeTpuSettings_::Priority_PRIORITY_HIGH:
return proto::GoogleEdgeTpuSettings::PRIORITY_HIGH;
}
}
proto::GoogleEdgeTpuSettings::TriState ConvertGoogleEdgeTpuTriState(
GoogleEdgeTpuSettings_::TriState tri_state) {
switch (tri_state) {
case GoogleEdgeTpuSettings_::TriState_TRISTATE_UNDEFINED:
return proto::GoogleEdgeTpuSettings::TRISTATE_UNDEFINED;
case GoogleEdgeTpuSettings_::TriState_TRISTATE_FALSE:
return proto::GoogleEdgeTpuSettings::TRISTATE_FALSE;
case GoogleEdgeTpuSettings_::TriState_TRISTATE_TRUE:
return proto::GoogleEdgeTpuSettings::TRISTATE_TRUE;
}
}
proto::GoogleEdgeTpuSettings ConvertGoogleEdgetpuSettings(
const GoogleEdgeTpuSettings& settings) {
proto::GoogleEdgeTpuSettings proto_settings;
proto_settings.set_log_verbosity(settings.log_verbosity());
proto_settings.set_enable_tracing(settings.enable_tracing());
proto_settings.set_priority(
ConvertGoogleEdgeTpuPriority(settings.priority()));
if (settings.extension_data()) {
proto_settings.set_extension_data(settings.extension_data()->data(),
settings.extension_data()->size());
}
if (settings.model_identifier()) {
proto_settings.set_model_identifier(settings.model_identifier()->str());
}
proto_settings.set_use_async_api(settings.use_async_api());
proto_settings.set_delegate_should_manage_cache_for_inputs(
settings.delegate_should_manage_cache_for_inputs());
proto_settings.set_delegate_should_manage_cache_for_outputs(
settings.delegate_should_manage_cache_for_outputs());
proto_settings.set_prefer_cache_coherency_for_inputs(
ConvertGoogleEdgeTpuTriState(
settings.prefer_cache_coherency_for_inputs()));
proto_settings.set_prefer_cache_coherency_for_outputs(
ConvertGoogleEdgeTpuTriState(
settings.prefer_cache_coherency_for_outputs()));
proto_settings.set_allow_fp16_precision_for_fp32(
settings.allow_fp16_precision_for_fp32());
return proto_settings;
}
proto::CompilationCachingSettings ConvertCompilationCachingSettings(
const CompilationCachingSettings& settings) {
proto::CompilationCachingSettings proto_settings;
if (settings.cache_dir() != nullptr) {
proto_settings.set_cache_dir(settings.cache_dir()->str());
}
if (settings.model_token() != nullptr) {
proto_settings.set_model_token(settings.model_token()->str());
}
return proto_settings;
}
proto::MtkNeuronSettings ConvertMtkNeuronSettings(
const MtkNeuronSettings& settings) {
proto::MtkNeuronSettings proto_settings;
proto_settings.set_execution_preference(
static_cast<proto::MtkNeuronSettings_ExecutionPreference>(
settings.execution_preference()));
proto_settings.set_execution_priority(
static_cast<proto::MtkNeuronSettings_ExecutionPriority>(
settings.execution_priority()));
auto optimization_hints = settings.optimization_hints();
if (optimization_hints != nullptr) {
for (auto hint : *optimization_hints) {
proto_settings.add_optimization_hints(
static_cast<proto::MtkNeuronSettings_OptimizationHint>(hint));
}
}
proto_settings.set_operation_check_mode(
static_cast<proto::MtkNeuronSettings_OperationCheckMode>(
settings.operation_check_mode()));
proto_settings.set_allow_fp16_precision_for_fp32(
settings.allow_fp16_precision_for_fp32());
proto_settings.set_use_ahwb(settings.use_ahwb());
proto_settings.set_use_cacheable_buffer(settings.use_cacheable_buffer());
auto compile_options = settings.compile_options();
if (compile_options != nullptr) {
for (auto option : *compile_options) {
proto_settings.add_compile_options(option->str());
}
}
auto accelerator_names = settings.accelerator_names();
if (accelerator_names != nullptr) {
for (auto name : *accelerator_names) {
proto_settings.add_accelerator_names(name->str());
}
}
if (settings.neuron_config_path()) {
proto_settings.set_neuron_config_path(settings.neuron_config_path()->str());
}
proto_settings.set_inference_deadline_ms(settings.inference_deadline_ms());
proto_settings.set_inference_abort_time_ms(
settings.inference_abort_time_ms());
return proto_settings;
}
proto::TFLiteSettings ConvertTfliteSettings(const TFLiteSettings& settings) {
proto::TFLiteSettings proto_settings;
proto_settings.set_delegate(ConvertDelegate(settings.delegate()));
if (settings.nnapi_settings() != nullptr) {
*proto_settings.mutable_nnapi_settings() =
ConvertNNAPISettings(*settings.nnapi_settings());
}
if (settings.gpu_settings() != nullptr) {
*proto_settings.mutable_gpu_settings() =
ConvertGPUSettings(*settings.gpu_settings());
}
if (settings.hexagon_settings() != nullptr) {
*proto_settings.mutable_hexagon_settings() =
ConvertHexagonSettings(*settings.hexagon_settings());
}
if (settings.xnnpack_settings() != nullptr) {
*proto_settings.mutable_xnnpack_settings() =
ConvertXNNPackSettings(*settings.xnnpack_settings());
}
if (settings.coreml_settings() != nullptr) {
*proto_settings.mutable_coreml_settings() =
ConvertCoreMLSettings(*settings.coreml_settings());
}
if (settings.cpu_settings() != nullptr) {
*proto_settings.mutable_cpu_settings() =
ConvertCPUSettings(*settings.cpu_settings());
}
proto_settings.set_max_delegated_partitions(
settings.max_delegated_partitions());
if (settings.edgetpu_settings() != nullptr) {
*proto_settings.mutable_edgetpu_settings() =
ConvertEdgeTpuSettings(*settings.edgetpu_settings());
}
if (settings.coral_settings() != nullptr) {
*proto_settings.mutable_coral_settings() =
ConvertCoralSettings(*settings.coral_settings());
}
if (settings.fallback_settings() != nullptr) {
*proto_settings.mutable_fallback_settings() =
ConvertFallbackSettings(*settings.fallback_settings());
}
proto_settings.set_disable_default_delegates(
settings.disable_default_delegates());
if (settings.stable_delegate_loader_settings() != nullptr) {
*proto_settings.mutable_stable_delegate_loader_settings() =
ConvertStableDelegateLoaderSettings(
*settings.stable_delegate_loader_settings());
}
if (settings.google_edgetpu_settings() != nullptr) {
*proto_settings.mutable_google_edgetpu_settings() =
ConvertGoogleEdgetpuSettings(*settings.google_edgetpu_settings());
}
if (settings.compilation_caching_settings() != nullptr) {
*proto_settings.mutable_compilation_caching_settings() =
ConvertCompilationCachingSettings(
*settings.compilation_caching_settings());
}
if (settings.mtk_neuron_settings() != nullptr) {
*proto_settings.mutable_mtk_neuron_settings() =
ConvertMtkNeuronSettings(*settings.mtk_neuron_settings());
}
return proto_settings;
}
proto::ModelFile ConvertModelFile(const ModelFile& model_file) {
proto::ModelFile proto_settings;
if (model_file.filename() != nullptr) {
proto_settings.set_filename(model_file.filename()->str());
}
proto_settings.set_fd(model_file.fd());
proto_settings.set_offset(model_file.offset());
proto_settings.set_length(model_file.length());
return proto_settings;
}
proto::BenchmarkStoragePaths ConvertBenchmarkStoragePaths(
const BenchmarkStoragePaths& storage_paths) {
proto::BenchmarkStoragePaths proto_settings;
if (storage_paths.storage_file_path() != nullptr) {
proto_settings.set_storage_file_path(
storage_paths.storage_file_path()->str());
}
if (storage_paths.data_directory_path() != nullptr) {
proto_settings.set_data_directory_path(
storage_paths.data_directory_path()->str());
}
return proto_settings;
}
proto::MinibenchmarkSettings ConvertMinibenchmarkSettings(
const MinibenchmarkSettings& settings) {
proto::MinibenchmarkSettings proto_settings;
if (settings.settings_to_test() != nullptr &&
settings.settings_to_test()->size() > 0) {
for (int i = 0; i < settings.settings_to_test()->size(); ++i) {
auto tflite_setting = settings.settings_to_test()->Get(i);
auto proto_tflite_setting = proto_settings.add_settings_to_test();
*proto_tflite_setting = ConvertTfliteSettings(*tflite_setting);
}
}
if (settings.model_file() != nullptr) {
*(proto_settings.mutable_model_file()) =
ConvertModelFile(*settings.model_file());
}
if (settings.storage_paths() != nullptr) {
*(proto_settings.mutable_storage_paths()) =
ConvertBenchmarkStoragePaths(*settings.storage_paths());
}
return proto_settings;
}
proto::BenchmarkEventType ConvertBenchmarkEventType(BenchmarkEventType type) {
switch (type) {
case BenchmarkEventType_UNDEFINED_BENCHMARK_EVENT_TYPE:
return proto::BenchmarkEventType::UNDEFINED_BENCHMARK_EVENT_TYPE;
case BenchmarkEventType_START:
return proto::BenchmarkEventType::START;
case BenchmarkEventType_END:
return proto::BenchmarkEventType::END;
case BenchmarkEventType_ERROR:
return proto::BenchmarkEventType::ERROR;
case BenchmarkEventType_LOGGED:
return proto::BenchmarkEventType::LOGGED;
case BenchmarkEventType_RECOVERED_ERROR:
return proto::BenchmarkEventType::RECOVERED_ERROR;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for BenchmarkEventType: %d", type);
return proto::BenchmarkEventType::UNDEFINED_BENCHMARK_EVENT_TYPE;
}
proto::BenchmarkMetric ConvertBenchmarkMetric(const BenchmarkMetric& metric) {
proto::BenchmarkMetric proto_metric;
if (metric.name() != nullptr) {
proto_metric.set_name(metric.name()->str());
}
auto values = metric.values();
if (values != nullptr) {
for (int i = 0; i < values->size(); ++i) {
proto_metric.add_values(values->Get(i));
}
}
return proto_metric;
}
proto::BenchmarkResult ConvertBenchmarkResult(const BenchmarkResult& result) {
proto::BenchmarkResult proto_result;
auto initialization_time_us = result.initialization_time_us();
if (initialization_time_us != nullptr) {
for (int i = 0; i < initialization_time_us->size(); ++i) {
proto_result.add_initialization_time_us(initialization_time_us->Get(i));
}
}
auto inference_time_us = result.inference_time_us();
if (inference_time_us != nullptr) {
for (int i = 0; i < inference_time_us->size(); ++i) {
proto_result.add_inference_time_us(inference_time_us->Get(i));
}
}
proto_result.set_max_memory_kb(result.max_memory_kb());
proto_result.set_ok(result.ok());
auto metrics = result.metrics();
if (metrics != nullptr) {
for (int i = 0; i < metrics->size(); ++i) {
*proto_result.add_metrics() = ConvertBenchmarkMetric(*metrics->Get(i));
}
}
return proto_result;
}
proto::BenchmarkStage ConvertBenchmarkStage(BenchmarkStage stage) {
switch (stage) {
case BenchmarkStage_UNKNOWN:
return proto::BenchmarkStage::UNKNOWN;
case BenchmarkStage_INITIALIZATION:
return proto::BenchmarkStage::INITIALIZATION;
case BenchmarkStage_INFERENCE:
return proto::BenchmarkStage::INFERENCE;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Unexpected value for BenchmarkStage: %d",
stage);
return proto::BenchmarkStage::UNKNOWN;
}
proto::ErrorCode ConvertBenchmarkErrorCode(const ErrorCode& code) {
proto::ErrorCode proto_code;
proto_code.set_source(ConvertDelegate(code.source()));
proto_code.set_tflite_error(code.tflite_error());
proto_code.set_underlying_api_error(code.underlying_api_error());
return proto_code;
}
proto::BenchmarkError ConvertBenchmarkError(const BenchmarkError& error) {
proto::BenchmarkError proto_error;
proto_error.set_stage(ConvertBenchmarkStage(error.stage()));
proto_error.set_exit_code(error.exit_code());
proto_error.set_signal(error.signal());
auto error_codes = error.error_code();
if (error_codes != nullptr) {
for (int i = 0; i < error_codes->size(); ++i) {
*proto_error.add_error_code() =
ConvertBenchmarkErrorCode(*error_codes->Get(i));
}
}
proto_error.set_mini_benchmark_error_code(error.mini_benchmark_error_code());
return proto_error;
}
proto::BenchmarkEvent ConvertBenchmarkEvent(const BenchmarkEvent& event) {
proto::BenchmarkEvent proto_event;
if (event.tflite_settings() != nullptr) {
*proto_event.mutable_tflite_settings() =
ConvertTfliteSettings(*event.tflite_settings());
}
proto_event.set_event_type(ConvertBenchmarkEventType(event.event_type()));
if (event.result() != nullptr) {
*proto_event.mutable_result() = ConvertBenchmarkResult(*event.result());
}
if (event.error() != nullptr) {
*proto_event.mutable_error() = ConvertBenchmarkError(*event.error());
}
proto_event.set_boottime_us(event.boottime_us());
proto_event.set_wallclock_us(event.wallclock_us());
return proto_event;
}
proto::BestAccelerationDecision ConvertBestAccelerationDecision(
const BestAccelerationDecision& decision) {
proto::BestAccelerationDecision proto_decision;
proto_decision.set_number_of_source_events(
decision.number_of_source_events());
if (decision.min_latency_event() != nullptr) {
*proto_decision.mutable_min_latency_event() =
ConvertBenchmarkEvent(*decision.min_latency_event());
}
proto_decision.set_min_inference_time_us(decision.min_inference_time_us());
return proto_decision;
}
proto::BenchmarkInitializationFailure ConvertBenchmarkInitializationFailure(
const BenchmarkInitializationFailure& init_failure) {
proto::BenchmarkInitializationFailure proto_init_failure;
proto_init_failure.set_initialization_status(
init_failure.initialization_status());
return proto_init_failure;
}
} // namespace
proto::ComputeSettings ConvertFromFlatbuffer(
const ComputeSettings& settings, bool skip_mini_benchmark_settings) {
proto::ComputeSettings proto_settings;
proto_settings.set_preference(
ConvertExecutionPreference(settings.preference()));
if (settings.tflite_settings() != nullptr) {
*(proto_settings.mutable_tflite_settings()) =
ConvertTfliteSettings(*settings.tflite_settings());
}
if (settings.model_namespace_for_statistics() != nullptr) {
proto_settings.set_model_namespace_for_statistics(
settings.model_namespace_for_statistics()->str());
}
if (settings.model_identifier_for_statistics() != nullptr) {
proto_settings.set_model_identifier_for_statistics(
settings.model_identifier_for_statistics()->str());
}
if (!skip_mini_benchmark_settings &&
settings.settings_to_test_locally() != nullptr) {
*(proto_settings.mutable_settings_to_test_locally()) =
ConvertMinibenchmarkSettings(*settings.settings_to_test_locally());
}
return proto_settings;
}
proto::ComputeSettings ConvertFromFlatbuffer(
const ComputeSettingsT& settings, bool skip_mini_benchmark_settings) {
flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(ComputeSettings::Pack(fbb, &settings));
auto settings_fbb =
flatbuffers::GetRoot<ComputeSettings>(fbb.GetBufferPointer());
return ConvertFromFlatbuffer(*settings_fbb, skip_mini_benchmark_settings);
}
proto::MiniBenchmarkEvent ConvertFromFlatbuffer(
const MiniBenchmarkEvent& event) {
proto::MiniBenchmarkEvent proto_event;
proto_event.set_is_log_flushing_event(event.is_log_flushing_event());
if (event.best_acceleration_decision() != nullptr) {
*proto_event.mutable_best_acceleration_decision() =
ConvertBestAccelerationDecision(*event.best_acceleration_decision());
}
if (event.initialization_failure() != nullptr) {
*proto_event.mutable_initialization_failure() =
ConvertBenchmarkInitializationFailure(*event.initialization_failure());
}
if (event.benchmark_event() != nullptr) {
*proto_event.mutable_benchmark_event() =
ConvertBenchmarkEvent(*event.benchmark_event());
}
return proto_event;
}
proto::MiniBenchmarkEvent ConvertFromFlatbuffer(
const MiniBenchmarkEventT& event) {
flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(MiniBenchmarkEvent::Pack(fbb, &event));
auto event_fbb =
flatbuffers::GetRoot<MiniBenchmarkEvent>(fbb.GetBufferPointer());
return ConvertFromFlatbuffer(*event_fbb);
}
} // namespace tflite
@@ -0,0 +1,41 @@
/* Copyright 2021 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_ACCELERATION_CONFIGURATION_FLATBUFFER_TO_PROTO_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_FLATBUFFER_TO_PROTO_H_
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/acceleration/configuration/configuration.pb.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
namespace tflite {
// Converts the provided ComputeSettings from flatbuffer to proto format.
proto::ComputeSettings ConvertFromFlatbuffer(
const ComputeSettings& settings, bool skip_mini_benchmark_settings = false);
proto::ComputeSettings ConvertFromFlatbuffer(
const ComputeSettingsT& settings,
bool skip_mini_benchmark_settings = false);
// Converts the provided MiniBenchmarkEvent from flatbuffer to proto format.
proto::MiniBenchmarkEvent ConvertFromFlatbuffer(
const MiniBenchmarkEvent& event);
proto::MiniBenchmarkEvent ConvertFromFlatbuffer(
const MiniBenchmarkEventT& event);
} // namespace tflite
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_FLATBUFFER_TO_PROTO_H_
@@ -0,0 +1,801 @@
/* Copyright 2021 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/acceleration/configuration/flatbuffer_to_proto.h"
#include <cstdint>
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <gtest/gtest.h>
#include "tensorflow/lite/acceleration/configuration/configuration.pb.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
namespace tflite {
namespace acceleration {
namespace {
class ConversionTest : public ::testing::Test {
protected:
void CheckDelegateEnum(Delegate input, proto::Delegate output) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->delegate = input;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(output, compute.tflite_settings().delegate());
}
void CheckExecutionPreference(ExecutionPreference input,
proto::ExecutionPreference output) {
settings_.preference = input;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(output, compute.preference());
}
void CheckNNAPIExecutionPreference(NNAPIExecutionPreference input,
proto::NNAPIExecutionPreference output) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->nnapi_settings =
std::make_unique<NNAPISettingsT>();
settings_.tflite_settings->nnapi_settings->execution_preference = input;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(
output,
compute.tflite_settings().nnapi_settings().execution_preference());
}
void CheckNNAPIExecutionPriority(NNAPIExecutionPriority input,
proto::NNAPIExecutionPriority output) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->nnapi_settings =
std::make_unique<NNAPISettingsT>();
settings_.tflite_settings->nnapi_settings->execution_priority = input;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(output,
compute.tflite_settings().nnapi_settings().execution_priority());
}
void CheckGPUBackend(GPUBackend input, proto::GPUBackend output) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->gpu_settings = std::make_unique<GPUSettingsT>();
settings_.tflite_settings->gpu_settings->force_backend = input;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(output, compute.tflite_settings().gpu_settings().force_backend());
}
ComputeSettingsT settings_;
MiniBenchmarkEventT event_;
};
TEST_F(ConversionTest, Delegate) {
CheckDelegateEnum(Delegate_NONE, proto::Delegate::NONE);
CheckDelegateEnum(Delegate_NNAPI, proto::Delegate::NNAPI);
CheckDelegateEnum(Delegate_GPU, proto::Delegate::GPU);
CheckDelegateEnum(Delegate_HEXAGON, proto::Delegate::HEXAGON);
CheckDelegateEnum(Delegate_EDGETPU, proto::Delegate::EDGETPU);
CheckDelegateEnum(Delegate_EDGETPU_CORAL, proto::Delegate::EDGETPU_CORAL);
CheckDelegateEnum(Delegate_XNNPACK, proto::Delegate::XNNPACK);
CheckDelegateEnum(Delegate_CORE_ML, proto::Delegate::CORE_ML);
}
TEST_F(ConversionTest, ExecutionPreference) {
CheckExecutionPreference(ExecutionPreference_ANY,
proto::ExecutionPreference::ANY);
CheckExecutionPreference(ExecutionPreference_LOW_LATENCY,
proto::ExecutionPreference::LOW_LATENCY);
CheckExecutionPreference(ExecutionPreference_LOW_POWER,
proto::ExecutionPreference::LOW_POWER);
CheckExecutionPreference(ExecutionPreference_FORCE_CPU,
proto::ExecutionPreference::FORCE_CPU);
}
TEST_F(ConversionTest, ModelIdentifier) {
settings_.model_identifier_for_statistics = "id";
settings_.model_namespace_for_statistics = "ns";
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(compute.model_namespace_for_statistics(), "ns");
EXPECT_EQ(compute.model_identifier_for_statistics(), "id");
}
TEST_F(ConversionTest, NNAPISettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->nnapi_settings =
std::make_unique<NNAPISettingsT>();
NNAPISettingsT* input_settings =
settings_.tflite_settings->nnapi_settings.get();
input_settings->accelerator_name = "a";
input_settings->cache_directory = "d";
input_settings->model_token = "t";
input_settings->allow_fp16_precision_for_fp32 = true;
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::NNAPISettings output_settings =
compute.tflite_settings().nnapi_settings();
EXPECT_EQ(output_settings.accelerator_name(), "a");
EXPECT_EQ(output_settings.cache_directory(), "d");
EXPECT_EQ(output_settings.model_token(), "t");
EXPECT_TRUE(output_settings.allow_fp16_precision_for_fp32());
EXPECT_FALSE(output_settings.allow_nnapi_cpu_on_android_10_plus());
EXPECT_FALSE(output_settings.fallback_settings()
.allow_automatic_fallback_on_compilation_error());
EXPECT_FALSE(output_settings.fallback_settings()
.allow_automatic_fallback_on_execution_error());
input_settings->fallback_settings = std::make_unique<FallbackSettingsT>();
input_settings->fallback_settings
->allow_automatic_fallback_on_compilation_error = true;
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().nnapi_settings();
EXPECT_TRUE(output_settings.fallback_settings()
.allow_automatic_fallback_on_compilation_error());
EXPECT_FALSE(output_settings.fallback_settings()
.allow_automatic_fallback_on_execution_error());
input_settings->fallback_settings
->allow_automatic_fallback_on_compilation_error = false;
input_settings->fallback_settings
->allow_automatic_fallback_on_execution_error = true;
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().nnapi_settings();
EXPECT_FALSE(output_settings.fallback_settings()
.allow_automatic_fallback_on_compilation_error());
EXPECT_TRUE(output_settings.fallback_settings()
.allow_automatic_fallback_on_execution_error());
input_settings->allow_fp16_precision_for_fp32 = false;
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().nnapi_settings();
EXPECT_FALSE(output_settings.allow_fp16_precision_for_fp32());
}
TEST_F(ConversionTest, NNAPIAllowDynamicDimensions) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->nnapi_settings =
std::make_unique<NNAPISettingsT>();
NNAPISettingsT* input_settings =
settings_.tflite_settings->nnapi_settings.get();
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::NNAPISettings output_settings =
compute.tflite_settings().nnapi_settings();
EXPECT_FALSE(output_settings.allow_dynamic_dimensions());
input_settings->allow_dynamic_dimensions = true;
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().nnapi_settings();
EXPECT_TRUE(output_settings.allow_dynamic_dimensions());
}
TEST_F(ConversionTest, NNAPIBurstComputation) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->nnapi_settings =
std::make_unique<NNAPISettingsT>();
NNAPISettingsT* input_settings =
settings_.tflite_settings->nnapi_settings.get();
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::NNAPISettings output_settings =
compute.tflite_settings().nnapi_settings();
EXPECT_FALSE(output_settings.use_burst_computation());
input_settings->use_burst_computation = true;
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().nnapi_settings();
EXPECT_TRUE(output_settings.use_burst_computation());
}
TEST_F(ConversionTest, NNAPIExecutionPreference) {
CheckNNAPIExecutionPreference(
NNAPIExecutionPreference_NNAPI_FAST_SINGLE_ANSWER,
proto::NNAPIExecutionPreference::NNAPI_FAST_SINGLE_ANSWER);
CheckNNAPIExecutionPreference(
NNAPIExecutionPreference_NNAPI_LOW_POWER,
proto::NNAPIExecutionPreference::NNAPI_LOW_POWER);
CheckNNAPIExecutionPreference(
NNAPIExecutionPreference_NNAPI_SUSTAINED_SPEED,
proto::NNAPIExecutionPreference::NNAPI_SUSTAINED_SPEED);
CheckNNAPIExecutionPreference(NNAPIExecutionPreference_UNDEFINED,
proto::NNAPIExecutionPreference::UNDEFINED);
}
TEST_F(ConversionTest, NNAPIExecutionPriority) {
CheckNNAPIExecutionPriority(
NNAPIExecutionPriority_NNAPI_PRIORITY_LOW,
proto::NNAPIExecutionPriority::NNAPI_PRIORITY_LOW);
CheckNNAPIExecutionPriority(
NNAPIExecutionPriority_NNAPI_PRIORITY_MEDIUM,
proto::NNAPIExecutionPriority::NNAPI_PRIORITY_MEDIUM);
CheckNNAPIExecutionPriority(
NNAPIExecutionPriority_NNAPI_PRIORITY_HIGH,
proto::NNAPIExecutionPriority::NNAPI_PRIORITY_HIGH);
CheckNNAPIExecutionPriority(
NNAPIExecutionPriority_NNAPI_PRIORITY_UNDEFINED,
proto::NNAPIExecutionPriority::NNAPI_PRIORITY_UNDEFINED);
}
TEST_F(ConversionTest, NNAPISupportLibraryHandle) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->nnapi_settings =
std::make_unique<NNAPISettingsT>();
NNAPISettingsT* input_settings =
settings_.tflite_settings->nnapi_settings.get();
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::NNAPISettings output_settings =
compute.tflite_settings().nnapi_settings();
EXPECT_EQ(output_settings.support_library_handle(), 0);
input_settings->support_library_handle = std::numeric_limits<int64_t>::max();
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().nnapi_settings();
EXPECT_EQ(output_settings.support_library_handle(),
std::numeric_limits<int64_t>::max());
}
TEST_F(ConversionTest, GPUSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->gpu_settings = std::make_unique<GPUSettingsT>();
GPUSettingsT* input_settings = settings_.tflite_settings->gpu_settings.get();
input_settings->is_precision_loss_allowed = true;
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::GPUSettings output_settings = compute.tflite_settings().gpu_settings();
EXPECT_TRUE(output_settings.is_precision_loss_allowed());
input_settings->is_precision_loss_allowed = false;
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().gpu_settings();
EXPECT_FALSE(output_settings.is_precision_loss_allowed());
EXPECT_TRUE(output_settings.enable_quantized_inference());
input_settings->enable_quantized_inference = false;
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().gpu_settings();
EXPECT_FALSE(output_settings.enable_quantized_inference());
}
TEST_F(ConversionTest, GPUBacked) {
CheckGPUBackend(GPUBackend_UNSET, proto::GPUBackend::UNSET);
CheckGPUBackend(GPUBackend_OPENCL, proto::GPUBackend::OPENCL);
CheckGPUBackend(GPUBackend_OPENGL, proto::GPUBackend::OPENGL);
}
TEST_F(ConversionTest, GPUInferencePriority) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->gpu_settings = std::make_unique<GPUSettingsT>();
GPUSettingsT* input_settings = settings_.tflite_settings->gpu_settings.get();
input_settings->inference_priority1 =
GPUInferencePriority_GPU_PRIORITY_MIN_MEMORY_USAGE;
input_settings->inference_priority2 =
GPUInferencePriority_GPU_PRIORITY_MIN_LATENCY;
// Third priority is AUTO by default.
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::GPUSettings output_settings = compute.tflite_settings().gpu_settings();
EXPECT_EQ(proto::GPUInferencePriority::GPU_PRIORITY_MIN_MEMORY_USAGE,
output_settings.inference_priority1());
EXPECT_EQ(proto::GPUInferencePriority::GPU_PRIORITY_MIN_LATENCY,
output_settings.inference_priority2());
EXPECT_EQ(proto::GPUInferencePriority::GPU_PRIORITY_AUTO,
output_settings.inference_priority3());
}
TEST_F(ConversionTest, GPUInferencePreference) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->gpu_settings = std::make_unique<GPUSettingsT>();
GPUSettingsT* input_settings = settings_.tflite_settings->gpu_settings.get();
input_settings->inference_preference =
GPUInferenceUsage_GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER;
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::GPUSettings output_settings = compute.tflite_settings().gpu_settings();
EXPECT_EQ(
proto::GPUInferenceUsage::GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER,
output_settings.inference_preference());
input_settings->inference_preference =
GPUInferenceUsage_GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED;
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().gpu_settings();
EXPECT_EQ(proto::GPUInferenceUsage::GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED,
output_settings.inference_preference());
}
TEST_F(ConversionTest, HexagonSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->hexagon_settings =
std::make_unique<HexagonSettingsT>();
HexagonSettingsT* input_settings =
settings_.tflite_settings->hexagon_settings.get();
input_settings->debug_level = 1;
input_settings->powersave_level = 2;
input_settings->print_graph_profile = true;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
const proto::HexagonSettings& output_settings =
compute.tflite_settings().hexagon_settings();
EXPECT_EQ(1, output_settings.debug_level());
EXPECT_EQ(2, output_settings.powersave_level());
EXPECT_TRUE(output_settings.print_graph_profile());
EXPECT_FALSE(output_settings.print_graph_debug());
}
TEST_F(ConversionTest, EdgeTpuSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->edgetpu_settings =
std::make_unique<EdgeTpuSettingsT>();
EdgeTpuSettingsT* input_settings =
settings_.tflite_settings->edgetpu_settings.get();
constexpr EdgeTpuPowerState kInferencePowerState = EdgeTpuPowerState_ACTIVE;
constexpr EdgeTpuPowerState kInactivePowerState =
EdgeTpuPowerState_ACTIVE_MIN_POWER;
constexpr int64_t kInactiveTimeoutUs = 300000;
constexpr int kInferencePriority = 2;
const std::string kModelToken = "model_token";
constexpr EdgeTpuSettings_::FloatTruncationType kFloatTruncationType =
EdgeTpuSettings_::FloatTruncationType_HALF;
constexpr bool kUseTpuServer = true;
input_settings->inference_power_state = kInferencePowerState;
input_settings->inference_priority = kInferencePriority;
input_settings->model_token = kModelToken;
input_settings->float_truncation_type = kFloatTruncationType;
input_settings->use_tpu_server = kUseTpuServer;
std::unique_ptr<EdgeTpuInactivePowerConfigT> inactive_power_config(
new EdgeTpuInactivePowerConfigT());
inactive_power_config->inactive_power_state = kInactivePowerState;
inactive_power_config->inactive_timeout_us = kInactiveTimeoutUs;
input_settings->inactive_power_configs.emplace_back(
std::move(inactive_power_config));
constexpr EdgeTpuDeviceSpec_::PlatformType kPlatformType =
EdgeTpuDeviceSpec_::PlatformType_MMIO;
constexpr int kNumChips = 1;
const std::string kDevicePath = "/dev/abrolhos";
constexpr int kChipFamily = 1;
input_settings->edgetpu_device_spec = std::make_unique<EdgeTpuDeviceSpecT>();
EdgeTpuDeviceSpecT* input_spec = input_settings->edgetpu_device_spec.get();
input_spec->platform_type = kPlatformType;
input_spec->num_chips = kNumChips;
input_spec->chip_family = kChipFamily;
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::EdgeTpuSettings output_settings =
compute.tflite_settings().edgetpu_settings();
EXPECT_EQ(
static_cast<EdgeTpuPowerState>(output_settings.inference_power_state()),
kInferencePowerState);
EXPECT_EQ(output_settings.inactive_power_configs().size(), 1);
EXPECT_EQ(
static_cast<EdgeTpuPowerState>(output_settings.inactive_power_configs()
.at(0)
.inactive_power_state()),
kInactivePowerState);
EXPECT_EQ(
output_settings.inactive_power_configs().at(0).inactive_timeout_us(),
kInactiveTimeoutUs);
EXPECT_EQ(output_settings.inference_priority(), kInferencePriority);
EXPECT_EQ(output_settings.model_token(), kModelToken);
EXPECT_EQ(static_cast<EdgeTpuSettings_::FloatTruncationType>(
output_settings.float_truncation_type()),
kFloatTruncationType);
EXPECT_EQ(output_settings.use_tpu_server(), kUseTpuServer);
EXPECT_EQ(static_cast<EdgeTpuDeviceSpec_::PlatformType>(
output_settings.edgetpu_device_spec().platform_type()),
kPlatformType);
EXPECT_EQ(output_settings.edgetpu_device_spec().num_chips(), kNumChips);
EXPECT_EQ(output_settings.edgetpu_device_spec().device_paths_size(), 0);
EXPECT_EQ(output_settings.edgetpu_device_spec().chip_family(), kChipFamily);
input_spec->device_paths.push_back(kDevicePath);
compute = ConvertFromFlatbuffer(settings_);
output_settings = compute.tflite_settings().edgetpu_settings();
EXPECT_EQ(output_settings.edgetpu_device_spec().device_paths().size(), 1);
EXPECT_EQ(output_settings.edgetpu_device_spec().device_paths()[0],
kDevicePath);
}
TEST_F(ConversionTest, XNNPackSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->xnnpack_settings =
std::make_unique<XNNPackSettingsT>();
XNNPackSettingsT* input_settings =
settings_.tflite_settings->xnnpack_settings.get();
input_settings->num_threads = 2;
input_settings->flags =
tflite::XNNPackFlags::XNNPackFlags_TFLITE_XNNPACK_DELEGATE_FLAG_QS8_QU8;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(compute.tflite_settings().xnnpack_settings().num_threads(), 2);
EXPECT_EQ(compute.tflite_settings().xnnpack_settings().flags(), 3);
}
TEST_F(ConversionTest, CoreMLSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->coreml_settings =
std::make_unique<CoreMLSettingsT>();
CoreMLSettingsT* input_settings =
settings_.tflite_settings->coreml_settings.get();
input_settings->enabled_devices =
CoreMLSettings_::EnabledDevices_DEVICES_WITH_NEURAL_ENGINE;
input_settings->coreml_version = 3;
input_settings->max_delegated_partitions = 10;
input_settings->min_nodes_per_partition = 4;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(compute.tflite_settings().coreml_settings().enabled_devices(),
proto::CoreMLSettings::DEVICES_WITH_NEURAL_ENGINE);
EXPECT_EQ(compute.tflite_settings().coreml_settings().coreml_version(), 3);
EXPECT_EQ(
compute.tflite_settings().coreml_settings().max_delegated_partitions(),
10);
EXPECT_EQ(
compute.tflite_settings().coreml_settings().min_nodes_per_partition(), 4);
}
TEST_F(ConversionTest, CoralSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->coral_settings =
std::make_unique<CoralSettingsT>();
CoralSettingsT* input_settings =
settings_.tflite_settings->coral_settings.get();
input_settings->device = "test";
input_settings->performance = CoralSettings_::Performance_HIGH;
input_settings->usb_always_dfu = true;
input_settings->usb_max_bulk_in_queue_length = 768;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
const proto::CoralSettings& output_settings =
compute.tflite_settings().coral_settings();
EXPECT_EQ("test", output_settings.device());
EXPECT_TRUE(output_settings.usb_always_dfu());
EXPECT_EQ(proto::CoralSettings::HIGH, output_settings.performance());
EXPECT_EQ(768, output_settings.usb_max_bulk_in_queue_length());
}
TEST_F(ConversionTest, StableDelegateLoaderSettings) {
const std::string kDelegatePath = "TEST_DELEGATE_PATH";
const std::string kDelegateName = "TEST_DELEGATE_NAME";
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->stable_delegate_loader_settings =
std::make_unique<StableDelegateLoaderSettingsT>();
settings_.tflite_settings->stable_delegate_loader_settings->delegate_path =
kDelegatePath;
settings_.tflite_settings->stable_delegate_loader_settings->delegate_name =
kDelegateName;
const proto::StableDelegateLoaderSettings output_settings =
ConvertFromFlatbuffer(settings_)
.tflite_settings()
.stable_delegate_loader_settings();
EXPECT_EQ(output_settings.delegate_path(), kDelegatePath);
EXPECT_EQ(output_settings.delegate_name(), kDelegateName);
}
TEST_F(ConversionTest, CPUSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->cpu_settings = std::make_unique<CPUSettingsT>();
settings_.tflite_settings->cpu_settings->num_threads = 2;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(compute.tflite_settings().cpu_settings().num_threads(), 2);
}
TEST_F(ConversionTest, MaxDelegatedPartitions) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->max_delegated_partitions = 2;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(compute.tflite_settings().max_delegated_partitions(), 2);
}
TEST_F(ConversionTest, GoogleEdgeTpuSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->google_edgetpu_settings =
std::make_unique<GoogleEdgeTpuSettingsT>();
GoogleEdgeTpuSettingsT* input_settings =
settings_.tflite_settings->google_edgetpu_settings.get();
input_settings->priority = GoogleEdgeTpuSettings_::Priority_PRIORITY_HIGH;
input_settings->allow_fp16_precision_for_fp32 = true;
std::vector<uint8_t> extension_data{1, 2, 3};
input_settings->extension_data = extension_data;
input_settings->model_identifier = "model";
input_settings->prefer_cache_coherency_for_inputs =
GoogleEdgeTpuSettings_::TriState_TRISTATE_TRUE;
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::GoogleEdgeTpuSettings output_settings =
compute.tflite_settings().google_edgetpu_settings();
EXPECT_EQ(output_settings.priority(),
proto::GoogleEdgeTpuSettings::PRIORITY_HIGH);
EXPECT_TRUE(output_settings.allow_fp16_precision_for_fp32());
EXPECT_EQ(output_settings.extension_data().size(), 3);
EXPECT_EQ(output_settings.model_identifier(), "model");
EXPECT_EQ(output_settings.prefer_cache_coherency_for_inputs(),
proto::GoogleEdgeTpuSettings::TRISTATE_TRUE);
}
TEST_F(ConversionTest, CompilationCachingSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->compilation_caching_settings =
std::make_unique<CompilationCachingSettingsT>();
CompilationCachingSettingsT* input_settings =
settings_.tflite_settings->compilation_caching_settings.get();
input_settings->cache_dir = "/tmp";
input_settings->model_token = "model";
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
proto::CompilationCachingSettings output_settings =
compute.tflite_settings().compilation_caching_settings();
EXPECT_EQ(output_settings.cache_dir(), "/tmp");
EXPECT_EQ(output_settings.model_token(), "model");
}
TEST_F(ConversionTest, MtkNeuronSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->mtk_neuron_settings =
std::make_unique<MtkNeuronSettingsT>();
MtkNeuronSettingsT* input_settings =
settings_.tflite_settings->mtk_neuron_settings.get();
input_settings->execution_preference =
MtkNeuronSettings_::ExecutionPreference_PREFERENCE_UNDEFINED;
input_settings->execution_priority =
MtkNeuronSettings_::ExecutionPriority_PRIORITY_MEDIUM;
input_settings->optimization_hints = {
MtkNeuronSettings_::OptimizationHint_OPTIMIZATION_LOW_LATENCY,
MtkNeuronSettings_::OptimizationHint_OPTIMIZATION_BATCH_PROCESSING};
input_settings->operation_check_mode =
MtkNeuronSettings_::OperationCheckMode_PER_NODE_OPERATION_CHECK;
input_settings->allow_fp16_precision_for_fp32 = true;
input_settings->use_ahwb = false;
input_settings->use_cacheable_buffer = true;
input_settings->compile_options = {"TEST_COMPILE_OPTIONS"};
input_settings->accelerator_names = {"TEST_ACCELERATOR_NAME"};
input_settings->neuron_config_path = "TEST_NEURON_CONFIG_PATH";
input_settings->inference_deadline_ms = 1337;
input_settings->inference_abort_time_ms = 42;
const proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
const proto::MtkNeuronSettings& output_settings =
compute.tflite_settings().mtk_neuron_settings();
EXPECT_EQ(output_settings.execution_preference(),
proto::MtkNeuronSettings::PREFERENCE_UNDEFINED);
EXPECT_EQ(output_settings.execution_priority(),
proto::MtkNeuronSettings::PRIORITY_MEDIUM);
EXPECT_EQ(output_settings.optimization_hints().size(), 2);
EXPECT_EQ(output_settings.optimization_hints().at(0),
proto::MtkNeuronSettings::OPTIMIZATION_LOW_LATENCY);
EXPECT_EQ(output_settings.optimization_hints().at(1),
proto::MtkNeuronSettings::OPTIMIZATION_BATCH_PROCESSING);
EXPECT_EQ(output_settings.operation_check_mode(),
proto::MtkNeuronSettings::PER_NODE_OPERATION_CHECK);
EXPECT_TRUE(output_settings.allow_fp16_precision_for_fp32());
EXPECT_FALSE(output_settings.use_ahwb());
EXPECT_TRUE(output_settings.use_cacheable_buffer());
EXPECT_EQ(output_settings.compile_options().size(), 1);
EXPECT_EQ(output_settings.compile_options().at(0), "TEST_COMPILE_OPTIONS");
EXPECT_EQ(output_settings.accelerator_names().size(), 1);
EXPECT_EQ(output_settings.accelerator_names().at(0), "TEST_ACCELERATOR_NAME");
EXPECT_EQ(output_settings.neuron_config_path(), "TEST_NEURON_CONFIG_PATH");
EXPECT_EQ(output_settings.inference_deadline_ms(), 1337);
EXPECT_EQ(output_settings.inference_abort_time_ms(), 42);
}
TEST_F(ConversionTest, MiniBenchmarkSettings) {
settings_.tflite_settings = std::make_unique<TFLiteSettingsT>();
settings_.tflite_settings->cpu_settings = std::make_unique<CPUSettingsT>();
settings_.tflite_settings->cpu_settings->num_threads = 2;
settings_.model_identifier_for_statistics = "id";
settings_.model_namespace_for_statistics = "ns";
settings_.settings_to_test_locally =
std::make_unique<MinibenchmarkSettingsT>();
MinibenchmarkSettingsT* mini_settings =
settings_.settings_to_test_locally.get();
mini_settings->model_file = std::make_unique<ModelFileT>();
mini_settings->model_file->filename = "test_model";
mini_settings->storage_paths = std::make_unique<BenchmarkStoragePathsT>();
mini_settings->storage_paths->storage_file_path = "/data/local/tmp";
std::unique_ptr<TFLiteSettingsT> xnnpack(new TFLiteSettingsT());
xnnpack->xnnpack_settings = std::make_unique<XNNPackSettingsT>();
xnnpack->xnnpack_settings->num_threads = 2;
std::unique_ptr<TFLiteSettingsT> hexagon(new TFLiteSettingsT());
hexagon->hexagon_settings = std::make_unique<HexagonSettingsT>();
hexagon->hexagon_settings->powersave_level = 3;
std::unique_ptr<TFLiteSettingsT> coreml(new TFLiteSettingsT());
coreml->coreml_settings = std::make_unique<CoreMLSettingsT>();
coreml->coreml_settings->enabled_devices =
CoreMLSettings_::EnabledDevices_DEVICES_WITH_NEURAL_ENGINE;
coreml->coreml_settings->coreml_version = 3;
coreml->coreml_settings->max_delegated_partitions = 10;
coreml->coreml_settings->min_nodes_per_partition = 4;
mini_settings->settings_to_test.emplace_back(std::move(xnnpack));
mini_settings->settings_to_test.emplace_back(std::move(hexagon));
mini_settings->settings_to_test.emplace_back(std::move(coreml));
proto::ComputeSettings compute = ConvertFromFlatbuffer(settings_);
EXPECT_EQ(2, compute.tflite_settings().cpu_settings().num_threads());
EXPECT_EQ("id", compute.model_identifier_for_statistics());
EXPECT_EQ("ns", compute.model_namespace_for_statistics());
EXPECT_TRUE(compute.has_settings_to_test_locally());
const proto::MinibenchmarkSettings& mini_output =
compute.settings_to_test_locally();
EXPECT_EQ("test_model", mini_output.model_file().filename());
EXPECT_EQ("/data/local/tmp", mini_output.storage_paths().storage_file_path());
EXPECT_EQ(3, mini_output.settings_to_test_size());
EXPECT_EQ(
2, mini_output.settings_to_test().at(0).xnnpack_settings().num_threads());
EXPECT_EQ(3, mini_output.settings_to_test()
.at(1)
.hexagon_settings()
.powersave_level());
EXPECT_EQ(
proto::CoreMLSettings::DEVICES_WITH_NEURAL_ENGINE,
mini_output.settings_to_test().at(2).coreml_settings().enabled_devices());
EXPECT_EQ(
3,
mini_output.settings_to_test().at(2).coreml_settings().coreml_version());
EXPECT_EQ(10, mini_output.settings_to_test()
.at(2)
.coreml_settings()
.max_delegated_partitions());
EXPECT_EQ(4, mini_output.settings_to_test()
.at(2)
.coreml_settings()
.min_nodes_per_partition());
compute =
ConvertFromFlatbuffer(settings_, /*skip_mini_benchmark_settings=*/true);
EXPECT_EQ(2, compute.tflite_settings().cpu_settings().num_threads());
EXPECT_EQ("id", compute.model_identifier_for_statistics());
EXPECT_EQ("ns", compute.model_namespace_for_statistics());
EXPECT_FALSE(compute.has_settings_to_test_locally());
}
TEST_F(ConversionTest, BestAccelerationDecisionEvent) {
event_.is_log_flushing_event = true;
event_.best_acceleration_decision =
std::make_unique<BestAccelerationDecisionT>();
event_.best_acceleration_decision->number_of_source_events = 4;
event_.best_acceleration_decision->min_inference_time_us = 3000;
proto::MiniBenchmarkEvent proto_event = ConvertFromFlatbuffer(event_);
EXPECT_TRUE(proto_event.is_log_flushing_event());
const auto& best_decision = proto_event.best_acceleration_decision();
EXPECT_EQ(4, best_decision.number_of_source_events());
EXPECT_EQ(3000, best_decision.min_inference_time_us());
EXPECT_FALSE(best_decision.has_min_latency_event());
event_.best_acceleration_decision->min_latency_event =
std::make_unique<BenchmarkEventT>();
auto* min_event = event_.best_acceleration_decision->min_latency_event.get();
min_event->event_type = BenchmarkEventType_END;
min_event->tflite_settings = std::make_unique<TFLiteSettingsT>();
min_event->tflite_settings->delegate = Delegate_XNNPACK;
min_event->tflite_settings->xnnpack_settings =
std::make_unique<XNNPackSettingsT>();
min_event->tflite_settings->xnnpack_settings->num_threads = 2;
min_event->result = std::make_unique<BenchmarkResultT>();
min_event->result->initialization_time_us.push_back(100);
min_event->result->initialization_time_us.push_back(110);
min_event->result->inference_time_us.push_back(3000);
min_event->result->inference_time_us.push_back(3500);
min_event->result->max_memory_kb = 1234;
min_event->result->ok = true;
min_event->boottime_us = 1111;
min_event->wallclock_us = 2222;
proto_event = ConvertFromFlatbuffer(event_);
EXPECT_TRUE(proto_event.best_acceleration_decision().has_min_latency_event());
const auto& proto_min_event =
proto_event.best_acceleration_decision().min_latency_event();
EXPECT_EQ(proto::BenchmarkEventType::END, proto_min_event.event_type());
EXPECT_EQ(proto::Delegate::XNNPACK,
proto_min_event.tflite_settings().delegate());
EXPECT_EQ(2,
proto_min_event.tflite_settings().xnnpack_settings().num_threads());
EXPECT_TRUE(proto_min_event.has_result());
EXPECT_EQ(2, proto_min_event.result().initialization_time_us_size());
EXPECT_EQ(100, proto_min_event.result().initialization_time_us()[0]);
EXPECT_EQ(110, proto_min_event.result().initialization_time_us()[1]);
EXPECT_EQ(2, proto_min_event.result().inference_time_us_size());
EXPECT_EQ(3000, proto_min_event.result().inference_time_us()[0]);
EXPECT_EQ(3500, proto_min_event.result().inference_time_us()[1]);
EXPECT_EQ(1234, proto_min_event.result().max_memory_kb());
EXPECT_TRUE(proto_min_event.result().ok());
EXPECT_EQ(1111, proto_min_event.boottime_us());
EXPECT_EQ(2222, proto_min_event.wallclock_us());
}
TEST_F(ConversionTest, BenchmarkInitializationEvent) {
event_.initialization_failure =
std::make_unique<BenchmarkInitializationFailureT>();
event_.initialization_failure->initialization_status = 101;
proto::MiniBenchmarkEvent proto_event = ConvertFromFlatbuffer(event_);
EXPECT_FALSE(proto_event.is_log_flushing_event());
EXPECT_EQ(101, proto_event.initialization_failure().initialization_status());
}
TEST_F(ConversionTest, BenchmarkError) {
event_.benchmark_event = std::make_unique<BenchmarkEventT>();
event_.benchmark_event->error = std::make_unique<BenchmarkErrorT>();
auto* error = event_.benchmark_event->error.get();
error->stage = BenchmarkStage_INITIALIZATION;
error->exit_code = 123;
error->signal = 321;
error->mini_benchmark_error_code = 456;
std::unique_ptr<ErrorCodeT> code1(new ErrorCodeT());
code1->source = Delegate_EDGETPU;
code1->tflite_error = 3;
code1->underlying_api_error = 301;
error->error_code.emplace_back(std::move(code1));
std::unique_ptr<ErrorCodeT> code2(new ErrorCodeT());
code2->source = Delegate_NNAPI;
code2->tflite_error = 4;
code2->underlying_api_error = 404;
error->error_code.emplace_back(std::move(code2));
const proto::MiniBenchmarkEvent proto_event = ConvertFromFlatbuffer(event_);
const auto& proto_error = proto_event.benchmark_event().error();
EXPECT_EQ(proto::BenchmarkStage::INITIALIZATION, proto_error.stage());
EXPECT_EQ(123, proto_error.exit_code());
EXPECT_EQ(321, proto_error.signal());
EXPECT_EQ(456, proto_error.mini_benchmark_error_code());
EXPECT_EQ(2, proto_error.error_code_size());
EXPECT_EQ(proto::Delegate::EDGETPU, proto_error.error_code()[0].source());
EXPECT_EQ(3, proto_error.error_code()[0].tflite_error());
EXPECT_EQ(301, proto_error.error_code()[0].underlying_api_error());
EXPECT_EQ(proto::Delegate::NNAPI, proto_error.error_code()[1].source());
EXPECT_EQ(4, proto_error.error_code()[1].tflite_error());
EXPECT_EQ(404, proto_error.error_code()[1].underlying_api_error());
}
TEST_F(ConversionTest, BenchmarkMetric) {
event_.benchmark_event = std::make_unique<BenchmarkEventT>();
event_.benchmark_event->result = std::make_unique<BenchmarkResultT>();
std::unique_ptr<BenchmarkMetricT> metric(new BenchmarkMetricT());
metric->name = "test";
metric->values.push_back(1.234);
metric->values.push_back(5.678);
event_.benchmark_event->result->metrics.emplace_back(std::move(metric));
const proto::MiniBenchmarkEvent proto_event = ConvertFromFlatbuffer(event_);
EXPECT_EQ(1, proto_event.benchmark_event().result().metrics_size());
const auto& proto_metric =
proto_event.benchmark_event().result().metrics()[0];
EXPECT_EQ("test", proto_metric.name());
EXPECT_EQ(2, proto_metric.values_size());
EXPECT_FLOAT_EQ(1.234, proto_metric.values()[0]);
EXPECT_FLOAT_EQ(5.678, proto_metric.values()[1]);
}
} // namespace
} // namespace acceleration
} // namespace tflite
@@ -0,0 +1,165 @@
/* 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/acceleration/configuration/gpu_plugin.h"
#include <memory>
#include <string>
#include "absl/memory/memory.h"
namespace tflite {
namespace delegates {
int GpuPlugin::GetDelegateErrno(TfLiteDelegate* from_delegate) { return 0; }
std::unique_ptr<DelegatePluginInterface> GpuPlugin::New(
const TFLiteSettings& acceleration) {
return std::make_unique<GpuPlugin>(acceleration);
}
#if TFLITE_SUPPORTS_GPU_DELEGATE
namespace {
TfLiteGpuInferencePriority ConvertInferencePriority(
GPUInferencePriority priority) {
switch (priority) {
case GPUInferencePriority_GPU_PRIORITY_AUTO:
return TFLITE_GPU_INFERENCE_PRIORITY_AUTO;
case GPUInferencePriority_GPU_PRIORITY_MAX_PRECISION:
return TFLITE_GPU_INFERENCE_PRIORITY_MAX_PRECISION;
case GPUInferencePriority_GPU_PRIORITY_MIN_LATENCY:
return TFLITE_GPU_INFERENCE_PRIORITY_MIN_LATENCY;
case GPUInferencePriority_GPU_PRIORITY_MIN_MEMORY_USAGE:
return TFLITE_GPU_INFERENCE_PRIORITY_MIN_MEMORY_USAGE;
}
}
std::string GetCacheDirImpl(const TFLiteSettings& tflite_settings) {
if (tflite_settings.compilation_caching_settings() &&
tflite_settings.compilation_caching_settings()->cache_dir() &&
tflite_settings.compilation_caching_settings()->cache_dir()->size() > 0) {
return tflite_settings.compilation_caching_settings()->cache_dir()->str();
} else if (tflite_settings.gpu_settings() &&
tflite_settings.gpu_settings()->cache_directory() &&
tflite_settings.gpu_settings()->cache_directory()->size() > 0) {
return tflite_settings.gpu_settings()->cache_directory()->str();
} else {
return "";
}
}
std::string GetModelTokenImpl(const TFLiteSettings& tflite_settings) {
if (tflite_settings.compilation_caching_settings() &&
tflite_settings.compilation_caching_settings()->model_token() &&
tflite_settings.compilation_caching_settings()->model_token()->size() >
0) {
return tflite_settings.compilation_caching_settings()->model_token()->str();
} else if (tflite_settings.gpu_settings() &&
tflite_settings.gpu_settings()->model_token() &&
tflite_settings.gpu_settings()->model_token()->size()) {
return tflite_settings.gpu_settings()->model_token()->str();
} else {
return "";
}
}
} // namespace
TfLiteDelegatePtr GpuPlugin::Create() {
return TfLiteDelegatePtr(TfLiteGpuDelegateV2Create(&options_),
TfLiteGpuDelegateV2Delete);
}
GpuPlugin::GpuPlugin(const TFLiteSettings& tflite_settings)
: options_(TfLiteGpuDelegateOptionsV2Default()) {
if (tflite_settings.max_delegated_partitions() >= 0) {
options_.max_delegated_partitions =
tflite_settings.max_delegated_partitions();
}
const auto* gpu_settings = tflite_settings.gpu_settings();
if (!gpu_settings) return;
options_.inference_preference = gpu_settings->inference_preference();
if (gpu_settings->inference_priority1() > 0) {
// User has specified their own inference priorities, so just copy over.
options_.inference_priority1 =
ConvertInferencePriority(gpu_settings->inference_priority1());
options_.inference_priority2 =
ConvertInferencePriority(gpu_settings->inference_priority2());
options_.inference_priority3 =
ConvertInferencePriority(gpu_settings->inference_priority3());
} else {
options_.inference_priority1 =
gpu_settings->is_precision_loss_allowed()
? TFLITE_GPU_INFERENCE_PRIORITY_MIN_LATENCY
: TFLITE_GPU_INFERENCE_PRIORITY_MAX_PRECISION;
}
if (gpu_settings->enable_quantized_inference()) {
options_.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_QUANT;
}
if (gpu_settings->force_backend() == GPUBackend_OPENCL) {
options_.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_CL_ONLY;
} else if (gpu_settings->force_backend() == GPUBackend_OPENGL) {
options_.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_GL_ONLY;
}
const std::string cache_dir = GetCacheDirImpl(tflite_settings);
const std::string model_token = GetModelTokenImpl(tflite_settings);
if (!cache_dir.empty() && !model_token.empty()) {
cache_dir_ = cache_dir;
model_token_ = model_token;
options_.serialization_dir = cache_dir_.c_str();
options_.model_token = model_token_.c_str();
options_.experimental_flags |=
TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
}
}
#elif defined(REAL_IPHONE_DEVICE)
TfLiteDelegatePtr GpuPlugin::Create() {
return TfLiteDelegatePtr(TFLGpuDelegateCreate(&options_),
&TFLGpuDelegateDelete);
}
GpuPlugin::GpuPlugin(const TFLiteSettings& tflite_settings) {
options_ = {0};
const auto* gpu_settings = tflite_settings.gpu_settings();
if (!gpu_settings) return;
options_.allow_precision_loss = gpu_settings->is_precision_loss_allowed();
options_.enable_quantization = gpu_settings->enable_quantized_inference();
}
#else
TfLiteDelegatePtr GpuPlugin::Create() {
return TfLiteDelegatePtr(nullptr, [](TfLiteDelegate*) {});
}
// In case GPU acceleration is not supported for this platform, we still need to
// construct an empty object so that Create() can later be called on it.
GpuPlugin::GpuPlugin(const TFLiteSettings& tflite_settings) {}
#endif
TFLITE_REGISTER_DELEGATE_FACTORY_FUNCTION(GpuPlugin, GpuPlugin::New);
} // namespace delegates
} // namespace tflite
@@ -0,0 +1,79 @@
/* Copyright 2021 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_ACCELERATION_CONFIGURATION_GPU_PLUGIN_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_GPU_PLUGIN_H_
// This file provides the GpuPlugin class, which implements the
// TFLite Delegate Plugin for the GPU Delegate.
#if defined(__ANDROID__) || defined(CL_DELEGATE_NO_GL)
#define TFLITE_SUPPORTS_GPU_DELEGATE 1
#endif
#include <string>
#if TFLITE_SUPPORTS_GPU_DELEGATE
#include "tensorflow/lite/delegates/gpu/delegate.h"
#elif defined(__APPLE__)
#include "TargetConditionals.h"
#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR) || \
(TARGET_OS_OSX && TARGET_CPU_ARM64)
// Only enable metal delegate when using a real iPhone device or Apple Silicon.
#define REAL_IPHONE_DEVICE
#include "tensorflow/lite/delegates/gpu/metal_delegate.h"
#endif
#endif
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/core/acceleration/configuration/delegate_registry.h"
namespace tflite {
namespace delegates {
// Note that if running on GPU is not supported for some reason (e.g., desktop
// machine with no OpenGL/CL), this library will still compile but calling
// Create() will return a nullptr.
class GpuPlugin : public DelegatePluginInterface {
public:
explicit GpuPlugin(const TFLiteSettings& tflite_settings);
static std::unique_ptr<DelegatePluginInterface> New(
const TFLiteSettings& acceleration);
TfLiteDelegatePtr Create() override;
int GetDelegateErrno(TfLiteDelegate* from_delegate) override;
#if TFLITE_SUPPORTS_GPU_DELEGATE
const TfLiteGpuDelegateOptionsV2& Options() { return options_; }
#elif defined(REAL_IPHONE_DEVICE)
const TFLGpuDelegateOptions& Options() { return options_; }
#endif
std::string GetCacheDir() const { return cache_dir_; }
std::string GetModelToken() const { return model_token_; }
private:
#if TFLITE_SUPPORTS_GPU_DELEGATE
TfLiteGpuDelegateOptionsV2 options_;
#elif defined(REAL_IPHONE_DEVICE)
TFLGpuDelegateOptions options_;
#endif
std::string cache_dir_;
std::string model_token_;
};
} // namespace delegates
} // namespace tflite
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_GPU_PLUGIN_H_
@@ -0,0 +1,209 @@
/* 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.
==============================================================================*/
#include "tensorflow/lite/acceleration/configuration/gpu_plugin.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/acceleration/configuration/configuration.pb.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/acceleration/configuration/proto_to_flatbuffer.h"
#include "tensorflow/lite/core/acceleration/configuration/delegate_registry.h"
namespace tflite {
namespace delegates {
namespace {
#if TFLITE_SUPPORTS_GPU_DELEGATE || defined(REAL_IPHONE_DEVICE)
// While we could easily move the preprocessor lines around the expect part, we
// prefer to have two separate tests so it's clear which test is being
// exercised.
TEST(GpuPluginTest, GpuIsSupported) {
flatbuffers::FlatBufferBuilder fbb;
tflite::proto::ComputeSettings compute_settings;
compute_settings.mutable_tflite_settings()->set_delegate(
tflite::proto::Delegate::GPU);
const tflite::ComputeSettings* compute_settings_fb =
tflite::ConvertFromProto(compute_settings, &fbb);
TfLiteDelegatePtr gpu_delegate =
DelegatePluginRegistry::CreateByName(
"GpuPlugin", *compute_settings_fb->tflite_settings())
->Create();
EXPECT_NE(gpu_delegate, nullptr);
}
TEST(GpuPluginTest, CachingFieldsMissing) {
flatbuffers::FlatBufferBuilder fbb;
tflite::proto::ComputeSettings compute_settings;
compute_settings.mutable_tflite_settings()->set_delegate(
tflite::proto::Delegate::GPU);
const tflite::ComputeSettings* compute_settings_fb =
tflite::ConvertFromProto(compute_settings, &fbb);
GpuPlugin gpu_plugin(*compute_settings_fb->tflite_settings());
EXPECT_TRUE(gpu_plugin.GetCacheDir().empty());
EXPECT_TRUE(gpu_plugin.GetModelToken().empty());
}
TEST(GpuPluginTest, CompilationCachingFieldsSourcedFromGpuSettings) {
flatbuffers::FlatBufferBuilder fbb;
auto gpu_settings_cache_dir = fbb.CreateString("gpu_settings_cache_dir");
auto gpu_settings_model_token = fbb.CreateString("gpu_settings_model_token");
GPUSettingsBuilder gpu_settings_builder(fbb);
gpu_settings_builder.add_cache_directory(gpu_settings_cache_dir);
gpu_settings_builder.add_model_token(gpu_settings_model_token);
auto gpu_settings = gpu_settings_builder.Finish();
TFLiteSettingsBuilder tflite_settings_builder(fbb);
tflite_settings_builder.add_gpu_settings(gpu_settings);
auto tflite_settings = tflite_settings_builder.Finish();
fbb.Finish(tflite_settings);
auto tflite_settings_root =
flatbuffers::GetRoot<TFLiteSettings>(fbb.GetBufferPointer());
GpuPlugin gpu_plugin(*tflite_settings_root);
EXPECT_STREQ("gpu_settings_cache_dir", gpu_plugin.GetCacheDir().c_str());
EXPECT_STREQ("gpu_settings_model_token", gpu_plugin.GetModelToken().c_str());
}
TEST(GpuPluginTest,
CacheDirFromCompilationSettingsAndModelTokenFromGpuSettings) {
flatbuffers::FlatBufferBuilder fbb;
auto gpu_settings_cache_dir = fbb.CreateString("gpu_settings_cache_dir");
auto gpu_settings_model_token = fbb.CreateString("gpu_settings_model_token");
GPUSettingsBuilder gpu_settings_builder(fbb);
gpu_settings_builder.add_cache_directory(gpu_settings_cache_dir);
gpu_settings_builder.add_model_token(gpu_settings_model_token);
auto gpu_settings = gpu_settings_builder.Finish();
auto compilation_caching_dir =
fbb.CreateString("top_level_compilation_caching_dir");
CompilationCachingSettingsBuilder compilation_caching_settings_builder(fbb);
compilation_caching_settings_builder.add_cache_dir(compilation_caching_dir);
auto compilation_caching_settings =
compilation_caching_settings_builder.Finish();
TFLiteSettingsBuilder tflite_settings_builder(fbb);
tflite_settings_builder.add_gpu_settings(gpu_settings);
tflite_settings_builder.add_compilation_caching_settings(
compilation_caching_settings);
auto tflite_settings = tflite_settings_builder.Finish();
fbb.Finish(tflite_settings);
auto tflite_settings_root =
flatbuffers::GetRoot<TFLiteSettings>(fbb.GetBufferPointer());
GpuPlugin gpu_plugin(*tflite_settings_root);
EXPECT_STREQ("top_level_compilation_caching_dir",
gpu_plugin.GetCacheDir().c_str());
EXPECT_STREQ("gpu_settings_model_token", gpu_plugin.GetModelToken().c_str());
}
TEST(GpuPluginTest,
ModelTokenFromCompilationSettingsAndCacheDirFromGpuSettings) {
flatbuffers::FlatBufferBuilder fbb;
auto gpu_settings_cache_dir = fbb.CreateString("gpu_settings_cache_dir");
auto gpu_settings_model_token = fbb.CreateString("gpu_settings_model_token");
GPUSettingsBuilder gpu_settings_builder(fbb);
gpu_settings_builder.add_cache_directory(gpu_settings_cache_dir);
gpu_settings_builder.add_model_token(gpu_settings_model_token);
auto gpu_settings = gpu_settings_builder.Finish();
auto top_level_compilation_model_token =
fbb.CreateString("top_level_compilation_model_token");
CompilationCachingSettingsBuilder compilation_caching_settings_builder(fbb);
compilation_caching_settings_builder.add_model_token(
top_level_compilation_model_token);
auto compilation_caching_settings =
compilation_caching_settings_builder.Finish();
TFLiteSettingsBuilder tflite_settings_builder(fbb);
tflite_settings_builder.add_gpu_settings(gpu_settings);
tflite_settings_builder.add_compilation_caching_settings(
compilation_caching_settings);
auto tflite_settings = tflite_settings_builder.Finish();
fbb.Finish(tflite_settings);
auto tflite_settings_root =
flatbuffers::GetRoot<TFLiteSettings>(fbb.GetBufferPointer());
GpuPlugin gpu_plugin(*tflite_settings_root);
EXPECT_STREQ("gpu_settings_cache_dir", gpu_plugin.GetCacheDir().c_str());
EXPECT_STREQ("top_level_compilation_model_token",
gpu_plugin.GetModelToken().c_str());
}
TEST(GpuPluginTest, CacheDirAndModelTokenCompilationSettings) {
flatbuffers::FlatBufferBuilder fbb;
auto gpu_settings_cache_dir = fbb.CreateString("gpu_settings_cache_dir");
auto gpu_settings_model_token = fbb.CreateString("gpu_settings_model_token");
GPUSettingsBuilder gpu_settings_builder(fbb);
gpu_settings_builder.add_cache_directory(gpu_settings_cache_dir);
gpu_settings_builder.add_model_token(gpu_settings_model_token);
auto gpu_settings = gpu_settings_builder.Finish();
auto top_level_compilation_model_token =
fbb.CreateString("top_level_compilation_model_token");
auto compilation_caching_dir =
fbb.CreateString("top_level_compilation_caching_dir");
CompilationCachingSettingsBuilder compilation_caching_settings_builder(fbb);
compilation_caching_settings_builder.add_cache_dir(compilation_caching_dir);
compilation_caching_settings_builder.add_model_token(
top_level_compilation_model_token);
auto compilation_caching_settings =
compilation_caching_settings_builder.Finish();
TFLiteSettingsBuilder tflite_settings_builder(fbb);
tflite_settings_builder.add_gpu_settings(gpu_settings);
tflite_settings_builder.add_compilation_caching_settings(
compilation_caching_settings);
auto tflite_settings = tflite_settings_builder.Finish();
fbb.Finish(tflite_settings);
auto tflite_settings_root =
flatbuffers::GetRoot<TFLiteSettings>(fbb.GetBufferPointer());
GpuPlugin gpu_plugin(*tflite_settings_root);
EXPECT_STREQ("top_level_compilation_caching_dir",
gpu_plugin.GetCacheDir().c_str());
EXPECT_STREQ("top_level_compilation_model_token",
gpu_plugin.GetModelToken().c_str());
}
#else
TEST(GpuPluginTest, GpuNotSupported) {
flatbuffers::FlatBufferBuilder fbb;
tflite::proto::ComputeSettings compute_settings;
compute_settings.mutable_tflite_settings()->set_delegate(
tflite::proto::Delegate::GPU);
const tflite::ComputeSettings* compute_settings_fb =
tflite::ConvertFromProto(compute_settings, &fbb);
TfLiteDelegatePtr gpu_delegate =
DelegatePluginRegistry::CreateByName(
"GpuPlugin", *compute_settings_fb->tflite_settings())
->Create();
EXPECT_EQ(gpu_delegate, nullptr);
}
#endif
} // namespace
} // namespace delegates
} // namespace tflite
@@ -0,0 +1,77 @@
/* 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 <memory>
#include "absl/memory/memory.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/core/acceleration/configuration/delegate_registry.h"
#if defined(__ARM_ARCH)
#include "tensorflow/lite/delegates/hexagon/hexagon_delegate.h"
#endif
namespace tflite {
namespace delegates {
class HexagonPlugin : public DelegatePluginInterface {
public:
TfLiteDelegatePtr Create() override {
#if defined(__ARM_ARCH)
TfLiteHexagonInit();
auto* delegate_ptr = TfLiteHexagonDelegateCreate(&options_);
TfLiteDelegatePtr delegate(delegate_ptr, [](TfLiteDelegate* delegate) {
TfLiteHexagonDelegateDelete(delegate);
TfLiteHexagonTearDown();
});
return delegate;
#else // !defined(__ARM_ARCH)
return TfLiteDelegatePtr(nullptr, [](TfLiteDelegate*) {});
#endif // defined(__ARM_ARCH)
}
int GetDelegateErrno(TfLiteDelegate* /* from_delegate */) override {
return 0;
}
static std::unique_ptr<HexagonPlugin> New(
const TFLiteSettings& tflite_settings) {
return std::make_unique<HexagonPlugin>(tflite_settings);
}
explicit HexagonPlugin(const TFLiteSettings& tflite_settings) {
const HexagonSettings* settings = tflite_settings.hexagon_settings();
#if defined(__ARM_ARCH)
options_ = TfLiteHexagonDelegateOptions({0});
if (settings) {
options_.debug_level = settings->debug_level();
options_.powersave_level = settings->powersave_level();
options_.print_graph_profile = settings->print_graph_profile();
options_.print_graph_debug = settings->print_graph_debug();
if (tflite_settings.max_delegated_partitions() >= 0) {
options_.max_delegated_partitions =
tflite_settings.max_delegated_partitions();
}
}
#else
(void)settings;
#endif
}
private:
#if defined(__ARM_ARCH)
TfLiteHexagonDelegateOptions options_;
#endif
};
TFLITE_REGISTER_DELEGATE_FACTORY_FUNCTION(HexagonPlugin, HexagonPlugin::New);
} // namespace delegates
} // namespace tflite
@@ -0,0 +1,26 @@
#!/bin/bash
# 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.
set -o nounset
set -o errexit
readonly DIR_PREFIX="third_party/tensorflow/lite/acceleration/configuration"
readonly CURRENT_PROTO="$DIR_PREFIX/configuration.proto"
readonly PREV_PROTO="$DIR_PREFIX/testdata/configuration.proto_prev"
diff -u $PREV_PROTO $CURRENT_PROTO &&
die "Current proto should be different than prev proto"
echo "PASS"
@@ -0,0 +1,528 @@
/* 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/acceleration/configuration/proto_to_flatbuffer.h"
#include <cstdint>
#include <vector>
#include "flatbuffers/buffer.h" // from @flatbuffers
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/acceleration/configuration/configuration.pb.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/minimal_logging.h"
namespace tflite {
using ::flatbuffers::FlatBufferBuilder;
using ::flatbuffers::Offset;
using ::flatbuffers::String;
using ::flatbuffers::Vector;
ExecutionPreference ConvertExecutionPreference(
proto::ExecutionPreference preference) {
switch (preference) {
case proto::ExecutionPreference::ANY:
return ExecutionPreference_ANY;
case proto::ExecutionPreference::LOW_LATENCY:
return ExecutionPreference_LOW_LATENCY;
case proto::ExecutionPreference::LOW_POWER:
return ExecutionPreference_LOW_POWER;
case proto::ExecutionPreference::FORCE_CPU:
return ExecutionPreference_FORCE_CPU;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for ExecutionPreference: %d", preference);
return ExecutionPreference_ANY;
}
Delegate ConvertDelegate(proto::Delegate delegate) {
switch (delegate) {
case proto::Delegate::NONE:
return Delegate_NONE;
case proto::Delegate::NNAPI:
return Delegate_NNAPI;
case proto::Delegate::GPU:
return Delegate_GPU;
case proto::Delegate::HEXAGON:
return Delegate_HEXAGON;
case proto::Delegate::XNNPACK:
return Delegate_XNNPACK;
case proto::Delegate::EDGETPU:
return Delegate_EDGETPU;
case proto::Delegate::EDGETPU_CORAL:
return Delegate_EDGETPU_CORAL;
case proto::Delegate::CORE_ML:
return Delegate_CORE_ML;
case proto::Delegate::ARMNN:
return Delegate_ARMNN;
case proto::Delegate::MTK_NEURON:
return Delegate_MTK_NEURON;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Unexpected value for Delegate: %d",
delegate);
return Delegate_NONE;
}
NNAPIExecutionPreference ConvertNNAPIExecutionPreference(
proto::NNAPIExecutionPreference preference) {
switch (preference) {
case proto::NNAPIExecutionPreference::UNDEFINED:
return NNAPIExecutionPreference_UNDEFINED;
case proto::NNAPIExecutionPreference::NNAPI_LOW_POWER:
return NNAPIExecutionPreference_NNAPI_LOW_POWER;
case proto::NNAPIExecutionPreference::NNAPI_FAST_SINGLE_ANSWER:
return NNAPIExecutionPreference_NNAPI_FAST_SINGLE_ANSWER;
case proto::NNAPIExecutionPreference::NNAPI_SUSTAINED_SPEED:
return NNAPIExecutionPreference_NNAPI_SUSTAINED_SPEED;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for NNAPIExecutionPreference: %d",
preference);
return NNAPIExecutionPreference_UNDEFINED;
}
NNAPIExecutionPriority ConvertNNAPIExecutionPriority(
proto::NNAPIExecutionPriority priority) {
switch (priority) {
case proto::NNAPIExecutionPriority::NNAPI_PRIORITY_UNDEFINED:
return NNAPIExecutionPriority_NNAPI_PRIORITY_UNDEFINED;
case proto::NNAPIExecutionPriority::NNAPI_PRIORITY_LOW:
return NNAPIExecutionPriority_NNAPI_PRIORITY_LOW;
case proto::NNAPIExecutionPriority::NNAPI_PRIORITY_MEDIUM:
return NNAPIExecutionPriority_NNAPI_PRIORITY_MEDIUM;
case proto::NNAPIExecutionPriority::NNAPI_PRIORITY_HIGH:
return NNAPIExecutionPriority_NNAPI_PRIORITY_HIGH;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for NNAPIExecutionPriority: %d", priority);
return NNAPIExecutionPriority_NNAPI_PRIORITY_UNDEFINED;
}
GPUBackend ConvertGPUBackend(proto::GPUBackend backend) {
switch (backend) {
case proto::GPUBackend::UNSET:
return GPUBackend_UNSET;
case proto::GPUBackend::OPENCL:
return GPUBackend_OPENCL;
case proto::GPUBackend::OPENGL:
return GPUBackend_OPENGL;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Unexpected value for GPUBackend: %d",
backend);
return GPUBackend_UNSET;
}
GPUInferenceUsage ConvertGPUInferenceUsage(
proto::GPUInferenceUsage preference) {
switch (preference) {
case proto::GPUInferenceUsage::GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER:
return GPUInferenceUsage_GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER;
case proto::GPUInferenceUsage::GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED:
return GPUInferenceUsage_GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for GPUInferenceUsage: %d", preference);
return GPUInferenceUsage_GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER;
}
GPUInferencePriority ConvertGPUInferencePriority(
proto::GPUInferencePriority priority) {
switch (priority) {
case proto::GPUInferencePriority::GPU_PRIORITY_AUTO:
return GPUInferencePriority_GPU_PRIORITY_AUTO;
case proto::GPUInferencePriority::GPU_PRIORITY_MAX_PRECISION:
return GPUInferencePriority_GPU_PRIORITY_MAX_PRECISION;
case proto::GPUInferencePriority::GPU_PRIORITY_MIN_LATENCY:
return GPUInferencePriority_GPU_PRIORITY_MIN_LATENCY;
case proto::GPUInferencePriority::GPU_PRIORITY_MIN_MEMORY_USAGE:
return GPUInferencePriority_GPU_PRIORITY_MIN_MEMORY_USAGE;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for GPUInferencePriority: %d", priority);
return GPUInferencePriority_GPU_PRIORITY_AUTO;
}
EdgeTpuPowerState ConvertEdgeTpuPowerState(proto::EdgeTpuPowerState state) {
switch (state) {
case proto::EdgeTpuPowerState::UNDEFINED_POWERSTATE:
return EdgeTpuPowerState_UNDEFINED_POWERSTATE;
case proto::EdgeTpuPowerState::TPU_CORE_OFF:
return EdgeTpuPowerState_TPU_CORE_OFF;
case proto::EdgeTpuPowerState::READY:
return EdgeTpuPowerState_READY;
case proto::EdgeTpuPowerState::ACTIVE_MIN_POWER:
return EdgeTpuPowerState_ACTIVE_MIN_POWER;
case proto::EdgeTpuPowerState::ACTIVE_VERY_LOW_POWER:
return EdgeTpuPowerState_ACTIVE_VERY_LOW_POWER;
case proto::EdgeTpuPowerState::ACTIVE_LOW_POWER:
return EdgeTpuPowerState_ACTIVE_LOW_POWER;
case proto::EdgeTpuPowerState::ACTIVE:
return EdgeTpuPowerState_ACTIVE;
case proto::EdgeTpuPowerState::OVER_DRIVE:
return EdgeTpuPowerState_OVER_DRIVE;
}
TFLITE_LOG_PROD(TFLITE_LOG_ERROR,
"Unexpected value for EdgeTpuSettings::PowerState: %d",
state);
return EdgeTpuPowerState_UNDEFINED_POWERSTATE;
}
Offset<FallbackSettings> ConvertFallbackSettings(
const proto::FallbackSettings& settings, FlatBufferBuilder& builder) {
return CreateFallbackSettings(
builder, /*allow_automatic_fallback_on_compilation_error=*/
settings.allow_automatic_fallback_on_compilation_error(),
/*allow_automatic_fallback_on_execution_error=*/
settings.allow_automatic_fallback_on_execution_error());
}
Offset<NNAPISettings> ConvertNNAPISettings(const proto::NNAPISettings& settings,
FlatBufferBuilder& builder) {
return CreateNNAPISettings(
builder,
/*accelerator_name=*/builder.CreateString(settings.accelerator_name()),
/*cache_directory=*/builder.CreateString(settings.cache_directory()),
/*model_token=*/builder.CreateString(settings.model_token()),
ConvertNNAPIExecutionPreference(settings.execution_preference()),
/*no_of_nnapi_instances_to_cache=*/
settings.no_of_nnapi_instances_to_cache(),
ConvertFallbackSettings(settings.fallback_settings(), builder),
/*allow_nnapi_cpu_on_android_10_plus=*/
settings.allow_nnapi_cpu_on_android_10_plus(),
ConvertNNAPIExecutionPriority(settings.execution_priority()),
/*allow_dynamic_dimensions=*/
settings.allow_dynamic_dimensions(),
/*allow_fp16_precision_for_fp32=*/
settings.allow_fp16_precision_for_fp32(),
/*use_burst_computation=*/
settings.use_burst_computation(),
/*support_library_handle=*/
settings.support_library_handle());
}
Offset<GPUSettings> ConvertGPUSettings(const proto::GPUSettings& settings,
FlatBufferBuilder& builder) {
return CreateGPUSettings(
builder,
/*is_precision_loss_allowed=*/settings.is_precision_loss_allowed(),
/*enable_quantized_inference=*/settings.enable_quantized_inference(),
ConvertGPUBackend(settings.force_backend()),
ConvertGPUInferencePriority(settings.inference_priority1()),
ConvertGPUInferencePriority(settings.inference_priority2()),
ConvertGPUInferencePriority(settings.inference_priority3()),
ConvertGPUInferenceUsage(settings.inference_preference()),
/*cache_directory=*/builder.CreateString(settings.cache_directory()),
/*model_token=*/builder.CreateString(settings.model_token()));
}
Offset<HexagonSettings> ConvertHexagonSettings(
const proto::HexagonSettings& settings, FlatBufferBuilder& builder) {
return CreateHexagonSettings(
builder,
/*debug_level=*/settings.debug_level(),
/*powersave_level=*/settings.powersave_level(),
/*print_graph_profile=*/settings.print_graph_profile(),
/*print_graph_debug=*/settings.print_graph_debug());
}
Offset<XNNPackSettings> ConvertXNNPackSettings(
const proto::XNNPackSettings& settings, FlatBufferBuilder& builder) {
return CreateXNNPackSettings(
builder,
/*num_threads=*/settings.num_threads(),
/*flags=*/tflite::XNNPackFlags(settings.flags()));
}
Offset<CoreMLSettings> ConvertCoreMLSettings(
const proto::CoreMLSettings& settings, FlatBufferBuilder& builder) {
tflite::CoreMLSettings_::EnabledDevices enabled_devices =
tflite::CoreMLSettings_::EnabledDevices_DEVICES_ALL;
switch (settings.enabled_devices()) {
case proto::CoreMLSettings::DEVICES_ALL:
enabled_devices = tflite::CoreMLSettings_::EnabledDevices_DEVICES_ALL;
break;
case proto::CoreMLSettings::DEVICES_WITH_NEURAL_ENGINE:
enabled_devices =
tflite::CoreMLSettings_::EnabledDevices_DEVICES_WITH_NEURAL_ENGINE;
break;
default:
TFLITE_LOG_PROD(TFLITE_LOG_ERROR, "Invalid devices enum: %d",
settings.enabled_devices());
}
return CreateCoreMLSettings(
builder, enabled_devices, settings.coreml_version(),
settings.max_delegated_partitions(), settings.min_nodes_per_partition());
}
Offset<StableDelegateLoaderSettings> ConvertStableDelegateLoaderSettings(
const proto::StableDelegateLoaderSettings& settings,
FlatBufferBuilder& builder) {
return CreateStableDelegateLoaderSettings(
builder, builder.CreateString(settings.delegate_path()),
builder.CreateString(settings.delegate_name()));
}
Offset<CPUSettings> ConvertCPUSettings(const proto::CPUSettings& settings,
FlatBufferBuilder& builder) {
return CreateCPUSettings(builder,
/*num_threads=*/settings.num_threads());
}
Offset<tflite::EdgeTpuDeviceSpec> ConvertEdgeTpuDeviceSpec(
FlatBufferBuilder& builder, const proto::EdgeTpuDeviceSpec& device_spec) {
Offset<Vector<Offset<String>>> device_paths_fb = 0;
if (device_spec.device_paths_size() > 0) {
std::vector<Offset<String>> device_paths;
for (const auto& device_path : device_spec.device_paths()) {
auto device_path_fb = builder.CreateString(device_path);
device_paths.push_back(device_path_fb);
}
device_paths_fb = builder.CreateVector(device_paths);
}
return tflite::CreateEdgeTpuDeviceSpec(
builder,
static_cast<tflite::EdgeTpuDeviceSpec_::PlatformType>(
device_spec.platform_type()),
device_spec.num_chips(), device_paths_fb, device_spec.chip_family());
}
Offset<GoogleEdgeTpuSettings> ConvertGoogleEdgeTpuSettings(
const proto::GoogleEdgeTpuSettings& settings, FlatBufferBuilder& builder) {
Offset<String> model_identifier = 0;
if (settings.has_model_identifier()) {
model_identifier = builder.CreateString(settings.model_identifier());
}
Offset<Vector<uint8_t>> extension_data = 0;
if (settings.has_extension_data()) {
extension_data = builder.CreateVector(
reinterpret_cast<const uint8_t*>(settings.extension_data().data()),
settings.extension_data().size());
}
GoogleEdgeTpuSettingsBuilder builder_(builder);
builder_.add_log_verbosity(settings.log_verbosity());
builder_.add_enable_tracing(settings.enable_tracing());
builder_.add_priority(static_cast<tflite::GoogleEdgeTpuSettings_::Priority>(
settings.priority()));
builder_.add_model_identifier(model_identifier);
builder_.add_use_async_api(settings.use_async_api());
builder_.add_delegate_should_manage_cache_for_inputs(
settings.delegate_should_manage_cache_for_inputs());
builder_.add_delegate_should_manage_cache_for_outputs(
settings.delegate_should_manage_cache_for_outputs());
builder_.add_prefer_cache_coherency_for_inputs(
static_cast<tflite::GoogleEdgeTpuSettings_::TriState>(
settings.prefer_cache_coherency_for_inputs()));
builder_.add_prefer_cache_coherency_for_outputs(
static_cast<tflite::GoogleEdgeTpuSettings_::TriState>(
settings.prefer_cache_coherency_for_outputs()));
builder_.add_allow_fp16_precision_for_fp32(
settings.allow_fp16_precision_for_fp32());
builder_.add_extension_data(extension_data);
return builder_.Finish();
}
Offset<EdgeTpuSettings> ConvertEdgeTpuSettings(
const proto::EdgeTpuSettings& settings, FlatBufferBuilder& builder) {
Offset<Vector<Offset<tflite::EdgeTpuInactivePowerConfig>>>
inactive_power_configs = 0;
// Uses std vector to first construct the list and creates the flatbuffer
// offset from it later.
std::vector<Offset<tflite::EdgeTpuInactivePowerConfig>>
inactive_power_configs_std;
if (settings.inactive_power_configs_size() > 0) {
for (const auto& config : settings.inactive_power_configs()) {
inactive_power_configs_std.push_back(
tflite::CreateEdgeTpuInactivePowerConfig(
builder,
static_cast<tflite::EdgeTpuPowerState>(
config.inactive_power_state()),
config.inactive_timeout_us()));
}
inactive_power_configs =
builder.CreateVector<Offset<tflite::EdgeTpuInactivePowerConfig>>(
inactive_power_configs_std);
}
Offset<tflite::EdgeTpuDeviceSpec> edgetpu_device_spec = 0;
if (settings.has_edgetpu_device_spec()) {
edgetpu_device_spec =
ConvertEdgeTpuDeviceSpec(builder, settings.edgetpu_device_spec());
}
Offset<String> model_token = 0;
if (settings.has_model_token()) {
model_token = builder.CreateString(settings.model_token());
}
// First convert to std::vector, then convert to flatbuffer.
std::vector<int32_t> hardware_cluster_ids_std{
settings.hardware_cluster_ids().begin(),
settings.hardware_cluster_ids().end()};
auto hardware_cluster_ids_fb =
builder.CreateVector<int32_t>(hardware_cluster_ids_std);
Offset<String> public_model_id = 0;
if (settings.has_public_model_id()) {
public_model_id = builder.CreateString(settings.public_model_id());
}
return CreateEdgeTpuSettings(
builder, ConvertEdgeTpuPowerState(settings.inference_power_state()),
inactive_power_configs, settings.inference_priority(),
edgetpu_device_spec, model_token,
static_cast<tflite::EdgeTpuSettings_::FloatTruncationType>(
settings.float_truncation_type()),
static_cast<tflite::EdgeTpuSettings_::QosClass>(settings.qos_class()),
hardware_cluster_ids_fb, public_model_id,
static_cast<tflite::EdgeTpuSettings_::UseLayerIrTgcBackend>(
settings.use_layer_ir_tgc_backend()),
settings.use_tpu_server());
}
Offset<CompilationCachingSettings> ConvertCompilationCachingSettings(
const proto::CompilationCachingSettings& settings,
FlatBufferBuilder& builder) {
return CreateCompilationCachingSettings(
builder, builder.CreateString(settings.cache_dir()),
builder.CreateString(settings.model_token()));
}
Offset<ArmNNSettings> ConvertArmNNSettings(const proto::ArmNNSettings& settings,
FlatBufferBuilder& builder) {
return CreateArmNNSettings(
builder, builder.CreateString(settings.backends()), settings.fastmath(),
builder.CreateString(settings.additional_parameters()));
}
Offset<MtkNeuronSettings> ConvertMtkNeuronSettings(
const proto::MtkNeuronSettings& settings, FlatBufferBuilder& builder) {
return CreateMtkNeuronSettings(
builder,
static_cast<MtkNeuronSettings_::ExecutionPreference>(
settings.execution_preference()),
static_cast<MtkNeuronSettings_::ExecutionPriority>(
settings.execution_priority()),
builder.CreateVector(settings.optimization_hints().data(),
settings.optimization_hints().size()),
static_cast<MtkNeuronSettings_::OperationCheckMode>(
settings.operation_check_mode()),
settings.allow_fp16_precision_for_fp32(), settings.use_ahwb(),
settings.use_cacheable_buffer(),
builder.CreateVectorOfStrings(settings.compile_options().begin(),
settings.compile_options().end()),
builder.CreateVectorOfStrings(settings.accelerator_names().begin(),
settings.accelerator_names().end()),
builder.CreateString(settings.neuron_config_path()),
settings.inference_deadline_ms(), settings.inference_abort_time_ms());
}
Offset<CoralSettings> ConvertCoralSettings(const proto::CoralSettings& settings,
FlatBufferBuilder& builder) {
return CreateCoralSettings(
builder, builder.CreateString(settings.device()),
static_cast<tflite::CoralSettings_::Performance>(settings.performance()),
settings.usb_always_dfu(), settings.usb_max_bulk_in_queue_length());
}
Offset<TFLiteSettings> ConvertTfliteSettings(
const proto::TFLiteSettings& settings, FlatBufferBuilder& builder) {
return CreateTFLiteSettings(
builder, ConvertDelegate(settings.delegate()),
ConvertNNAPISettings(settings.nnapi_settings(), builder),
ConvertGPUSettings(settings.gpu_settings(), builder),
ConvertHexagonSettings(settings.hexagon_settings(), builder),
ConvertXNNPackSettings(settings.xnnpack_settings(), builder),
ConvertCoreMLSettings(settings.coreml_settings(), builder),
ConvertCPUSettings(settings.cpu_settings(), builder),
/*max_delegated_partitions=*/settings.max_delegated_partitions(),
ConvertEdgeTpuSettings(settings.edgetpu_settings(), builder),
ConvertCoralSettings(settings.coral_settings(), builder),
ConvertFallbackSettings(settings.fallback_settings(), builder),
settings.disable_default_delegates(),
ConvertStableDelegateLoaderSettings(
settings.stable_delegate_loader_settings(), builder),
ConvertGoogleEdgeTpuSettings(settings.google_edgetpu_settings(), builder),
ConvertCompilationCachingSettings(settings.compilation_caching_settings(),
builder),
ConvertArmNNSettings(settings.armnn_settings(), builder),
ConvertMtkNeuronSettings(settings.mtk_neuron_settings(), builder));
}
Offset<ModelFile> ConvertModelFile(const proto::ModelFile& model_file,
FlatBufferBuilder& builder) {
return CreateModelFile(builder, builder.CreateString(model_file.filename()),
model_file.fd(), model_file.offset(),
model_file.length());
}
Offset<BenchmarkStoragePaths> ConvertBenchmarkStoragePaths(
const proto::BenchmarkStoragePaths& storage_paths,
FlatBufferBuilder& builder) {
return CreateBenchmarkStoragePaths(
builder, builder.CreateString(storage_paths.storage_file_path()),
builder.CreateString(storage_paths.data_directory_path()));
}
Offset<MinibenchmarkSettings> ConvertMinibenchmarkSettings(
const proto::MinibenchmarkSettings& settings, FlatBufferBuilder& builder) {
Offset<Vector<Offset<TFLiteSettings>>> settings_to_test = 0;
std::vector<Offset<TFLiteSettings>> settings_to_test_vec;
if (settings.settings_to_test_size() > 0) {
for (const auto& one : settings.settings_to_test()) {
settings_to_test_vec.push_back(ConvertTfliteSettings(one, builder));
}
settings_to_test =
builder.CreateVector<Offset<TFLiteSettings>>(settings_to_test_vec);
}
return CreateMinibenchmarkSettings(
builder, settings_to_test,
ConvertModelFile(settings.model_file(), builder),
ConvertBenchmarkStoragePaths(settings.storage_paths(), builder));
}
const TFLiteSettings* ConvertFromProto(
const proto::TFLiteSettings& proto_settings, FlatBufferBuilder* builder) {
Offset<TFLiteSettings> settings =
ConvertTfliteSettings(proto_settings, *builder);
return flatbuffers::GetTemporaryPointer(*builder, settings);
}
const ComputeSettings* ConvertFromProto(
const proto::ComputeSettings& proto_settings, FlatBufferBuilder* builder) {
auto settings = CreateComputeSettings(
*builder, ConvertExecutionPreference(proto_settings.preference()),
ConvertTfliteSettings(proto_settings.tflite_settings(), *builder),
builder->CreateString(proto_settings.model_namespace_for_statistics()),
builder->CreateString(proto_settings.model_identifier_for_statistics()),
ConvertMinibenchmarkSettings(proto_settings.settings_to_test_locally(),
*builder));
return flatbuffers::GetTemporaryPointer(*builder, settings);
}
const MinibenchmarkSettings* ConvertFromProto(
const proto::MinibenchmarkSettings& proto_settings,
flatbuffers::FlatBufferBuilder* builder) {
auto settings = ConvertMinibenchmarkSettings(proto_settings, *builder);
return flatbuffers::GetTemporaryPointer(*builder, settings);
}
} // namespace tflite
@@ -0,0 +1,47 @@
/* 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_ACCELERATION_CONFIGURATION_PROTO_TO_FLATBUFFER_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_PROTO_TO_FLATBUFFER_H_
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/acceleration/configuration/configuration.pb.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
namespace tflite {
// Converts the provided TFLiteSettings from proto to flatbuffer format.
// The returned TFLiteSettings pointer is only valid until either the
// FlatBufferBuilder is modified or when the FlatBufferBuilder's lifetime ends.
const TFLiteSettings* ConvertFromProto(
const proto::TFLiteSettings& proto_settings,
flatbuffers::FlatBufferBuilder* builder);
// Converts the provided ComputeSettings from proto to flatbuffer format.
// The returned ComputeSettings pointer is only valid until either the
// FlatBufferBuilder is modified or when the FlatBufferBuilder's lifetime ends.
const ComputeSettings* ConvertFromProto(
const proto::ComputeSettings& proto_settings,
flatbuffers::FlatBufferBuilder* builder);
// Converts the provided MiniBenchmarkSettings from proto to flatbuffer format.
// The returned MinibenchmarkSettings pointer is only valid until either the
// FlatBufferBuilder is modified or when the FlatBufferBuilder's lifetime ends.
const MinibenchmarkSettings* ConvertFromProto(
const proto::MinibenchmarkSettings& proto_settings,
flatbuffers::FlatBufferBuilder* builder);
} // namespace tflite
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_PROTO_TO_FLATBUFFER_H_
@@ -0,0 +1,249 @@
/* 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/acceleration/configuration/proto_to_flatbuffer.h"
#include <cstdint>
#include <string>
#include <vector>
#include <gtest/gtest.h>
#include "tensorflow/lite/acceleration/configuration/configuration.pb.h"
namespace tflite {
namespace {
// Tests converting EdgeTpuSettings from proto to flatbuffer format.
TEST(ConversionTest, EdgeTpuSettings) {
// Define the fields to be tested.
const std::vector<int32_t> kHardwareClusterIds{1};
const std::string kPublicModelId = "public_model_id";
const tflite::proto::EdgeTpuSettings_UseLayerIrTgcBackend
kUseLayerIrTgcBackend =
tflite::proto::EdgeTpuSettings::USE_LAYER_IR_TGC_BACKEND_YES;
const bool kUseTpuServer = true;
// Create the proto settings.
proto::ComputeSettings input_settings;
auto* edgetpu_settings =
input_settings.mutable_tflite_settings()->mutable_edgetpu_settings();
edgetpu_settings->set_public_model_id(kPublicModelId);
edgetpu_settings->set_use_layer_ir_tgc_backend(kUseLayerIrTgcBackend);
flatbuffers::FlatBufferBuilder flatbuffers_builder;
*edgetpu_settings->mutable_hardware_cluster_ids() = {
kHardwareClusterIds.begin(), kHardwareClusterIds.end()};
edgetpu_settings->set_use_tpu_server(kUseTpuServer);
// Convert.
auto output_settings = ConvertFromProto(input_settings, &flatbuffers_builder)
->tflite_settings()
->edgetpu_settings();
// Verify the conversion results.
EXPECT_EQ(output_settings->hardware_cluster_ids()->size(), 1);
EXPECT_EQ(output_settings->hardware_cluster_ids()->Get(0),
kHardwareClusterIds[0]);
EXPECT_EQ(output_settings->public_model_id()->str(), kPublicModelId);
EXPECT_EQ(output_settings->use_layer_ir_tgc_backend(),
tflite::EdgeTpuSettings_::
UseLayerIrTgcBackend_USE_LAYER_IR_TGC_BACKEND_YES);
EXPECT_EQ(output_settings->use_tpu_server(), kUseTpuServer);
}
// Tests converting TFLiteSettings from proto to flatbuffer format.
TEST(ConversionTest, TFLiteSettings) {
// Define the fields to be tested.
const std::vector<int32_t> kHardwareClusterIds{1};
const std::string kPublicModelId = "public_model_id";
const tflite::proto::EdgeTpuSettings_UseLayerIrTgcBackend
kUseLayerIrTgcBackend =
tflite::proto::EdgeTpuSettings::USE_LAYER_IR_TGC_BACKEND_YES;
// Create the proto settings.
proto::TFLiteSettings input_settings;
input_settings.set_delegate(::tflite::proto::EDGETPU);
auto* edgetpu_settings = input_settings.mutable_edgetpu_settings();
edgetpu_settings->set_public_model_id(kPublicModelId);
edgetpu_settings->set_use_layer_ir_tgc_backend(kUseLayerIrTgcBackend);
flatbuffers::FlatBufferBuilder flatbuffers_builder;
*edgetpu_settings->mutable_hardware_cluster_ids() = {
kHardwareClusterIds.begin(), kHardwareClusterIds.end()};
// Convert.
auto output_settings = ConvertFromProto(input_settings, &flatbuffers_builder);
// Verify the conversion results.
EXPECT_EQ(output_settings->delegate(), ::tflite::Delegate_EDGETPU);
const auto* output_edgetpu_settings = output_settings->edgetpu_settings();
EXPECT_EQ(output_edgetpu_settings->hardware_cluster_ids()->size(), 1);
EXPECT_EQ(output_edgetpu_settings->hardware_cluster_ids()->Get(0),
kHardwareClusterIds[0]);
EXPECT_EQ(output_edgetpu_settings->public_model_id()->str(), kPublicModelId);
EXPECT_EQ(output_edgetpu_settings->use_layer_ir_tgc_backend(),
tflite::EdgeTpuSettings_::
UseLayerIrTgcBackend_USE_LAYER_IR_TGC_BACKEND_YES);
}
TEST(ConversionTest, StableDelegateLoaderSettings) {
// Define the fields to be tested.
const std::string kDelegatePath = "TEST_DELEGATE_PATH";
const std::string kDelegateName = "TEST_DELEGATE_NAME";
// Create the proto settings.
proto::TFLiteSettings input_settings;
auto* stable_delegate_loader_settings =
input_settings.mutable_stable_delegate_loader_settings();
stable_delegate_loader_settings->set_delegate_path(kDelegatePath);
stable_delegate_loader_settings->set_delegate_name(kDelegateName);
flatbuffers::FlatBufferBuilder flatbuffers_builder;
// Convert.
auto output_settings = ConvertFromProto(input_settings, &flatbuffers_builder);
// Verify the conversion results.
const auto* output_stable_delegate_loader_settings =
output_settings->stable_delegate_loader_settings();
ASSERT_NE(output_stable_delegate_loader_settings, nullptr);
EXPECT_EQ(output_stable_delegate_loader_settings->delegate_path()->str(),
kDelegatePath);
EXPECT_EQ(output_stable_delegate_loader_settings->delegate_name()->str(),
kDelegateName);
}
TEST(ConversionTest, CompilationCachingSettings) {
// Define the fields to be tested.
const std::string kCacheDir = "TEST_CACHE_DIR";
const std::string kModelToken = "TEST_MODEL_TOKEN";
// Create the proto settings.
proto::TFLiteSettings input_settings;
auto* compilation_caching_settings =
input_settings.mutable_compilation_caching_settings();
compilation_caching_settings->set_cache_dir(kCacheDir);
compilation_caching_settings->set_model_token(kModelToken);
flatbuffers::FlatBufferBuilder flatbuffers_builder;
// Convert.
auto output_settings = ConvertFromProto(input_settings, &flatbuffers_builder);
// Verify the conversion results.
const auto* output_compilation_caching_settings =
output_settings->compilation_caching_settings();
ASSERT_NE(output_compilation_caching_settings, nullptr);
EXPECT_EQ(output_compilation_caching_settings->cache_dir()->str(), kCacheDir);
EXPECT_EQ(output_compilation_caching_settings->model_token()->str(),
kModelToken);
}
TEST(ConversionTest, ArmNNSettings) {
// Define the fields to be tested.
const std::string kBackends = "TEST_BACKENDS";
const bool kFastmath = true;
const std::string kAdditionalParameters = "TEST_ADDITIONAL_PARAMETERS";
// Create the proto settings.
proto::TFLiteSettings input_settings;
auto* armnn_settings = input_settings.mutable_armnn_settings();
armnn_settings->set_backends(kBackends);
armnn_settings->set_fastmath(kFastmath);
armnn_settings->set_additional_parameters(kAdditionalParameters);
flatbuffers::FlatBufferBuilder flatbuffers_builder;
// Convert.
auto output_settings = ConvertFromProto(input_settings, &flatbuffers_builder);
// Verify the conversion results.
const auto* output_armnn_settings = output_settings->armnn_settings();
ASSERT_NE(output_armnn_settings, nullptr);
EXPECT_EQ(output_armnn_settings->backends()->str(), kBackends);
EXPECT_EQ(output_armnn_settings->fastmath(), kFastmath);
EXPECT_EQ(output_armnn_settings->additional_parameters()->str(),
kAdditionalParameters);
}
TEST(ConversionTest, MtkNeuronSettings) {
// Define the fields to be tested.
const proto::MtkNeuronSettings_ExecutionPreference kExecutionPreference =
proto::MtkNeuronSettings::PREFERENCE_FAST_SINGLE_ANSWER;
const proto::MtkNeuronSettings_ExecutionPriority kExecutionPriority =
proto::MtkNeuronSettings::PRIORITY_MEDIUM;
const proto::MtkNeuronSettings_OptimizationHint kOptimizationHint =
proto::MtkNeuronSettings::OPTIMIZATION_LOW_LATENCY;
const proto::MtkNeuronSettings_OperationCheckMode kOperationCheckMode =
proto::MtkNeuronSettings::PER_NODE_OPERATION_CHECK;
const bool kAllowFp16 = true;
const bool kUseAhwb = false;
const bool kUseCacheableBuffer = true;
const std::string kCompileOptions = "TEST_COMPILE_OPTIONS";
const std::string kAcceleratorName = "TEST_ACCELERATOR_NAME";
const std::string kNeuronConfigPath = "TEST_NEURON_CONFIG_PATH";
const int32_t kInferenceDeadlineMs = 1337;
const int32_t kInferenceAbortTimeMs = 42;
// Create the proto settings.
proto::TFLiteSettings input_settings;
auto* mtk_neuron_settings = input_settings.mutable_mtk_neuron_settings();
mtk_neuron_settings->set_execution_preference(kExecutionPreference);
mtk_neuron_settings->set_execution_priority(kExecutionPriority);
mtk_neuron_settings->add_optimization_hints(kOptimizationHint);
mtk_neuron_settings->set_operation_check_mode(kOperationCheckMode);
mtk_neuron_settings->set_allow_fp16_precision_for_fp32(kAllowFp16);
mtk_neuron_settings->set_use_ahwb(kUseAhwb);
mtk_neuron_settings->set_use_cacheable_buffer(kUseCacheableBuffer);
mtk_neuron_settings->add_compile_options(kCompileOptions);
mtk_neuron_settings->add_accelerator_names(kAcceleratorName);
mtk_neuron_settings->set_neuron_config_path(kNeuronConfigPath);
mtk_neuron_settings->set_inference_deadline_ms(kInferenceDeadlineMs);
mtk_neuron_settings->set_inference_abort_time_ms(kInferenceAbortTimeMs);
flatbuffers::FlatBufferBuilder flatbuffers_builder;
// Convert.
auto output_settings = ConvertFromProto(input_settings, &flatbuffers_builder);
// Verify the conversion results.
const auto* output_mtk_neuron_settings =
output_settings->mtk_neuron_settings();
ASSERT_NE(output_mtk_neuron_settings, nullptr);
EXPECT_EQ(
output_mtk_neuron_settings->execution_preference(),
MtkNeuronSettings_::ExecutionPreference_PREFERENCE_FAST_SINGLE_ANSWER);
EXPECT_EQ(output_mtk_neuron_settings->execution_priority(),
MtkNeuronSettings_::ExecutionPriority_PRIORITY_MEDIUM);
EXPECT_EQ(output_mtk_neuron_settings->optimization_hints()->size(), 1);
EXPECT_EQ(output_mtk_neuron_settings->optimization_hints()->Get(0),
kOptimizationHint);
EXPECT_EQ(output_mtk_neuron_settings->operation_check_mode(),
MtkNeuronSettings_::OperationCheckMode_PER_NODE_OPERATION_CHECK);
EXPECT_EQ(output_mtk_neuron_settings->allow_fp16_precision_for_fp32(),
kAllowFp16);
EXPECT_EQ(output_mtk_neuron_settings->use_ahwb(), kUseAhwb);
EXPECT_EQ(output_mtk_neuron_settings->use_cacheable_buffer(),
kUseCacheableBuffer);
EXPECT_EQ(output_mtk_neuron_settings->compile_options()->size(), 1);
EXPECT_EQ(output_mtk_neuron_settings->compile_options()->Get(0)->str(),
kCompileOptions);
EXPECT_EQ(output_mtk_neuron_settings->accelerator_names()->size(), 1);
EXPECT_EQ(output_mtk_neuron_settings->accelerator_names()->Get(0)->str(),
kAcceleratorName);
EXPECT_EQ(output_mtk_neuron_settings->neuron_config_path()->str(),
kNeuronConfigPath);
EXPECT_EQ(output_mtk_neuron_settings->inference_deadline_ms(),
kInferenceDeadlineMs);
EXPECT_EQ(output_mtk_neuron_settings->inference_abort_time_ms(),
kInferenceAbortTimeMs);
}
} // namespace
} // namespace tflite
@@ -0,0 +1,27 @@
/* 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.
==============================================================================*/
// This file implements the TFLite Delegate Plugin for the NNAPI Delegate.
#include "tensorflow/lite/acceleration/configuration/stable_delegate_plugin.h"
namespace tflite {
namespace delegates {
TFLITE_REGISTER_DELEGATE_FACTORY_FUNCTION(StableDelegatePlugin,
StableDelegatePlugin::New);
} // namespace delegates
} // namespace tflite
@@ -0,0 +1,114 @@
/* 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_ACCELERATION_CONFIGURATION_STABLE_DELEGATE_PLUGIN_H_
#define TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_STABLE_DELEGATE_PLUGIN_H_
// This file provides the StableDelegatePlugin class, which implements the
// TFLite Delegate Plugin Interface for the stable delegates.
#include <memory>
#include <string>
#include "flatbuffers/flatbuffers.h"
#include "tensorflow/lite/acceleration/configuration/c/delegate_plugin.h"
#include "tensorflow/lite/acceleration/configuration/c/stable_delegate.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/core/acceleration/configuration/delegate_registry.h"
#include "tensorflow/lite/delegates/utils/experimental/stable_delegate/delegate_loader.h"
#include "tensorflow/lite/tools/logging.h"
namespace tflite {
namespace delegates {
class StableDelegatePlugin : public DelegatePluginInterface {
public:
static std::unique_ptr<StableDelegatePlugin> New(
const TFLiteSettings& tflite_settings) {
return std::make_unique<StableDelegatePlugin>(tflite_settings);
}
explicit StableDelegatePlugin(const TFLiteSettings& tflite_settings) {
const StableDelegateLoaderSettings* stable_delegate_loader_settings =
tflite_settings.stable_delegate_loader_settings();
if (!stable_delegate_loader_settings ||
!stable_delegate_loader_settings->delegate_path() ||
stable_delegate_loader_settings->delegate_path()->size() == 0) {
TFLITE_LOG(ERROR) << "The delegate path field is not available from the "
"provided stable delegate loader settings.";
return;
}
// Creates a copy of TFLiteSettings within the stable delegate plugin.
TFLiteSettingsT tflite_settings_t;
tflite_settings.UnPackTo(&tflite_settings_t);
tflite_settings_builder_.Finish(
CreateTFLiteSettings(tflite_settings_builder_, &tflite_settings_t));
const TfLiteStableDelegate* stable_delegate =
utils::LoadDelegateFromSharedLibrary(
stable_delegate_loader_settings->delegate_path()->str());
if (!stable_delegate) {
TFLITE_LOG(ERROR)
<< "Failed to load stable delegate plugin symbol from "
<< stable_delegate_loader_settings->delegate_path()->str();
return;
}
if (!stable_delegate->delegate_plugin || !stable_delegate->delegate_name) {
TFLITE_LOG(ERROR)
<< "Invalid stable delegate struct loaded from "
<< stable_delegate_loader_settings->delegate_path()->str();
return;
}
stable_delegate_plugin_ = stable_delegate->delegate_plugin;
TFLITE_LOG(INFO)
<< "The stable delegate plugin has loaded delegate plugin for "
<< stable_delegate->delegate_name;
}
TfLiteDelegatePtr Create() override {
if (!stable_delegate_plugin_ || !stable_delegate_plugin_->create ||
!stable_delegate_plugin_->destroy) {
return TfLiteDelegatePtr(nullptr, [](TfLiteDelegate*) {});
}
return TfLiteDelegatePtr(
reinterpret_cast<TfLiteDelegate*>(
stable_delegate_plugin_->create(GetTFLiteSettings())),
reinterpret_cast<void (*)(TfLiteDelegate*)>(
stable_delegate_plugin_->destroy));
}
int GetDelegateErrno(TfLiteDelegate* from_delegate) override {
if (!stable_delegate_plugin_ ||
!stable_delegate_plugin_->get_delegate_errno) {
return 0;
}
return stable_delegate_plugin_->get_delegate_errno(
reinterpret_cast<TfLiteOpaqueDelegate*>(from_delegate));
}
private:
const TFLiteSettings* GetTFLiteSettings() const {
return flatbuffers::GetRoot<TFLiteSettings>(
tflite_settings_builder_.GetBufferPointer());
}
const TfLiteOpaqueDelegatePlugin* stable_delegate_plugin_ = nullptr;
flatbuffers::FlatBufferBuilder tflite_settings_builder_;
};
} // namespace delegates
} // namespace tflite
#endif // TENSORFLOW_LITE_ACCELERATION_CONFIGURATION_STABLE_DELEGATE_PLUGIN_H_
@@ -0,0 +1,159 @@
/* 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.
==============================================================================*/
// Some very simple unit tests of the Stable Delegate Plugin.
#include "tensorflow/lite/acceleration/configuration/stable_delegate_plugin.h"
#include <memory>
#include <string>
#include "flatbuffers/flatbuffers.h"
#include <gtest/gtest.h>
#include "pthreadpool.h" // from @pthreadpool
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/core/acceleration/configuration/delegate_registry.h"
#include "tensorflow/lite/delegates/xnnpack/xnnpack_delegate.h"
namespace tflite {
class StableDelegatePluginTest : public testing::Test {
public:
static constexpr int kNumThreadsForTest = 7;
static constexpr XNNPackFlags kFlagsForTest =
XNNPackFlags_TFLITE_XNNPACK_DELEGATE_FLAG_QS8_QU8;
static constexpr char kDelegateBinaryPath[] =
"tensorflow/lite/delegates/utils/experimental/"
"stable_delegate/libtensorflowlite_stable_xnnpack_delegate.so";
void SetUp() override {
// Construct a FlatBuffer that contains
// TFLiteSettings {
// delegate: Delegate.XNNPACK,
// XNNPackSettings { num_threads: kNumThreadsForTest
// flags: TFLITE_XNNPACK_DELEGATE_FLAG_QS8 |
// TFLITE_XNNPACK_DELEGATE_FLAG_QU8
// },
// StableDelegateLoaderSettings { delegate_path: kDelegateBinaryPath }
// }.
// We use the stable XNNPack delegate binary for testing stable delegate
// provider.
flatbuffers::Offset<flatbuffers::String> stable_delegate_path_offset =
flatbuffer_builder_.CreateString(kDelegateBinaryPath);
StableDelegateLoaderSettingsBuilder stable_delegate_loader_settings_builder(
flatbuffer_builder_);
stable_delegate_loader_settings_builder.add_delegate_path(
stable_delegate_path_offset);
flatbuffers::Offset<StableDelegateLoaderSettings>
stable_delegate_loader_settings =
stable_delegate_loader_settings_builder.Finish();
XNNPackSettingsBuilder xnnpack_settings_builder(flatbuffer_builder_);
xnnpack_settings_builder.add_num_threads(kNumThreadsForTest);
xnnpack_settings_builder.add_flags(kFlagsForTest);
flatbuffers::Offset<XNNPackSettings> xnnpack_settings =
xnnpack_settings_builder.Finish();
TFLiteSettingsBuilder tflite_settings_builder(flatbuffer_builder_);
tflite_settings_builder.add_stable_delegate_loader_settings(
stable_delegate_loader_settings);
tflite_settings_builder.add_xnnpack_settings(xnnpack_settings);
// Stable delegate plugin doesn't rely on the delegate specified in the
// TFLiteSettings provided.
tflite_settings_builder.add_delegate(Delegate_XNNPACK);
flatbuffers::Offset<TFLiteSettings> tflite_settings =
tflite_settings_builder.Finish();
flatbuffer_builder_.Finish(tflite_settings);
tflite_settings_ = flatbuffers::GetRoot<TFLiteSettings>(
flatbuffer_builder_.GetBufferPointer());
// Create a stable delegate plugin for an XNNPack delegate using the
// settings from the flatbuffer.
delegate_plugin_ = delegates::DelegatePluginRegistry::CreateByName(
"StableDelegatePlugin", *tflite_settings_);
ASSERT_NE(delegate_plugin_, nullptr);
}
protected:
// tflite_settings_ points into storage owned by flatbuffer_builder_.
flatbuffers::FlatBufferBuilder flatbuffer_builder_;
const TFLiteSettings* tflite_settings_;
std::unique_ptr<delegates::DelegatePluginInterface> delegate_plugin_;
};
TEST_F(StableDelegatePluginTest, CanCreateAndDestroyDelegate) {
delegates::TfLiteDelegatePtr delegate = delegate_plugin_->Create();
EXPECT_NE(delegate, nullptr);
}
TEST_F(StableDelegatePluginTest, CanGetDelegateErrno) {
delegates::TfLiteDelegatePtr delegate = delegate_plugin_->Create();
ASSERT_NE(delegate, nullptr);
EXPECT_EQ(delegate_plugin_->GetDelegateErrno(delegate.get()), 0);
}
TEST_F(StableDelegatePluginTest, SetsCorrectThreadCount) {
delegates::TfLiteDelegatePtr delegate = delegate_plugin_->Create();
ASSERT_NE(delegate, nullptr);
pthreadpool_t threadpool = static_cast<pthreadpool_t>(
TfLiteXNNPackDelegateGetThreadPool(delegate.get()));
ASSERT_NE(threadpool, nullptr);
EXPECT_EQ(pthreadpool_get_threads_count(threadpool), kNumThreadsForTest);
}
static std::unique_ptr<delegates::DelegatePluginInterface>
CreatePluginWithDelegatePath(const std::string& delegate_path) {
flatbuffers::FlatBufferBuilder flatbuffer_builder;
flatbuffers::Offset<flatbuffers::String> stable_delegate_path_offset =
delegate_path.empty() ? 0
: flatbuffer_builder.CreateString(delegate_path);
StableDelegateLoaderSettingsBuilder stable_delegate_loader_settings_builder(
flatbuffer_builder);
if (stable_delegate_path_offset.o != 0) {
stable_delegate_loader_settings_builder.add_delegate_path(
stable_delegate_path_offset);
}
flatbuffers::Offset<StableDelegateLoaderSettings>
stable_delegate_loader_settings =
stable_delegate_loader_settings_builder.Finish();
TFLiteSettingsBuilder tflite_settings_builder(flatbuffer_builder);
tflite_settings_builder.add_stable_delegate_loader_settings(
stable_delegate_loader_settings);
tflite_settings_builder.add_delegate(Delegate_XNNPACK);
flatbuffers::Offset<TFLiteSettings> tflite_settings =
tflite_settings_builder.Finish();
flatbuffer_builder.Finish(tflite_settings);
const TFLiteSettings* settings = flatbuffers::GetRoot<TFLiteSettings>(
flatbuffer_builder.GetBufferPointer());
return delegates::DelegatePluginRegistry::CreateByName("StableDelegatePlugin",
*settings);
}
TEST(StableDelegatePluginNullTest, MissingDelegatePath) {
std::unique_ptr<delegates::DelegatePluginInterface> delegate_plugin =
CreatePluginWithDelegatePath("");
ASSERT_NE(delegate_plugin, nullptr);
EXPECT_EQ(delegate_plugin->Create(), nullptr);
EXPECT_EQ(delegate_plugin->GetDelegateErrno(nullptr), 0);
}
TEST(StableDelegatePluginNullTest, InvalidDelegatePath) {
std::unique_ptr<delegates::DelegatePluginInterface> delegate_plugin =
CreatePluginWithDelegatePath("invalid_path.so");
ASSERT_NE(delegate_plugin, nullptr);
EXPECT_EQ(delegate_plugin->Create(), nullptr);
EXPECT_EQ(delegate_plugin->GetDelegateErrno(nullptr), 0);
}
} // namespace tflite
@@ -0,0 +1,355 @@
// 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.
// Generated from configuration.proto
namespace tflite;
enum ExecutionPreference : int {
ANY = 0,
LOW_LATENCY = 1,
LOW_POWER = 2,
FORCE_CPU = 3,
}
enum Delegate : int {
NONE = 0,
NNAPI = 1,
GPU = 2,
HEXAGON = 3,
XNNPACK = 4,
EDGETPU = 5,
EDGETPU_CORAL = 6,
CORE_ML = 7,
}
enum NNAPIExecutionPreference : int {
UNDEFINED = 0,
NNAPI_LOW_POWER = 1,
NNAPI_FAST_SINGLE_ANSWER = 2,
NNAPI_SUSTAINED_SPEED = 3,
}
enum NNAPIExecutionPriority : int {
NNAPI_PRIORITY_UNDEFINED = 0,
NNAPI_PRIORITY_LOW = 1,
NNAPI_PRIORITY_MEDIUM = 2,
NNAPI_PRIORITY_HIGH = 3,
}
enum GPUBackend : int {
UNSET = 0,
OPENCL = 1,
OPENGL = 2,
}
enum GPUInferencePriority : int {
GPU_PRIORITY_AUTO = 0,
GPU_PRIORITY_MAX_PRECISION = 1,
GPU_PRIORITY_MIN_LATENCY = 2,
GPU_PRIORITY_MIN_MEMORY_USAGE = 3,
}
enum GPUInferenceUsage : int {
GPU_INFERENCE_PREFERENCE_FAST_SINGLE_ANSWER = 0,
GPU_INFERENCE_PREFERENCE_SUSTAINED_SPEED = 1,
}
enum XNNPackFlags : int {
TFLITE_XNNPACK_DELEGATE_NO_FLAGS = 0,
TFLITE_XNNPACK_DELEGATE_FLAG_QS8 = 1,
TFLITE_XNNPACK_DELEGATE_FLAG_QU8 = 2,
TFLITE_XNNPACK_DELEGATE_FLAG_QS8_QU8 = 3,
TFLITE_XNNPACK_DELEGATE_FLAG_FORCE_FP16 = 4,
}
namespace tflite.CoreMLSettings_;
enum EnabledDevices : int {
DEVICES_ALL = 0,
DEVICES_WITH_NEURAL_ENGINE = 1,
}
namespace tflite.EdgeTpuDeviceSpec_;
enum PlatformType : int {
MMIO = 0,
REFERENCE = 1,
SIMULATOR = 2,
REMOTE_SIMULATOR = 3,
}
namespace tflite;
enum EdgeTpuPowerState : int {
UNDEFINED_POWERSTATE = 0,
TPU_CORE_OFF = 1,
READY = 2,
ACTIVE_MIN_POWER = 3,
ACTIVE_VERY_LOW_POWER = 4,
ACTIVE_LOW_POWER = 5,
ACTIVE = 6,
OVER_DRIVE = 7,
}
namespace tflite.EdgeTpuSettings_;
enum FloatTruncationType : int {
UNSPECIFIED = 0,
NO_TRUNCATION = 1,
BFLOAT16 = 2,
HALF = 3,
}
enum QosClass : int {
QOS_UNDEFINED = 0,
BEST_EFFORT = 1,
REALTIME = 2,
}
namespace tflite.CoralSettings_;
enum Performance : int {
UNDEFINED = 0,
MAXIMUM = 1,
HIGH = 2,
MEDIUM = 3,
LOW = 4,
}
namespace tflite;
enum BenchmarkEventType : int {
UNDEFINED_BENCHMARK_EVENT_TYPE = 0,
START = 1,
END = 2,
ERROR = 3,
LOGGED = 4,
RECOVERED_ERROR = 5,
}
enum BenchmarkStage : int {
UNKNOWN = 0,
INITIALIZATION = 1,
INFERENCE = 2,
}
table ComputeSettings {
preference:tflite.ExecutionPreference;
tflite_settings:tflite.TFLiteSettings;
model_namespace_for_statistics:string;
model_identifier_for_statistics:string;
settings_to_test_locally:tflite.MinibenchmarkSettings;
}
table NNAPISettings {
accelerator_name:string;
cache_directory:string;
model_token:string;
execution_preference:tflite.NNAPIExecutionPreference;
no_of_nnapi_instances_to_cache:int;
fallback_settings:tflite.FallbackSettings;
allow_nnapi_cpu_on_android_10_plus:bool;
execution_priority:tflite.NNAPIExecutionPriority;
allow_dynamic_dimensions:bool;
allow_fp16_precision_for_fp32:bool;
use_burst_computation:bool;
support_library_handle:long;
}
table GPUSettings {
is_precision_loss_allowed:bool;
enable_quantized_inference:bool = true;
force_backend:tflite.GPUBackend;
inference_priority1:tflite.GPUInferencePriority;
inference_priority2:tflite.GPUInferencePriority;
inference_priority3:tflite.GPUInferencePriority;
inference_preference:tflite.GPUInferenceUsage;
cache_directory:string;
model_token:string;
}
table HexagonSettings {
debug_level:int;
powersave_level:int;
print_graph_profile:bool;
print_graph_debug:bool;
}
table XNNPackSettings {
num_threads:int;
flags:tflite.XNNPackFlags;
}
table CoreMLSettings {
enabled_devices:tflite.CoreMLSettings_.EnabledDevices;
coreml_version:int;
max_delegated_partitions:int;
min_nodes_per_partition:int = 2;
}
table StableDelegateLoaderSettings {
delegate_path:string;
}
table EdgeTpuDeviceSpec {
platform_type:tflite.EdgeTpuDeviceSpec_.PlatformType;
num_chips:int;
device_paths:[string];
chip_family:int;
}
table EdgeTpuInactivePowerConfig {
inactive_power_state:tflite.EdgeTpuPowerState;
inactive_timeout_us:long;
}
table EdgeTpuSettings {
inference_power_state:tflite.EdgeTpuPowerState;
inactive_power_configs:[tflite.EdgeTpuInactivePowerConfig];
inference_priority:int = -1;
edgetpu_device_spec:tflite.EdgeTpuDeviceSpec;
model_token:string;
float_truncation_type:tflite.EdgeTpuSettings_.FloatTruncationType;
qos_class:tflite.EdgeTpuSettings_.QosClass;
}
table CoralSettings {
device:string;
performance:tflite.CoralSettings_.Performance;
usb_always_dfu:bool;
usb_max_bulk_in_queue_length:int;
}
table CPUSettings {
num_threads:int = -1;
}
table TFLiteSettings {
delegate:tflite.Delegate;
nnapi_settings:tflite.NNAPISettings;
gpu_settings:tflite.GPUSettings;
hexagon_settings:tflite.HexagonSettings;
xnnpack_settings:tflite.XNNPackSettings;
coreml_settings:tflite.CoreMLSettings;
cpu_settings:tflite.CPUSettings;
max_delegated_partitions:int;
edgetpu_settings:tflite.EdgeTpuSettings;
coral_settings:tflite.CoralSettings;
fallback_settings:tflite.FallbackSettings;
disable_default_delegates:bool;
stable_delegate_loader_settings:tflite.StableDelegateLoaderSettings;
}
table FallbackSettings {
allow_automatic_fallback_on_compilation_error:bool;
allow_automatic_fallback_on_execution_error:bool;
}
table BenchmarkMetric {
name:string;
values:[float];
}
table BenchmarkResult {
initialization_time_us:[long];
inference_time_us:[long];
max_memory_kb:int;
ok:bool;
metrics:[tflite.BenchmarkMetric];
actual_output:[tflite.BenchmarkResult_.InferenceOutput];
}
namespace tflite.BenchmarkResult_;
table InferenceOutput {
value:[ubyte];
}
namespace tflite;
table ErrorCode {
source:tflite.Delegate;
tflite_error:int;
underlying_api_error:long;
}
table BenchmarkError {
stage:tflite.BenchmarkStage;
exit_code:int;
signal:int;
error_code:[tflite.ErrorCode];
mini_benchmark_error_code:int;
}
table BenchmarkEvent {
tflite_settings:tflite.TFLiteSettings;
event_type:tflite.BenchmarkEventType;
result:tflite.BenchmarkResult;
error:tflite.BenchmarkError;
boottime_us:long;
wallclock_us:long;
}
table BestAccelerationDecision {
number_of_source_events:int;
min_latency_event:tflite.BenchmarkEvent;
min_inference_time_us:long;
}
table BenchmarkInitializationFailure {
initialization_status:int;
}
table MiniBenchmarkEvent {
is_log_flushing_event:bool;
best_acceleration_decision:tflite.BestAccelerationDecision;
initialization_failure:tflite.BenchmarkInitializationFailure;
benchmark_event:tflite.BenchmarkEvent;
}
table ModelFile {
filename:string;
fd:long;
offset:long;
length:long;
model_id_group:tflite.ModelIdGroup;
}
table ModelIdGroup {
model_namespace:string;
model_id:string;
}
table BenchmarkStoragePaths {
storage_file_path:string;
data_directory_path:string;
}
table ValidationSettings {
per_test_timeout_ms:long;
}
table MinibenchmarkSettings {
settings_to_test:[tflite.TFLiteSettings];
model_file:tflite.ModelFile;
storage_paths:tflite.BenchmarkStoragePaths;
validation_settings:tflite.ValidationSettings;
}
table BenchmarkEventStorage {
model_id_group:tflite.ModelIdGroup;
benchmark_event:tflite.BenchmarkEvent;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,84 @@
/* Copyright 2021 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.
==============================================================================*/
// Some very simple unit tests of the (C++) XNNPack Delegate Plugin.
#include <memory>
#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "pthreadpool.h" // from @pthreadpool
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/acceleration/configuration/delegate_registry.h"
#include "tensorflow/lite/test_util.h"
namespace tflite {
class XnnpackPluginTest : public tflite::testing::Test {
public:
static constexpr int kNumThreadsForTest = 7;
static constexpr tflite::XNNPackFlags kFlagsForTest =
tflite::XNNPackFlags::XNNPackFlags_TFLITE_XNNPACK_DELEGATE_FLAG_QS8_QU8;
void SetUp() override {
// Construct a FlatBuffer that contains
// TFLiteSettings {
// delegate: Delegate.XNNPACK,
// XNNPackSettings { num_threads: kNumThreadsForTest
// flags: TFLITE_XNNPACK_DELEGATE_FLAG_QS8 |
// TFLITE_XNNPACK_DELEGATE_FLAG_QU8
// }
// }.
XNNPackSettingsBuilder xnnpack_settings_builder(flatbuffer_builder_);
xnnpack_settings_builder.add_num_threads(kNumThreadsForTest);
xnnpack_settings_builder.add_flags(kFlagsForTest);
flatbuffers::Offset<XNNPackSettings> xnnpack_settings =
xnnpack_settings_builder.Finish();
TFLiteSettingsBuilder tflite_settings_builder(flatbuffer_builder_);
tflite_settings_builder.add_xnnpack_settings(xnnpack_settings);
tflite_settings_builder.add_delegate(Delegate_XNNPACK);
flatbuffers::Offset<TFLiteSettings> tflite_settings =
tflite_settings_builder.Finish();
flatbuffer_builder_.Finish(tflite_settings);
tflite_settings_ = flatbuffers::GetRoot<TFLiteSettings>(
flatbuffer_builder_.GetBufferPointer());
// Create an XNNPack delegate plugin using the settings from the flatbuffer.
delegate_plugin_ = delegates::DelegatePluginRegistry::CreateByName(
"XNNPackPlugin", *tflite_settings_);
ASSERT_NE(delegate_plugin_, nullptr);
}
void TearDown() override { delegate_plugin_.reset(); }
~XnnpackPluginTest() override {}
protected:
// settings_ points into storage owned by flatbuffer_builder_.
flatbuffers::FlatBufferBuilder flatbuffer_builder_;
const TFLiteSettings *tflite_settings_;
std::unique_ptr<delegates::DelegatePluginInterface> delegate_plugin_;
};
constexpr int XnnpackPluginTest::kNumThreadsForTest;
TEST_F(XnnpackPluginTest, CanCreateAndDestroyDelegate) {
delegates::TfLiteOpaqueDelegatePtr delegate = delegate_plugin_->Create();
EXPECT_NE(delegate, nullptr);
}
TEST_F(XnnpackPluginTest, CanGetDelegateErrno) {
delegates::TfLiteOpaqueDelegatePtr delegate = delegate_plugin_->Create();
int error_number = delegate_plugin_->GetDelegateErrno(delegate.get());
EXPECT_EQ(error_number, 0);
}
} // namespace tflite