# Generates VariableType.h/cpp
#
+# **If any changes are being made to the VariableType codegen please also check
+# if updates are needed in torch/csrc/autograd/autograd_not_implemented_fallback.cpp
+#
# VariableType is a subclass of at::Type that provides the binding code
# necessary to provide a differentiable version of ATen operators. There are a
# number of different things we could mean:
from .gen_inplace_or_view_type import (
get_view_info, is_tensor_type, is_tensor_list_type, unpack_args, get_base_name,
use_derived, modifies_arguments, WRAPPER_REGISTRATION, TMP_VAR, METHOD_DEFINITION,
- ASSIGN_RETURN_VALUE, gen_formals, ALL_VIEW_FUNCTIONS, unpacked_name
+ ASSIGN_RETURN_VALUE, gen_formals, ALL_VIEW_FUNCTIONS, unpacked_name,
+ AUTOGRAD_NOT_IMPLEMENTED_REGISTRATION
)
from tools.codegen.api.types import (Binding, DispatcherSignature, BaseCType, intArrayRefT,
name = cpp.name(f.func)
formals = gen_formals(f)
- type_definition = METHOD_DEFINITION.substitute(
- return_type=cpp.returns_type(f.func.returns).cpp_type(),
- type_wrapper_name=type_wrapper_name(f),
- type_definition_body=emit_body(fn),
- formals=formals,
- )
- wrapper_registration = gen_wrapper_registration(f)
+ if fn.info is None and not get_base_name(f) in RESET_GRAD_ACCUMULATOR \
+ and not get_base_name(f) in DONT_REQUIRE_DERIVATIVE \
+ and len(gen_differentiable_outputs(fn)) > 0 \
+ and not get_base_name(f) in DONT_ENFORCE_SAME_TENSOR_IMPL_OR_STORAGE \
+ and not get_base_name(f) in DONT_ENFORCE_STORAGE_IMPL_USE_COUNT \
+ and not get_base_name(f) in DONT_ENFORCE_TENSOR_IMPL_USE_COUNT:
+ # NOTE: [ Registering AutogradNotImplemented boxed kernel ]
+ #
+ # When there is no derivatives.yaml entry, we register a generic boxed
+ # NotImplemented kernel to set grad_fn to be NotImplemented, so that forward
+ # proceeds as usual but an error is properly produced on backward.
+ # TODO: it would be nice to not have these special cases
+ #
+ # There are several cases where still let codegen handle it:
+ # 1) ops that need to reset grad accumulator (we let codegen handle this case
+ # because) the list is (currently) only accessible in Python.
+ # 2) User explicitly specifies DONT_REQUIRE_DERIVATIVE. This basically makes
+ # autograd a fallthrough with NDEBUG checks. This can be useful for when all
+ # outputs are integral.
+ # 3) When there are no differentiable outputs. This is similar to (2).
+ # 4) There are certain ops where we skip certain NDEBUG checks. this is similar
+ # to (1).
+ type_definition = ""
+ wrapper_registration = AUTOGRAD_NOT_IMPLEMENTED_REGISTRATION.substitute(
+ unqual_operator_name_with_overload=f.func.name)
+ else:
+ type_definition = METHOD_DEFINITION.substitute(
+ return_type=cpp.returns_type(f.func.returns).cpp_type(),
+ type_wrapper_name=type_wrapper_name(f),
+ type_definition_body=emit_body(fn),
+ formals=formals,
+ )
+ wrapper_registration = gen_wrapper_registration(f)
# See Note [Manual Backend kernels]
assert (name in MANUAL_BACKEND) == f.manual_kernel_registration