Skip to content

Conversation

@ezyang
Copy link
Contributor

@ezyang ezyang commented Sep 28, 2018

Stack:
    :black_circle:  #12180 Make caffe2::Tensor::dims() return an IntList instead of a const vector&  💛

I had to fix a lot of call sites, because a lot of places assume that
you can actually get a const vector&, and if the internal representation
of sizes in a tensor is NOT a vector, it's not possible to fulfill
this API contract.

Framework changes:

  • I deleted TensorImpl::dims(); caffe2::Tensor::dims() just forwards to
    sizes() now.
  • De-templatized SetDims; now it is an explicit list of ArrayRef and
    variadic overloads. This makes implicit conversions work again,
    so I don't need to explicitly list the std::vector cases too.
    • As a knock-on effect, this causes Reset() to accept at::IntList as well as
      const std::vector<int64_t>&
  • Edited variadic overloads of SetDims to all forward to the underlying
    arbitrary-dim implementation, reducing code duplication. (It's probably
    marginally less efficient in the new world.)
  • Replace Tensor constructor accepting const std::vector<int64_t>& with at::IntList
  • Make MKLTensor accept ArrayRef along with vector in constructor and
    Reset (unfortunately, no implicit conversions here, since it's templated on
    index type.)
  • There are a few other places, like cudnn, where I changed functions
    that previously took const std::vector<int64_t>& to take at::IntList
    instead.

Classification of call site changes:

  • 'const std::vector<int64_t>& x_dims = x.dims()' ==>
    'at::IntList x_dims = x.dims()'
  • 'std::vector<int64_t> x_dims = x.dims()' ==>
    'std::vector<int64_t> x_dims = x.dims().vec()' (we need a copy!)
    Usually this is because we're about to mutably modify the vector
    to compute some new dimension. However, it also very commonly occurs in the
    form: 'x_dims_ = x.dims()' because we frequently cache sizes in operators.
  • Instead of constructing std::vector<int64_t>{blah, blah}, construct an
    at::IntList directly

ArrayRef changes:

  • cbegin()/cend() iterators, they operate the same aas begin()/end() because
    everything on ArrayRef is const.
  • Moved operator<< into ArrayRef.h, so that it's always available when
    working with ArrayRef. I also templated it, so it now works on an
    ArrayRef of any type.
  • Add operator== overload for ArrayRef, and also add variants to permit
    comparison of ArrayRef with std::vector, a very common operation.
    (The non-templated version of operator== can get these automatically
    via implicit conversion, but with templates C++ refuses to do
    any explicit conversions.)

I'm planning to audit all dims() call sites to make sure they don't
expect 'auto x = t.dims()' to give you an x whose lifetime can validly
outlive the tensor.

I opted not to do a dims() to sizes() rename, because dims() also matches
the protobufs accessor. Bad news!

Differential Revision: D10111759

Differential Revision: D10111759
Differential Version: 59338051
ezyang added 7 commits October 1, 2018 08:47
Differential Revision: D10111759
Differential Version: 59338596
Differential Revision: D10111759
Differential Version: 59341276
Differential Revision: D10111759
Differential Version: 59342913
Differential Revision: D10111759
Differential Version: 59343031
Differential Revision: D10111759
Differential Version: 59343283
Differential Revision: D10111759
Differential Version: 59345162
Differential Revision: D10111759
Differential Version: 59345518
ezyang added 2 commits October 4, 2018 14:52
Differential Revision: D10111759
Differential Version: 59774883
Differential Revision: D10111759
Differential Version: 59810994
@ezyang
Copy link
Contributor Author

ezyang commented Oct 5, 2018

@pytorchbot retest this please

Differential Revision: D10111759
Differential Version: 59835297
zdevito pushed a commit to zdevito/ATen that referenced this pull request Oct 6, 2018
…or& (#12180)

Summary:
Pull Request resolved: pytorch/pytorch#12180

I had to fix a lot of call sites, because a lot of places assume that
you can actually get a const vector&, and if the internal representation
of sizes in a tensor is NOT a vector, it's not possible to fulfill
this API contract.

Framework changes:
- I deleted TensorImpl::dims(); caffe2::Tensor::dims() just forwards to
  sizes() now.
- De-templatized SetDims; now it is an explicit list of ArrayRef and
  variadic overloads.  This makes implicit conversions work again,
  so I don't need to explicitly list the std::vector cases too.
  - As a knock-on effect, this causes Reset() to accept at::IntList as well as
    const std::vector<int64_t>&
- Edited variadic overloads of SetDims to all forward to the underlying
  arbitrary-dim implementation, reducing code duplication. (It's probably
  marginally less efficient in the new world.)
- Replace Tensor constructor accepting const std::vector<int64_t>& with at::IntList
- Make MKLTensor accept ArrayRef along with vector in constructor and
  Reset (unfortunately, no implicit conversions here, since it's templated on
  index type.)
- There are a few other places, like cudnn, where I changed functions
  that previously took const std::vector<int64_t>& to take at::IntList
  instead.

Classification of call site changes:
- 'const std::vector<int64_t>& x_dims = x.dims()' ==>
  'at::IntList x_dims = x.dims()'
- 'std::vector<int64_t> x_dims = x.dims()' ==>
  'std::vector<int64_t> x_dims = x.dims().vec()' (we need a copy!)
  Usually this is because we're about to mutably modify the vector
  to compute some new dimension.  However, it also very commonly occurs in the
  form: 'x_dims_ = x.dims()' because we frequently cache sizes in operators.
- Instead of constructing std::vector<int64_t>{blah, blah}, construct an
  at::IntList directly

ArrayRef changes:
- cbegin()/cend() iterators, they operate the same aas begin()/end() because
  everything on ArrayRef is const.
- Moved operator<< into ArrayRef.h, so that it's always available when
  working with ArrayRef.  I also templated it, so it now works on an
  ArrayRef of any type.
- Add operator== overload for ArrayRef, and also add variants to permit
  comparison of ArrayRef with std::vector, a very common operation.
  (The non-templated version of operator== can get these automatically
  via implicit conversion, but with templates C++ refuses to do
  any explicit conversions.)

I'm planning to audit all dims() call sites to make sure they don't
expect 'auto x = t.dims()' to give you an x whose lifetime can validly
outlive the tensor.

I opted not to do a dims() to sizes() rename, because dims() also matches
the protobufs accessor.  Bad news!

Reviewed By: jerryzh168

Differential Revision: D10111759

fbshipit-source-id: a2a81dc4b92c22ad4b3b8ef4077a7e97b6479452
@soumith soumith deleted the export-D10111759 branch February 21, 2019 12:11
@ezyang ezyang added the merged label Jun 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants