Skip to content

Commit 2673714

Browse files
cccclaifacebook-github-bot
authored andcommitted
Allow getting all backend names (#8520)
Summary: Allow getting all backends name in both python and c++ Reviewed By: larryliu0820 Differential Revision: D69691354
1 parent b5c0c61 commit 2673714

File tree

9 files changed

+88
-0
lines changed

9 files changed

+88
-0
lines changed

extension/pybindings/portable_lib.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
# Disable "imported but unused" (F401) checks.
3838
_create_profile_block, # noqa: F401
3939
_dump_profile_results, # noqa: F401
40+
_get_backend_names, # noqa: F401
4041
_get_operator_names, # noqa: F401
4142
_load_bundled_program_from_buffer, # noqa: F401
4243
_load_for_executorch, # noqa: F401

extension/pybindings/pybindings.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <executorch/extension/data_loader/buffer_data_loader.h>
2424
#include <executorch/extension/data_loader/mmap_data_loader.h>
2525
#include <executorch/extension/memory_allocator/malloc_memory_allocator.h>
26+
#include <executorch/runtime/backend/interface.h>
2627
#include <executorch/runtime/core/data_loader.h>
2728
#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
2829
#include <executorch/runtime/executor/method.h>
@@ -87,10 +88,13 @@ using ::executorch::extension::BufferDataLoader;
8788
using ::executorch::extension::MallocMemoryAllocator;
8889
using ::executorch::extension::MmapDataLoader;
8990
using ::executorch::runtime::ArrayRef;
91+
using ::executorch::runtime::Backend;
9092
using ::executorch::runtime::DataLoader;
9193
using ::executorch::runtime::Error;
9294
using ::executorch::runtime::EValue;
9395
using ::executorch::runtime::EventTracerDebugLogLevel;
96+
using ::executorch::runtime::get_backend_name;
97+
using ::executorch::runtime::get_num_registered_backends;
9498
using ::executorch::runtime::get_registered_kernels;
9599
using ::executorch::runtime::HierarchicalAllocator;
96100
using ::executorch::runtime::Kernel;
@@ -975,6 +979,19 @@ py::list get_operator_names() {
975979
return res;
976980
}
977981

982+
py::list get_backend_names() {
983+
size_t n_of_registered_backends = get_num_registered_backends();
984+
py::list res;
985+
for (size_t i = 0; i < n_of_registered_backends; i++) {
986+
auto backend_name_res = get_backend_name(i);
987+
THROW_IF_ERROR(backend_name_res.error(), "Failed to get backend name");
988+
auto backend_name = backend_name_res.get();
989+
printf("backend name: %s\n", backend_name);
990+
res.append(backend_name);
991+
}
992+
return res;
993+
}
994+
978995
} // namespace
979996

980997
PYBIND11_MODULE(EXECUTORCH_PYTHON_MODULE_NAME, m) {
@@ -1028,6 +1045,7 @@ PYBIND11_MODULE(EXECUTORCH_PYTHON_MODULE_NAME, m) {
10281045
prof_result.num_bytes);
10291046
},
10301047
call_guard);
1048+
m.def("_get_backend_names", &get_backend_names, call_guard);
10311049
m.def("_get_operator_names", &get_operator_names);
10321050
m.def("_create_profile_block", &create_profile_block, call_guard);
10331051
m.def(

extension/pybindings/pybindings.pyi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,15 @@ def _load_bundled_program_from_buffer(
211211
"""
212212
...
213213

214+
@experimental("This API is experimental and subject to change without notice.")
215+
def _get_backend_names() -> List[str]:
216+
"""
217+
.. warning::
218+
219+
This API is experimental and subject to change without notice.
220+
"""
221+
...
222+
214223
@experimental("This API is experimental and subject to change without notice.")
215224
def _get_operator_names() -> List[str]:
216225
"""

extension/pybindings/test/TARGETS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ runtime.python_test(
4747
"//executorch/kernels/quantized:aot_lib",
4848
],
4949
)
50+
51+
runtime.python_test(
52+
name = "test_backend_pybinding",
53+
srcs = ["test_backend_pybinding.py"],
54+
deps = [
55+
"//executorch/extension/pybindings:portable_lib",
56+
],
57+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import unittest
2+
3+
from executorch.extension.pybindings.portable_lib import _get_backend_names
4+
5+
6+
class TestBackendsPybinding(unittest.TestCase):
7+
def test_backend_name_list(
8+
self,
9+
) -> None:
10+
all_backend_name = _get_backend_names()
11+
self.assertGreaterEqual(len(all_backend_name), 1)
12+
self.assertIn("XnnpackBackend", all_backend_name)

runtime/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,21 @@ def load_method(self, name: str) -> Optional[Method]:
125125
return self._methods.get(name, None)
126126

127127

128+
class BackendRegistry:
129+
"""The registry of backends that are available to the runtime."""
130+
131+
def __init__(self, legacy_module: ModuleType) -> None:
132+
# TODO: Expose the kernel callables to Python.
133+
self._legacy_module = legacy_module
134+
135+
@property
136+
def _get_backend_names(self) -> Set[str]:
137+
"""
138+
Returns the names of all registered backends as a list of strings.
139+
"""
140+
return self._legacy_module._get_backend_names()
141+
142+
128143
class OperatorRegistry:
129144
"""The registry of operators that are available to the runtime."""
130145

runtime/backend/interface.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,16 @@ Error register_backend(const Backend& backend) {
5555
return Error::Ok;
5656
}
5757

58+
size_t get_num_registered_backends() {
59+
return num_registered_backends;
60+
}
61+
62+
Result<const char*> get_backend_name(size_t index) {
63+
if (index >= num_registered_backends) {
64+
return Error::BackendTableAccessFail;
65+
}
66+
return registered_backends[index].name;
67+
}
68+
5869
} // namespace runtime
5970
} // namespace executorch

runtime/backend/interface.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <executorch/runtime/core/freeable_buffer.h>
1919
#include <executorch/runtime/core/memory_allocator.h>
2020
#include <executorch/runtime/core/result.h>
21+
#include <executorch/runtime/core/span.h>
2122
#include <executorch/runtime/platform/compiler.h>
2223

2324
namespace executorch {
@@ -139,6 +140,16 @@ struct Backend {
139140
*/
140141
ET_NODISCARD Error register_backend(const Backend& backend);
141142

143+
/**
144+
* Returns the number of registered backends.
145+
*/
146+
size_t get_num_registered_backends();
147+
148+
/**
149+
* Returns the backend name at the given index.
150+
*/
151+
Result<const char*> get_backend_name(size_t index);
152+
142153
} // namespace runtime
143154
} // namespace executorch
144155

runtime/core/error.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ enum class Error : error_code_t {
9393
/// Execute stage: The handle is invalid.
9494
DelegateInvalidHandle = 0x32,
9595

96+
/// Backend registration: trying to access an invalid index in the backend
97+
/// registration table.
98+
BackendTableAccessFail = 0x33,
9699
};
97100

98101
} // namespace runtime

0 commit comments

Comments
 (0)