7
7
*/
8
8
9
9
#include < executorch/backends/xnnpack/runtime/XNNCompiler.h>
10
+ #include < executorch/backends/xnnpack/runtime/XNNPACKBackend.h>
10
11
#include < executorch/backends/xnnpack/runtime/XNNWeightsCache.h>
11
12
#include < executorch/runtime/backend/interface.h>
12
13
#include < executorch/runtime/core/error.h>
@@ -51,21 +52,9 @@ class XnnpackBackend final
51
52
}
52
53
53
54
#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 ());
55
+ enable_shared_workspace_ = true ;
56
+ #else
57
+ enable_shared_workspace_ = false ;
69
58
#endif // ENABLE_XNNPACK_SHARED_WORKSPACE
70
59
}
71
60
@@ -86,9 +75,29 @@ class XnnpackBackend final
86
75
const NamedDataMap* named_data_map = context.get_named_data_map ();
87
76
// thread safe. This can heppen when multiple threads call init() on
88
77
// the same backend instance.
89
- #ifdef ENABLE_XNNPACK_SHARED_WORKSPACE
90
- const std::lock_guard<std::mutex> lock (workspace_mutex_);
91
- #endif
78
+
79
+ std::unique_lock<std::mutex> lock (workspace_mutex_, std::defer_lock);
80
+ if (enable_shared_workspace_) {
81
+ lock.lock ();
82
+ if (!workspace_) {
83
+ // Create a workspace for the XNNExecutor to use. This workspace will be
84
+ // shared across all delegate instances.
85
+ ET_LOG (Debug, " Creating XNN workspace" );
86
+ xnn_workspace_t workspace = nullptr ;
87
+ auto status = xnn_create_workspace (&workspace);
88
+ if (status != xnn_status_success) {
89
+ ET_LOG (
90
+ Error,
91
+ " Failed to create XNN workspace, XNNPACK status: 0x%x" ,
92
+ (unsigned int )status);
93
+ workspace = nullptr ;
94
+ return Error::Internal;
95
+ }
96
+ // NOLINTNEXTLINE(facebook-hte-NullableDereference) - false positive
97
+ workspace_.reset (workspace);
98
+ ET_LOG (Debug, " Created XNN workspace: %p" , workspace_.get ());
99
+ }
100
+ }
92
101
93
102
#ifdef ENABLE_XNNPACK_WEIGHTS_CACHE
94
103
const std::lock_guard<std::mutex> lock_weight_cache (weights_cache_mutex_);
@@ -129,9 +138,10 @@ class XnnpackBackend final
129
138
EValue** args) const override {
130
139
auto executor = static_cast <xnnpack::delegate::XNNExecutor*>(handle);
131
140
132
- #ifdef ENABLE_XNNPACK_SHARED_WORKSPACE
133
- const std::lock_guard<std::mutex> lock (workspace_mutex_);
134
- #endif
141
+ std::unique_lock<std::mutex> lock (workspace_mutex_, std::defer_lock);
142
+ if (enable_shared_workspace_) {
143
+ lock.lock ();
144
+ }
135
145
136
146
#ifdef ENABLE_XNNPACK_WEIGHTS_CACHE
137
147
const std::lock_guard<std::mutex> lock_weights_cache (weights_cache_mutex_);
@@ -160,9 +170,10 @@ class XnnpackBackend final
160
170
// This is needed to serialize access to xnn_delete_runtime which is not
161
171
// thread safe. This can heppen when multiple threads call destroy() on
162
172
// the same backend instance.
163
- #ifdef ENABLE_XNNPACK_SHARED_WORKSPACE
164
- const std::lock_guard<std::mutex> lock (workspace_mutex_);
165
- #endif
173
+ std::unique_lock<std::mutex> lock (workspace_mutex_, std::defer_lock);
174
+ if (enable_shared_workspace_) {
175
+ lock.lock ();
176
+ }
166
177
167
178
auto executor = static_cast <xnnpack::delegate::XNNExecutor*>(handle);
168
179
@@ -181,12 +192,16 @@ class XnnpackBackend final
181
192
}
182
193
}
183
194
195
+ void set_workspace_sharing_enabled (bool enable) {
196
+ this ->enable_shared_workspace_ = enable;
197
+ }
198
+
184
199
private:
200
+ bool enable_shared_workspace_;
185
201
// This is a global workspace for all delegate instances.
186
202
mutable std::mutex workspace_mutex_;
187
- std::unique_ptr<xnn_workspace, decltype (&xnn_release_workspace)> workspace_{
188
- nullptr ,
189
- &xnn_release_workspace};
203
+ mutable std::unique_ptr<xnn_workspace, decltype (&xnn_release_workspace)>
204
+ workspace_{nullptr , &xnn_release_workspace};
190
205
191
206
// Weights cache is global to all delegate instances.
192
207
mutable std::mutex weights_cache_mutex_;
@@ -199,10 +214,16 @@ class XnnpackBackend final
199
214
};
200
215
201
216
namespace {
202
- auto cls = XnnpackBackend();
203
- Backend backend{" XnnpackBackend" , &cls };
217
+ auto backend_instance = XnnpackBackend();
218
+ Backend backend{" XnnpackBackend" , &backend_instance };
204
219
static auto success_with_compiler = register_backend(backend);
205
220
} // namespace
206
221
222
+ namespace xnnpack {
223
+ void set_workspace_sharing_enabled (bool enable) {
224
+ backend_instance.set_workspace_sharing_enabled (enable);
225
+ }
226
+ } // namespace xnnpack
227
+
207
228
} // namespace backends
208
229
} // namespace executorch
0 commit comments