diff --git a/backends/xnnpack/runtime/XNNExecutor.h b/backends/xnnpack/runtime/XNNExecutor.h index c7926744dd6..6c07771b02a 100644 --- a/backends/xnnpack/runtime/XNNExecutor.h +++ b/backends/xnnpack/runtime/XNNExecutor.h @@ -53,6 +53,10 @@ class XNNExecutor { return packed_data_names_; } + inline bool uses_weight_cache() const { + return !packed_data_names_.empty(); + } + inline std::shared_ptr get_workspace() { return workspace_; } diff --git a/backends/xnnpack/runtime/XNNPACKBackend.cpp b/backends/xnnpack/runtime/XNNPACKBackend.cpp index 76e83d4b57b..7609946e7de 100644 --- a/backends/xnnpack/runtime/XNNPACKBackend.cpp +++ b/backends/xnnpack/runtime/XNNPACKBackend.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,7 +24,6 @@ namespace executorch { namespace backends { -using executorch::backends::xnnpack::WorkspaceSharingMode; using executorch::backends::xnnpack::XNNWorkspace; using executorch::backends::xnnpack::delegate::XNNWeightsCache; using executorch::ET_RUNTIME_NAMESPACE::Backend; @@ -57,9 +56,6 @@ class XnnpackBackend final (unsigned int)status); return; } - - // Workspace manager is initialized with the appropriate default mode in its - // constructor } bool is_available() const override { @@ -82,17 +78,24 @@ class XnnpackBackend final auto program_id = reinterpret_cast(context.get_runtime_allocator()); - auto workspace_result = get_or_create_workspace(program_id); + auto sharing_mode_result = options_.resolve_sharing_mode(context); + if (!sharing_mode_result.ok()) { + return sharing_mode_result.error(); + } + auto workspace_result = + options_.workspace_manager().get_or_create_workspace( + program_id, sharing_mode_result.get()); if (!workspace_result.ok()) { return workspace_result.error(); } auto workspace = workspace_result.get(); -#ifdef ENABLE_XNNPACK_WEIGHTS_CACHE - const std::lock_guard lock_weight_cache(weights_cache_mutex_); - weights_cache_->initialize_for_runtime( - context.get_runtime_allocator(), named_data_map); -#endif + bool use_weight_cache = options_.resolve_weight_cache(context); + if (use_weight_cache) { + const std::lock_guard lock_weight_cache(weights_cache_mutex_); + weights_cache_->initialize_for_runtime( + context.get_runtime_allocator(), named_data_map); + } auto [workspace_lock, workspace_ptr] = workspace->acquire(); @@ -129,9 +132,11 @@ class XnnpackBackend final Span args) const override { auto executor = static_cast(handle); -#ifdef ENABLE_XNNPACK_WEIGHTS_CACHE - const std::lock_guard lock_weights_cache(weights_cache_mutex_); -#endif + std::unique_lock lock_weights_cache( + weights_cache_mutex_, std::defer_lock); + if (executor->uses_weight_cache()) { + lock_weights_cache.lock(); + } auto [raii_lock, _] = executor->get_workspace()->acquire(); @@ -161,11 +166,11 @@ class XnnpackBackend final executor->print_avg_op_timings(); #endif -#ifdef ENABLE_XNNPACK_WEIGHTS_CACHE - const std::lock_guard lock_weights_cache( - weights_cache_mutex_); - weights_cache_->delete_packed_data(executor->get_packed_data_names()); -#endif + if (executor->uses_weight_cache()) { + const std::lock_guard lock_weights_cache( + weights_cache_mutex_); + weights_cache_->delete_packed_data(executor->get_packed_data_names()); + } // This is needed to serialize access to xnn_delete_runtime which is not // thread safe. This can heppen when multiple threads call destroy() on @@ -181,72 +186,32 @@ class XnnpackBackend final } } - Error get_option_internal( + Error get_option( BackendOptionContext& context, - executorch::runtime::Span& - backend_options) const { - // Intentionally not locking here as it is not required. - - // Verify that the expected option key is present and modify the value + Span& backend_options) override { for (size_t i = 0; i < backend_options.size(); ++i) { - if (strcmp( - backend_options[i].key, - xnnpack::workspace_sharing_mode_option_key) == 0) { - // Set the value to what was stored by set_option - backend_options[i].value = - static_cast(workspace_manager_.get_sharing_mode()); + Error err = options_.get_option(backend_options[i]); + if (err != Error::Ok) { + return err; } } - return Error::Ok; } - Error get_option( - BackendOptionContext& context, - executorch::runtime::Span& - backend_options) override { - return get_option_internal(context, backend_options); - } - Error set_option( BackendOptionContext& context, - const executorch::runtime::Span& - backend_options) override { - if (backend_options.size() > 0) { - for (const auto& option : backend_options) { - if (strcmp(option.key, xnnpack::workspace_sharing_mode_option_key) == - 0) { - if (auto* val = std::get_if(&option.value)) { - if (*val < 0 || - *val > static_cast(WorkspaceSharingMode::Count)) { - ET_LOG( - Error, - "XNNPACK workspace sharing mode must be between 0 and %d, inclusive, but was %d.", - static_cast(WorkspaceSharingMode::Count), - *val); - return Error::InvalidArgument; - } - - ET_LOG( - Debug, "Setting XNNPACK workspace sharing mode to %d.", *val); - auto status = workspace_manager_.set_sharing_mode( - static_cast(*val)); - if (status != Error::Ok) { - return status; - } - } else { - ET_LOG(Error, "XNNPACK workspace sharing mode must be an integer."); - return Error::InvalidArgument; - } - } + const Span& backend_options) override { + for (const auto& option : backend_options) { + Error err = options_.set_option(option); + if (err != Error::Ok) { + return err; } } return Error::Ok; } private: - // Workspace manager for handling workspace sharing modes - mutable xnnpack::XNNWorkspaceManager workspace_manager_; + mutable xnnpack::XnnpackBackendOptions options_; // Weights cache is global to all delegate instances. mutable std::mutex weights_cache_mutex_; @@ -257,13 +222,6 @@ class XnnpackBackend final // weights_cache_mutex_ // workspace_meta_mutex_ // workspace_mutex_ (owned by executor) - - // Retrieve a workspace for the given method ID, depending on the sharing - // mode. - Result> get_or_create_workspace( - uintptr_t program_id) const { - return workspace_manager_.get_or_create_workspace(program_id); - } }; namespace { diff --git a/backends/xnnpack/runtime/XNNPACKBackend.h b/backends/xnnpack/runtime/XNNPACKBackend.h index aca72f8652b..eb40047f3f8 100644 --- a/backends/xnnpack/runtime/XNNPACKBackend.h +++ b/backends/xnnpack/runtime/XNNPACKBackend.h @@ -9,6 +9,10 @@ const char xnnpack_backend_key[] = "XnnpackBackend"; /// for a description of the associated functionality. const char workspace_sharing_mode_option_key[] = "workspace_sharing_mode"; +/// The key for the weight cache option. When enabled, packed weights are shared +// across delegate instances. Changes only affect subsequently loaded models. +const char weight_cache_option_key[] = "weight_cache_enabled"; + /// Workspace sharing mode. This is a backend option that can be set via the /// set_option API to control memory sharing between CALL_DELEGATE instances. /// This is useful for reducing memory consumption. diff --git a/backends/xnnpack/runtime/XNNWorkspaceManager.cpp b/backends/xnnpack/runtime/XNNWorkspaceManager.cpp index 5af3395ed89..d3550da5cc7 100644 --- a/backends/xnnpack/runtime/XNNWorkspaceManager.cpp +++ b/backends/xnnpack/runtime/XNNWorkspaceManager.cpp @@ -46,9 +46,14 @@ WorkspaceSharingMode XNNWorkspaceManager::get_sharing_mode() const { Result> XNNWorkspaceManager::get_or_create_workspace(uintptr_t program_id) const { - auto mode = sharing_mode_.load(); + return get_or_create_workspace(program_id, sharing_mode_.load()); +} - // Get or create the workspace according to the current sharing mode. +Result> +XNNWorkspaceManager::get_or_create_workspace( + uintptr_t program_id, + WorkspaceSharingMode mode) const { + // Get or create the workspace according to the specified sharing mode. if (mode == WorkspaceSharingMode::Disabled) { ET_LOG(Debug, "Instantiating workspace."); auto create_result = XNNWorkspace::create(); @@ -121,8 +126,7 @@ XNNWorkspaceManager::get_or_create_model_workspace(uintptr_t program_id) const { "Created workspace %p for program %" PRIuPTR ".", workspace->unsafe_get_workspace(), program_id); - model_workspaces_.insert( - {program_id, std::weak_ptr(workspace)}); + model_workspaces_[program_id] = workspace; } return workspace; diff --git a/backends/xnnpack/runtime/XNNWorkspaceManager.h b/backends/xnnpack/runtime/XNNWorkspaceManager.h index 52db1184bbd..2e5689f266e 100644 --- a/backends/xnnpack/runtime/XNNWorkspaceManager.h +++ b/backends/xnnpack/runtime/XNNWorkspaceManager.h @@ -58,6 +58,18 @@ class XNNWorkspaceManager { runtime::Result> get_or_create_workspace( uintptr_t program_id) const; + /** + * Retrieve a workspace for the given program ID, using the specified sharing + * mode instead of the stored mode. A workspace will be created if needed. + * + * @param program_id The ID of the program requesting a workspace. + * @param mode The workspace sharing mode to use. + * @return A Result containing a shared_ptr to the workspace, or an error. + */ + runtime::Result> get_or_create_workspace( + uintptr_t program_id, + WorkspaceSharingMode mode) const; + private: // The active sharing mode. Changes to this affect only models loaded after // the change. diff --git a/backends/xnnpack/runtime/XnnpackBackendOptions.cpp b/backends/xnnpack/runtime/XnnpackBackendOptions.cpp new file mode 100644 index 00000000000..aa5f6f0302b --- /dev/null +++ b/backends/xnnpack/runtime/XnnpackBackendOptions.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include + +namespace executorch::backends::xnnpack { + +using executorch::runtime::BackendOption; +using executorch::runtime::Error; + +namespace { + +// Resolve an option value, preferring the runtime spec override if present. +template +T resolve_option( + const ET_RUNTIME_NAMESPACE::BackendInitContext& context, + const char* key, + T global_default) { + auto spec = context.get_runtime_spec(key); + if (spec.ok()) { + return spec.get(); + } + return global_default; +} + +} // namespace + +Error XnnpackBackendOptions::get_option(BackendOption& option) const { + if (strcmp(option.key, workspace_sharing_mode_option_key) == 0) { + option.value = static_cast(sharing_mode_.load()); + } else if (strcmp(option.key, weight_cache_option_key) == 0) { + option.value = weight_cache_enabled_.load(); + } + return Error::Ok; +} + +Error XnnpackBackendOptions::set_option(const BackendOption& option) { + if (strcmp(option.key, workspace_sharing_mode_option_key) == 0) { + auto* val = std::get_if(&option.value); + if (!val) { + ET_LOG(Error, "XNNPACK workspace sharing mode must be an integer."); + return Error::InvalidArgument; + } + if (*val < 0 || *val >= static_cast(WorkspaceSharingMode::Count)) { + ET_LOG( + Error, + "XNNPACK workspace sharing mode must be between 0 and %d, inclusive, but was %d.", + static_cast(WorkspaceSharingMode::Count) - 1, + *val); + return Error::InvalidArgument; + } + ET_LOG(Debug, "Setting XNNPACK workspace sharing mode to %d.", *val); + sharing_mode_.store(static_cast(*val)); + } else if (strcmp(option.key, weight_cache_option_key) == 0) { + auto* val = std::get_if(&option.value); + if (!val) { + ET_LOG(Error, "XNNPACK weight cache enabled must be a bool."); + return Error::InvalidArgument; + } + ET_LOG(Debug, "Setting XNNPACK weight cache enabled to %d.", *val); + weight_cache_enabled_.store(*val); + } + return Error::Ok; +} + +bool XnnpackBackendOptions::resolve_weight_cache( + const ET_RUNTIME_NAMESPACE::BackendInitContext& context) const { + return resolve_option( + context, weight_cache_option_key, weight_cache_enabled_.load()); +} + +runtime::Result +XnnpackBackendOptions::resolve_sharing_mode( + const ET_RUNTIME_NAMESPACE::BackendInitContext& context) const { + auto global_mode = sharing_mode_.load(); + int raw_mode = resolve_option( + context, + workspace_sharing_mode_option_key, + static_cast(global_mode)); + if (raw_mode < 0 || + raw_mode >= static_cast(WorkspaceSharingMode::Count)) { + ET_LOG( + Error, + "XNNPACK workspace sharing mode must be between 0 and %d, inclusive, but was %d.", + static_cast(WorkspaceSharingMode::Count) - 1, + raw_mode); + return runtime::Error::InvalidArgument; + } + return static_cast(raw_mode); +} + +WorkspaceSharingMode XnnpackBackendOptions::get_sharing_mode() const { + return sharing_mode_.load(); +} + +XNNWorkspaceManager& XnnpackBackendOptions::workspace_manager() { + return workspace_manager_; +} + +const XNNWorkspaceManager& XnnpackBackendOptions::workspace_manager() const { + return workspace_manager_; +} + +} // namespace executorch::backends::xnnpack diff --git a/backends/xnnpack/runtime/XnnpackBackendOptions.h b/backends/xnnpack/runtime/XnnpackBackendOptions.h new file mode 100644 index 00000000000..ab6c93c21a3 --- /dev/null +++ b/backends/xnnpack/runtime/XnnpackBackendOptions.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace executorch::backends::xnnpack { + +class XnnpackBackendOptions { + public: + // Get a single option by key. The key field of the option must be set. + runtime::Error get_option(runtime::BackendOption& option) const; + + // Set a single option by key. Validates type and domain. + runtime::Error set_option(const runtime::BackendOption& option); + + // Resolve the effective weight cache setting for a delegate, applying + // any runtime spec override. + bool resolve_weight_cache( + const ET_RUNTIME_NAMESPACE::BackendInitContext& context) const; + + // Resolve the effective workspace sharing mode for a delegate, applying + // any runtime spec override. Returns InvalidArgument for out-of-range values. + runtime::Result resolve_sharing_mode( + const ET_RUNTIME_NAMESPACE::BackendInitContext& context) const; + + WorkspaceSharingMode get_sharing_mode() const; + XNNWorkspaceManager& workspace_manager(); + const XNNWorkspaceManager& workspace_manager() const; + + private: + XNNWorkspaceManager workspace_manager_; + +#ifdef ENABLE_XNNPACK_SHARED_WORKSPACE + std::atomic sharing_mode_{WorkspaceSharingMode::Global}; +#else + std::atomic sharing_mode_{ + WorkspaceSharingMode::Disabled}; +#endif + +#ifdef ENABLE_XNNPACK_WEIGHTS_CACHE + std::atomic weight_cache_enabled_{true}; +#else + std::atomic weight_cache_enabled_{false}; +#endif +}; + +} // namespace executorch::backends::xnnpack diff --git a/backends/xnnpack/test/runtime/test_weight_cache.cpp b/backends/xnnpack/test/runtime/test_weight_cache.cpp new file mode 100644 index 00000000000..d2c079c057a --- /dev/null +++ b/backends/xnnpack/test/runtime/test_weight_cache.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace ::testing; + +using executorch::backends::xnnpack::weight_cache_option_key; +using executorch::backends::xnnpack::workspace_sharing_mode_option_key; +using executorch::backends::xnnpack::WorkspaceSharingMode; +using executorch::backends::xnnpack::xnnpack_backend_key; +using executorch::extension::Module; +using executorch::extension::TensorPtr; +using executorch::runtime::BackendOption; +using executorch::runtime::BackendOptions; +using executorch::runtime::Error; +using executorch::runtime::LoadBackendOptionsMap; + +static void set_and_check_weight_cache_enabled(bool enabled) { + executorch::runtime::runtime_init(); + + BackendOptions<1> backend_options; + backend_options.set_option(weight_cache_option_key, enabled); + + auto status = executorch::runtime::set_option( + xnnpack_backend_key, backend_options.view()); + ASSERT_EQ(status, Error::Ok); + + BackendOption read_option; + strcpy(read_option.key, weight_cache_option_key); + read_option.value = !enabled; + status = get_option(xnnpack_backend_key, read_option); + + ASSERT_EQ(std::get(read_option.value), enabled); +} + +static TensorPtr create_input_tensor(float val) { + std::vector data(1000, val); + return executorch::extension::make_tensor_ptr({10, 10, 10}, std::move(data)); +} + +static void load_and_run_model_with_runtime_specs( + const char* model_path_env, + const LoadBackendOptionsMap& backend_options_map, + float input_a, + float input_b, + float input_c, + float expected_output) { + Module module(std::getenv(model_path_env)); + + auto err = module.load(backend_options_map); + ASSERT_EQ(err, Error::Ok); + + auto a = create_input_tensor(input_a); + auto b = create_input_tensor(input_b); + auto c = create_input_tensor(input_c); + + auto result = module.forward({a, b, c}); + ASSERT_TRUE(result.ok()); + + auto& output_tensor = result.get()[0].toTensor(); + for (auto i = 0; i < output_tensor.numel(); ++i) { + ASSERT_EQ(output_tensor.const_data_ptr()[i], expected_output); + } +} + +TEST(WeightCache, SetEnabled) { + set_and_check_weight_cache_enabled(true); + set_and_check_weight_cache_enabled(false); + set_and_check_weight_cache_enabled(true); +} + +TEST(WeightCache, SetInvalidType) { + executorch::runtime::runtime_init(); + + // Weight cache option expects a bool, not an int. + BackendOptions<1> backend_options; + backend_options.set_option(weight_cache_option_key, 1); + + auto status = executorch::runtime::set_option( + xnnpack_backend_key, backend_options.view()); + ASSERT_EQ(status, Error::InvalidArgument); +} + +TEST(WeightCache, SetMultipleOptions) { + executorch::runtime::runtime_init(); + + // Set both options at once. + BackendOptions<2> backend_options; + backend_options.set_option( + workspace_sharing_mode_option_key, + static_cast(WorkspaceSharingMode::Global)); + backend_options.set_option(weight_cache_option_key, false); + + auto status = executorch::runtime::set_option( + xnnpack_backend_key, backend_options.view()); + ASSERT_EQ(status, Error::Ok); + + // Read both back. + BackendOption read_workspace; + strcpy(read_workspace.key, workspace_sharing_mode_option_key); + read_workspace.value = -1; + status = get_option(xnnpack_backend_key, read_workspace); + ASSERT_EQ( + std::get(read_workspace.value), + static_cast(WorkspaceSharingMode::Global)); + + BackendOption read_cache; + strcpy(read_cache.key, weight_cache_option_key); + read_cache.value = true; + status = get_option(xnnpack_backend_key, read_cache); + ASSERT_EQ(std::get(read_cache.value), false); +} + +TEST(RuntimeSpec, OverridesGlobalWeightCache) { + executorch::runtime::runtime_init(); + + // Set global weight cache to enabled. + set_and_check_weight_cache_enabled(true); + + // Load a model with runtime spec disabling weight cache. + BackendOptions<1> xnnpack_opts; + xnnpack_opts.set_option(weight_cache_option_key, false); + LoadBackendOptionsMap map; + map.set_options(xnnpack_backend_key, xnnpack_opts.view()); + + // The model should load and run correctly without weight cache. + load_and_run_model_with_runtime_specs( + "ET_XNNPACK_GENERATED_ADD_LARGE_PTE_PATH", map, 1.0, 2.0, 3.0, 9.0); + + // Verify the global setting is still enabled. + BackendOption read_option; + strcpy(read_option.key, weight_cache_option_key); + read_option.value = false; + get_option(xnnpack_backend_key, read_option); + ASSERT_EQ(std::get(read_option.value), true); +} diff --git a/backends/xnnpack/test/runtime/test_workspace_sharing.cpp b/backends/xnnpack/test/runtime/test_workspace_sharing.cpp index 66f0d012acd..bb3c6ab1733 100644 --- a/backends/xnnpack/test/runtime/test_workspace_sharing.cpp +++ b/backends/xnnpack/test/runtime/test_workspace_sharing.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ using executorch::extension::TensorPtr; using executorch::runtime::BackendOption; using executorch::runtime::BackendOptions; using executorch::runtime::Error; +using executorch::runtime::LoadBackendOptionsMap; TensorPtr create_input_tensor(float val); void run_and_validate_two_models( @@ -177,3 +179,72 @@ void set_and_check_workspace_sharing_mode(WorkspaceSharingMode mode) { ASSERT_TRUE(std::get(read_option.value) == static_cast(mode)); } + +static void load_and_run_model_with_runtime_specs( + const char* model_path_env, + const LoadBackendOptionsMap& backend_options_map, + float input_a, + float input_b, + float input_c, + float expected_output) { + Module module(std::getenv(model_path_env)); + + auto err = module.load(backend_options_map); + ASSERT_EQ(err, Error::Ok); + + auto a = create_input_tensor(input_a); + auto b = create_input_tensor(input_b); + auto c = create_input_tensor(input_c); + + auto result = module.forward({a, b, c}); + ASSERT_TRUE(result.ok()); + + auto& output_tensor = result.get()[0].toTensor(); + for (auto i = 0; i < output_tensor.numel(); ++i) { + ASSERT_EQ(output_tensor.const_data_ptr()[i], expected_output); + } +} + +TEST(RuntimeSpec, OverridesGlobalWorkspaceMode) { + executorch::runtime::runtime_init(); + + // Set global mode to Disabled. + set_and_check_workspace_sharing_mode(WorkspaceSharingMode::Disabled); + + // Load a model with runtime spec overriding to Global. + BackendOptions<1> xnnpack_opts; + xnnpack_opts.set_option( + workspace_sharing_mode_option_key, + static_cast(WorkspaceSharingMode::Global)); + LoadBackendOptionsMap map; + map.set_options(xnnpack_backend_key, xnnpack_opts.view()); + + // The model should load and run correctly with the overridden mode. + // Expected output of add model: 2a + 2b + c = 2*1 + 2*2 + 3 = 9. + load_and_run_model_with_runtime_specs( + "ET_XNNPACK_GENERATED_ADD_LARGE_PTE_PATH", map, 1.0, 2.0, 3.0, 9.0); + + // Verify the global mode is still Disabled (not modified by runtime spec). + BackendOption read_option; + strcpy(read_option.key, workspace_sharing_mode_option_key); + read_option.value = -1; + auto status = get_option(xnnpack_backend_key, read_option); + ASSERT_EQ(status, Error::Ok); + ASSERT_EQ( + std::get(read_option.value), + static_cast(WorkspaceSharingMode::Disabled)); +} + +TEST(RuntimeSpec, NotSetFallsBackToGlobal) { + executorch::runtime::runtime_init(); + + // Set global mode to PerModel. + set_and_check_workspace_sharing_mode(WorkspaceSharingMode::PerModel); + + // Load a model with empty runtime specs (no overrides). + LoadBackendOptionsMap map; + + // The model should load and run correctly using the global PerModel mode. + load_and_run_model_with_runtime_specs( + "ET_XNNPACK_GENERATED_ADD_LARGE_PTE_PATH", map, 1.0, 2.0, 3.0, 9.0); +} diff --git a/backends/xnnpack/test/targets.bzl b/backends/xnnpack/test/targets.bzl index 04517c035fe..812986a12e6 100644 --- a/backends/xnnpack/test/targets.bzl +++ b/backends/xnnpack/test/targets.bzl @@ -64,6 +64,20 @@ def define_common_targets(): }, ) + runtime.cxx_test( + name = "test_weight_cache", + srcs = ["runtime/test_weight_cache.cpp"], + deps = [ + "//executorch/extension/module:module", + "//executorch/extension/tensor:tensor", + "//executorch/backends/xnnpack:xnnpack_backend", + "//executorch/runtime/backend:backend_options_map", + ], + env = { + "ET_XNNPACK_GENERATED_ADD_LARGE_PTE_PATH": "$(location fbcode//executorch/test/models:exported_xnnp_delegated_programs[ModuleAddLarge.pte])", + }, + ) + runtime.cxx_test( name = "test_workspace_sharing", srcs = ["runtime/test_workspace_sharing.cpp"], @@ -71,6 +85,7 @@ def define_common_targets(): "//executorch/extension/module:module", "//executorch/extension/tensor:tensor", "//executorch/backends/xnnpack:xnnpack_backend", + "//executorch/runtime/backend:backend_options_map", ], env = { "ET_XNNPACK_GENERATED_ADD_LARGE_PTE_PATH": "$(location fbcode//executorch/test/models:exported_xnnp_delegated_programs[ModuleAddLarge.pte])", diff --git a/shim_et/xplat/executorch/build/build_variables.bzl b/shim_et/xplat/executorch/build/build_variables.bzl index 8844ae165f6..edddc1da916 100644 --- a/shim_et/xplat/executorch/build/build_variables.bzl +++ b/shim_et/xplat/executorch/build/build_variables.bzl @@ -474,6 +474,7 @@ XNNPACK_BACKEND_BUCK_SRCS = [ "runtime/XNNPACKBackend.cpp", "runtime/XNNWeightsCache.cpp", "runtime/XNNWorkspaceManager.cpp", + "runtime/XnnpackBackendOptions.cpp", "runtime/profiling/XNNProfiler.cpp", ]