Commit Graph

104 Commits

Author SHA1 Message Date
Edward Z. Yang
a249016044 New index computation strategy in Functions.cpp (Tensor/TensorList) (#4775)
When generating autograd::Function wrappers for ATen functions, we need
to take derivative expressions in derivatives.yaml (identified by name)
and correlate them with the correct index they should take in
grad_inputs (identified positionally only).  Previously, this
computation was done *statically* in load_derivatives.py (set_up_derivatives)
and then we hard-coded indices in the generated Functions.cpp.
This is sufficient for supporting ATen operations which consist solely
of Tensor arguments, or a single TensorList argument.  However, this
strategy will not work for mixed Tensor/TensorList arguments, as the
index of any Tensor after a TensorList is not known at codegen time,
since it will vary depending on the length of the TensorList, e.g.,

  foo({x1, x2}, y)      ==>  y is index 2
  foo({x1, x2, x3}, y)  ==>  y is index 3

This commit introduces a new strategy for generating these indices which
pushes index computation to *runtime* (though any decent C++ optimizer
can re-optimize the index computation back into constants; this was
verified in Godbolt.)  Instead of hard-coding constants, a small
IndexRangeGenerator object is created and used to generate the correct
index ranges (std::pair<size_t, size_t>) for each argument.

Here is an example of mm rewritten in the new codegen format:

  variable_list MmBackward::apply(const variable_list& grads) {
    IndexRangeGenerator gen;
    auto self_ix = gen.range(1);
    auto mat2_ix = gen.range(1);
    variable_list grad_inputs(gen.size());
    auto& grad = grads[0];
    auto self = self_.unpack();
    auto mat2 = mat2_.unpack();
    if (should_compute_output({ mat2_ix })) {
      auto grad_result = mm_mat2_backward(grad, self, mat2_sizes, mat2.strides(), 1);
      copy_range(grad_inputs, mat2_ix, grad_result);
    }
    if (should_compute_output({ self_ix })) {
      auto grad_result = mm_mat1_backward(grad, mat2, self_sizes, self.strides(), 1);
      copy_range(grad_inputs, self_ix, grad_result);
    }
    return grad_inputs;
  }

Unlike before, where self_ix and mat2_ix were hardcoded as 0 and 1,
we derive them by invoking IndexRangeGenerator (which internally
is just a little counter which bumps up each invocation of 'range').
Each _ix variable actually represents a range, as can be seen here.

  variable_list CatBackward::apply(const variable_list& grads) {
    IndexRangeGenerator gen;
    auto tensors_ix = gen.range(tensors_size_);
    variable_list grad_inputs(gen.size());
    auto& grad = grads[0];
    if (should_compute_output({ tensors_ix })) {
      auto grad_result = cat_tensors_backward(grad, tensors_sizes_dim, dim);
      copy_range(grad_inputs, tensors_ix, grad_result);
    }
    return grad_inputs;
  }

The invocation of 'copy_range' reads a TensorList returned by the
backward function into the correct entries in grad_inputs.
tensors_size_ is a new member of CatBackward which is filled with
the size of the forward input tensor when cat is originally invoked.

With this new code generation strategy, we can completely eliminate
the special cases for Tensor and TensorList in index selection, and
we can smoothly support mixed Tensor/TensorList by making multiple
invocations of gen.range() with non-one arguments.

Signed-off-by: Edward Z. Yang <ezyang@fb.com>
2018-01-27 21:46:08 +01:00
Sam Gross
04ad23252a
Refactor gen_variable_type (#4487)
The gen_variable_type.py script now is only responsible for generating
VariableType.h/cpp. The parent script, "gen_autograd.py", delegates to
gen_autograd_functions.py, gen_variable_type.py, and
gen_python_functions.py.

I've removed "fallthrough" functions. It's replaced by
DONT_RECORD_TRACE, DONT_PROFILE, and DONT_REQUIRE_DERIVATIVE.

In preparation for binding the _out variants, I changed some static
types to Tensor (from Variable) and we now unpack and name tuple return
values.
2018-01-08 13:43:09 -05:00
Edward Z. Yang
6a266f5832 s/uses_grad/uses_single_grad/ for more clarity.
Signed-off-by: Edward Z. Yang <ezyang@fb.com>
2018-01-06 10:58:05 -05:00
Sam Gross
f8a4b1a266
Split off load_derivatives and gen_autograd_functions from gen_variable_type (#4370) 2017-12-27 18:59:41 -05:00