Bring up new-style registration API as wrapper around old-style (#33205)
Summary:
Pull Request resolved: https://github.com/pytorch/pytorch/pull/33205
A number of important use-cases are implemented:
- def(schema): defines a schema, with no implementation (alias
inferred from schema, by default)
- def(schema, fn_ptr): registers fn_ptr as a catch-all kernel
for the operation
- def(schema, lambda): registers lambda as a catch-all kernel
for the operation
- def(schema, torch::dispatch(dispatch_key, fn)), and
def(schema, torch::dispatch(device_type, fn)): registers
the function to only be executed when dispatch_key/device_type
is selected for use
- def(schema, TORCH_OPTIMIZED_FN(fn)): registers the function
as unboxed only, using the inline syntax
All of our code generated registrations in ATen are switched to
the new API.
Some aspects of the API which are not fully implemented:
- It's still not valid to omit the schema when registering a function
pointer, due to #32549
- Although it's possible to take advantage of top-level namespaces
ala torch::import("aten"), we don't use it because this results
in worse code (as we have to cat everything back together). This
is not an essential problem, we just need the internals to be less
stupid.
There are some aspects of the API which don't semantically make sense,
but I chose not to fix them in this PR:
- For some reason, TORCH_OPTIMIZED_FN uses the *runtime* wrapper to
do wrapping, rather than the compile time one which inlines the
function in. This means that there isn't any reason we should be
passing in the function pointer as a template argument; a regular
old argument ought to have worked fine. This is seemingly
consistent with the current API though; needs further investigation.
- There's no reason to optional<DispatchKey>, DispatchKey would
work just fine (use DispatchKey::Undefined for the nullopt case)
In the long term, we should swap the wrapper around: the new-style
API has the real implementation, and the old-style API is backwards
compatibility. However, this implies a lot of internal refactoring,
so I decided to short circuit around it to get this in faster
Ancillary changes:
- I stopped moving optional<DispatchKey>, it's literally just two
words, pass it by value please.
- Needed to add a & qualified version of RegisterOps::op, since
I'm storing RegisterOps as a member inside the new style
Namespace and I cannot conveniently get a rvalue reference
to it in that situation. (BTW, register_ = std::move(register_)
really doesn't work, don't try it!)
Signed-off-by: Edward Z. Yang <ezyang@fb.com>
Test Plan: Imported from OSS
Differential Revision: D19856626
Pulled By: ezyang
fbshipit-source-id: 104de24b33fdfdde9447c104853479b305cbca9a