/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ #include namespace executorch { namespace ET_RUNTIME_NAMESPACE { // Pure-virtual dtors still need an implementation. BackendInterface::~BackendInterface() {} namespace { // The max number of backends that can be registered globally. constexpr size_t kMaxRegisteredBackends = 16; // TODO(T128866626): Remove global static variables. We want to be able to run // multiple Executor instances and having a global registration isn't a viable // solution in the long term. /// Global table of registered backends. Backend registered_backends[kMaxRegisteredBackends]; /// The number of backends registered in the table. size_t num_registered_backends = 0; } // namespace BackendInterface* get_backend_class(const char* name) { for (size_t i = 0; i < num_registered_backends; i++) { Backend backend = registered_backends[i]; if (strcmp(backend.name, name) == 0) { return backend.backend; } } return nullptr; } Error register_backend(const Backend& backend) { if (num_registered_backends >= kMaxRegisteredBackends) { return Error::Internal; } // Check if the name already exists in the table if (get_backend_class(backend.name) != nullptr) { return Error::InvalidArgument; } registered_backends[num_registered_backends++] = backend; return Error::Ok; } size_t get_num_registered_backends() { return num_registered_backends; } Result get_backend_name(size_t index) { if (index >= num_registered_backends) { return Error::InvalidArgument; } return registered_backends[index].name; } Error set_option( const char* backend_name, const executorch::runtime::Span backend_options) { auto backend_class = get_backend_class(backend_name); if (!backend_class) { return Error::NotFound; } BackendOptionContext backend_option_context; Error result = backend_class->set_option(backend_option_context, backend_options); if (result != Error::Ok) { return result; } return Error::Ok; } Error get_option( const char* backend_name, executorch::runtime::Span backend_options) { auto backend_class = get_backend_class(backend_name); if (!backend_class) { return Error::NotFound; } BackendOptionContext backend_option_context; executorch::runtime::Span backend_options_ref( backend_options.data(), backend_options.size()); auto result = backend_class->get_option(backend_option_context, backend_options_ref); if (result != Error::Ok) { return result; } return Error::Ok; } } // namespace ET_RUNTIME_NAMESPACE } // namespace executorch