xref: /aosp_15_r20/external/pytorch/torch/library.h (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker #pragma once
2*da0073e9SAndroid Build Coastguard Worker 
3*da0073e9SAndroid Build Coastguard Worker /// \file
4*da0073e9SAndroid Build Coastguard Worker ///
5*da0073e9SAndroid Build Coastguard Worker /// This header provides an API for extending PyTorch's core library
6*da0073e9SAndroid Build Coastguard Worker /// of operators with user defined operators and data types.  This
7*da0073e9SAndroid Build Coastguard Worker /// API can be used in a few ways:
8*da0073e9SAndroid Build Coastguard Worker ///
9*da0073e9SAndroid Build Coastguard Worker /// * You can define new custom operators and classes with TORCH_LIBRARY(),
10*da0073e9SAndroid Build Coastguard Worker ///   making them available for use in both eager Python as well as in
11*da0073e9SAndroid Build Coastguard Worker ///   TorchScript. This API is modeled off of pybind11's `PYBIND11_MODULE`
12*da0073e9SAndroid Build Coastguard Worker ///   macro, as the provided functionality is similar (pybind11 lets you bind
13*da0073e9SAndroid Build Coastguard Worker ///   C++ to Python only; `torch/library.h` lets you bind C++ simultaneously to
14*da0073e9SAndroid Build Coastguard Worker ///   Python and TorchScript).
15*da0073e9SAndroid Build Coastguard Worker ///
16*da0073e9SAndroid Build Coastguard Worker /// * You can override existing operators with TORCH_LIBRARY_IMPL(),
17*da0073e9SAndroid Build Coastguard Worker ///   providing a new implementation for these operators for a custom
18*da0073e9SAndroid Build Coastguard Worker ///   backend (e.g., XLA).  When you pass operators with tensors of your custom
19*da0073e9SAndroid Build Coastguard Worker ///   backend, your overridden implementations will be called instead
20*da0073e9SAndroid Build Coastguard Worker ///   of the standard implementations.
21*da0073e9SAndroid Build Coastguard Worker ///
22*da0073e9SAndroid Build Coastguard Worker /// * You can use both capabilities at the same time, allowing you
23*da0073e9SAndroid Build Coastguard Worker ///   to write custom operators that register CPU/CUDA/Autograd
24*da0073e9SAndroid Build Coastguard Worker ///   implementations without having to write the boilerplate
25*da0073e9SAndroid Build Coastguard Worker ///   conditionals yourself.
26*da0073e9SAndroid Build Coastguard Worker ///
27*da0073e9SAndroid Build Coastguard Worker /// For a tutorial style introduction to the library API, check
28*da0073e9SAndroid Build Coastguard Worker /// out the [Extending TorchScript with Custom C++
29*da0073e9SAndroid Build Coastguard Worker /// Operators](https://pytorch.org/tutorials/advanced/torch_script_custom_ops.html)
30*da0073e9SAndroid Build Coastguard Worker /// tutorial.
31*da0073e9SAndroid Build Coastguard Worker ///
32*da0073e9SAndroid Build Coastguard Worker /// ```
33*da0073e9SAndroid Build Coastguard Worker /// // Define a library whose operators live in the namespace 'myops'.
34*da0073e9SAndroid Build Coastguard Worker /// // You must define all of the operators for this library in
35*da0073e9SAndroid Build Coastguard Worker /// // this namespace.
36*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY(myops, m) {
37*da0073e9SAndroid Build Coastguard Worker ///   // Define a operator with exactly one implementation for all backends.
38*da0073e9SAndroid Build Coastguard Worker ///   m.def("add(Tensor self, Tensor other) -> Tensor", &add_impl);
39*da0073e9SAndroid Build Coastguard Worker ///
40*da0073e9SAndroid Build Coastguard Worker ///   // Define a schema for an operator, but provide no implementation
41*da0073e9SAndroid Build Coastguard Worker ///   // (use this syntax if you want to use the dispatcher)
42*da0073e9SAndroid Build Coastguard Worker ///   m.def("mul(Tensor self, Tensor other) -> Tensor");
43*da0073e9SAndroid Build Coastguard Worker ///
44*da0073e9SAndroid Build Coastguard Worker ///   // Provide an implementation for a defined operator (you can
45*da0073e9SAndroid Build Coastguard Worker ///   // provide multiple; one per backend).  The dispatcher takes care of
46*da0073e9SAndroid Build Coastguard Worker ///   // calling the correct implementation depending on if we get a CPU
47*da0073e9SAndroid Build Coastguard Worker ///   // tensor or a CUDA tensor
48*da0073e9SAndroid Build Coastguard Worker ///   m.impl("mul", torch::kCPU, &mul_cpu_impl);
49*da0073e9SAndroid Build Coastguard Worker ///   m.impl("mul", torch::kCUDA, &mul_cuda_impl);
50*da0073e9SAndroid Build Coastguard Worker /// }
51*da0073e9SAndroid Build Coastguard Worker ///
52*da0073e9SAndroid Build Coastguard Worker /// // Define implementations for operators for a non-standard backend,
53*da0073e9SAndroid Build Coastguard Worker /// // e.g., XLA (valid values are entries of DispatchKey).  This can
54*da0073e9SAndroid Build Coastguard Worker /// // be used to define operators in a different file than the initial
55*da0073e9SAndroid Build Coastguard Worker /// // TORCH_LIBRARY definition (e.g., if it is in an external library)
56*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY_IMPL(myops, XLA, m) {
57*da0073e9SAndroid Build Coastguard Worker ///   m.impl("mul", &mul_xla_impl);
58*da0073e9SAndroid Build Coastguard Worker /// }
59*da0073e9SAndroid Build Coastguard Worker /// ```
60*da0073e9SAndroid Build Coastguard Worker 
61*da0073e9SAndroid Build Coastguard Worker #include <ATen/core/op_registration/infer_schema.h>
62*da0073e9SAndroid Build Coastguard Worker #include <ATen/core/op_registration/op_allowlist.h>
63*da0073e9SAndroid Build Coastguard Worker #include <ATen/core/dispatch/Dispatcher.h>
64*da0073e9SAndroid Build Coastguard Worker #include <c10/core/DispatchKey.h>
65*da0073e9SAndroid Build Coastguard Worker #include <torch/csrc/jit/frontend/function_schema_parser.h>
66*da0073e9SAndroid Build Coastguard Worker 
67*da0073e9SAndroid Build Coastguard Worker // Just for inferFunctionSchemaFromFunctor
68*da0073e9SAndroid Build Coastguard Worker #include <ATen/core/enum_tag.h>
69*da0073e9SAndroid Build Coastguard Worker #include <ATen/core/op_registration/op_registration.h>
70*da0073e9SAndroid Build Coastguard Worker 
71*da0073e9SAndroid Build Coastguard Worker namespace torch {
72*da0073e9SAndroid Build Coastguard Worker 
73*da0073e9SAndroid Build Coastguard Worker #if defined C10_MOBILE
74*da0073e9SAndroid Build Coastguard Worker /**
75*da0073e9SAndroid Build Coastguard Worker  * The NoInferSchemaTag is a type name used to indicate that this call to the
76*da0073e9SAndroid Build Coastguard Worker  * CppFunction constructor should not trigger schema inference from functor.
77*da0073e9SAndroid Build Coastguard Worker  * Schema inference from functor utilizes template meta-programming, and is
78*da0073e9SAndroid Build Coastguard Worker  * costly from a size perspective. Ideally, one would expect that the schema
79*da0073e9SAndroid Build Coastguard Worker  * inference would require very little binary size since most of the
80*da0073e9SAndroid Build Coastguard Worker  * computation can be done by the compiler at build time, but that isn't
81*da0073e9SAndroid Build Coastguard Worker  * necessarily the case.
82*da0073e9SAndroid Build Coastguard Worker  *
83*da0073e9SAndroid Build Coastguard Worker  * Schema inference is elided only for mobile use-cases where we don't need
84*da0073e9SAndroid Build Coastguard Worker  * the additional runtime cost or size overhead on client devices.
85*da0073e9SAndroid Build Coastguard Worker  *
86*da0073e9SAndroid Build Coastguard Worker  */
87*da0073e9SAndroid Build Coastguard Worker struct NoInferSchemaTag {};
88*da0073e9SAndroid Build Coastguard Worker #endif
89*da0073e9SAndroid Build Coastguard Worker 
90*da0073e9SAndroid Build Coastguard Worker #define HAS_PT2_COMPLIANT_TAG
91*da0073e9SAndroid Build Coastguard Worker 
92*da0073e9SAndroid Build Coastguard Worker // For multipy/torchdeploy use case
93*da0073e9SAndroid Build Coastguard Worker enum class _RegisterOrVerify { REGISTER, VERIFY };
94*da0073e9SAndroid Build Coastguard Worker 
95*da0073e9SAndroid Build Coastguard Worker template <class CurClass>
96*da0073e9SAndroid Build Coastguard Worker class class_;
97*da0073e9SAndroid Build Coastguard Worker 
98*da0073e9SAndroid Build Coastguard Worker #define HAS_IMPL_ABSTRACT_PYSTUB
99*da0073e9SAndroid Build Coastguard Worker 
100*da0073e9SAndroid Build Coastguard Worker /// Represents a C++ function that implements an operator.  Most users won't
101*da0073e9SAndroid Build Coastguard Worker /// interact directly with this class, except via error messages: the
102*da0073e9SAndroid Build Coastguard Worker /// constructors this function define the set of permissible "function"-like
103*da0073e9SAndroid Build Coastguard Worker /// things you can bind via the interface.
104*da0073e9SAndroid Build Coastguard Worker ///
105*da0073e9SAndroid Build Coastguard Worker /// This class erases the type of the passed in function, but durably records
106*da0073e9SAndroid Build Coastguard Worker /// the type via an inferred schema for the function.
107*da0073e9SAndroid Build Coastguard Worker class TORCH_API CppFunction final {
108*da0073e9SAndroid Build Coastguard Worker   // TODO: This is morally the same thing as KernelRegistrationConfig, but it's
109*da0073e9SAndroid Build Coastguard Worker   // opaque to the user.
110*da0073e9SAndroid Build Coastguard Worker 
111*da0073e9SAndroid Build Coastguard Worker  public:
112*da0073e9SAndroid Build Coastguard Worker   /// This overload accepts function pointers, e.g., `CppFunction(&add_impl)`
113*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
114*da0073e9SAndroid Build Coastguard Worker   explicit CppFunction(
115*da0073e9SAndroid Build Coastguard Worker       Func* f,
116*da0073e9SAndroid Build Coastguard Worker       std::enable_if_t<
117*da0073e9SAndroid Build Coastguard Worker           c10::guts::is_function_type<Func>::value,
118*da0073e9SAndroid Build Coastguard Worker           std::nullptr_t> = nullptr)
func_(c10::KernelFunction::makeFromUnboxedRuntimeFunction (f))119*da0073e9SAndroid Build Coastguard Worker       : func_(c10::KernelFunction::makeFromUnboxedRuntimeFunction(f)),
120*da0073e9SAndroid Build Coastguard Worker         cpp_signature_(c10::impl::CppSignature::make<Func>()),
121*da0073e9SAndroid Build Coastguard Worker         schema_(
122*da0073e9SAndroid Build Coastguard Worker             c10::detail::inferFunctionSchemaFromFunctor<std::decay_t<Func>>()),
123*da0073e9SAndroid Build Coastguard Worker         debug_() {}
124*da0073e9SAndroid Build Coastguard Worker 
125*da0073e9SAndroid Build Coastguard Worker   /// This overload accepts compile time function pointers, e.g.,
126*da0073e9SAndroid Build Coastguard Worker   /// `CppFunction(TORCH_FN(add_impl))`
127*da0073e9SAndroid Build Coastguard Worker   template <typename FuncPtr>
128*da0073e9SAndroid Build Coastguard Worker   explicit CppFunction(
129*da0073e9SAndroid Build Coastguard Worker       FuncPtr f,
130*da0073e9SAndroid Build Coastguard Worker       std::enable_if_t<
131*da0073e9SAndroid Build Coastguard Worker           c10::is_compile_time_function_pointer<FuncPtr>::value,
132*da0073e9SAndroid Build Coastguard Worker           std::nullptr_t> = nullptr)
func_(c10::KernelFunction::makeFromUnboxedFunction (f))133*da0073e9SAndroid Build Coastguard Worker       : func_(c10::KernelFunction::makeFromUnboxedFunction(f)),
134*da0073e9SAndroid Build Coastguard Worker         cpp_signature_(
135*da0073e9SAndroid Build Coastguard Worker             c10::impl::CppSignature::make<typename FuncPtr::FuncType>()),
136*da0073e9SAndroid Build Coastguard Worker         schema_(c10::detail::inferFunctionSchemaFromFunctor<
137*da0073e9SAndroid Build Coastguard Worker                 typename FuncPtr::FuncType>()),
138*da0073e9SAndroid Build Coastguard Worker         debug_() {}
139*da0073e9SAndroid Build Coastguard Worker 
140*da0073e9SAndroid Build Coastguard Worker   /// This overload accepts lambdas, e.g., `CppFunction([](const Tensor& self) {
141*da0073e9SAndroid Build Coastguard Worker   /// ... })`
142*da0073e9SAndroid Build Coastguard Worker   template <typename Lambda>
143*da0073e9SAndroid Build Coastguard Worker   explicit CppFunction(
144*da0073e9SAndroid Build Coastguard Worker       Lambda&& f,
145*da0073e9SAndroid Build Coastguard Worker       std::enable_if_t<
146*da0073e9SAndroid Build Coastguard Worker           c10::guts::is_functor<std::decay_t<Lambda>>::value,
147*da0073e9SAndroid Build Coastguard Worker           std::nullptr_t> = nullptr)
func_(c10::KernelFunction::makeFromUnboxedLambda (std::forward<Lambda> (f)))148*da0073e9SAndroid Build Coastguard Worker       : func_(c10::KernelFunction::makeFromUnboxedLambda(
149*da0073e9SAndroid Build Coastguard Worker             std::forward<Lambda>(f))),
150*da0073e9SAndroid Build Coastguard Worker         cpp_signature_(c10::impl::CppSignature::make<Lambda>()),
151*da0073e9SAndroid Build Coastguard Worker         schema_(c10::detail::inferFunctionSchemaFromFunctor<
152*da0073e9SAndroid Build Coastguard Worker                 std::decay_t<Lambda>>()),
153*da0073e9SAndroid Build Coastguard Worker         debug_() {}
154*da0073e9SAndroid Build Coastguard Worker 
155*da0073e9SAndroid Build Coastguard Worker #if defined C10_MOBILE
156*da0073e9SAndroid Build Coastguard Worker   /// This overload accepts function pointers, e.g., `CppFunction(&add_impl,
157*da0073e9SAndroid Build Coastguard Worker   /// NoInferSchemaTag())`
158*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
159*da0073e9SAndroid Build Coastguard Worker   explicit CppFunction(
160*da0073e9SAndroid Build Coastguard Worker       Func* f,
161*da0073e9SAndroid Build Coastguard Worker       NoInferSchemaTag,
162*da0073e9SAndroid Build Coastguard Worker       std::enable_if_t<
163*da0073e9SAndroid Build Coastguard Worker           c10::guts::is_function_type<Func>::value,
164*da0073e9SAndroid Build Coastguard Worker           std::nullptr_t> = nullptr)
func_(c10::KernelFunction::makeFromUnboxedRuntimeFunction (f))165*da0073e9SAndroid Build Coastguard Worker       : func_(c10::KernelFunction::makeFromUnboxedRuntimeFunction(f)),
166*da0073e9SAndroid Build Coastguard Worker         cpp_signature_(c10::impl::CppSignature::make<Func>())
167*da0073e9SAndroid Build Coastguard Worker         // TODO: Don't go through WrapRuntimeKernelFunctor
168*da0073e9SAndroid Build Coastguard Worker         ,
169*da0073e9SAndroid Build Coastguard Worker         schema_(nullptr),
170*da0073e9SAndroid Build Coastguard Worker         debug_() {}
171*da0073e9SAndroid Build Coastguard Worker 
172*da0073e9SAndroid Build Coastguard Worker   /// This overload accepts compile time function pointers, e.g.,
173*da0073e9SAndroid Build Coastguard Worker   /// `CppFunction(TORCH_FN(add_impl), NoInferSchemaTag())`
174*da0073e9SAndroid Build Coastguard Worker   template <typename FuncPtr>
175*da0073e9SAndroid Build Coastguard Worker   explicit CppFunction(
176*da0073e9SAndroid Build Coastguard Worker       FuncPtr f,
177*da0073e9SAndroid Build Coastguard Worker       NoInferSchemaTag,
178*da0073e9SAndroid Build Coastguard Worker       std::enable_if_t<
179*da0073e9SAndroid Build Coastguard Worker           c10::is_compile_time_function_pointer<FuncPtr>::value,
180*da0073e9SAndroid Build Coastguard Worker           std::nullptr_t> = nullptr)
func_(c10::KernelFunction::makeFromUnboxedFunction (f))181*da0073e9SAndroid Build Coastguard Worker       : func_(c10::KernelFunction::makeFromUnboxedFunction(f)),
182*da0073e9SAndroid Build Coastguard Worker         cpp_signature_(
183*da0073e9SAndroid Build Coastguard Worker             c10::impl::CppSignature::make<typename FuncPtr::FuncType>())
184*da0073e9SAndroid Build Coastguard Worker         // TODO: Don't go through WrapRuntimeKernelFunctor
185*da0073e9SAndroid Build Coastguard Worker         ,
186*da0073e9SAndroid Build Coastguard Worker         schema_(nullptr),
187*da0073e9SAndroid Build Coastguard Worker         debug_() {}
188*da0073e9SAndroid Build Coastguard Worker 
189*da0073e9SAndroid Build Coastguard Worker   /// This overload accepts lambdas, e.g., `CppFunction([](const Tensor& self) {
190*da0073e9SAndroid Build Coastguard Worker   /// ... }. NoInferSchemaTag())`
191*da0073e9SAndroid Build Coastguard Worker   template <typename Lambda>
192*da0073e9SAndroid Build Coastguard Worker   explicit CppFunction(
193*da0073e9SAndroid Build Coastguard Worker       Lambda&& f,
194*da0073e9SAndroid Build Coastguard Worker       NoInferSchemaTag,
195*da0073e9SAndroid Build Coastguard Worker       std::enable_if_t<
196*da0073e9SAndroid Build Coastguard Worker           c10::guts::is_functor<std::decay_t<Lambda>>::value,
197*da0073e9SAndroid Build Coastguard Worker           std::nullptr_t> = nullptr)
func_(c10::KernelFunction::makeFromUnboxedLambda (std::forward<Lambda> (f)))198*da0073e9SAndroid Build Coastguard Worker       : func_(c10::KernelFunction::makeFromUnboxedLambda(
199*da0073e9SAndroid Build Coastguard Worker             std::forward<Lambda>(f))),
200*da0073e9SAndroid Build Coastguard Worker         cpp_signature_(c10::impl::CppSignature::make<Lambda>())
201*da0073e9SAndroid Build Coastguard Worker         // TODO: Don't go through WrapRuntimeKernelFunctor
202*da0073e9SAndroid Build Coastguard Worker         ,
203*da0073e9SAndroid Build Coastguard Worker         schema_(nullptr),
204*da0073e9SAndroid Build Coastguard Worker         debug_() {}
205*da0073e9SAndroid Build Coastguard Worker #endif
206*da0073e9SAndroid Build Coastguard Worker 
207*da0073e9SAndroid Build Coastguard Worker   ~CppFunction();
208*da0073e9SAndroid Build Coastguard Worker 
209*da0073e9SAndroid Build Coastguard Worker   CppFunction(CppFunction&&) noexcept = default;
210*da0073e9SAndroid Build Coastguard Worker 
211*da0073e9SAndroid Build Coastguard Worker   CppFunction& operator=(CppFunction&&) = default;
212*da0073e9SAndroid Build Coastguard Worker 
213*da0073e9SAndroid Build Coastguard Worker   /// \private
214*da0073e9SAndroid Build Coastguard Worker   /// Creates a function from a type-erased boxed kernel.
makeFromBoxedKernel(c10::BoxedKernel kernel)215*da0073e9SAndroid Build Coastguard Worker   static CppFunction makeFromBoxedKernel(c10::BoxedKernel kernel) {
216*da0073e9SAndroid Build Coastguard Worker     return CppFunction(
217*da0073e9SAndroid Build Coastguard Worker         c10::KernelFunction::makeFromBoxedKernel(std::move(kernel)),
218*da0073e9SAndroid Build Coastguard Worker         /* cpp_signature */ std::nullopt, // not known for boxed functions
219*da0073e9SAndroid Build Coastguard Worker         /* schema */ nullptr);
220*da0073e9SAndroid Build Coastguard Worker   }
221*da0073e9SAndroid Build Coastguard Worker 
222*da0073e9SAndroid Build Coastguard Worker   /// This creates a fallthrough function.  Fallthrough functions
223*da0073e9SAndroid Build Coastguard Worker   /// immediately redispatch to the next available dispatch key,
224*da0073e9SAndroid Build Coastguard Worker   /// but are implemented more efficiently than a hand written
225*da0073e9SAndroid Build Coastguard Worker   /// function done in the same way.
makeFallthrough()226*da0073e9SAndroid Build Coastguard Worker   static CppFunction makeFallthrough() {
227*da0073e9SAndroid Build Coastguard Worker     return makeFromBoxedKernel(c10::BoxedKernel::makeFallthrough());
228*da0073e9SAndroid Build Coastguard Worker   }
229*da0073e9SAndroid Build Coastguard Worker 
230*da0073e9SAndroid Build Coastguard Worker   /// \private
231*da0073e9SAndroid Build Coastguard Worker   ///
232*da0073e9SAndroid Build Coastguard Worker   /// Creates a function that raises an error saying that named tensors
233*da0073e9SAndroid Build Coastguard Worker   /// are not supported when called.
makeNamedNotSupported()234*da0073e9SAndroid Build Coastguard Worker   static CppFunction makeNamedNotSupported() {
235*da0073e9SAndroid Build Coastguard Worker     return makeFromBoxedKernel(c10::BoxedKernel::makeNamedNotSupported());
236*da0073e9SAndroid Build Coastguard Worker   }
237*da0073e9SAndroid Build Coastguard Worker 
238*da0073e9SAndroid Build Coastguard Worker   /// Create a function from a boxed kernel function with signature
239*da0073e9SAndroid Build Coastguard Worker   /// `void(const OperatorHandle&, Stack*)`; i.e., they receive a
240*da0073e9SAndroid Build Coastguard Worker   /// stack of arguments in a boxed calling convention, rather than
241*da0073e9SAndroid Build Coastguard Worker   /// in the native C++ calling convention.  Boxed functions are
242*da0073e9SAndroid Build Coastguard Worker   /// typically only used to register backend fallbacks via
243*da0073e9SAndroid Build Coastguard Worker   /// torch::Library::fallback().
244*da0073e9SAndroid Build Coastguard Worker   template <c10::BoxedKernel::BoxedKernelFunction* func>
makeFromBoxedFunction()245*da0073e9SAndroid Build Coastguard Worker   static CppFunction makeFromBoxedFunction() {
246*da0073e9SAndroid Build Coastguard Worker     return makeFromBoxedKernel(c10::BoxedKernel::makeFromFunction<func>());
247*da0073e9SAndroid Build Coastguard Worker   }
248*da0073e9SAndroid Build Coastguard Worker 
249*da0073e9SAndroid Build Coastguard Worker   // Variant that takes in a boxed kernel function with a plumbed
250*da0073e9SAndroid Build Coastguard Worker   // DispatchKeySet. See Note [Plumbing Keys Through The Dispatcher] for
251*da0073e9SAndroid Build Coastguard Worker   // details.
252*da0073e9SAndroid Build Coastguard Worker   template <c10::BoxedKernel::BoxedKernelFunction_withDispatchKeys* func>
makeFromBoxedFunction()253*da0073e9SAndroid Build Coastguard Worker   static CppFunction makeFromBoxedFunction() {
254*da0073e9SAndroid Build Coastguard Worker     return makeFromBoxedKernel(c10::BoxedKernel::makeFromFunction<func>());
255*da0073e9SAndroid Build Coastguard Worker   }
256*da0073e9SAndroid Build Coastguard Worker 
257*da0073e9SAndroid Build Coastguard Worker   /// Create a function from a boxed kernel functor which defines
258*da0073e9SAndroid Build Coastguard Worker   /// `operator()(const OperatorHandle&, DispatchKeySet, Stack*)`
259*da0073e9SAndroid Build Coastguard Worker   /// (receiving arguments from boxed calling convention) and inherits
260*da0073e9SAndroid Build Coastguard Worker   /// from `c10::OperatorKernel`.  Unlike makeFromBoxedFunction, functions
261*da0073e9SAndroid Build Coastguard Worker   /// registered in this way can also carry additional state which
262*da0073e9SAndroid Build Coastguard Worker   /// is managed by the functor; this is useful if you're writing an
263*da0073e9SAndroid Build Coastguard Worker   /// adapter to some other implementation, e.g., a Python callable, which
264*da0073e9SAndroid Build Coastguard Worker   /// is dynamically associated with the registered kernel.
265*da0073e9SAndroid Build Coastguard Worker   template <class KernelFunctor>
makeFromBoxedFunctor(std::unique_ptr<KernelFunctor> kernelFunctor)266*da0073e9SAndroid Build Coastguard Worker   static CppFunction makeFromBoxedFunctor(
267*da0073e9SAndroid Build Coastguard Worker       std::unique_ptr<KernelFunctor> kernelFunctor) {
268*da0073e9SAndroid Build Coastguard Worker     return makeFromBoxedKernel(
269*da0073e9SAndroid Build Coastguard Worker         c10::BoxedKernel::makeFromFunctor(std::move(kernelFunctor)));
270*da0073e9SAndroid Build Coastguard Worker   }
271*da0073e9SAndroid Build Coastguard Worker 
272*da0073e9SAndroid Build Coastguard Worker   /// Create a function from an unboxed kernel function.
273*da0073e9SAndroid Build Coastguard Worker   /// This is typically used to register common operators.
274*da0073e9SAndroid Build Coastguard Worker   template <
275*da0073e9SAndroid Build Coastguard Worker       typename FuncPtr,
276*da0073e9SAndroid Build Coastguard Worker       std::enable_if_t<
277*da0073e9SAndroid Build Coastguard Worker           c10::guts::is_function_type<FuncPtr>::value,
278*da0073e9SAndroid Build Coastguard Worker           std::nullptr_t> = nullptr>
makeFromUnboxedFunction(FuncPtr * f)279*da0073e9SAndroid Build Coastguard Worker   static CppFunction makeFromUnboxedFunction(FuncPtr* f) {
280*da0073e9SAndroid Build Coastguard Worker     return CppFunction(f);
281*da0073e9SAndroid Build Coastguard Worker   }
282*da0073e9SAndroid Build Coastguard Worker 
283*da0073e9SAndroid Build Coastguard Worker   /// Create a function from a compile time unboxed kernel function pointer.
284*da0073e9SAndroid Build Coastguard Worker   /// This is typically used to register common operators.
285*da0073e9SAndroid Build Coastguard Worker   /// Compile time function pointers can be used to allow the compiler
286*da0073e9SAndroid Build Coastguard Worker   /// to optimize (e.g. inline) calls to it.
287*da0073e9SAndroid Build Coastguard Worker   template <
288*da0073e9SAndroid Build Coastguard Worker       typename FuncPtr,
289*da0073e9SAndroid Build Coastguard Worker       std::enable_if_t<
290*da0073e9SAndroid Build Coastguard Worker           c10::is_compile_time_function_pointer<FuncPtr>::value,
291*da0073e9SAndroid Build Coastguard Worker           std::nullptr_t> = nullptr>
makeFromUnboxedFunction(FuncPtr f)292*da0073e9SAndroid Build Coastguard Worker   static CppFunction makeFromUnboxedFunction(FuncPtr f) {
293*da0073e9SAndroid Build Coastguard Worker     return CppFunction(f);
294*da0073e9SAndroid Build Coastguard Worker   }
295*da0073e9SAndroid Build Coastguard Worker 
debug(std::string d)296*da0073e9SAndroid Build Coastguard Worker   CppFunction&& debug(std::string d) && {
297*da0073e9SAndroid Build Coastguard Worker     debug_ = std::move(d);
298*da0073e9SAndroid Build Coastguard Worker     return std::move(*this);
299*da0073e9SAndroid Build Coastguard Worker   }
300*da0073e9SAndroid Build Coastguard Worker 
301*da0073e9SAndroid Build Coastguard Worker  private:
302*da0073e9SAndroid Build Coastguard Worker   std::optional<c10::DispatchKey> dispatch_key_;
303*da0073e9SAndroid Build Coastguard Worker   c10::KernelFunction func_;
304*da0073e9SAndroid Build Coastguard Worker   std::optional<c10::impl::CppSignature> cpp_signature_;
305*da0073e9SAndroid Build Coastguard Worker   std::unique_ptr<c10::FunctionSchema> schema_;
306*da0073e9SAndroid Build Coastguard Worker   std::string debug_;
307*da0073e9SAndroid Build Coastguard Worker 
308*da0073e9SAndroid Build Coastguard Worker   // The "setter" for dispatch_key_
309*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
310*da0073e9SAndroid Build Coastguard Worker   friend CppFunction dispatch(c10::DispatchKey, Func&&);
311*da0073e9SAndroid Build Coastguard Worker 
312*da0073e9SAndroid Build Coastguard Worker   // The only class which actually pulls out values from CppFunction (does so
313*da0073e9SAndroid Build Coastguard Worker   // destructively, felt too lazy to write accessors that I don't even
314*da0073e9SAndroid Build Coastguard Worker   // want users to use)
315*da0073e9SAndroid Build Coastguard Worker   friend class Library;
316*da0073e9SAndroid Build Coastguard Worker 
317*da0073e9SAndroid Build Coastguard Worker   CppFunction(
318*da0073e9SAndroid Build Coastguard Worker       c10::KernelFunction func,
319*da0073e9SAndroid Build Coastguard Worker       std::optional<c10::impl::CppSignature> cpp_signature,
320*da0073e9SAndroid Build Coastguard Worker       std::unique_ptr<c10::FunctionSchema> schema);
321*da0073e9SAndroid Build Coastguard Worker };
322*da0073e9SAndroid Build Coastguard Worker 
323*da0073e9SAndroid Build Coastguard Worker /// \defgroup torch-dispatch-overloads torch::dispatch overloads
324*da0073e9SAndroid Build Coastguard Worker 
325*da0073e9SAndroid Build Coastguard Worker /// Create a torch::CppFunction which is associated with a specific
326*da0073e9SAndroid Build Coastguard Worker /// dispatch key.  torch::CppFunctions that are tagged with a
327*da0073e9SAndroid Build Coastguard Worker /// c10::DispatchKey don't get invoked unless the dispatcher determines
328*da0073e9SAndroid Build Coastguard Worker /// that this particular c10::DispatchKey is the one that should be
329*da0073e9SAndroid Build Coastguard Worker /// dispatched to.
330*da0073e9SAndroid Build Coastguard Worker ///
331*da0073e9SAndroid Build Coastguard Worker /// This function is generally not used directly, instead, prefer using
332*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY_IMPL(), which will implicitly set the c10::DispatchKey
333*da0073e9SAndroid Build Coastguard Worker /// for all registration calls inside of its body.
334*da0073e9SAndroid Build Coastguard Worker ///
335*da0073e9SAndroid Build Coastguard Worker /// \ingroup torch-dispatch-overloads
336*da0073e9SAndroid Build Coastguard Worker template <typename Func>
dispatch(c10::DispatchKey k,Func && raw_f)337*da0073e9SAndroid Build Coastguard Worker inline CppFunction dispatch(c10::DispatchKey k, Func&& raw_f) {
338*da0073e9SAndroid Build Coastguard Worker   CppFunction f(std::forward<Func>(raw_f));
339*da0073e9SAndroid Build Coastguard Worker   if (k == c10::DispatchKey::CatchAll) {
340*da0073e9SAndroid Build Coastguard Worker     f.dispatch_key_ = std::nullopt;
341*da0073e9SAndroid Build Coastguard Worker   } else {
342*da0073e9SAndroid Build Coastguard Worker     f.dispatch_key_ = k;
343*da0073e9SAndroid Build Coastguard Worker   }
344*da0073e9SAndroid Build Coastguard Worker   return f;
345*da0073e9SAndroid Build Coastguard Worker }
346*da0073e9SAndroid Build Coastguard Worker 
347*da0073e9SAndroid Build Coastguard Worker /// Convenience overload of dispatch() which accepts c10::DeviceType
348*da0073e9SAndroid Build Coastguard Worker ///
349*da0073e9SAndroid Build Coastguard Worker /// \ingroup torch-dispatch-overloads
350*da0073e9SAndroid Build Coastguard Worker template <typename Func>
dispatch(c10::DeviceType type,Func && raw_f)351*da0073e9SAndroid Build Coastguard Worker inline CppFunction dispatch(c10::DeviceType type, Func&& raw_f) {
352*da0073e9SAndroid Build Coastguard Worker   auto deviceTypeToDispatchKey = [](c10::DeviceType t) {
353*da0073e9SAndroid Build Coastguard Worker     switch (t) {
354*da0073e9SAndroid Build Coastguard Worker       // This list is synchronized with the k-constants in c10/core/DeviceType.h
355*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::CPU:
356*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::CPU;
357*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::CUDA:
358*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::CUDA;
359*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::IPU:
360*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::IPU;
361*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::XLA:
362*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::XLA;
363*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::Lazy:
364*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::Lazy;
365*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::XPU:
366*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::XPU;
367*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::MPS:
368*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::MPS;
369*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::Meta:
370*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::Meta;
371*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::HIP:
372*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::HIP;
373*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::MAIA:
374*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::MAIA;
375*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::HPU:
376*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::HPU;
377*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::MTIA:
378*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::MTIA;
379*da0073e9SAndroid Build Coastguard Worker       case c10::DeviceType::PrivateUse1:
380*da0073e9SAndroid Build Coastguard Worker         return c10::DispatchKey::PrivateUse1;
381*da0073e9SAndroid Build Coastguard Worker       default:
382*da0073e9SAndroid Build Coastguard Worker         TORCH_CHECK(
383*da0073e9SAndroid Build Coastguard Worker             false,
384*da0073e9SAndroid Build Coastguard Worker             "Device type ",
385*da0073e9SAndroid Build Coastguard Worker             t,
386*da0073e9SAndroid Build Coastguard Worker             " cannot be overloaded at dispatch time, "
387*da0073e9SAndroid Build Coastguard Worker             "please file a bug report explaining what you were trying to do.");
388*da0073e9SAndroid Build Coastguard Worker     }
389*da0073e9SAndroid Build Coastguard Worker   };
390*da0073e9SAndroid Build Coastguard Worker   return dispatch(deviceTypeToDispatchKey(type), std::forward<Func>(raw_f));
391*da0073e9SAndroid Build Coastguard Worker }
392*da0073e9SAndroid Build Coastguard Worker 
393*da0073e9SAndroid Build Coastguard Worker /// \defgroup torch-schema-overloads torch::schema overloads
394*da0073e9SAndroid Build Coastguard Worker 
395*da0073e9SAndroid Build Coastguard Worker /// Construct a c10::FunctionSchema from a string, with an explicitly
396*da0073e9SAndroid Build Coastguard Worker /// specified c10::AliasAnalysisKind.  Ordinarily, schemas are simply
397*da0073e9SAndroid Build Coastguard Worker /// passed in as strings, but if you need to specify a custom alias
398*da0073e9SAndroid Build Coastguard Worker /// analysis, you can replace the string with a call to this function.
399*da0073e9SAndroid Build Coastguard Worker ///
400*da0073e9SAndroid Build Coastguard Worker /// ```
401*da0073e9SAndroid Build Coastguard Worker /// // Default alias analysis (FROM_SCHEMA)
402*da0073e9SAndroid Build Coastguard Worker /// m.def("def3(Tensor self) -> Tensor");
403*da0073e9SAndroid Build Coastguard Worker /// // Pure function alias analysis
404*da0073e9SAndroid Build Coastguard Worker /// m.def(torch::schema("def3(Tensor self) -> Tensor",
405*da0073e9SAndroid Build Coastguard Worker /// c10::AliasAnalysisKind::PURE_FUNCTION));
406*da0073e9SAndroid Build Coastguard Worker /// ```
407*da0073e9SAndroid Build Coastguard Worker ///
408*da0073e9SAndroid Build Coastguard Worker /// \ingroup torch-schema-overloads
409*da0073e9SAndroid Build Coastguard Worker inline c10::FunctionSchema schema(const char* str, c10::AliasAnalysisKind k, bool allow_typevars=false) {
410*da0073e9SAndroid Build Coastguard Worker   c10::FunctionSchema s = torch::jit::parseSchema(str, /*allow_typevars*/allow_typevars);
411*da0073e9SAndroid Build Coastguard Worker   s.setAliasAnalysis(k);
412*da0073e9SAndroid Build Coastguard Worker   return s;
413*da0073e9SAndroid Build Coastguard Worker }
414*da0073e9SAndroid Build Coastguard Worker 
415*da0073e9SAndroid Build Coastguard Worker /// Function schemas can be directly constructed from string literals.
416*da0073e9SAndroid Build Coastguard Worker ///
417*da0073e9SAndroid Build Coastguard Worker /// \ingroup torch-schema-overloads
418*da0073e9SAndroid Build Coastguard Worker inline c10::FunctionSchema schema(const char* s, bool allow_typevars=false) {
419*da0073e9SAndroid Build Coastguard Worker   return schema(s, c10::AliasAnalysisKind::FROM_SCHEMA, allow_typevars);
420*da0073e9SAndroid Build Coastguard Worker }
421*da0073e9SAndroid Build Coastguard Worker 
422*da0073e9SAndroid Build Coastguard Worker /// \private
423*da0073e9SAndroid Build Coastguard Worker ///
424*da0073e9SAndroid Build Coastguard Worker /// Already constructed function schemas are accepted if they are
425*da0073e9SAndroid Build Coastguard Worker /// rvalues.
426*da0073e9SAndroid Build Coastguard Worker ///
427*da0073e9SAndroid Build Coastguard Worker /// \ingroup torch-schema-overloads
schema(c10::FunctionSchema && s)428*da0073e9SAndroid Build Coastguard Worker inline c10::FunctionSchema&& schema(c10::FunctionSchema&& s) {
429*da0073e9SAndroid Build Coastguard Worker   return std::move(s);
430*da0073e9SAndroid Build Coastguard Worker }
431*da0073e9SAndroid Build Coastguard Worker 
432*da0073e9SAndroid Build Coastguard Worker namespace detail {
433*da0073e9SAndroid Build Coastguard Worker 
constructSchemaOrName(c10::FunctionSchema && s)434*da0073e9SAndroid Build Coastguard Worker inline std::variant<c10::OperatorName, c10::FunctionSchema> constructSchemaOrName(
435*da0073e9SAndroid Build Coastguard Worker     c10::FunctionSchema&& s) {
436*da0073e9SAndroid Build Coastguard Worker   return std::move(s);
437*da0073e9SAndroid Build Coastguard Worker }
constructSchemaOrName(c10::OperatorName && n)438*da0073e9SAndroid Build Coastguard Worker inline std::variant<c10::OperatorName, c10::FunctionSchema> constructSchemaOrName(
439*da0073e9SAndroid Build Coastguard Worker     c10::OperatorName&& n) {
440*da0073e9SAndroid Build Coastguard Worker   return std::move(n);
441*da0073e9SAndroid Build Coastguard Worker }
442*da0073e9SAndroid Build Coastguard Worker inline std::variant<c10::OperatorName, c10::FunctionSchema>
constructSchemaOrName(const char * str)443*da0073e9SAndroid Build Coastguard Worker constructSchemaOrName(const char* str) {
444*da0073e9SAndroid Build Coastguard Worker   auto s = torch::jit::parseSchemaOrName(str);
445*da0073e9SAndroid Build Coastguard Worker   if (std::holds_alternative<c10::FunctionSchema>(s)) {
446*da0073e9SAndroid Build Coastguard Worker     std::get<c10::FunctionSchema>(s).setAliasAnalysis(
447*da0073e9SAndroid Build Coastguard Worker         c10::AliasAnalysisKind::FROM_SCHEMA);
448*da0073e9SAndroid Build Coastguard Worker   }
449*da0073e9SAndroid Build Coastguard Worker   return s;
450*da0073e9SAndroid Build Coastguard Worker }
451*da0073e9SAndroid Build Coastguard Worker 
452*da0073e9SAndroid Build Coastguard Worker class TorchLibraryInit;
453*da0073e9SAndroid Build Coastguard Worker 
454*da0073e9SAndroid Build Coastguard Worker } // namespace detail
455*da0073e9SAndroid Build Coastguard Worker 
456*da0073e9SAndroid Build Coastguard Worker // Note [Selective build]
457*da0073e9SAndroid Build Coastguard Worker // ~~~~~~~~~~~~~~~~~~~~~~
458*da0073e9SAndroid Build Coastguard Worker // In some settings, especially mobile, it is important to avoid compiling any
459*da0073e9SAndroid Build Coastguard Worker // references to functions that you aren't actually going to use, so that they
460*da0073e9SAndroid Build Coastguard Worker // can be eliminated by the linker.  We call this capability "selective build".
461*da0073e9SAndroid Build Coastguard Worker //
462*da0073e9SAndroid Build Coastguard Worker // A very easy way to implement selective build which results in a lot of
463*da0073e9SAndroid Build Coastguard Worker // boilerplate is to just add ifdef's around every registration call, but this
464*da0073e9SAndroid Build Coastguard Worker // means you have to write a lot of extra lines of code at every registration
465*da0073e9SAndroid Build Coastguard Worker // site, and it also means you have to define some munging scheme to map
466*da0073e9SAndroid Build Coastguard Worker // operators to macros.
467*da0073e9SAndroid Build Coastguard Worker //
468*da0073e9SAndroid Build Coastguard Worker // Instead of doing this, we have a different mechanism centered around the
469*da0073e9SAndroid Build Coastguard Worker // concept of a SelectiveStr.  A selective name is like a const char* string,
470*da0073e9SAndroid Build Coastguard Worker // except it also carries at compile time a boolean saying whether or not a
471*da0073e9SAndroid Build Coastguard Worker // registration should actually happen or not.  We then have extra overloads
472*da0073e9SAndroid Build Coastguard Worker // which bypass registration entirely if a selective name is disabled.  We do a
473*da0073e9SAndroid Build Coastguard Worker // constexpr test to see if a operator should be enabled or not; this is
474*da0073e9SAndroid Build Coastguard Worker // currently implemented in ATen/core/op_registration/op_allowlist.h
475*da0073e9SAndroid Build Coastguard Worker 
476*da0073e9SAndroid Build Coastguard Worker namespace detail {
477*da0073e9SAndroid Build Coastguard Worker 
478*da0073e9SAndroid Build Coastguard Worker // dummy class for non selected custom torchbind classes
479*da0073e9SAndroid Build Coastguard Worker class ClassNotSelected {
480*da0073e9SAndroid Build Coastguard Worker  public:
def_pickle(...)481*da0073e9SAndroid Build Coastguard Worker   ClassNotSelected& def_pickle(...) {
482*da0073e9SAndroid Build Coastguard Worker     return *this;
483*da0073e9SAndroid Build Coastguard Worker   }
def(...)484*da0073e9SAndroid Build Coastguard Worker   ClassNotSelected& def(...) {
485*da0073e9SAndroid Build Coastguard Worker     return *this;
486*da0073e9SAndroid Build Coastguard Worker   }
487*da0073e9SAndroid Build Coastguard Worker };
488*da0073e9SAndroid Build Coastguard Worker 
489*da0073e9SAndroid Build Coastguard Worker // A SelectiveStr is like a const char*, except that it also comes
490*da0073e9SAndroid Build Coastguard Worker // with a type brand that says whether or not the name is enabled or
491*da0073e9SAndroid Build Coastguard Worker // not.  If the string is disabled, then (at compile time) we DON'T generate
492*da0073e9SAndroid Build Coastguard Worker // a registration call for it.  This class is not intended to be called
493*da0073e9SAndroid Build Coastguard Worker // directly; use TORCH_SELECTIVE_NAME or TORCH_SELECTIVE_SCHEMA macros below
494*da0073e9SAndroid Build Coastguard Worker // to create it.
495*da0073e9SAndroid Build Coastguard Worker template <bool enabled>
496*da0073e9SAndroid Build Coastguard Worker class SelectiveStr {
497*da0073e9SAndroid Build Coastguard Worker  public:
SelectiveStr(const char * name)498*da0073e9SAndroid Build Coastguard Worker   constexpr explicit SelectiveStr(const char* name) : name_(name) {}
499*da0073e9SAndroid Build Coastguard Worker   constexpr operator const char*() {
500*da0073e9SAndroid Build Coastguard Worker     return name_;
501*da0073e9SAndroid Build Coastguard Worker   }
502*da0073e9SAndroid Build Coastguard Worker 
503*da0073e9SAndroid Build Coastguard Worker  private:
504*da0073e9SAndroid Build Coastguard Worker   const char* name_;
505*da0073e9SAndroid Build Coastguard Worker };
506*da0073e9SAndroid Build Coastguard Worker 
507*da0073e9SAndroid Build Coastguard Worker #define TORCH_SELECTIVE_CLASS(n) \
508*da0073e9SAndroid Build Coastguard Worker   torch::detail::SelectiveStr<c10::impl::custom_class_allowlist_check(n)>(n)
509*da0073e9SAndroid Build Coastguard Worker #define TORCH_SELECTIVE_NAME(n) \
510*da0073e9SAndroid Build Coastguard Worker   torch::detail::SelectiveStr<c10::impl::op_allowlist_check(n)>(n)
511*da0073e9SAndroid Build Coastguard Worker #define TORCH_SELECTIVE_SCHEMA(n) \
512*da0073e9SAndroid Build Coastguard Worker   torch::detail::SelectiveStr<c10::impl::schema_allowlist_check(n)>(n)
513*da0073e9SAndroid Build Coastguard Worker 
514*da0073e9SAndroid Build Coastguard Worker } // namespace detail
515*da0073e9SAndroid Build Coastguard Worker 
516*da0073e9SAndroid Build Coastguard Worker /// This object provides the API for defining operators and providing
517*da0073e9SAndroid Build Coastguard Worker /// implementations at dispatch keys.  Typically, a torch::Library
518*da0073e9SAndroid Build Coastguard Worker /// is not allocated directly; instead it is created by the
519*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY() or TORCH_LIBRARY_IMPL() macros.
520*da0073e9SAndroid Build Coastguard Worker ///
521*da0073e9SAndroid Build Coastguard Worker /// Most methods on torch::Library return a reference to itself,
522*da0073e9SAndroid Build Coastguard Worker /// supporting method chaining.
523*da0073e9SAndroid Build Coastguard Worker ///
524*da0073e9SAndroid Build Coastguard Worker /// ```
525*da0073e9SAndroid Build Coastguard Worker /// // Examples:
526*da0073e9SAndroid Build Coastguard Worker ///
527*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY(torchvision, m) {
528*da0073e9SAndroid Build Coastguard Worker ///    // m is a torch::Library
529*da0073e9SAndroid Build Coastguard Worker ///    m.def("roi_align", ...);
530*da0073e9SAndroid Build Coastguard Worker ///    ...
531*da0073e9SAndroid Build Coastguard Worker /// }
532*da0073e9SAndroid Build Coastguard Worker ///
533*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY_IMPL(aten, XLA, m) {
534*da0073e9SAndroid Build Coastguard Worker ///    // m is a torch::Library
535*da0073e9SAndroid Build Coastguard Worker ///    m.impl("add", ...);
536*da0073e9SAndroid Build Coastguard Worker ///    ...
537*da0073e9SAndroid Build Coastguard Worker /// }
538*da0073e9SAndroid Build Coastguard Worker /// ```
539*da0073e9SAndroid Build Coastguard Worker ///
540*da0073e9SAndroid Build Coastguard Worker class TORCH_API Library final {
541*da0073e9SAndroid Build Coastguard Worker  public:
542*da0073e9SAndroid Build Coastguard Worker   /// \private
543*da0073e9SAndroid Build Coastguard Worker   ///
544*da0073e9SAndroid Build Coastguard Worker   /// Which type of macro produced this Library
545*da0073e9SAndroid Build Coastguard Worker   enum Kind {
546*da0073e9SAndroid Build Coastguard Worker     DEF, // from TORCH_LIBRARY (no qualifier)
547*da0073e9SAndroid Build Coastguard Worker     IMPL,
548*da0073e9SAndroid Build Coastguard Worker     FRAGMENT,
549*da0073e9SAndroid Build Coastguard Worker   };
550*da0073e9SAndroid Build Coastguard Worker 
551*da0073e9SAndroid Build Coastguard Worker   /// \private
552*da0073e9SAndroid Build Coastguard Worker   ///
553*da0073e9SAndroid Build Coastguard Worker   /// Use TORCH_LIBRARY() or TORCH_LIBRARY_IMPL() instead of using these
554*da0073e9SAndroid Build Coastguard Worker   /// constructors directly
555*da0073e9SAndroid Build Coastguard Worker   Library(
556*da0073e9SAndroid Build Coastguard Worker       Kind kind,
557*da0073e9SAndroid Build Coastguard Worker       std::string ns,
558*da0073e9SAndroid Build Coastguard Worker       std::optional<c10::DispatchKey> k,
559*da0073e9SAndroid Build Coastguard Worker       const char* file,
560*da0073e9SAndroid Build Coastguard Worker       uint32_t line);
561*da0073e9SAndroid Build Coastguard Worker 
562*da0073e9SAndroid Build Coastguard Worker   Library(const Library&) = delete;
563*da0073e9SAndroid Build Coastguard Worker   Library& operator=(const Library&) = delete;
564*da0073e9SAndroid Build Coastguard Worker   Library(Library&&) = default;
565*da0073e9SAndroid Build Coastguard Worker   Library& operator=(Library&&) = default;
566*da0073e9SAndroid Build Coastguard Worker 
567*da0073e9SAndroid Build Coastguard Worker   // Some notes about the API design here.  We had the following constraints:
568*da0073e9SAndroid Build Coastguard Worker   //
569*da0073e9SAndroid Build Coastguard Worker   //  - We need to support multiple "types" of arguments for schema and
570*da0073e9SAndroid Build Coastguard Worker   //    functions (e.g., unnamed lambda types, regular functions, const char*,
571*da0073e9SAndroid Build Coastguard Worker   //    fully instantiated schemas)
572*da0073e9SAndroid Build Coastguard Worker   //  - We don't want to write exponentially many overloads
573*da0073e9SAndroid Build Coastguard Worker   //  - We don't want to rely on implicit conversion to a common type,
574*da0073e9SAndroid Build Coastguard Worker   //    because the C++ compiler will only be willing to do a single
575*da0073e9SAndroid Build Coastguard Worker   //    implicit conversion (reducing the set of valid types which you
576*da0073e9SAndroid Build Coastguard Worker   //    can invoke with); also error messages are worse when an implicit
577*da0073e9SAndroid Build Coastguard Worker   //    conversion is not selected (as the compiler will not explain
578*da0073e9SAndroid Build Coastguard Worker   //    why it didn't select an implicit conversion; this is different
579*da0073e9SAndroid Build Coastguard Worker   //    from overloads where it will explain each candidate overload and
580*da0073e9SAndroid Build Coastguard Worker   //    why it didn't apply)
581*da0073e9SAndroid Build Coastguard Worker   //
582*da0073e9SAndroid Build Coastguard Worker   // To solve all of these constraints at the same time, we use a trick taken
583*da0073e9SAndroid Build Coastguard Worker   // from the pybind11 library: template over the argument in the user visible
584*da0073e9SAndroid Build Coastguard Worker   // API, and inside of the templated function explicitly call an overloaded
585*da0073e9SAndroid Build Coastguard Worker   // function to resolve the argument to a real type.  You get the good error
586*da0073e9SAndroid Build Coastguard Worker   // messages from overloads, but at the same time you only need to write the
587*da0073e9SAndroid Build Coastguard Worker   // overload for any given argument type once.
588*da0073e9SAndroid Build Coastguard Worker 
589*da0073e9SAndroid Build Coastguard Worker   /// Declare an operator with a schema, but don't provide any implementations
590*da0073e9SAndroid Build Coastguard Worker   /// for it.  You're expected to then provide implementations using the
591*da0073e9SAndroid Build Coastguard Worker   /// impl() method.  All template arguments are inferred.
592*da0073e9SAndroid Build Coastguard Worker   ///
593*da0073e9SAndroid Build Coastguard Worker   /// \param raw_schema The schema of the operator to be defined.
594*da0073e9SAndroid Build Coastguard Worker   ///     Typically, this is a `const char*` string literal, but any type
595*da0073e9SAndroid Build Coastguard Worker   ///     accepted by torch::schema() is accepted here.
596*da0073e9SAndroid Build Coastguard Worker   ///
597*da0073e9SAndroid Build Coastguard Worker   /// ```
598*da0073e9SAndroid Build Coastguard Worker   /// // Example:
599*da0073e9SAndroid Build Coastguard Worker   /// TORCH_LIBRARY(myops, m) {
600*da0073e9SAndroid Build Coastguard Worker   ///   m.def("add(Tensor self, Tensor other) -> Tensor");
601*da0073e9SAndroid Build Coastguard Worker   /// }
602*da0073e9SAndroid Build Coastguard Worker   /// ```
603*da0073e9SAndroid Build Coastguard Worker 
604*da0073e9SAndroid Build Coastguard Worker   template <typename Schema>
605*da0073e9SAndroid Build Coastguard Worker   Library& def(
606*da0073e9SAndroid Build Coastguard Worker       Schema&& raw_schema,
607*da0073e9SAndroid Build Coastguard Worker       const std::vector<at::Tag>& tags = {},
608*da0073e9SAndroid Build Coastguard Worker       _RegisterOrVerify rv = _RegisterOrVerify::REGISTER) & {
609*da0073e9SAndroid Build Coastguard Worker     c10::FunctionSchema s = schema(std::forward<Schema>(raw_schema));
610*da0073e9SAndroid Build Coastguard Worker     return _def(std::move(s), nullptr, tags, rv);
611*da0073e9SAndroid Build Coastguard Worker   }
612*da0073e9SAndroid Build Coastguard Worker 
613*da0073e9SAndroid Build Coastguard Worker   /// Declares that for all operators that are subsequently def'ed, their
614*da0073e9SAndroid Build Coastguard Worker   /// fake impls may be found in the given Python module (pymodule).
615*da0073e9SAndroid Build Coastguard Worker   /// This registers some help text that is used if the fake impl
616*da0073e9SAndroid Build Coastguard Worker   /// cannot be found.
617*da0073e9SAndroid Build Coastguard Worker   ///
618*da0073e9SAndroid Build Coastguard Worker   /// Args:
619*da0073e9SAndroid Build Coastguard Worker   /// - pymodule: the python module
620*da0073e9SAndroid Build Coastguard Worker   /// - context: We may include this in the error message.
621*da0073e9SAndroid Build Coastguard Worker   Library& set_python_module(const char* pymodule, const char* context = "") {
622*da0073e9SAndroid Build Coastguard Worker     python_module_ = {pymodule, context};
623*da0073e9SAndroid Build Coastguard Worker     return *this;
624*da0073e9SAndroid Build Coastguard Worker   }
625*da0073e9SAndroid Build Coastguard Worker 
626*da0073e9SAndroid Build Coastguard Worker   /// Deprecated; use set_python_module instead
627*da0073e9SAndroid Build Coastguard Worker   Library& impl_abstract_pystub(const char* pymodule, const char* context = "") {
628*da0073e9SAndroid Build Coastguard Worker     return set_python_module(pymodule, context);
629*da0073e9SAndroid Build Coastguard Worker   }
630*da0073e9SAndroid Build Coastguard Worker 
631*da0073e9SAndroid Build Coastguard Worker   /// Define an operator for a schema and then register an implementation for
632*da0073e9SAndroid Build Coastguard Worker   /// it.  This is typically what you would use if you aren't planning
633*da0073e9SAndroid Build Coastguard Worker   /// on making use of the dispatcher to structure your operator
634*da0073e9SAndroid Build Coastguard Worker   /// implementation.  It's roughly equivalent to calling def() and
635*da0073e9SAndroid Build Coastguard Worker   /// then impl(), but if you omit the schema of the operator, we will
636*da0073e9SAndroid Build Coastguard Worker   /// infer it from the type of your C++ function.  All template
637*da0073e9SAndroid Build Coastguard Worker   /// arguments are inferred.
638*da0073e9SAndroid Build Coastguard Worker   ///
639*da0073e9SAndroid Build Coastguard Worker   /// \param raw_name_or_schema The schema of the operator to be
640*da0073e9SAndroid Build Coastguard Worker   ///   defined, or just the name of the operator if the schema is to be
641*da0073e9SAndroid Build Coastguard Worker   ///   inferred from `raw_f`.  Typically a `const char*` literal.
642*da0073e9SAndroid Build Coastguard Worker   /// \param raw_f The C++ function that implements this operator.
643*da0073e9SAndroid Build Coastguard Worker   ///   Any valid constructor of torch::CppFunction is accepted here;
644*da0073e9SAndroid Build Coastguard Worker   ///   typically you provide a function pointer or lambda.
645*da0073e9SAndroid Build Coastguard Worker   ///
646*da0073e9SAndroid Build Coastguard Worker   /// ```
647*da0073e9SAndroid Build Coastguard Worker   /// // Example:
648*da0073e9SAndroid Build Coastguard Worker   /// TORCH_LIBRARY(myops, m) {
649*da0073e9SAndroid Build Coastguard Worker   ///   m.def("add", add_fn);
650*da0073e9SAndroid Build Coastguard Worker   /// }
651*da0073e9SAndroid Build Coastguard Worker   /// ```
652*da0073e9SAndroid Build Coastguard Worker   template <typename NameOrSchema, typename Func>
653*da0073e9SAndroid Build Coastguard Worker   Library& def(NameOrSchema&& raw_name_or_schema, Func&& raw_f,
654*da0073e9SAndroid Build Coastguard Worker       const std::vector<at::Tag>& tags = {}) & {
655*da0073e9SAndroid Build Coastguard Worker     CppFunction f(std::forward<Func>(raw_f));
656*da0073e9SAndroid Build Coastguard Worker     return _def(
657*da0073e9SAndroid Build Coastguard Worker         detail::constructSchemaOrName(
658*da0073e9SAndroid Build Coastguard Worker             ::std::forward<NameOrSchema>(raw_name_or_schema)),
659*da0073e9SAndroid Build Coastguard Worker         ::std::move(f), tags);
660*da0073e9SAndroid Build Coastguard Worker   }
661*da0073e9SAndroid Build Coastguard Worker 
662*da0073e9SAndroid Build Coastguard Worker   /// Register an implementation for an operator.  You may register multiple
663*da0073e9SAndroid Build Coastguard Worker   /// implementations for a single operator at different dispatch keys
664*da0073e9SAndroid Build Coastguard Worker   /// (see torch::dispatch()).  Implementations must have a corresponding
665*da0073e9SAndroid Build Coastguard Worker   /// declaration (from def()), otherwise they are invalid.  If you plan
666*da0073e9SAndroid Build Coastguard Worker   /// to register multiple implementations, DO NOT provide a function
667*da0073e9SAndroid Build Coastguard Worker   /// implementation when you def() the operator.
668*da0073e9SAndroid Build Coastguard Worker   ///
669*da0073e9SAndroid Build Coastguard Worker   /// \param name The name of the operator to implement.  Do NOT provide
670*da0073e9SAndroid Build Coastguard Worker   ///   schema here.
671*da0073e9SAndroid Build Coastguard Worker   /// \param raw_f The C++ function that implements this operator.  Any
672*da0073e9SAndroid Build Coastguard Worker   ///   valid constructor of torch::CppFunction is accepted here;
673*da0073e9SAndroid Build Coastguard Worker   ///   typically you provide a function pointer or lambda.
674*da0073e9SAndroid Build Coastguard Worker   ///
675*da0073e9SAndroid Build Coastguard Worker   /// ```
676*da0073e9SAndroid Build Coastguard Worker   /// // Example:
677*da0073e9SAndroid Build Coastguard Worker   /// TORCH_LIBRARY_IMPL(myops, CUDA, m) {
678*da0073e9SAndroid Build Coastguard Worker   ///   m.impl("add", add_cuda);
679*da0073e9SAndroid Build Coastguard Worker   /// }
680*da0073e9SAndroid Build Coastguard Worker   /// ```
681*da0073e9SAndroid Build Coastguard Worker   template <typename Name, typename Func>
682*da0073e9SAndroid Build Coastguard Worker   Library& impl(
683*da0073e9SAndroid Build Coastguard Worker       Name name,
684*da0073e9SAndroid Build Coastguard Worker       Func&& raw_f,
685*da0073e9SAndroid Build Coastguard Worker       _RegisterOrVerify rv = _RegisterOrVerify::REGISTER) & {
686*da0073e9SAndroid Build Coastguard Worker     // TODO: need to raise an error when you impl a function that has a
687*da0073e9SAndroid Build Coastguard Worker     // catch all def
688*da0073e9SAndroid Build Coastguard Worker #if defined C10_MOBILE
689*da0073e9SAndroid Build Coastguard Worker     CppFunction f(std::forward<Func>(raw_f), NoInferSchemaTag());
690*da0073e9SAndroid Build Coastguard Worker #else
691*da0073e9SAndroid Build Coastguard Worker     CppFunction f(std::forward<Func>(raw_f));
692*da0073e9SAndroid Build Coastguard Worker #endif
693*da0073e9SAndroid Build Coastguard Worker     return _impl(name, std::move(f), rv);
694*da0073e9SAndroid Build Coastguard Worker   }
695*da0073e9SAndroid Build Coastguard Worker 
696*da0073e9SAndroid Build Coastguard Worker #if defined C10_MOBILE
697*da0073e9SAndroid Build Coastguard Worker   // Note: This overload is needed only for C10_MOBILE, since the automatically
698*da0073e9SAndroid Build Coastguard Worker   // defined copy constructor for the CppFunction doesn't have the additional
699*da0073e9SAndroid Build Coastguard Worker   // NoInferSchemaTag argument. We define the overload for the impl() function
700*da0073e9SAndroid Build Coastguard Worker   // to accept a CppFunction&& argument. The already constructed CppFunction
701*da0073e9SAndroid Build Coastguard Worker   // object may or may not have the inferred schema, but it doesn't matter
702*da0073e9SAndroid Build Coastguard Worker   // for our purposes since if it already has the inferred schema, then we
703*da0073e9SAndroid Build Coastguard Worker   // might as well just pass it through directly.
704*da0073e9SAndroid Build Coastguard Worker   //
705*da0073e9SAndroid Build Coastguard Worker   template <typename Name>
impl(Name name,CppFunction && raw_f)706*da0073e9SAndroid Build Coastguard Worker   Library& impl(Name name, CppFunction&& raw_f) & {
707*da0073e9SAndroid Build Coastguard Worker     // TODO: need to raise an error when you impl a function that has a
708*da0073e9SAndroid Build Coastguard Worker     // catch all def
709*da0073e9SAndroid Build Coastguard Worker     CppFunction f(std::forward<CppFunction>(raw_f));
710*da0073e9SAndroid Build Coastguard Worker     return _impl(name, std::move(f));
711*da0073e9SAndroid Build Coastguard Worker   }
712*da0073e9SAndroid Build Coastguard Worker #endif
713*da0073e9SAndroid Build Coastguard Worker 
714*da0073e9SAndroid Build Coastguard Worker   // Helper for getting an OperatorName for a const char*.  You probably
715*da0073e9SAndroid Build Coastguard Worker   // don't need this.
716*da0073e9SAndroid Build Coastguard Worker   c10::OperatorName _resolve(const char* name) const;
717*da0073e9SAndroid Build Coastguard Worker 
718*da0073e9SAndroid Build Coastguard Worker   /// \private
719*da0073e9SAndroid Build Coastguard Worker   ///
720*da0073e9SAndroid Build Coastguard Worker   /// Convenience overload for directly specifying the dispatch key when
721*da0073e9SAndroid Build Coastguard Worker   /// impl().  You probably don't need this; instead, prefer specifying
722*da0073e9SAndroid Build Coastguard Worker   /// the dispatch key for the entire block in TORCH_LIBRARY_IMPL()
723*da0073e9SAndroid Build Coastguard Worker   template <typename Name, typename Dispatch, typename Func>
impl(Name name,Dispatch && key,Func && raw_f)724*da0073e9SAndroid Build Coastguard Worker   Library& impl(Name name, Dispatch&& key, Func&& raw_f) & {
725*da0073e9SAndroid Build Coastguard Worker     return impl(
726*da0073e9SAndroid Build Coastguard Worker         name, dispatch(std::forward<Dispatch>(key), std::forward<Func>(raw_f)));
727*da0073e9SAndroid Build Coastguard Worker   }
728*da0073e9SAndroid Build Coastguard Worker 
729*da0073e9SAndroid Build Coastguard Worker   template <typename Name, typename Func>
impl_UNBOXED(Name,Func *)730*da0073e9SAndroid Build Coastguard Worker   Library& impl_UNBOXED(Name /*name*/, Func* /*raw_f*/) & {
731*da0073e9SAndroid Build Coastguard Worker     static_assert(
732*da0073e9SAndroid Build Coastguard Worker         c10::guts::false_t<Func>(),
733*da0073e9SAndroid Build Coastguard Worker         ".impl_UNBOXED(...) was removed. Please use .impl(...) instead.");
734*da0073e9SAndroid Build Coastguard Worker     return *this;
735*da0073e9SAndroid Build Coastguard Worker   }
736*da0073e9SAndroid Build Coastguard Worker 
737*da0073e9SAndroid Build Coastguard Worker   // These overloads cover cases when a SelectiveStr (see Note [Selective
738*da0073e9SAndroid Build Coastguard Worker   // build]) has been disabled at compile time.  In that case, don't generate
739*da0073e9SAndroid Build Coastguard Worker   // any code referencing the passed in functions at all.
740*da0073e9SAndroid Build Coastguard Worker   Library& def(detail::SelectiveStr<false>, const std::vector<at::Tag>& tags [[maybe_unused]] = {}) & {
741*da0073e9SAndroid Build Coastguard Worker     return *this;
742*da0073e9SAndroid Build Coastguard Worker   }
743*da0073e9SAndroid Build Coastguard Worker   Library& def(detail::SelectiveStr<true> raw_schema, const std::vector<at::Tag>& tags = {}) & {
744*da0073e9SAndroid Build Coastguard Worker     return def(raw_schema.operator const char*(), tags);
745*da0073e9SAndroid Build Coastguard Worker   }
746*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
747*da0073e9SAndroid Build Coastguard Worker   Library& def(detail::SelectiveStr<false>, Func&& /*raw_f*/, const std::vector<at::Tag>& tags [[maybe_unused]] = {}) & {
748*da0073e9SAndroid Build Coastguard Worker     return *this;
749*da0073e9SAndroid Build Coastguard Worker   }
750*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
751*da0073e9SAndroid Build Coastguard Worker   Library& def(detail::SelectiveStr<true> raw_name_or_schema, Func&& raw_f, const std::vector<at::Tag>& tags = {}) & {
752*da0073e9SAndroid Build Coastguard Worker     return def(
753*da0073e9SAndroid Build Coastguard Worker         raw_name_or_schema.operator const char*(), std::forward<Func>(raw_f), tags);
754*da0073e9SAndroid Build Coastguard Worker   }
755*da0073e9SAndroid Build Coastguard Worker 
756*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
757*da0073e9SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
impl(detail::SelectiveStr<false>,Func &&)758*da0073e9SAndroid Build Coastguard Worker   Library& impl(detail::SelectiveStr<false>, Func&& /*raw_f*/) & {
759*da0073e9SAndroid Build Coastguard Worker     return *this;
760*da0073e9SAndroid Build Coastguard Worker   }
761*da0073e9SAndroid Build Coastguard Worker   template <typename Dispatch, typename Func>
impl(detail::SelectiveStr<false>,Dispatch &&,Func &&)762*da0073e9SAndroid Build Coastguard Worker   Library& impl(
763*da0073e9SAndroid Build Coastguard Worker       detail::SelectiveStr<false>,
764*da0073e9SAndroid Build Coastguard Worker       // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
765*da0073e9SAndroid Build Coastguard Worker       Dispatch&& /*key*/,
766*da0073e9SAndroid Build Coastguard Worker       // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
767*da0073e9SAndroid Build Coastguard Worker       Func&& /*raw_f*/) & {
768*da0073e9SAndroid Build Coastguard Worker     return *this;
769*da0073e9SAndroid Build Coastguard Worker   }
770*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
impl_UNBOXED(detail::SelectiveStr<false>,Func *)771*da0073e9SAndroid Build Coastguard Worker   Library& impl_UNBOXED(
772*da0073e9SAndroid Build Coastguard Worker       detail::SelectiveStr<false> /*name*/,
773*da0073e9SAndroid Build Coastguard Worker       Func* /*raw_f*/) & {
774*da0073e9SAndroid Build Coastguard Worker     static_assert(
775*da0073e9SAndroid Build Coastguard Worker         c10::guts::false_t<Func>(),
776*da0073e9SAndroid Build Coastguard Worker         ".impl_UNBOXED(...) was removed. Please use .impl(...) instead.");
777*da0073e9SAndroid Build Coastguard Worker     return *this;
778*da0073e9SAndroid Build Coastguard Worker   }
779*da0073e9SAndroid Build Coastguard Worker 
780*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
impl(detail::SelectiveStr<true> name,Func && raw_f)781*da0073e9SAndroid Build Coastguard Worker   Library& impl(detail::SelectiveStr<true> name, Func&& raw_f) & {
782*da0073e9SAndroid Build Coastguard Worker     return impl(name.operator const char*(), std::forward<Func>(raw_f));
783*da0073e9SAndroid Build Coastguard Worker   }
784*da0073e9SAndroid Build Coastguard Worker   template <typename Dispatch, typename Func>
impl(detail::SelectiveStr<true> name,Dispatch && key,Func && raw_f)785*da0073e9SAndroid Build Coastguard Worker   Library& impl(
786*da0073e9SAndroid Build Coastguard Worker       detail::SelectiveStr<true> name,
787*da0073e9SAndroid Build Coastguard Worker       Dispatch&& key,
788*da0073e9SAndroid Build Coastguard Worker       Func&& raw_f) & {
789*da0073e9SAndroid Build Coastguard Worker     return impl(
790*da0073e9SAndroid Build Coastguard Worker         name.operator const char*(),
791*da0073e9SAndroid Build Coastguard Worker         std::forward<Dispatch>(key),
792*da0073e9SAndroid Build Coastguard Worker         std::forward<Func>(raw_f));
793*da0073e9SAndroid Build Coastguard Worker   }
794*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
impl_UNBOXED(detail::SelectiveStr<true>,Func *)795*da0073e9SAndroid Build Coastguard Worker   Library& impl_UNBOXED(
796*da0073e9SAndroid Build Coastguard Worker       detail::SelectiveStr<true> /*name*/,
797*da0073e9SAndroid Build Coastguard Worker       Func* /*raw_f*/) & {
798*da0073e9SAndroid Build Coastguard Worker     static_assert(
799*da0073e9SAndroid Build Coastguard Worker         c10::guts::false_t<Func>(),
800*da0073e9SAndroid Build Coastguard Worker         ".impl_UNBOXED(...) was removed. Please use .impl(...) instead.");
801*da0073e9SAndroid Build Coastguard Worker     return *this;
802*da0073e9SAndroid Build Coastguard Worker   }
803*da0073e9SAndroid Build Coastguard Worker 
804*da0073e9SAndroid Build Coastguard Worker   /// Register a fallback implementation for all operators which will be used
805*da0073e9SAndroid Build Coastguard Worker   /// if there is not a specific implementation for an operator available.
806*da0073e9SAndroid Build Coastguard Worker   /// There MUST be a DispatchKey associated with a fallback; e.g.,
807*da0073e9SAndroid Build Coastguard Worker   /// only call this from TORCH_LIBRARY_IMPL() with namespace `_`.
808*da0073e9SAndroid Build Coastguard Worker   ///
809*da0073e9SAndroid Build Coastguard Worker   /// \param raw_f The function that implements the fallback.  Unboxed
810*da0073e9SAndroid Build Coastguard Worker   ///   functions typically do not work as fallback functions, as
811*da0073e9SAndroid Build Coastguard Worker   ///   fallback functions must work for every operator (even though
812*da0073e9SAndroid Build Coastguard Worker   ///   they have varying type signatures).  Typical arguments are
813*da0073e9SAndroid Build Coastguard Worker   ///   CppFunction::makeFallthrough() or
814*da0073e9SAndroid Build Coastguard Worker   ///   CppFunction::makeFromBoxedFunction()
815*da0073e9SAndroid Build Coastguard Worker   ///
816*da0073e9SAndroid Build Coastguard Worker   /// ```
817*da0073e9SAndroid Build Coastguard Worker   /// // Example:
818*da0073e9SAndroid Build Coastguard Worker   ///
819*da0073e9SAndroid Build Coastguard Worker   /// TORCH_LIBRARY_IMPL(_, AutogradXLA, m) {
820*da0073e9SAndroid Build Coastguard Worker   ///   // If there is not a kernel explicitly registered
821*da0073e9SAndroid Build Coastguard Worker   ///   // for AutogradXLA, fallthrough to the next
822*da0073e9SAndroid Build Coastguard Worker   ///   // available kernel
823*da0073e9SAndroid Build Coastguard Worker   ///   m.fallback(torch::CppFunction::makeFallthrough());
824*da0073e9SAndroid Build Coastguard Worker   /// }
825*da0073e9SAndroid Build Coastguard Worker   ///
826*da0073e9SAndroid Build Coastguard Worker   /// // See aten/src/ATen/core/dispatch/backend_fallback_test.cpp
827*da0073e9SAndroid Build Coastguard Worker   /// // for a full example of boxed fallback
828*da0073e9SAndroid Build Coastguard Worker   /// ```
829*da0073e9SAndroid Build Coastguard Worker   template <typename Func>
fallback(Func && raw_f)830*da0073e9SAndroid Build Coastguard Worker   Library& fallback(Func&& raw_f) & {
831*da0073e9SAndroid Build Coastguard Worker     CppFunction f((std::forward<Func>(raw_f)));
832*da0073e9SAndroid Build Coastguard Worker     return _fallback(std::move(f));
833*da0073e9SAndroid Build Coastguard Worker   }
834*da0073e9SAndroid Build Coastguard Worker 
835*da0073e9SAndroid Build Coastguard Worker   template <class CurClass>
836*da0073e9SAndroid Build Coastguard Worker   inline torch::class_<CurClass> class_(const std::string& className);
837*da0073e9SAndroid Build Coastguard Worker 
838*da0073e9SAndroid Build Coastguard Worker   // These overloads enable the use of selective build on classes registered
839*da0073e9SAndroid Build Coastguard Worker   // within a library. The API is the same as before with 1 minor change.
840*da0073e9SAndroid Build Coastguard Worker   // Instead of m.class_<foo>("foo") you instead do
841*da0073e9SAndroid Build Coastguard Worker   // m.class_<foo>(TORCH_SELECTIVE_CLASS("foo"))
842*da0073e9SAndroid Build Coastguard Worker   template <class CurClass>
843*da0073e9SAndroid Build Coastguard Worker   inline torch::class_<CurClass> class_(detail::SelectiveStr<true> className);
844*da0073e9SAndroid Build Coastguard Worker 
845*da0073e9SAndroid Build Coastguard Worker   template <class CurClass>
846*da0073e9SAndroid Build Coastguard Worker   inline detail::ClassNotSelected class_(detail::SelectiveStr<false> className);
847*da0073e9SAndroid Build Coastguard Worker 
848*da0073e9SAndroid Build Coastguard Worker   // De-registers all registrations created with this Library
849*da0073e9SAndroid Build Coastguard Worker   void reset();
850*da0073e9SAndroid Build Coastguard Worker 
851*da0073e9SAndroid Build Coastguard Worker  private:
852*da0073e9SAndroid Build Coastguard Worker   Kind kind_;
853*da0073e9SAndroid Build Coastguard Worker   std::optional<std::string> ns_;
854*da0073e9SAndroid Build Coastguard Worker   std::optional<c10::DispatchKey> dispatch_key_;
855*da0073e9SAndroid Build Coastguard Worker   std::optional<std::pair<const char*, const char*>> python_module_;
856*da0073e9SAndroid Build Coastguard Worker   const char* file_;
857*da0073e9SAndroid Build Coastguard Worker   uint32_t line_;
858*da0073e9SAndroid Build Coastguard Worker 
859*da0073e9SAndroid Build Coastguard Worker   std::vector<c10::RegistrationHandleRAII> registrars_;
860*da0073e9SAndroid Build Coastguard Worker 
861*da0073e9SAndroid Build Coastguard Worker   friend class detail::TorchLibraryInit;
862*da0073e9SAndroid Build Coastguard Worker 
863*da0073e9SAndroid Build Coastguard Worker   // Non-user visible actual implementations of functions.  These aren't
864*da0073e9SAndroid Build Coastguard Worker   // public because we only implement & qualifier and not && qualifier
865*da0073e9SAndroid Build Coastguard Worker   Library& _def(
866*da0073e9SAndroid Build Coastguard Worker       c10::FunctionSchema&& schema,
867*da0073e9SAndroid Build Coastguard Worker       c10::OperatorName* out_name = nullptr,
868*da0073e9SAndroid Build Coastguard Worker       const std::vector<at::Tag>& tags = {},
869*da0073e9SAndroid Build Coastguard Worker       _RegisterOrVerify rv = _RegisterOrVerify::REGISTER) &;
870*da0073e9SAndroid Build Coastguard Worker   Library& _def(
871*da0073e9SAndroid Build Coastguard Worker       std::variant<c10::OperatorName, c10::FunctionSchema>&&,
872*da0073e9SAndroid Build Coastguard Worker       CppFunction&& f,
873*da0073e9SAndroid Build Coastguard Worker       const std::vector<at::Tag>& tags = {}) &;
874*da0073e9SAndroid Build Coastguard Worker   Library& _impl(
875*da0073e9SAndroid Build Coastguard Worker       const char* name,
876*da0073e9SAndroid Build Coastguard Worker       CppFunction&& f,
877*da0073e9SAndroid Build Coastguard Worker       _RegisterOrVerify rv = _RegisterOrVerify::REGISTER) &;
878*da0073e9SAndroid Build Coastguard Worker   Library& _fallback(CppFunction&& f) &;
879*da0073e9SAndroid Build Coastguard Worker 
880*da0073e9SAndroid Build Coastguard Worker   at::OperatorName _parseNameForLib(const char* name_str) const;
881*da0073e9SAndroid Build Coastguard Worker };
882*da0073e9SAndroid Build Coastguard Worker 
883*da0073e9SAndroid Build Coastguard Worker namespace detail {
884*da0073e9SAndroid Build Coastguard Worker 
885*da0073e9SAndroid Build Coastguard Worker class TorchLibraryInit final {
886*da0073e9SAndroid Build Coastguard Worker  private:
887*da0073e9SAndroid Build Coastguard Worker   using InitFn = void(Library&);
888*da0073e9SAndroid Build Coastguard Worker   Library lib_;
889*da0073e9SAndroid Build Coastguard Worker 
890*da0073e9SAndroid Build Coastguard Worker  public:
TorchLibraryInit(Library::Kind kind,InitFn * fn,const char * ns,std::optional<c10::DispatchKey> k,const char * file,uint32_t line)891*da0073e9SAndroid Build Coastguard Worker   TorchLibraryInit(
892*da0073e9SAndroid Build Coastguard Worker       Library::Kind kind,
893*da0073e9SAndroid Build Coastguard Worker       InitFn* fn,
894*da0073e9SAndroid Build Coastguard Worker       const char* ns,
895*da0073e9SAndroid Build Coastguard Worker       std::optional<c10::DispatchKey> k,
896*da0073e9SAndroid Build Coastguard Worker       const char* file,
897*da0073e9SAndroid Build Coastguard Worker       uint32_t line)
898*da0073e9SAndroid Build Coastguard Worker       : lib_(kind, ns, k, file, line) {
899*da0073e9SAndroid Build Coastguard Worker     fn(lib_);
900*da0073e9SAndroid Build Coastguard Worker   }
901*da0073e9SAndroid Build Coastguard Worker };
902*da0073e9SAndroid Build Coastguard Worker 
903*da0073e9SAndroid Build Coastguard Worker } // namespace detail
904*da0073e9SAndroid Build Coastguard Worker 
905*da0073e9SAndroid Build Coastguard Worker } // namespace torch
906*da0073e9SAndroid Build Coastguard Worker 
907*da0073e9SAndroid Build Coastguard Worker // NB: The EXACT NAMING of the initializer functions (e.g.,
908*da0073e9SAndroid Build Coastguard Worker // TORCH_LIBRARY_init_aten) matters for the code analyzer;
909*da0073e9SAndroid Build Coastguard Worker // see the regexes at tools/code_analyzer/run_analyzer.sh
910*da0073e9SAndroid Build Coastguard Worker 
911*da0073e9SAndroid Build Coastguard Worker /// Macro for defining a function that will be run at static
912*da0073e9SAndroid Build Coastguard Worker /// initialization time to define a library of operators in the
913*da0073e9SAndroid Build Coastguard Worker /// namespace `ns` (must be a valid C++ identifier, no quotes).
914*da0073e9SAndroid Build Coastguard Worker /// Use this macro when you want to define a new set of custom operators
915*da0073e9SAndroid Build Coastguard Worker /// that do not already exist in PyTorch.
916*da0073e9SAndroid Build Coastguard Worker ///
917*da0073e9SAndroid Build Coastguard Worker /// Example usage:
918*da0073e9SAndroid Build Coastguard Worker ///
919*da0073e9SAndroid Build Coastguard Worker /// ```
920*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY(myops, m) {
921*da0073e9SAndroid Build Coastguard Worker ///   // m is a torch::Library; methods on it will define
922*da0073e9SAndroid Build Coastguard Worker ///   // operators in the myops namespace
923*da0073e9SAndroid Build Coastguard Worker ///   m.def("add", add_impl);
924*da0073e9SAndroid Build Coastguard Worker /// }
925*da0073e9SAndroid Build Coastguard Worker /// ```
926*da0073e9SAndroid Build Coastguard Worker ///
927*da0073e9SAndroid Build Coastguard Worker /// The `m` argument is bound to a torch::Library that is used to
928*da0073e9SAndroid Build Coastguard Worker /// register operators.  There may only be one TORCH_LIBRARY()
929*da0073e9SAndroid Build Coastguard Worker /// for any given namespace.
930*da0073e9SAndroid Build Coastguard Worker #define TORCH_LIBRARY(ns, m)                                                   \
931*da0073e9SAndroid Build Coastguard Worker   static void TORCH_LIBRARY_init_##ns(torch::Library&);                        \
932*da0073e9SAndroid Build Coastguard Worker   static const torch::detail::TorchLibraryInit TORCH_LIBRARY_static_init_##ns( \
933*da0073e9SAndroid Build Coastguard Worker       torch::Library::DEF,                                                     \
934*da0073e9SAndroid Build Coastguard Worker       &TORCH_LIBRARY_init_##ns,                                                \
935*da0073e9SAndroid Build Coastguard Worker       #ns,                                                                     \
936*da0073e9SAndroid Build Coastguard Worker       std::nullopt,                                                            \
937*da0073e9SAndroid Build Coastguard Worker       __FILE__,                                                                \
938*da0073e9SAndroid Build Coastguard Worker       __LINE__);                                                               \
939*da0073e9SAndroid Build Coastguard Worker   void TORCH_LIBRARY_init_##ns(torch::Library& m)
940*da0073e9SAndroid Build Coastguard Worker 
941*da0073e9SAndroid Build Coastguard Worker /// \private
942*da0073e9SAndroid Build Coastguard Worker ///
943*da0073e9SAndroid Build Coastguard Worker /// This macro is a version of TORCH_LIBRARY() that doesn't enforce that there
944*da0073e9SAndroid Build Coastguard Worker /// is only one library (it is a "fragment").  This is used inside the
945*da0073e9SAndroid Build Coastguard Worker /// PerOpRegistration.cpp file, as well as in places where all op registrations
946*da0073e9SAndroid Build Coastguard Worker /// within the same namespace cannot be easily put into one macro block
947*da0073e9SAndroid Build Coastguard Worker /// (this is mostly the case for custom ops in fbcode that were ported from
948*da0073e9SAndroid Build Coastguard Worker /// the old API)
949*da0073e9SAndroid Build Coastguard Worker #define TORCH_LIBRARY_FRAGMENT(ns, m) _TORCH_LIBRARY_FRAGMENT(ns, m, C10_UID)
950*da0073e9SAndroid Build Coastguard Worker 
951*da0073e9SAndroid Build Coastguard Worker /// \private
952*da0073e9SAndroid Build Coastguard Worker ///
953*da0073e9SAndroid Build Coastguard Worker /// The above macro requires an extra unique identifier (uid) to prevent
954*da0073e9SAndroid Build Coastguard Worker /// variable name collisions This can happen if TORCH_LIBRARY_FRAGMENT is called
955*da0073e9SAndroid Build Coastguard Worker /// multiple times with the same namespace in the same translation unit. Note
956*da0073e9SAndroid Build Coastguard Worker /// that the TORCH_LIBRARY variant doesn't run into this problem, because it
957*da0073e9SAndroid Build Coastguard Worker /// enforces that it can only be called once for a given namespace.
958*da0073e9SAndroid Build Coastguard Worker #define _TORCH_LIBRARY_FRAGMENT(ns, m, uid)                       \
959*da0073e9SAndroid Build Coastguard Worker   static void C10_CONCATENATE(                                    \
960*da0073e9SAndroid Build Coastguard Worker       TORCH_LIBRARY_FRAGMENT_init_##ns##_, uid)(torch::Library&); \
961*da0073e9SAndroid Build Coastguard Worker   static const torch::detail::TorchLibraryInit C10_CONCATENATE(   \
962*da0073e9SAndroid Build Coastguard Worker       TORCH_LIBRARY_FRAGMENT_static_init_##ns##_, uid)(           \
963*da0073e9SAndroid Build Coastguard Worker       torch::Library::FRAGMENT,                                   \
964*da0073e9SAndroid Build Coastguard Worker       &C10_CONCATENATE(TORCH_LIBRARY_FRAGMENT_init_##ns##_, uid), \
965*da0073e9SAndroid Build Coastguard Worker       #ns,                                                        \
966*da0073e9SAndroid Build Coastguard Worker       std::nullopt,                                               \
967*da0073e9SAndroid Build Coastguard Worker       __FILE__,                                                   \
968*da0073e9SAndroid Build Coastguard Worker       __LINE__);                                                  \
969*da0073e9SAndroid Build Coastguard Worker   void C10_CONCATENATE(                                           \
970*da0073e9SAndroid Build Coastguard Worker       TORCH_LIBRARY_FRAGMENT_init_##ns##_, uid)(torch::Library & m)
971*da0073e9SAndroid Build Coastguard Worker 
972*da0073e9SAndroid Build Coastguard Worker /// Macro for defining a function that will be run at static
973*da0073e9SAndroid Build Coastguard Worker /// initialization time to define operator overrides for dispatch key
974*da0073e9SAndroid Build Coastguard Worker /// `k` (must be an unqualified enum member of c10::DispatchKey) in
975*da0073e9SAndroid Build Coastguard Worker /// namespace `ns` (must be a valid C++ identifer, no quotes).  Use this
976*da0073e9SAndroid Build Coastguard Worker /// macro when you want to implement a preexisting set of custom
977*da0073e9SAndroid Build Coastguard Worker /// operators on a new dispatch key (e.g., you want to provide CUDA
978*da0073e9SAndroid Build Coastguard Worker /// implementations of already existing operators).  One common usage
979*da0073e9SAndroid Build Coastguard Worker /// pattern is to use TORCH_LIBRARY() to define schema for all new
980*da0073e9SAndroid Build Coastguard Worker /// operators you want to define, and then use several
981*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY_IMPL() blocks to provide implementations of the
982*da0073e9SAndroid Build Coastguard Worker /// operator for CPU, CUDA and Autograd.
983*da0073e9SAndroid Build Coastguard Worker ///
984*da0073e9SAndroid Build Coastguard Worker /// In some cases, you need to define something that applies to all namespaces,
985*da0073e9SAndroid Build Coastguard Worker /// not just one namespace (usually a fallback).  In that case, use the reserved
986*da0073e9SAndroid Build Coastguard Worker /// namespace _, e.g.,
987*da0073e9SAndroid Build Coastguard Worker ///
988*da0073e9SAndroid Build Coastguard Worker /// ```
989*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY_IMPL(_, XLA, m) {
990*da0073e9SAndroid Build Coastguard Worker ///    m.fallback(xla_fallback);
991*da0073e9SAndroid Build Coastguard Worker /// }
992*da0073e9SAndroid Build Coastguard Worker /// ```
993*da0073e9SAndroid Build Coastguard Worker ///
994*da0073e9SAndroid Build Coastguard Worker /// Example usage:
995*da0073e9SAndroid Build Coastguard Worker ///
996*da0073e9SAndroid Build Coastguard Worker /// ```
997*da0073e9SAndroid Build Coastguard Worker /// TORCH_LIBRARY_IMPL(myops, CPU, m) {
998*da0073e9SAndroid Build Coastguard Worker ///   // m is a torch::Library; methods on it will define
999*da0073e9SAndroid Build Coastguard Worker ///   // CPU implementations of operators in the myops namespace.
1000*da0073e9SAndroid Build Coastguard Worker ///   // It is NOT valid to call torch::Library::def()
1001*da0073e9SAndroid Build Coastguard Worker ///   // in this context.
1002*da0073e9SAndroid Build Coastguard Worker ///   m.impl("add", add_cpu_impl);
1003*da0073e9SAndroid Build Coastguard Worker /// }
1004*da0073e9SAndroid Build Coastguard Worker /// ```
1005*da0073e9SAndroid Build Coastguard Worker ///
1006*da0073e9SAndroid Build Coastguard Worker /// If ``add_cpu_impl`` is an overloaded function, use a
1007*da0073e9SAndroid Build Coastguard Worker /// ``static_cast`` to specify which overload you want
1008*da0073e9SAndroid Build Coastguard Worker /// (by providing the full type).
1009*da0073e9SAndroid Build Coastguard Worker ///
1010*da0073e9SAndroid Build Coastguard Worker // NB: if the dispatch key is not whitelisted, we simply omit the Library
1011*da0073e9SAndroid Build Coastguard Worker // call entirely
1012*da0073e9SAndroid Build Coastguard Worker #define TORCH_LIBRARY_IMPL(ns, k, m) _TORCH_LIBRARY_IMPL(ns, k, m, C10_UID)
1013*da0073e9SAndroid Build Coastguard Worker 
1014*da0073e9SAndroid Build Coastguard Worker /// \private
1015*da0073e9SAndroid Build Coastguard Worker ///
1016*da0073e9SAndroid Build Coastguard Worker /// The above macro requires an extra unique identifier (uid) to prevent
1017*da0073e9SAndroid Build Coastguard Worker /// variable name collisions. This can happen if TORCH_LIBRARY_IMPL is called
1018*da0073e9SAndroid Build Coastguard Worker /// multiple times with the same namespace and dispatch key in the same
1019*da0073e9SAndroid Build Coastguard Worker /// translation unit.
1020*da0073e9SAndroid Build Coastguard Worker #define _TORCH_LIBRARY_IMPL(ns, k, m, uid)                                \
1021*da0073e9SAndroid Build Coastguard Worker   static void C10_CONCATENATE(                                            \
1022*da0073e9SAndroid Build Coastguard Worker       TORCH_LIBRARY_IMPL_init_##ns##_##k##_, uid)(torch::Library&);       \
1023*da0073e9SAndroid Build Coastguard Worker   static const torch::detail::TorchLibraryInit C10_CONCATENATE(           \
1024*da0073e9SAndroid Build Coastguard Worker       TORCH_LIBRARY_IMPL_static_init_##ns##_##k##_, uid)(                 \
1025*da0073e9SAndroid Build Coastguard Worker       torch::Library::IMPL,                                               \
1026*da0073e9SAndroid Build Coastguard Worker       (c10::impl::dispatch_key_allowlist_check(c10::DispatchKey::k)       \
1027*da0073e9SAndroid Build Coastguard Worker            ? &C10_CONCATENATE(TORCH_LIBRARY_IMPL_init_##ns##_##k##_, uid) \
1028*da0073e9SAndroid Build Coastguard Worker            : [](torch::Library&) -> void {}),                             \
1029*da0073e9SAndroid Build Coastguard Worker       #ns,                                                                \
1030*da0073e9SAndroid Build Coastguard Worker       std::make_optional(c10::DispatchKey::k),                            \
1031*da0073e9SAndroid Build Coastguard Worker       __FILE__,                                                           \
1032*da0073e9SAndroid Build Coastguard Worker       __LINE__);                                                          \
1033*da0073e9SAndroid Build Coastguard Worker   void C10_CONCATENATE(                                                   \
1034*da0073e9SAndroid Build Coastguard Worker       TORCH_LIBRARY_IMPL_init_##ns##_##k##_, uid)(torch::Library & m)
1035*da0073e9SAndroid Build Coastguard Worker 
1036*da0073e9SAndroid Build Coastguard Worker // These are variants of the macros above which are to be used for testing (they
1037*da0073e9SAndroid Build Coastguard Worker // don't setup the static initializer, so you can control the visibility of
1038*da0073e9SAndroid Build Coastguard Worker // the allocated library yourself).
1039*da0073e9SAndroid Build Coastguard Worker //
1040*da0073e9SAndroid Build Coastguard Worker // DO NOT use these in production code, they are NOT understood by the
1041*da0073e9SAndroid Build Coastguard Worker // code analyzer and will be incorrectly analyzed in those situations.
1042*da0073e9SAndroid Build Coastguard Worker 
1043*da0073e9SAndroid Build Coastguard Worker /// \private
1044*da0073e9SAndroid Build Coastguard Worker #define MAKE_TORCH_LIBRARY(ns) \
1045*da0073e9SAndroid Build Coastguard Worker   torch::Library(torch::Library::DEF, #ns, std::nullopt, __FILE__, __LINE__)
1046*da0073e9SAndroid Build Coastguard Worker /// \private
1047*da0073e9SAndroid Build Coastguard Worker #define MAKE_TORCH_LIBRARY_IMPL(ns, k)         \
1048*da0073e9SAndroid Build Coastguard Worker   torch::Library(                              \
1049*da0073e9SAndroid Build Coastguard Worker       torch::Library::IMPL,                    \
1050*da0073e9SAndroid Build Coastguard Worker       #ns,                                     \
1051*da0073e9SAndroid Build Coastguard Worker       std::make_optional(c10::DispatchKey::k), \
1052*da0073e9SAndroid Build Coastguard Worker       __FILE__,                                \
1053*da0073e9SAndroid Build Coastguard Worker       __LINE__)
1054*da0073e9SAndroid Build Coastguard Worker 
1055*da0073e9SAndroid Build Coastguard Worker // Make the custom class API visible, so it is available from
1056*da0073e9SAndroid Build Coastguard Worker // torch::Library.
1057*da0073e9SAndroid Build Coastguard Worker 
1058*da0073e9SAndroid Build Coastguard Worker #include <torch/custom_class.h>
1059