Skip to content

Commit 63ca2fb

Browse files
committed
Xnnpack test for program-data separation
Pull Request resolved: #10532 Add xnnpack test for program-data separation ghstack-source-id: 282132816 @exported-using-ghexport Differential Revision: [D73794695](https://our.internmc.facebook.com/intern/diff/D73794695/)
1 parent 0abd5bc commit 63ca2fb

File tree

3 files changed

+140
-6
lines changed

3 files changed

+140
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#include <executorch/extension/data_loader/file_data_loader.h>
10+
#include <executorch/extension/flat_tensor/flat_tensor_data_map.h>
11+
#include <executorch/runtime/core/error.h>
12+
#include <executorch/runtime/core/result.h>
13+
#include <executorch/runtime/executor/method.h>
14+
#include <executorch/runtime/executor/program.h>
15+
#include <executorch/runtime/executor/test/managed_memory_manager.h>
16+
#include <executorch/runtime/platform/runtime.h>
17+
18+
#include <gtest/gtest.h>
19+
20+
using namespace ::testing;
21+
using executorch::extension::FlatTensorDataMap;
22+
using executorch::runtime::DataLoader;
23+
using executorch::runtime::Error;
24+
using executorch::runtime::FreeableBuffer;
25+
using executorch::runtime::Method;
26+
using executorch::runtime::Program;
27+
using executorch::runtime::Result;
28+
using executorch::runtime::testing::ManagedMemoryManager;
29+
using torch::executor::util::FileDataLoader;
30+
31+
constexpr size_t kDefaultNonConstMemBytes = 32 * 1024U;
32+
constexpr size_t kDefaultRuntimeMemBytes = 32 * 1024U;
33+
34+
class DataSeparationTest : public ::testing::Test {
35+
protected:
36+
void SetUp() override {
37+
// Since these tests cause ET_LOG to be called, the PAL must be initialized
38+
// first.
39+
executorch::runtime::runtime_init();
40+
41+
// Create data loaders.
42+
Result<FileDataLoader> linear_program_loader =
43+
FileDataLoader::from(std::getenv("ET_MODULE_LINEAR_XNN_PROGRAM_PATH"));
44+
ASSERT_EQ(linear_program_loader.error(), Error::Ok);
45+
linear_program_loader_ = std::make_unique<FileDataLoader>(
46+
std::move(linear_program_loader.get()));
47+
48+
Result<FileDataLoader> linear_data_loader =
49+
FileDataLoader::from(std::getenv("ET_MODULE_LINEAR_XNN_DATA_PATH"));
50+
ASSERT_EQ(linear_data_loader.error(), Error::Ok);
51+
linear_data_loader_ =
52+
std::make_unique<FileDataLoader>(std::move(linear_data_loader.get()));
53+
54+
// Create programs.
55+
Result<Program> linear_program = Program::load(
56+
linear_program_loader_.get(),
57+
Program::Verification::InternalConsistency);
58+
ASSERT_EQ(linear_program.error(), Error::Ok);
59+
linear_program_ =
60+
std::make_unique<Program>(std::move(linear_program.get()));
61+
62+
Result<FlatTensorDataMap> linear_data_map =
63+
FlatTensorDataMap::load(linear_data_loader_.get());
64+
EXPECT_EQ(linear_data_map.error(), Error::Ok);
65+
linear_data_map_ =
66+
std::make_unique<FlatTensorDataMap>(std::move(linear_data_map.get()));
67+
}
68+
69+
private:
70+
std::unique_ptr<FileDataLoader> linear_program_loader_;
71+
std::unique_ptr<FileDataLoader> linear_data_loader_;
72+
73+
protected:
74+
std::unique_ptr<Program> linear_program_;
75+
std::unique_ptr<FlatTensorDataMap> linear_data_map_;
76+
};
77+
78+
TEST_F(DataSeparationTest, TestExternalData) {
79+
FlatTensorDataMap* data_map = linear_data_map_.get();
80+
EXPECT_EQ(data_map->get_num_keys().get(), 2);
81+
82+
Result<const char*> key0 = data_map->get_key(0);
83+
EXPECT_EQ(key0.error(), Error::Ok);
84+
Result<const char*> key1 = data_map->get_key(1);
85+
EXPECT_EQ(key1.error(), Error::Ok);
86+
87+
// Check that accessing keys out of bounds fails.
88+
EXPECT_EQ(data_map->get_key(2).error(), Error::InvalidArgument);
89+
90+
// Linear.weight
91+
Result<FreeableBuffer> data0 = data_map->get_data(key0.get());
92+
EXPECT_EQ(data0.error(), Error::Ok);
93+
EXPECT_EQ(data0.get().size(), 36); // 3*3*4 (3*3 matrix, 4 bytes per float)
94+
95+
// Linear.bias
96+
Result<FreeableBuffer> data1 = data_map->get_data(key1.get());
97+
EXPECT_EQ(data1.error(), Error::Ok);
98+
EXPECT_EQ(data1.get().size(), 12); // 3*4 (3 vector, 4 bytes per float)
99+
100+
// Check that accessing non-existent data fails.
101+
Result<FreeableBuffer> data2 = data_map->get_data("nonexistent");
102+
EXPECT_EQ(data2.error(), Error::NotFound);
103+
}
104+
105+
TEST_F(DataSeparationTest, TestE2E) {
106+
ManagedMemoryManager mmm(kDefaultNonConstMemBytes, kDefaultRuntimeMemBytes);
107+
Result<Method> method = linear_program_->load_method(
108+
"forward", &mmm.get(), nullptr, linear_data_map_.get());
109+
ASSERT_EQ(method.error(), Error::Ok);
110+
111+
// Can execute the method.
112+
Error err = method->execute();
113+
ASSERT_EQ(err, Error::Ok);
114+
}

backends/xnnpack/test/targets.bzl

+20
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,23 @@ def define_common_targets():
4343
"//executorch/schema:program",
4444
],
4545
)
46+
47+
runtime.cxx_test(
48+
name = "test_xnn_data_separation",
49+
srcs = ["runtime/test_xnn_data_separation.cpp"],
50+
deps = [
51+
"//executorch/runtime/executor/test:managed_memory_manager",
52+
"//executorch/runtime/executor:program",
53+
"//executorch/extension/data_loader:file_data_loader",
54+
"//executorch/backends/xnnpack:xnnpack_backend",
55+
"//executorch/extension/flat_tensor:flat_tensor_data_map",
56+
],
57+
env = {
58+
# The tests use these vars to find the program files to load.
59+
# Uses an fbcode target path because the authoring/export tools
60+
# intentionally don't work in xplat (since they're host-only
61+
# tools).
62+
"ET_MODULE_LINEAR_XNN_PROGRAM_PATH": "$(location fbcode//executorch/test/models:exported_xnnpack_program_and_data[ModuleLinear-e.pte])",
63+
"ET_MODULE_LINEAR_XNN_DATA_PATH": "$(location fbcode//executorch/test/models:exported_xnnpack_program_and_data[ModuleLinear.ptd])",
64+
},
65+
)

test/models/targets.bzl

+6-6
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def define_common_targets():
9898
"ModuleLinear",
9999
"ModuleSimpleTrain",
100100
]
101-
101+
102102
runtime.genrule(
103103
name = "exported_program_and_data",
104104
cmd = "$(exe :export_program) --modules " + ",".join(MODULES_AND_DATA_TO_EXPORT) + " --external-constants --outdir $OUT",
@@ -213,18 +213,18 @@ def define_common_targets():
213213
runtime.genrule(
214214
name = "exported_xnnpack_program_and_data",
215215
cmd = "$(exe :export_delegated_program)" +
216-
" --modules ModuleLinear" +
216+
" --modules ModuleLinear" +
217217
" --backend_id XnnpackBackend" +
218218
" --external_constants" +
219219
" --outdir $OUT",
220-
220+
221221
outs = {
222222
"ModuleLinear-e.pte": ["ModuleLinear-e.pte"],
223223
"ModuleLinear.ptd": ["ModuleLinear.ptd"],
224224
},
225225
default_outs = ["."],
226226
visibility = [
227-
"//executorch/runtime/executor/test/...",
227+
"//executorch/backends/xnnpack/test/...",
228228
"//executorch/test/...",
229229
],
230230
)
@@ -233,11 +233,11 @@ def define_common_targets():
233233
runtime.genrule(
234234
name = "exported_executor_backend_program_and_data",
235235
cmd = "$(exe :export_delegated_program)" +
236-
" --modules ModuleLinear" +
236+
" --modules ModuleLinear" +
237237
" --backend_id ExecutorBackend" +
238238
" --external_constants" +
239239
" --outdir $OUT",
240-
240+
241241
outs = {
242242
"ModuleLinear-e.pte": ["ModuleLinear-e.pte"],
243243
},

0 commit comments

Comments
 (0)