Skip to content

Commit 63c4dde

Browse files
committed
[7/N] Add sugar syntax for module.update
The update API in method is supposed to be portable, but we can make it more user friendly for the update API in module. Add a bit sugar syntax in module to improve UX. Such that user can update backend option in module like following: ``` Module module(stub_model_path_); int new_num_threads = 4; const auto update_result = module.update("forward", { {"StubBackend", {{IntKey("NumberOfThreads"), new_num_threads}} }, ); ``` Differential Revision: [D76242292](https://our.internmc.facebook.com/intern/diff/D76242292/) ghstack-source-id: 289276526 Pull Request resolved: #11534
1 parent 60a5a0f commit 63c4dde

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
#pragma once
3+
4+
#include <vector>
5+
#include <string>
6+
#include <initializer_list>
7+
#include <executorch/runtime/backend/backend_options.h>
8+
9+
namespace executorch {
10+
namespace runtime {
11+
12+
class DynamicBackendOptionsMap {
13+
public:
14+
using OptionList = std::initializer_list<BackendOption>;
15+
16+
DynamicBackendOptionsMap(
17+
std::initializer_list<std::pair<const char*, OptionList>> list) {
18+
entries_.reserve(list.size());
19+
for (const auto& item : list) {
20+
// Store backend name
21+
backend_names_.push_back(item.first);
22+
// Store options
23+
options_storage_.push_back(std::vector<BackendOption>(item.second));
24+
// Create Entry with stable references
25+
entries_.push_back({
26+
backend_names_.back().c_str(),
27+
ArrayRef<BackendOption>(options_storage_.back().data(), options_storage_.back().size())
28+
});
29+
}
30+
}
31+
32+
ArrayRef<Entry> entries() const {
33+
return ArrayRef<Entry>(entries_.data(), entries_.size());
34+
}
35+
36+
private:
37+
std::vector<std::string> backend_names_;
38+
std::vector<std::vector<BackendOption>> options_storage_;
39+
std::vector<Entry> entries_;
40+
};
41+
42+
} // namespace runtime
43+
} // namespace executorch

extension/module/module.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <vector>
1616

1717
#include <executorch/runtime/executor/program.h>
18+
#include <executorch/extension/module/dynamic_backend_options_map.h>
1819

1920
namespace executorch {
2021
namespace extension {
@@ -483,6 +484,12 @@ class Module {
483484
return update("forward", backend_options);
484485
}
485486

487+
ET_EXPERIMENTAL ET_NODISCARD inline runtime::Error update(
488+
const std::string& method_name,
489+
const runtime::DynamicBackendOptionsMap& backend_options) {
490+
return update(method_name, backend_options.entries());
491+
}
492+
486493
/**
487494
* Retrieves the EventTracer instance being used by the Module.
488495
* EventTracer is used for tracking and logging events during the execution

extension/module/targets.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def define_common_targets():
1717
],
1818
exported_headers = [
1919
"module.h",
20+
"dynamic_backend_options_map.h",
2021
],
2122
visibility = [
2223
"@EXECUTORCH_CLIENTS",

extension/module/test/module_test.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,18 @@ TEST_F(ModuleTest, TestUpdateNonExistentMethod) {
508508
const auto update_result = module.update("nonexistent", map.entries());
509509
EXPECT_NE(update_result, Error::Ok);
510510
}
511+
512+
TEST_F(ModuleTest, TestUpdateSugarSyntax) {
513+
Module module(stub_model_path_);
514+
int new_num_threads = 4;
515+
516+
// Clean sugar syntax
517+
const auto update_result = module.update("forward",
518+
{
519+
{"StubBackend", {{IntKey("NumberOfThreads"), new_num_threads}}
520+
},
521+
);
522+
523+
EXPECT_EQ(update_result, Error::Ok);
524+
ASSERT_EQ(StubBackend::singleton().num_threads(), new_num_threads);
525+
}

0 commit comments

Comments
 (0)