提交 310715d9 编写于 作者: F Fergus Henderson 提交者: TensorFlower Gardener

Add a test using the FlatBuffer C API (rather than the FlatBuffer C++ API)

to construct the TFLiteSettings FlatBuffer.

PiperOrigin-RevId: 565184361
上级 e54cae40
......@@ -16,19 +16,20 @@
# C API for delegate plugins.
load("//tensorflow:tensorflow.default.bzl", "get_compatible_with_portable")
load(
"//tensorflow/core/platform:build_config_root.bzl",
"tf_gpu_tests_tags",
)
load("//tensorflow/lite:build_def.bzl", "tflite_cc_library_with_c_headers_test", "tflite_copts", "tflite_copts_warnings")
load("//tensorflow/lite/delegates/gpu:build_defs.bzl", "gpu_delegate_linkopts")
load("//tensorflow/lite/core/c:special_rules.bzl", "experimental_acceleration_api_allowlist")
load(
"//tensorflow/lite/core/acceleration/configuration/c:special_rules.bzl",
"delegate_plugin_visibility_allowlist",
"gpu_plugin_visibility_allowlist",
"xnnpack_plugin_visibility_allowlist",
)
load(
"//tensorflow/core/platform:build_config_root.bzl",
"tf_gpu_tests_tags",
)
load("//tensorflow/lite/core/c:special_rules.bzl", "experimental_acceleration_api_allowlist")
load("//tensorflow/lite/core/shims:build_defs.bzl", "build_test")
load("//tensorflow/lite/delegates/gpu:build_defs.bzl", "gpu_delegate_linkopts")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
......@@ -173,6 +174,36 @@ cc_test(
],
)
tflite_cc_library_with_c_headers_test(
name = "xnnpack_plugin_c_test_lib",
testonly = True,
srcs = ["xnnpack_plugin_c_test_lib.c"],
hdrs = ["xnnpack_plugin_c_test_lib.h"],
deps = [
":configuration_c_fbs",
":xnnpack_plugin",
"//tensorflow/lite/core/c:common",
"//third_party/flatcc:runtime",
"@pthreadpool",
],
)
cc_test(
name = "xnnpack_plugin_c_test",
srcs = ["xnnpack_plugin_c_test.cc"],
deps = [
":configuration_c_fbs",
":xnnpack_plugin",
":xnnpack_plugin_c_test_lib",
"//tensorflow/lite/acceleration/configuration:configuration_fbs",
"//tensorflow/lite/core/c:common",
"//tensorflow/lite/delegates/xnnpack:xnnpack_delegate",
"//third_party/flatcc:runtime",
"@com_google_googletest//:gtest_main",
"@pthreadpool",
],
)
tflite_cc_library_with_c_headers_test(
name = "stable_delegate",
hdrs = ["stable_delegate.h"],
......@@ -181,3 +212,44 @@ tflite_cc_library_with_c_headers_test(
"//tensorflow/lite/core/acceleration/configuration/c:delegate_plugin",
],
)
# This rule invokes the "flatcc" FlatBuffer C API compiler to generate the sources
# use by the ":configuration_c_fbs" C library rule below.
genrule(
name = "configuration_c_fbs_gen",
srcs = ["//tensorflow/lite/acceleration/configuration:configuration.fbs"],
outs = [
"configuration_builder.h",
"configuration_reader.h",
],
cmd = "$(location //third_party/flatcc:flatcc) -o$(RULEDIR) --builder --reader $(SRCS)",
tools = ["//third_party/flatcc"],
# Currently this only enables the API for _building_ configuration flatbuffer objects,
# not the APIs for reading them, verifying them, or converting them to/from JSON.
# [If you need to enable those, replace the two lines above with the following
# outs = ["configuration_builder.h", "configuration_reader.h", "configuration_verifier.h",
# "configuration_json_parser.h", "configuration_json_printer.h"],
# cmd = "$(location //third_party/flatcc:flatcc) -o$(RULEDIR) " +
# "--builder --reader --verifier --json $(SRCS)",
# and then in the rule below -- or preferably in a separate target --
# add the additional header files in "hdrs" and fix the dependencies.]
)
# This rule defines a C library containing the Flatbuffer-generated C API for constructing objects
# using the FlatBuffer schema generated from tensorflow/lite/acceleration/configuration/configuration.proto,
# which defines the 'TFLiteSettings' FlatBuffer table and related types.
tflite_cc_library_with_c_headers_test(
name = "configuration_c_fbs",
hdrs = [
"configuration_builder.h",
"configuration_reader.h",
],
deps = ["//third_party/flatcc:runtime"],
)
build_test(
name = "configuration_c_fbs_build_test",
targets = [
":configuration_c_fbs",
],
)
/* 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 simple unit tests of the C API Delegate Plugin for the
// XNNPACK Delegate, implemented using the FlatBuffers C API
// to construct the TFLiteSettings FlatBuffer.
#include <gtest/gtest.h>
#include "pthreadpool.h" // from @pthreadpool
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/core/acceleration/configuration/c/configuration_reader.h"
#include "tensorflow/lite/core/acceleration/configuration/c/xnnpack_plugin.h"
#include "tensorflow/lite/core/acceleration/configuration/c/xnnpack_plugin_c_test_lib.h"
#include "tensorflow/lite/core/c/common.h"
#include "tensorflow/lite/delegates/xnnpack/xnnpack_delegate.h"
namespace tflite {
class XnnpackTest : public testing::Test {
public:
static constexpr int kNumThreadsForTest = 7;
void SetUp() override {
// Construct a FlatBuffer that contains
// TFLiteSettings { XNNPackSettings { num_threads: kNumThreadsForTest } }.
settings_storage_ =
SettingsStorageCreateWithXnnpackThreads(kNumThreadsForTest);
settings_ = SettingsStorageGetSettings(settings_storage_);
}
void TearDown() override {
SettingsStorageDestroy(settings_storage_);
settings_ = nullptr;
}
~XnnpackTest() override = default;
protected:
SettingsStorage *settings_storage_;
const void
*settings_; // settings_ points into storage owned by settings_storage_.
};
constexpr int XnnpackTest::kNumThreadsForTest;
TEST_F(XnnpackTest, CanCreateAndDestroyDelegate) {
TfLiteDelegate *delegate =
TfLiteXnnpackDelegatePluginCApi()->create(settings_);
EXPECT_NE(delegate, nullptr);
TfLiteXnnpackDelegatePluginCApi()->destroy(delegate);
}
TEST_F(XnnpackTest, CanGetDelegateErrno) {
TfLiteDelegate *delegate =
TfLiteXnnpackDelegatePluginCApi()->create(settings_);
int error_number =
TfLiteXnnpackDelegatePluginCApi()->get_delegate_errno(delegate);
EXPECT_EQ(error_number, 0);
TfLiteXnnpackDelegatePluginCApi()->destroy(delegate);
}
TEST_F(XnnpackTest, SetsCorrectThreadCount) {
TfLiteDelegate *delegate =
TfLiteXnnpackDelegatePluginCApi()->create(settings_);
pthreadpool_t threadpool =
static_cast<pthreadpool_t>(TfLiteXNNPackDelegateGetThreadPool(delegate));
int thread_count = pthreadpool_get_threads_count(threadpool);
EXPECT_EQ(thread_count, kNumThreadsForTest);
TfLiteXnnpackDelegatePluginCApi()->destroy(delegate);
}
TEST_F(XnnpackTest, UsesDefaultFlagsByDefault) {
TfLiteDelegate *delegate =
TfLiteXnnpackDelegatePluginCApi()->create(settings_);
int flags = TfLiteXNNPackDelegateGetFlags(delegate);
EXPECT_EQ(flags, TfLiteXNNPackDelegateOptionsDefault().flags);
TfLiteXnnpackDelegatePluginCApi()->destroy(delegate);
}
TEST_F(XnnpackTest, UsesSpecifiedFlagsWhenNonzero) {
SettingsStorageDestroy(settings_storage_);
settings_storage_ = SettingsStorageCreateWithXnnpackFlags(
tflite_XNNPackFlags_TFLITE_XNNPACK_DELEGATE_FLAG_QU8);
settings_ = SettingsStorageGetSettings(settings_storage_);
TfLiteDelegate *delegate =
TfLiteXnnpackDelegatePluginCApi()->create(settings_);
int flags = TfLiteXNNPackDelegateGetFlags(delegate);
EXPECT_EQ(flags, tflite::XNNPackFlags_TFLITE_XNNPACK_DELEGATE_FLAG_QU8);
TfLiteXnnpackDelegatePluginCApi()->destroy(delegate);
}
// Settings flags to XNNPackFlags_TFLITE_XNNPACK_DELEGATE_NO_FLAGS (zero)
// causes flags to be set to their default values, not zero.
// This is potentially confusing behaviour, but we can't distinguish
// the case when flags isn't set from the case when flags is set to zero.
TEST_F(XnnpackTest, UsesDefaultFlagsWhenZero) {
SettingsStorageDestroy(settings_storage_);
settings_storage_ = SettingsStorageCreateWithXnnpackFlags(
tflite_XNNPackFlags_TFLITE_XNNPACK_DELEGATE_NO_FLAGS);
settings_ = SettingsStorageGetSettings(settings_storage_);
TfLiteDelegate *delegate =
TfLiteXnnpackDelegatePluginCApi()->create(settings_);
int flags = TfLiteXNNPackDelegateGetFlags(delegate);
EXPECT_EQ(flags, TfLiteXNNPackDelegateOptionsDefault().flags);
TfLiteXnnpackDelegatePluginCApi()->destroy(delegate);
}
} // namespace tflite
/* 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 tests of the XNNPack Plugin using the FlatBuffers C API.
// This source file is C, not C++, to ensure that we're not accidentally
// depending on the FlatBuffers C++ API here.
#include "tensorflow/lite/core/acceleration/configuration/c/xnnpack_plugin_c_test_lib.h"
#include <stdio.h>
#include <stdlib.h>
#include "third_party/flatcc/include/flatcc/flatcc_builder.h"
#include "tensorflow/lite/core/acceleration/configuration/c/configuration_builder.h"
#include "tensorflow/lite/core/acceleration/configuration/c/configuration_reader.h"
struct SettingsStorage {
// The builder object that allocates the storage.
flatcc_builder_t builder;
// The raw buffer.
void* buffer;
size_t size;
// The parsed TFLiteSettings object.
const struct tflite_TFLiteSettings_table* tflite_settings;
};
typedef struct SettingsStorage SettingsStorage;
SettingsStorage* SettingsStorageCreateWithXnnpackThreads(int num_threads) {
struct SettingsStorage* storage =
(struct SettingsStorage*) malloc(sizeof(SettingsStorage));
flatcc_builder_t* builder = &storage->builder;
flatcc_builder_init(builder);
/* Construct a buffer specific to the schema. */
tflite_TFLiteSettings_start_as_root(builder);
tflite_TFLiteSettings_xnnpack_settings_start(builder);
tflite_XNNPackSettings_num_threads_add(builder, num_threads);
tflite_TFLiteSettings_xnnpack_settings_end(builder);
tflite_TFLiteSettings_end_as_root(builder);
/* Retrieve buffer - see also `flatcc_builder_get_direct_buffer`. */
storage->buffer = flatcc_builder_finalize_buffer(builder, &storage->size);
/* 'Parse' the buffer. (This is actually just an offset lookup.) */
storage->tflite_settings = tflite_TFLiteSettings_as_root(storage->buffer);
return storage;
}
SettingsStorage* SettingsStorageCreateWithXnnpackFlags(
tflite_XNNPackFlags_enum_t flags) {
struct SettingsStorage* storage =
(struct SettingsStorage*) malloc(sizeof(SettingsStorage));
flatcc_builder_t* builder = &storage->builder;
flatcc_builder_init(builder);
/* Construct a buffer specific to the schema. */
tflite_TFLiteSettings_start_as_root(builder);
tflite_TFLiteSettings_xnnpack_settings_start(builder);
tflite_XNNPackSettings_flags_add(builder, flags);
tflite_TFLiteSettings_xnnpack_settings_end(builder);
tflite_TFLiteSettings_end_as_root(builder);
/* Retrieve buffer - see also `flatcc_builder_get_direct_buffer`. */
storage->buffer = flatcc_builder_finalize_buffer(builder, &storage->size);
/* 'Parse' the buffer. (This is actually just an offset lookup.) */
storage->tflite_settings = tflite_TFLiteSettings_as_root(storage->buffer);
return storage;
}
tflite_TFLiteSettings_table_t SettingsStorageGetSettings(
const SettingsStorage* storage) {
return storage->tflite_settings;
}
void SettingsStorageDestroy(SettingsStorage* storage) {
free(storage->buffer);
flatcc_builder_clear(&storage->builder);
storage->tflite_settings = NULL;
storage->buffer = NULL;
storage->size = 0;
free(storage);
}
/* 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 library routines for constructing TFLiteSettings FlatBuffers,
// implemented using the FlatBuffers C API.
#ifndef TENSORFLOW_LITE_CORE_ACCELERATION_CONFIGURATION_C_XNNPACK_PLUGIN_C_TEST_LIB_H_
#define TENSORFLOW_LITE_CORE_ACCELERATION_CONFIGURATION_C_XNNPACK_PLUGIN_C_TEST_LIB_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "tensorflow/lite/core/acceleration/configuration/c/configuration_reader.h"
// Opaque type for building a TfLiteSettings flatbuffer object.
typedef struct SettingsStorage SettingsStorage;
// Constructs a TFLiteSettings FlatBuffer with the following contents:
//
// tflite_settings {
// xnnpack_settings {
// num_threads: <num_threads>
// }
// }
struct SettingsStorage* SettingsStorageCreateWithXnnpackThreads(
int num_threads);
// Constructs a TFLiteSettings FlatBuffer with the following contents:
//
// tflite_settings {
// xnnpack_settings {
// flags: <flags>
// }
// }
struct SettingsStorage* SettingsStorageCreateWithXnnpackFlags(
tflite_XNNPackFlags_enum_t flags);
// Gets the parsed TFLiteSettings FlatBuffer object from the SettingsStorage.
const struct tflite_TFLiteSettings_table* SettingsStorageGetSettings(
const SettingsStorage* storage);
// Deallocates the settings storage allocated by
// SettingsStorageCreateWithXnnpackThreads or
// SettingsStorageCreateWithXnnpackFlags.
void SettingsStorageDestroy(SettingsStorage* storage);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // TENSORFLOW_LITE_CORE_ACCELERATION_CONFIGURATION_C_XNNPACK_PLUGIN_C_TEST_LIB_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册