Skip to content

Commit d0d6b1f

Browse files
larryliu0820pytorchmergebot
authored andcommitted
[torchgen] Generate out variant for functional operator (#81437)
Summary: Previously we don't generate out variant (both schema and kernel) for an operator with functional variant only. This adds support for that and adds test. ## Changes on `native_function_generation.py` We are generating out variant for all functional variants if possible. This PR introduces a lot of newly generated out variants and `native_functions.yaml` needs to incorporate the changes by adding `autogen` keywords. The logic for determining what operators we should generate an out variant for is the following: 1. No existing out variant for this `NativeFunction` 2. Contains an existing in place, mutable or functional variant 3. Contains at least 1 tensor like return(s) For operators matching the first two conditions but failing the third, I listed them in `FUNCTIONAL_OPS_THAT_CANNOT_GET_AN_OUT_VARIANT`. ## Special handling The following operators satisfy all 3 criteria above but we chose to not autogen them, with some reasons. * `mkldnn_adaptive_avg_pool2d`, the generated out variant `mkldnn_adaptive_avg_pool2d.out` is colliding with the `mkldnn_adaptive_avg_pool2d_out` kernel in `adaptive_avg_pool2d.out` operator. I manually created `mkldnn_adaptive_avg_pool2d.out` and renamed `mkldnn_adaptive_avg_pool2d_out` to `mkldnn_adaptive_avg_pool2d_out_stub`. * `min`, `max` and `mean`. There already exist `min.out`, `max.out` and `mean.out` but they are having different semantics with the functional ones. I manually created `min.unary_out`, `max.unary_out` and `mean.dtype_out` to disambiguate. ## Autograd Changes We introduced a logic to not match derivatives info in `derivatives.yaml` to out variant, since we are generating `NOT_IMPLEMENTED` kernels for those out variants anyway. The issue we are seeing with the original logic is that it doesn't handle `TensorOption` arguments really well. For example we have these two operators: * `_to_copy(Tensor self, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, bool non_blocking=False, MemoryFormat? memory_format=None) -> Tensor` * `_to_copy.out(Tensor self, *, bool non_blocking=False, MemoryFormat? memory_format=None, Tensor(a!) out) -> Tensor(a!)` If we uses `_to_copy` derivative info, there will be compilation error since `dtype` is missing from `_to_copy.out` signature. Test Plan: Rely on unit test Differential Revision: D37832342 Pull Request resolved: #81437 Approved by: https://github.com/iseeyuan, https://github.com/bdhirsh
1 parent bb1e3d8 commit d0d6b1f

File tree

11 files changed

+647
-56
lines changed

11 files changed

+647
-56
lines changed

aten/src/ATen/native/RangeFactories.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ Tensor& range_out(const Scalar& start, const Scalar& end, const Scalar& step, Te
142142
return result;
143143
}
144144

145+
Tensor& range_out_no_step(const Scalar& start, const Scalar& end, Tensor& result) {
146+
return range_out(start, end, /*step = */ 1, result);
147+
}
148+
145149
Tensor& arange_out(const Scalar& start, const Scalar& end, const Scalar& step, Tensor& result) {
146150
AT_DISPATCH_ALL_TYPES_AND2(kHalf, kBFloat16, result.scalar_type(), "arange_cpu", [&]() {
147151
using accscalar_t = at::acc_type<scalar_t, false>;

aten/src/ATen/native/ReduceAllOps.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <ATen/native/ReduceAllOps.h>
2+
#include <ATen/native/Resize.h>
23

34
#include <ATen/ATen.h>
45
#include <ATen/NativeFunctions.h>
@@ -17,6 +18,13 @@ Tensor min(const Tensor &self) {
1718
return result;
1819
}
1920

21+
Tensor& min_unary_out(const Tensor &self, Tensor& out) {
22+
Tensor tmp_output = at::min(self);
23+
at::native::resize_output(out, tmp_output.sizes());
24+
out.copy_(tmp_output);
25+
return out;
26+
}
27+
2028
Tensor max(const Tensor &self) {
2129
TORCH_CHECK(self.numel() > 0,
2230
"max(): Expected reduction dim to be specified for input.numel() == 0. Specify the reduction dim with the 'dim' argument.");
@@ -25,6 +33,13 @@ Tensor max(const Tensor &self) {
2533
return result;
2634
}
2735

36+
Tensor& max_unary_out(const Tensor &self, Tensor& out) {
37+
Tensor tmp_output = at::max(self);
38+
at::native::resize_output(out, tmp_output.sizes());
39+
out.copy_(tmp_output);
40+
return out;
41+
}
42+
2843
// DEPRECATED: Use at::aminmax instead
2944
std::tuple<Tensor, Tensor> _aminmax_all(const Tensor &self) {
3045
TORCH_WARN_ONCE("_aminmax is deprecated as of PyTorch 1.11 and will be removed in a future release. Use aminmax instead."

aten/src/ATen/native/TensorFactories.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,12 @@ Tensor arange(
101101
return at::arange_out(result, start, end, step);
102102
}
103103

104+
Tensor& arange_start_out(const Scalar& start, const Scalar& end, Tensor& result) {
105+
return at::arange_out(result, start, end, /*step=*/1);
106+
}
107+
104108
Tensor& arange_out(const Scalar& end, Tensor& result) {
105-
return at::arange_out(result, /*start=*/0, end);
109+
return at::arange_out(result, /*start=*/0, end, /*step=*/1);
106110
}
107111

108112
Tensor& arange_out(Tensor& result, const Scalar& start, const Scalar& end) {

aten/src/ATen/native/mkldnn/Pooling.cpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <ATen/Config.h>
33
#include <ATen/NativeFunctions.h>
44
#include <ATen/core/grad_mode.h>
5+
#include <ATen/native/Resize.h>
56
#include <ATen/native/utils/ParamUtils.h>
67
#include <c10/util/irange.h>
78
#include <tuple>
@@ -80,6 +81,12 @@ Tensor mkldnn_adaptive_avg_pool2d(Tensor const& input, IntArrayRef output_size)
8081
TORCH_CHECK(false, "mkldnn_adaptive_avg_pool2d: ATen not compiled with MKLDNN support");
8182
}
8283

84+
Tensor& mkldnn_adaptive_avg_pool2d_out_stub(const Tensor& input,
85+
IntArrayRef output_size,
86+
Tensor& output) {
87+
TORCH_CHECK(false, "mkldnn_adaptive_avg_pool2d_out_stub: ATen not compiled with MKLDNN support");
88+
}
89+
8390
Tensor& mkldnn_adaptive_avg_pool2d_out(const Tensor& input,
8491
IntArrayRef output_size,
8592
Tensor& output) {
@@ -498,10 +505,19 @@ Tensor mkldnn_adaptive_avg_pool2d(
498505
/*algo*/ ideep::algorithm::pooling_avg);
499506
}
500507

508+
Tensor& mkldnn_adaptive_avg_pool2d_out_stub(const Tensor& input,
509+
IntArrayRef output_size,
510+
Tensor& output) {
511+
TORCH_CHECK(false, "mkldnn_adaptive_avg_pool2d_out_stub: in-place mkldnn operations are not supported yet");
512+
}
513+
501514
Tensor& mkldnn_adaptive_avg_pool2d_out(const Tensor& input,
502515
IntArrayRef output_size,
503516
Tensor& output) {
504-
TORCH_CHECK(false, "mkldnn_adaptive_avg_pool2d_out: in-place mkldnn operations are not supported yet");
517+
auto tmp_output = at::native::mkldnn_adaptive_avg_pool2d(input, output_size);
518+
at::native::resize_output(output, tmp_output.sizes());
519+
output.copy_(tmp_output);
520+
return output;
505521
}
506522

507523
Tensor mkldnn_max_pool2d_backward(

0 commit comments

Comments
 (0)