Skip to content

Commit f12f1ff

Browse files
committed
Refactor XNN workspace sharing to allow runtime gating
1 parent 7b39a0c commit f12f1ff

File tree

3 files changed

+57
-36
lines changed

3 files changed

+57
-36
lines changed

backends/xnnpack/runtime/XNNCompiler.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,24 +2237,22 @@ ET_NODISCARD Error XNNCompiler::compileModel(
22372237
xnn_weights_cache_t weights_cache_ptr = nullptr;
22382238
#endif
22392239

2240-
#ifdef ENABLE_XNNPACK_SHARED_WORKSPACE
2241-
ET_CHECK_OR_RETURN_ERROR(
2242-
workspace != nullptr, Internal, "Failed to initialize XNNPACK workspace");
2240+
if (workspace != nullptr) {
22432241
status = xnn_create_runtime_v4(
22442242
subgraph.get(),
22452243
weights_cache_ptr,
22462244
workspace,
22472245
::executorch::extension::threadpool::get_pthreadpool(),
22482246
runtime_flags,
22492247
&runtime_ptr);
2250-
#else
2251-
status = xnn_create_runtime_v3(
2252-
subgraph.get(),
2253-
weights_cache_ptr,
2254-
::executorch::extension::threadpool::get_pthreadpool(),
2255-
runtime_flags,
2256-
&runtime_ptr);
2257-
#endif
2248+
} else {
2249+
status = xnn_create_runtime_v3(
2250+
subgraph.get(),
2251+
weights_cache_ptr,
2252+
::executorch::extension::threadpool::get_pthreadpool(),
2253+
runtime_flags,
2254+
&runtime_ptr);
2255+
}
22582256

22592257
ET_CHECK_OR_RETURN_ERROR(
22602258
xnn_status_success == status,

backends/xnnpack/runtime/XNNPACKBackend.cpp

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,7 @@ class XnnpackBackend final
5151
}
5252

5353
#ifdef ENABLE_XNNPACK_SHARED_WORKSPACE
54-
// Create a workspace for the XNNExecutor to use. This workspace will be
55-
// shared across all delegate instances.
56-
ET_LOG(Debug, "Creating XNN workspace");
57-
xnn_workspace_t workspace = nullptr;
58-
status = xnn_create_workspace(&workspace);
59-
if (status != xnn_status_success) {
60-
ET_LOG(
61-
Error,
62-
"Failed to create XNN workspace, XNNPACK status: 0x%x",
63-
(unsigned int)status);
64-
workspace = nullptr;
65-
return;
66-
}
67-
workspace_.reset(workspace);
68-
ET_LOG(Debug, "Created XNN workspace: %p", workspace_.get());
54+
enable_shared_workspace_ = true;
6955
#endif // ENABLE_XNNPACK_SHARED_WORKSPACE
7056
}
7157

@@ -86,9 +72,28 @@ class XnnpackBackend final
8672
const NamedDataMap* named_data_map = context.get_named_data_map();
8773
// thread safe. This can heppen when multiple threads call init() on
8874
// the same backend instance.
89-
#ifdef ENABLE_XNNPACK_SHARED_WORKSPACE
90-
const std::lock_guard<std::mutex> lock(workspace_mutex_);
91-
#endif
75+
76+
std::unique_lock<std::mutex> lock(workspace_mutex_, std::defer_lock);
77+
if (enable_shared_workspace_) {
78+
lock.lock();
79+
if (!workspace_) {
80+
// Create a workspace for the XNNExecutor to use. This workspace will be
81+
// shared across all delegate instances.
82+
ET_LOG(Debug, "Creating XNN workspace");
83+
xnn_workspace_t workspace = nullptr;
84+
auto status = xnn_create_workspace(&workspace);
85+
if (status != xnn_status_success) {
86+
ET_LOG(
87+
Error,
88+
"Failed to create XNN workspace, XNNPACK status: 0x%x",
89+
(unsigned int)status);
90+
workspace = nullptr;
91+
return Error::Internal;
92+
}
93+
workspace_.reset(workspace);
94+
ET_LOG(Debug, "Created XNN workspace: %p", workspace_.get());
95+
}
96+
}
9297

9398
#ifdef ENABLE_XNNPACK_WEIGHTS_CACHE
9499
const std::lock_guard<std::mutex> lock_weight_cache(weights_cache_mutex_);
@@ -129,9 +134,10 @@ class XnnpackBackend final
129134
EValue** args) const override {
130135
auto executor = static_cast<xnnpack::delegate::XNNExecutor*>(handle);
131136

132-
#ifdef ENABLE_XNNPACK_SHARED_WORKSPACE
133-
const std::lock_guard<std::mutex> lock(workspace_mutex_);
134-
#endif
137+
std::unique_lock<std::mutex> lock(workspace_mutex_, std::defer_lock);
138+
if (enable_shared_workspace_) {
139+
lock.lock();
140+
}
135141

136142
#ifdef ENABLE_XNNPACK_WEIGHTS_CACHE
137143
const std::lock_guard<std::mutex> lock_weights_cache(weights_cache_mutex_);
@@ -160,9 +166,10 @@ class XnnpackBackend final
160166
// This is needed to serialize access to xnn_delete_runtime which is not
161167
// thread safe. This can heppen when multiple threads call destroy() on
162168
// the same backend instance.
163-
#ifdef ENABLE_XNNPACK_SHARED_WORKSPACE
164-
const std::lock_guard<std::mutex> lock(workspace_mutex_);
165-
#endif
169+
std::unique_lock<std::mutex> lock(workspace_mutex_, std::defer_lock);
170+
if (enable_shared_workspace_) {
171+
lock.lock();
172+
}
166173

167174
auto executor = static_cast<xnnpack::delegate::XNNExecutor*>(handle);
168175

@@ -181,10 +188,15 @@ class XnnpackBackend final
181188
}
182189
}
183190

191+
void set_workspace_sharing_enabled(bool enable) {
192+
this->enable_shared_workspace_ = enable;
193+
}
194+
184195
private:
196+
bool enable_shared_workspace_;
185197
// This is a global workspace for all delegate instances.
186198
mutable std::mutex workspace_mutex_;
187-
std::unique_ptr<xnn_workspace, decltype(&xnn_release_workspace)> workspace_{
199+
mutable std::unique_ptr<xnn_workspace, decltype(&xnn_release_workspace)> workspace_{
188200
nullptr,
189201
&xnn_release_workspace};
190202

@@ -204,5 +216,11 @@ Backend backend{"XnnpackBackend", &cls};
204216
static auto success_with_compiler = register_backend(backend);
205217
} // namespace
206218

219+
namespace executorch::backend::xnnpack {
220+
ET_EXPERIMENTAL void set_workspace_sharing_enabled(bool enable) {
221+
222+
}
223+
}
224+
207225
} // namespace backends
208226
} // namespace executorch
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <executorch/runtime/compiler.h>
2+
3+
namespace executorch::backend::xnnpack {
4+
ET_EXPERIMENTAL void set_workspace_sharing_enabled(bool enable);
5+
}

0 commit comments

Comments
 (0)