xref: /aosp_15_r20/external/executorch/runtime/backend/interface.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1*523fa7a6SAndroid Build Coastguard Worker /*
2*523fa7a6SAndroid Build Coastguard Worker  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*523fa7a6SAndroid Build Coastguard Worker  * All rights reserved.
4*523fa7a6SAndroid Build Coastguard Worker  *
5*523fa7a6SAndroid Build Coastguard Worker  * This source code is licensed under the BSD-style license found in the
6*523fa7a6SAndroid Build Coastguard Worker  * LICENSE file in the root directory of this source tree.
7*523fa7a6SAndroid Build Coastguard Worker  */
8*523fa7a6SAndroid Build Coastguard Worker 
9*523fa7a6SAndroid Build Coastguard Worker #pragma once
10*523fa7a6SAndroid Build Coastguard Worker 
11*523fa7a6SAndroid Build Coastguard Worker #include <cstring>
12*523fa7a6SAndroid Build Coastguard Worker 
13*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/backend/backend_execution_context.h>
14*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/backend/backend_init_context.h>
15*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/array_ref.h>
16*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/error.h>
17*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/evalue.h>
18*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/freeable_buffer.h>
19*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/memory_allocator.h>
20*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/result.h>
21*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/platform/compiler.h>
22*523fa7a6SAndroid Build Coastguard Worker 
23*523fa7a6SAndroid Build Coastguard Worker namespace executorch {
24*523fa7a6SAndroid Build Coastguard Worker namespace runtime {
25*523fa7a6SAndroid Build Coastguard Worker 
26*523fa7a6SAndroid Build Coastguard Worker struct SizedBuffer {
27*523fa7a6SAndroid Build Coastguard Worker   void* buffer;
28*523fa7a6SAndroid Build Coastguard Worker   size_t nbytes; // number of bytes of buffer
29*523fa7a6SAndroid Build Coastguard Worker };
30*523fa7a6SAndroid Build Coastguard Worker 
31*523fa7a6SAndroid Build Coastguard Worker struct CompileSpec {
32*523fa7a6SAndroid Build Coastguard Worker   const char* key; // spec key
33*523fa7a6SAndroid Build Coastguard Worker   SizedBuffer value; // spec value
34*523fa7a6SAndroid Build Coastguard Worker };
35*523fa7a6SAndroid Build Coastguard Worker 
36*523fa7a6SAndroid Build Coastguard Worker /**
37*523fa7a6SAndroid Build Coastguard Worker  * An opaque handle managed by a backend. Typically points to a backend-private
38*523fa7a6SAndroid Build Coastguard Worker  * class/struct.
39*523fa7a6SAndroid Build Coastguard Worker  */
40*523fa7a6SAndroid Build Coastguard Worker using DelegateHandle = void;
41*523fa7a6SAndroid Build Coastguard Worker 
42*523fa7a6SAndroid Build Coastguard Worker class BackendInterface {
43*523fa7a6SAndroid Build Coastguard Worker  public:
44*523fa7a6SAndroid Build Coastguard Worker   virtual ~BackendInterface() = 0;
45*523fa7a6SAndroid Build Coastguard Worker 
46*523fa7a6SAndroid Build Coastguard Worker   /**
47*523fa7a6SAndroid Build Coastguard Worker    * Returns true if the backend is available to process delegation calls.
48*523fa7a6SAndroid Build Coastguard Worker    */
49*523fa7a6SAndroid Build Coastguard Worker   ET_NODISCARD virtual bool is_available() const = 0;
50*523fa7a6SAndroid Build Coastguard Worker 
51*523fa7a6SAndroid Build Coastguard Worker   /**
52*523fa7a6SAndroid Build Coastguard Worker    * Responsible to further process (compile/transform/optimize) the compiled
53*523fa7a6SAndroid Build Coastguard Worker    * unit that was produced, ahead-of-time, as well as perform any backend
54*523fa7a6SAndroid Build Coastguard Worker    * initialization to ready it for execution. This method is called every time
55*523fa7a6SAndroid Build Coastguard Worker    * the ExecuTorch program is initialized. Consequently, this is the place to
56*523fa7a6SAndroid Build Coastguard Worker    * perform any backend initialization as well as transformations,
57*523fa7a6SAndroid Build Coastguard Worker    * optimizations, and even compilation that depend on the target device. As
58*523fa7a6SAndroid Build Coastguard Worker    * such, it is strongly encouraged to push as much processing as possible to
59*523fa7a6SAndroid Build Coastguard Worker    * the ahead-of-time processing.
60*523fa7a6SAndroid Build Coastguard Worker    *
61*523fa7a6SAndroid Build Coastguard Worker    * @param[in] processed An opaque (to ExecuTorch) backend-specific compiled
62*523fa7a6SAndroid Build Coastguard Worker    *     unit from the preprocessor. Can contain anything the backend needs to
63*523fa7a6SAndroid Build Coastguard Worker    *     execute the equivalent semantics of the passed-in Module and its
64*523fa7a6SAndroid Build Coastguard Worker    *     method. Often passed unmodified to `execute()` as a `DelegateHandle`,
65*523fa7a6SAndroid Build Coastguard Worker    *     unless it needs further processing at init time to be fully executable.
66*523fa7a6SAndroid Build Coastguard Worker    *     If the data is not needed after init(), calling processed->Free() can
67*523fa7a6SAndroid Build Coastguard Worker    *     reclaim its memory.
68*523fa7a6SAndroid Build Coastguard Worker    * @param[in] compile_specs The exact same compiler specification that
69*523fa7a6SAndroid Build Coastguard Worker    *     was used ahead-of-time to produce `processed`.
70*523fa7a6SAndroid Build Coastguard Worker    *
71*523fa7a6SAndroid Build Coastguard Worker    * @returns On success, an opaque handle representing the the method
72*523fa7a6SAndroid Build Coastguard Worker    *     implemented by the delegate. This handle is passed to `execute()` and
73*523fa7a6SAndroid Build Coastguard Worker    *     `destroy()`, and the memory it points to is owned by the backend.
74*523fa7a6SAndroid Build Coastguard Worker    *     Typically points to a backend-private class/struct.
75*523fa7a6SAndroid Build Coastguard Worker    * @returns On error, returns an error code other than Error::Ok. If the
76*523fa7a6SAndroid Build Coastguard Worker    *     compiled unit (the preprocessed result from ahead of time) is not
77*523fa7a6SAndroid Build Coastguard Worker    *     compatible with the current backend runtime, return the error code
78*523fa7a6SAndroid Build Coastguard Worker    *     Error::DelegateInvalidCompatibility. Other backend delegate
79*523fa7a6SAndroid Build Coastguard Worker    *     specific error codes can be found in error.h.
80*523fa7a6SAndroid Build Coastguard Worker    */
81*523fa7a6SAndroid Build Coastguard Worker   ET_NODISCARD virtual Result<DelegateHandle*> init(
82*523fa7a6SAndroid Build Coastguard Worker       BackendInitContext& context,
83*523fa7a6SAndroid Build Coastguard Worker       FreeableBuffer* processed,
84*523fa7a6SAndroid Build Coastguard Worker       ArrayRef<CompileSpec> compile_specs) const = 0;
85*523fa7a6SAndroid Build Coastguard Worker 
86*523fa7a6SAndroid Build Coastguard Worker   /**
87*523fa7a6SAndroid Build Coastguard Worker    * Responsible for executing the given method’s handle, as it was produced
88*523fa7a6SAndroid Build Coastguard Worker    * by compile.
89*523fa7a6SAndroid Build Coastguard Worker    *
90*523fa7a6SAndroid Build Coastguard Worker    * @param[in] handle An opaque handle returned by `init()`. Usually a backend
91*523fa7a6SAndroid Build Coastguard Worker    *     executable unit. This executable unit should be ready to execute the
92*523fa7a6SAndroid Build Coastguard Worker    *     delegate blobs.
93*523fa7a6SAndroid Build Coastguard Worker    * @param[in] args The method’s inputs and outputs.
94*523fa7a6SAndroid Build Coastguard Worker    * @retval Error::Ok if successful.
95*523fa7a6SAndroid Build Coastguard Worker    */
96*523fa7a6SAndroid Build Coastguard Worker   ET_NODISCARD virtual Error execute(
97*523fa7a6SAndroid Build Coastguard Worker       BackendExecutionContext& context,
98*523fa7a6SAndroid Build Coastguard Worker       DelegateHandle* handle,
99*523fa7a6SAndroid Build Coastguard Worker       EValue** args) const = 0;
100*523fa7a6SAndroid Build Coastguard Worker 
101*523fa7a6SAndroid Build Coastguard Worker   /**
102*523fa7a6SAndroid Build Coastguard Worker    * Responsible for destroying a handle, if it's required for some backend.
103*523fa7a6SAndroid Build Coastguard Worker    * It may be needed for some backends. For example, resources associated with
104*523fa7a6SAndroid Build Coastguard Worker    * this handle needs to be released. This method is called when the execution
105*523fa7a6SAndroid Build Coastguard Worker    * plan is destroyed (i.e., the program is out of its lifespan).
106*523fa7a6SAndroid Build Coastguard Worker    *
107*523fa7a6SAndroid Build Coastguard Worker    * @param[in] handle The handle to be destroyed. An opaque handle returned by
108*523fa7a6SAndroid Build Coastguard Worker    *     `init()`.
109*523fa7a6SAndroid Build Coastguard Worker    */
destroy(ET_UNUSED DelegateHandle * handle)110*523fa7a6SAndroid Build Coastguard Worker   virtual void destroy(ET_UNUSED DelegateHandle* handle) const {}
111*523fa7a6SAndroid Build Coastguard Worker };
112*523fa7a6SAndroid Build Coastguard Worker 
113*523fa7a6SAndroid Build Coastguard Worker /**
114*523fa7a6SAndroid Build Coastguard Worker  * Returns the corresponding object pointer for a given string name.
115*523fa7a6SAndroid Build Coastguard Worker  * The mapping is populated using register_backend method.
116*523fa7a6SAndroid Build Coastguard Worker  *
117*523fa7a6SAndroid Build Coastguard Worker  * @param[in] name Name of the user-defined backend delegate.
118*523fa7a6SAndroid Build Coastguard Worker  * @retval Pointer to the appropriate object that implements BackendInterface.
119*523fa7a6SAndroid Build Coastguard Worker  *         Nullptr if it can't find anything with the given name.
120*523fa7a6SAndroid Build Coastguard Worker  */
121*523fa7a6SAndroid Build Coastguard Worker BackendInterface* get_backend_class(const char* name);
122*523fa7a6SAndroid Build Coastguard Worker 
123*523fa7a6SAndroid Build Coastguard Worker /**
124*523fa7a6SAndroid Build Coastguard Worker  * A named instance of a backend.
125*523fa7a6SAndroid Build Coastguard Worker  */
126*523fa7a6SAndroid Build Coastguard Worker struct Backend {
127*523fa7a6SAndroid Build Coastguard Worker   /// The name of the backend. Must match the string used in the PTE file.
128*523fa7a6SAndroid Build Coastguard Worker   const char* name;
129*523fa7a6SAndroid Build Coastguard Worker   /// The instance of the backend to use when loading and executing programs.
130*523fa7a6SAndroid Build Coastguard Worker   BackendInterface* backend;
131*523fa7a6SAndroid Build Coastguard Worker };
132*523fa7a6SAndroid Build Coastguard Worker 
133*523fa7a6SAndroid Build Coastguard Worker /**
134*523fa7a6SAndroid Build Coastguard Worker  * Registers the Backend object (i.e. string name and BackendInterface pair) so
135*523fa7a6SAndroid Build Coastguard Worker  * that it could be called via the name during the runtime.
136*523fa7a6SAndroid Build Coastguard Worker  *
137*523fa7a6SAndroid Build Coastguard Worker  * @param[in] backend Backend object
138*523fa7a6SAndroid Build Coastguard Worker  * @retval Error code representing whether registration was successful.
139*523fa7a6SAndroid Build Coastguard Worker  */
140*523fa7a6SAndroid Build Coastguard Worker ET_NODISCARD Error register_backend(const Backend& backend);
141*523fa7a6SAndroid Build Coastguard Worker 
142*523fa7a6SAndroid Build Coastguard Worker } // namespace runtime
143*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch
144*523fa7a6SAndroid Build Coastguard Worker 
145*523fa7a6SAndroid Build Coastguard Worker namespace torch {
146*523fa7a6SAndroid Build Coastguard Worker namespace executor {
147*523fa7a6SAndroid Build Coastguard Worker // TODO(T197294990): Remove these deprecated aliases once all users have moved
148*523fa7a6SAndroid Build Coastguard Worker // to the new `::executorch` namespaces.
149*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::Backend;
150*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::CompileSpec;
151*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::DelegateHandle;
152*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::get_backend_class;
153*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::register_backend;
154*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::SizedBuffer;
155*523fa7a6SAndroid Build Coastguard Worker using PyTorchBackendInterface = ::executorch::runtime::BackendInterface;
156*523fa7a6SAndroid Build Coastguard Worker } // namespace executor
157*523fa7a6SAndroid Build Coastguard Worker } // namespace torch
158