| /* |
| * 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. |
| */ |
| |
| #pragma once |
| |
| #include <cstring> |
| |
| #include <executorch/runtime/backend/backend_execution_context.h> |
| #include <executorch/runtime/backend/backend_init_context.h> |
| #include <executorch/runtime/backend/backend_option_context.h> |
| #include <executorch/runtime/backend/options.h> |
| #include <executorch/runtime/core/array_ref.h> |
| #include <executorch/runtime/core/error.h> |
| #include <executorch/runtime/core/evalue.h> |
| #include <executorch/runtime/core/freeable_buffer.h> |
| #include <executorch/runtime/core/memory_allocator.h> |
| #include <executorch/runtime/core/named_data_map.h> |
| #include <executorch/runtime/core/result.h> |
| #include <executorch/runtime/platform/compiler.h> |
| |
| namespace executorch { |
| namespace ET_RUNTIME_NAMESPACE { |
| |
| struct SizedBuffer { |
| void* buffer; |
| size_t nbytes; // number of bytes of buffer |
| }; |
| |
| struct CompileSpec { |
| const char* key; // spec key |
| SizedBuffer value; // spec value |
| }; |
| |
| /** |
| * An opaque handle managed by a backend. Typically points to a backend-private |
| * class/struct. |
| */ |
| using DelegateHandle = void; |
| |
| class BackendInterface { |
| public: |
| virtual ~BackendInterface() = 0; |
| |
| /** |
| * Returns true if the backend is available to process delegation calls. |
| */ |
| ET_NODISCARD virtual bool is_available() const = 0; |
| |
| /** |
| * Responsible to further process (compile/transform/optimize) the compiled |
| * unit that was produced, ahead-of-time, as well as perform any backend |
| * initialization to ready it for execution. This method is called every time |
| * the ExecuTorch program is initialized. Consequently, this is the place to |
| * perform any backend initialization as well as transformations, |
| * optimizations, and even compilation that depend on the target device. As |
| * such, it is strongly encouraged to push as much processing as possible to |
| * the ahead-of-time processing. |
| * |
| * @param[in] processed An opaque (to ExecuTorch) backend-specific compiled |
| * unit from the preprocessor. Can contain anything the backend needs to |
| * execute the equivalent semantics of the passed-in Module and its |
| * method. Often passed unmodified to `execute()` as a `DelegateHandle`, |
| * unless it needs further processing at init time to be fully executable. |
| * If the data is not needed after init(), calling processed->Free() can |
| * reclaim its memory. |
| * @param[in] compile_specs The exact same compiler specification that |
| * was used ahead-of-time to produce `processed`. |
| * |
| * @returns On success, an opaque handle representing the the method |
| * implemented by the delegate. This handle is passed to `execute()` and |
| * `destroy()`, and the memory it points to is owned by the backend. |
| * Typically points to a backend-private class/struct. |
| * @returns On error, returns an error code other than Error::Ok. If the |
| * compiled unit (the preprocessed result from ahead of time) is not |
| * compatible with the current backend runtime, return the error code |
| * Error::DelegateInvalidCompatibility. Other backend delegate |
| * specific error codes can be found in error.h. |
| */ |
| ET_NODISCARD virtual Result<DelegateHandle*> init( |
| BackendInitContext& context, |
| FreeableBuffer* processed, |
| ArrayRef<CompileSpec> compile_specs) const = 0; |
| |
| /** |
| * Responsible for executing the given method’s handle, as it was produced |
| * by compile. |
| * |
| * @param[in] handle An opaque handle returned by `init()`. Usually a backend |
| * executable unit. This executable unit should be ready to execute the |
| * delegate blobs. |
| * @param[in] args The method’s inputs and outputs. |
| * @retval Error::Ok if successful. |
| */ |
| ET_NODISCARD virtual Error execute( |
| BackendExecutionContext& context, |
| DelegateHandle* handle, |
| Span<EValue*> args) const = 0; |
| |
| /** |
| * Responsible update the backend status, if any. The backend options are |
| * passed in by users, and the backend can update its internal status based on |
| * the options. |
| * |
| * @param[in] context Runtime context if any. Currently it's not used. |
| * @param[in] args A list of BackendOptions passed in by users. |
| * @retval Error::Ok if successful. |
| */ |
| ET_NODISCARD virtual Error set_option( |
| __ET_UNUSED BackendOptionContext& context, |
| const executorch::runtime::Span<BackendOption>& backend_options) { |
| return Error::Ok; |
| }; |
| |
| /** |
| * Responsible update the backend status, if any. The backend options are |
| * passed in by users, and the backend can update its internal status based on |
| * the options. |
| * |
| * @param[in] context Runtime context if any. Currently it's not used. |
| * @param[in] args A list of BackendOptions passed in by users, that will be |
| * filled by the backend |
| * @retval Error::Ok if successful. |
| */ |
| ET_NODISCARD virtual Error get_option( |
| __ET_UNUSED BackendOptionContext& context, |
| executorch::runtime::Span<BackendOption>& backend_options) { |
| return Error::Ok; |
| }; |
| |
| /** |
| * Responsible for destroying a handle, if it's required for some backend. |
| * It may be needed for some backends. For example, resources associated with |
| * this handle needs to be released. This method is called when the execution |
| * plan is destroyed (i.e., the program is out of its lifespan). |
| * |
| * @param[in] handle The handle to be destroyed. An opaque handle returned by |
| * `init()`. |
| */ |
| virtual void destroy(ET_UNUSED DelegateHandle* handle) const {} |
| }; |
| |
| /** |
| * Returns the corresponding object pointer for a given string name. |
| * The mapping is populated using register_backend method. |
| * |
| * @param[in] name Name of the user-defined backend delegate. |
| * @retval Pointer to the appropriate object that implements BackendInterface. |
| * Nullptr if it can't find anything with the given name. |
| */ |
| BackendInterface* get_backend_class(const char* name); |
| |
| /** |
| * A named instance of a backend. |
| */ |
| struct Backend { |
| /// The name of the backend. Must match the string used in the PTE file. |
| const char* name; |
| /// The instance of the backend to use when loading and executing programs. |
| BackendInterface* backend; |
| }; |
| |
| /** |
| * Registers the Backend object (i.e. string name and BackendInterface pair) so |
| * that it could be called via the name during the runtime. |
| * |
| * @param[in] backend Backend object |
| * @retval Error code representing whether registration was successful. |
| */ |
| ET_NODISCARD Error register_backend(const Backend& backend); |
| |
| /** |
| * Returns the number of registered backends. |
| */ |
| size_t get_num_registered_backends(); |
| |
| /** |
| * Returns the backend name at the given index. |
| */ |
| Result<const char*> get_backend_name(size_t index); |
| |
| /** |
| * Sets backend options for a specific backend. |
| * |
| * @param backend_name The name of the backend to set options for |
| * @param backend_options The backend option list containing the options |
| * to set |
| * @return Error::Ok on success, Error::NotFound if backend is not found, or |
| * other error codes on failure |
| */ |
| Error set_option( |
| const char* backend_name, |
| const executorch::runtime::Span<executorch::runtime::BackendOption> |
| backend_options); |
| |
| /** |
| * Retrieves backend options for a specific backend. |
| * |
| * @param backend_name The name of the backend to get options from |
| * @param backend_options The backend option objects that will be filled with |
| * the populated values from the backend |
| * @return Error::Ok on success, Error::NotFound if backend is not found, or |
| * other error codes on failure |
| */ |
| Error get_option( |
| const char* backend_name, |
| executorch::runtime::Span<executorch::runtime::BackendOption> |
| backend_options); |
| |
| } // namespace ET_RUNTIME_NAMESPACE |
| } // namespace executorch |
| |
| namespace torch { |
| namespace executor { |
| // TODO(T197294990): Remove these deprecated aliases once all users have moved |
| // to the new `::executorch` namespaces. |
| using ::executorch::ET_RUNTIME_NAMESPACE::Backend; |
| using ::executorch::ET_RUNTIME_NAMESPACE::CompileSpec; |
| using ::executorch::ET_RUNTIME_NAMESPACE::DelegateHandle; |
| using ::executorch::ET_RUNTIME_NAMESPACE::get_backend_class; |
| using ::executorch::ET_RUNTIME_NAMESPACE::register_backend; |
| using ::executorch::ET_RUNTIME_NAMESPACE::SizedBuffer; |
| using PyTorchBackendInterface = |
| ::executorch::ET_RUNTIME_NAMESPACE::BackendInterface; |
| } // namespace executor |
| } // namespace torch |