1010#include < executorch/backends/xnnpack/runtime/XNNPACKBackend.h>
1111#include < executorch/backends/xnnpack/runtime/XNNWeightsCache.h>
1212#include < executorch/backends/xnnpack/runtime/XNNWorkspace.h>
13- #include < executorch/backends/xnnpack/runtime/XNNWorkspaceManager .h>
13+ #include < executorch/backends/xnnpack/runtime/XnnpackBackendOptions .h>
1414#include < executorch/runtime/backend/interface.h>
1515#include < executorch/runtime/core/error.h>
1616#include < executorch/runtime/core/evalue.h>
2424namespace executorch {
2525namespace backends {
2626
27- using executorch::backends::xnnpack::WorkspaceSharingMode;
2827using executorch::backends::xnnpack::XNNWorkspace;
2928using executorch::backends::xnnpack::delegate::XNNWeightsCache;
3029using executorch::ET_RUNTIME_NAMESPACE ::Backend;
@@ -57,9 +56,6 @@ class XnnpackBackend final
5756 (unsigned int )status);
5857 return ;
5958 }
60-
61- // Workspace manager is initialized with the appropriate default mode in its
62- // constructor
6359 }
6460
6561 bool is_available () const override {
@@ -82,17 +78,24 @@ class XnnpackBackend final
8278
8379 auto program_id =
8480 reinterpret_cast <uintptr_t >(context.get_runtime_allocator ());
85- auto workspace_result = get_or_create_workspace (program_id);
81+ auto sharing_mode_result = options_.resolve_sharing_mode (context);
82+ if (!sharing_mode_result.ok ()) {
83+ return sharing_mode_result.error ();
84+ }
85+ auto workspace_result =
86+ options_.workspace_manager ().get_or_create_workspace (
87+ program_id, sharing_mode_result.get ());
8688 if (!workspace_result.ok ()) {
8789 return workspace_result.error ();
8890 }
8991 auto workspace = workspace_result.get ();
9092
91- #ifdef ENABLE_XNNPACK_WEIGHTS_CACHE
92- const std::lock_guard<std::mutex> lock_weight_cache (weights_cache_mutex_);
93- weights_cache_->initialize_for_runtime (
94- context.get_runtime_allocator (), named_data_map);
95- #endif
93+ bool use_weight_cache = options_.resolve_weight_cache (context);
94+ if (use_weight_cache) {
95+ const std::lock_guard<std::mutex> lock_weight_cache (weights_cache_mutex_);
96+ weights_cache_->initialize_for_runtime (
97+ context.get_runtime_allocator (), named_data_map);
98+ }
9699
97100 auto [workspace_lock, workspace_ptr] = workspace->acquire ();
98101
@@ -129,9 +132,11 @@ class XnnpackBackend final
129132 Span<EValue*> args) const override {
130133 auto executor = static_cast <xnnpack::delegate::XNNExecutor*>(handle);
131134
132- #ifdef ENABLE_XNNPACK_WEIGHTS_CACHE
133- const std::lock_guard<std::mutex> lock_weights_cache (weights_cache_mutex_);
134- #endif
135+ std::unique_lock<std::mutex> lock_weights_cache (
136+ weights_cache_mutex_, std::defer_lock);
137+ if (executor->uses_weight_cache ()) {
138+ lock_weights_cache.lock ();
139+ }
135140
136141 auto [raii_lock, _] = executor->get_workspace ()->acquire ();
137142
@@ -161,11 +166,11 @@ class XnnpackBackend final
161166 executor->print_avg_op_timings ();
162167#endif
163168
164- # ifdef ENABLE_XNNPACK_WEIGHTS_CACHE
165- const std::lock_guard<std::mutex> lock_weights_cache (
166- weights_cache_mutex_);
167- weights_cache_->delete_packed_data (executor->get_packed_data_names ());
168- # endif
169+ if (executor-> uses_weight_cache ()) {
170+ const std::lock_guard<std::mutex> lock_weights_cache (
171+ weights_cache_mutex_);
172+ weights_cache_->delete_packed_data (executor->get_packed_data_names ());
173+ }
169174
170175 // This is needed to serialize access to xnn_delete_runtime which is not
171176 // thread safe. This can heppen when multiple threads call destroy() on
@@ -181,72 +186,32 @@ class XnnpackBackend final
181186 }
182187 }
183188
184- Error get_option_internal (
189+ Error get_option (
185190 BackendOptionContext& context,
186- executorch::runtime::Span<executorch::runtime::BackendOption>&
187- backend_options) const {
188- // Intentionally not locking here as it is not required.
189-
190- // Verify that the expected option key is present and modify the value
191+ Span<BackendOption>& backend_options) override {
191192 for (size_t i = 0 ; i < backend_options.size (); ++i) {
192- if (strcmp (
193- backend_options[i].key ,
194- xnnpack::workspace_sharing_mode_option_key) == 0 ) {
195- // Set the value to what was stored by set_option
196- backend_options[i].value =
197- static_cast <int >(workspace_manager_.get_sharing_mode ());
193+ Error err = options_.get_option (backend_options[i]);
194+ if (err != Error::Ok) {
195+ return err;
198196 }
199197 }
200-
201198 return Error::Ok;
202199 }
203200
204- Error get_option (
205- BackendOptionContext& context,
206- executorch::runtime::Span<executorch::runtime::BackendOption>&
207- backend_options) override {
208- return get_option_internal (context, backend_options);
209- }
210-
211201 Error set_option (
212202 BackendOptionContext& context,
213- const executorch::runtime::Span<executorch::runtime::BackendOption>&
214- backend_options) override {
215- if (backend_options.size () > 0 ) {
216- for (const auto & option : backend_options) {
217- if (strcmp (option.key , xnnpack::workspace_sharing_mode_option_key) ==
218- 0 ) {
219- if (auto * val = std::get_if<int >(&option.value )) {
220- if (*val < 0 ||
221- *val > static_cast <int >(WorkspaceSharingMode::Count)) {
222- ET_LOG (
223- Error,
224- " XNNPACK workspace sharing mode must be between 0 and %d, inclusive, but was %d." ,
225- static_cast <int >(WorkspaceSharingMode::Count),
226- *val);
227- return Error::InvalidArgument;
228- }
229-
230- ET_LOG (
231- Debug, " Setting XNNPACK workspace sharing mode to %d." , *val);
232- auto status = workspace_manager_.set_sharing_mode (
233- static_cast <WorkspaceSharingMode>(*val));
234- if (status != Error::Ok) {
235- return status;
236- }
237- } else {
238- ET_LOG (Error, " XNNPACK workspace sharing mode must be an integer." );
239- return Error::InvalidArgument;
240- }
241- }
203+ const Span<BackendOption>& backend_options) override {
204+ for (const auto & option : backend_options) {
205+ Error err = options_.set_option (option);
206+ if (err != Error::Ok) {
207+ return err;
242208 }
243209 }
244210 return Error::Ok;
245211 }
246212
247213 private:
248- // Workspace manager for handling workspace sharing modes
249- mutable xnnpack::XNNWorkspaceManager workspace_manager_;
214+ mutable xnnpack::XnnpackBackendOptions options_;
250215
251216 // Weights cache is global to all delegate instances.
252217 mutable std::mutex weights_cache_mutex_;
@@ -257,13 +222,6 @@ class XnnpackBackend final
257222 // weights_cache_mutex_
258223 // workspace_meta_mutex_
259224 // workspace_mutex_ (owned by executor)
260-
261- // Retrieve a workspace for the given method ID, depending on the sharing
262- // mode.
263- Result<std::shared_ptr<XNNWorkspace>> get_or_create_workspace (
264- uintptr_t program_id) const {
265- return workspace_manager_.get_or_create_workspace (program_id);
266- }
267225};
268226
269227namespace {
0 commit comments