Skip to content

Commit 13a5235

Browse files
authored
Enable weight cache in multi-thread delegate stress test (pytorch#19706)
Differential Revision: D105859905 Pull Request resolved: pytorch#19706
1 parent 64684c7 commit 13a5235

2 files changed

Lines changed: 79 additions & 23 deletions

File tree

backends/test/multi_method_delegate_test.cpp

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <executorch/backends/xnnpack/runtime/XNNPACKBackend.h>
99

10+
#include <executorch/runtime/backend/backend_options_map.h>
1011
#include <executorch/runtime/backend/interface.h>
1112
#include <executorch/runtime/backend/options.h>
1213
#include <executorch/runtime/executor/program.h>
@@ -16,6 +17,7 @@
1617
#include <executorch/extension/memory_allocator/malloc_memory_allocator.h>
1718
#include <executorch/extension/runner_util/inputs.h>
1819

20+
using executorch::backends::xnnpack::weight_cache_option_key;
1921
using executorch::backends::xnnpack::workspace_sharing_mode_option_key;
2022
using executorch::backends::xnnpack::WorkspaceSharingMode;
2123
using executorch::backends::xnnpack::xnnpack_backend_key;
@@ -106,14 +108,17 @@ class ETPTEMethodRunBaseTest : public ::testing::Test {
106108
}
107109
};
108110

109-
class XNNPACKMultiDelegateTest : public ETPTEMethodRunBaseTest {
111+
class XNNPACKMultiDelegateTest : public ETPTEMethodRunBaseTest,
112+
public ::testing::WithParamInterface<
113+
std::tuple<WorkspaceSharingMode, bool>> {
110114
protected:
111115
std::string kTestPTE1Path, kTestPTE2Path;
112116
std::string kMethodName;
113117
int num_threads;
114118

115119
void SetUp() override {
116120
ETPTEMethodRunBaseTest::SetUp();
121+
117122
const char* pte1_path =
118123
std::getenv("ET_XNNPACK_GENERATED_ADD_LARGE_PTE_PATH");
119124
if (pte1_path == nullptr) {
@@ -164,33 +169,64 @@ class XNNPACKMultiDelegateTest : public ETPTEMethodRunBaseTest {
164169
ASSERT_EQ(count, num_threads);
165170
}
166171

167-
void setWorkspaceSharingMode(WorkspaceSharingMode mode) {
168-
executorch::runtime::runtime_init();
169-
170-
BackendOptions<1> backend_options;
172+
// Set both the workspace sharing mode and the weight cache flag in a single
173+
// call so each parameterized case starts from a clean, fully-specified
174+
// backend option state. set_option is process-global, and tests run
175+
// sequentially in the same process, so we must overwrite both options every
176+
// time to prevent leakage between cases.
177+
void setOptions(WorkspaceSharingMode mode, bool weight_cache_enabled) {
178+
BackendOptions<2> backend_options;
171179
backend_options.set_option(
172180
workspace_sharing_mode_option_key, static_cast<int>(mode));
181+
backend_options.set_option(weight_cache_option_key, weight_cache_enabled);
173182

174183
auto status = executorch::runtime::set_option(
175184
xnnpack_backend_key, backend_options.view());
176185
ASSERT_EQ(status, Error::Ok);
177186
}
178187
};
179188

180-
TEST_F(XNNPACKMultiDelegateTest, MultipleThreadsSharingDisabled) {
181-
setWorkspaceSharingMode(WorkspaceSharingMode::Disabled);
182-
runStressTest();
183-
}
184-
185-
TEST_F(XNNPACKMultiDelegateTest, MultipleThreadsPerModelSharing) {
186-
setWorkspaceSharingMode(WorkspaceSharingMode::PerModel);
189+
// Parameterized over (WorkspaceSharingMode, weight_cache_enabled) to exercise
190+
// every combination of XNNPACK concurrency-affecting options. The
191+
// weight_cache_enabled=true cases reproduce the race condition fixed by
192+
// D105753995 (TSAN-detected data race on XNNWeightsCache::is_finalized_ /
193+
// named_data_map_ when init() is called concurrently). The
194+
// weight_cache_enabled=false cases provide regression coverage for the
195+
// non-cache concurrent path.
196+
TEST_P(XNNPACKMultiDelegateTest, MultipleThreadsStress) {
197+
const auto [sharing_mode, weight_cache_enabled] = GetParam();
198+
setOptions(sharing_mode, weight_cache_enabled);
187199
runStressTest();
188200
}
189201

190-
TEST_F(XNNPACKMultiDelegateTest, MultipleThreadsGlobalSharing) {
191-
setWorkspaceSharingMode(WorkspaceSharingMode::Global);
192-
runStressTest();
193-
}
202+
INSTANTIATE_TEST_SUITE_P(
203+
AllConfigs,
204+
XNNPACKMultiDelegateTest,
205+
::testing::Combine(
206+
::testing::Values(
207+
WorkspaceSharingMode::Disabled,
208+
WorkspaceSharingMode::PerModel,
209+
WorkspaceSharingMode::Global),
210+
::testing::Bool()),
211+
[](const ::testing::TestParamInfo<XNNPACKMultiDelegateTest::ParamType>&
212+
info) {
213+
const auto sharing_mode = std::get<0>(info.param);
214+
const auto weight_cache_enabled = std::get<1>(info.param);
215+
const char* mode_name = "Unknown";
216+
switch (sharing_mode) {
217+
case WorkspaceSharingMode::Disabled:
218+
mode_name = "SharingDisabled";
219+
break;
220+
case WorkspaceSharingMode::PerModel:
221+
mode_name = "PerModelSharing";
222+
break;
223+
case WorkspaceSharingMode::Global:
224+
mode_name = "GlobalSharing";
225+
break;
226+
}
227+
return std::string(mode_name) +
228+
(weight_cache_enabled ? "_WeightCacheOn" : "_WeightCacheOff");
229+
});
194230

195231
// TODO(T208989291): Add more tests here. For example,
196232
// - PTEs with multiple methods

backends/test/targets.bzl

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,38 @@ def define_common_targets(is_fbcode = False):
4040
"ET_XNNPACK_GENERATED_SUB_LARGE_PTE_PATH": "$(location fbcode//executorch/test/models:exported_xnnp_delegated_programs[ModuleSubLarge.pte])",
4141
}
4242

43+
multi_method_delegate_test_deps = [
44+
"//executorch/runtime/executor:program",
45+
"//executorch/extension/data_loader:file_data_loader",
46+
"//executorch/extension/memory_allocator:malloc_memory_allocator",
47+
"//executorch/kernels/portable:generated_lib",
48+
"//executorch/backends/xnnpack:xnnpack_backend",
49+
"//executorch/extension/runner_util:inputs",
50+
]
51+
4352
runtime.cxx_test(
4453
name = "multi_method_delegate_test",
4554
srcs = [
4655
"multi_method_delegate_test.cpp",
4756
],
48-
deps = [
49-
"//executorch/runtime/executor:program",
50-
"//executorch/extension/data_loader:file_data_loader",
51-
"//executorch/extension/memory_allocator:malloc_memory_allocator",
52-
"//executorch/kernels/portable:generated_lib",
53-
"//executorch/backends/xnnpack:xnnpack_backend",
54-
"//executorch/extension/runner_util:inputs",
57+
deps = multi_method_delegate_test_deps,
58+
env = modules_env,
59+
)
60+
61+
# Sibling target that always builds and runs under ThreadSanitizer,
62+
# regardless of the user's --config fbcode.sanitizer / @mode/* selection.
63+
# This guarantees deterministic detection of the XNNWeightsCache data
64+
# race fixed by D105753995 (the non-TSAN variant is timing-dependent
65+
# and effectively flaky as a regression signal).
66+
runtime.cxx_test(
67+
name = "multi_method_delegate_test_tsan",
68+
srcs = [
69+
"multi_method_delegate_test.cpp",
5570
],
71+
deps = multi_method_delegate_test_deps,
5672
env = modules_env,
73+
modifiers = [
74+
"ovr_config//build_mode/constraints:sanitizer",
75+
"ovr_config//build_mode:sanitizer_type[tsan]",
76+
],
5777
)

0 commit comments

Comments
 (0)