KEMBAR78
Factor out TensorBase that doesn't depend on native operators by peterbell10 · Pull Request #63612 · pytorch/pytorch · GitHub
Skip to content

Conversation

@peterbell10
Copy link
Collaborator

@peterbell10 peterbell10 commented Aug 19, 2021

Stack from ghstack:

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making Tensor inherit from this class means that const TensorBase& parameters will be callable
with an ordinary Tensor. I've also made Tensor constructible and assignable from TensorBase to
minimize friction in code mixing the two types.

To help enforce that Tensor.h and Functions.h aren't accidentally included, I've added an error
into Operators.h if TORCH_ASSERT_NO_OPERATORS is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used contiguous operator.
The inline function's slow path defers to TensorBase::__dispatch_contiguous which is defined in
Tensor.cpp. I've made it so OptionalTensorRef is constructible from TensorBase, so I can
materialize a Tensor for use in dispatch without actually increasing its refcount.

Differential Revision: D30728580

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

[ghstack-poisoned]
@facebook-github-bot
Copy link
Contributor

facebook-github-bot commented Aug 19, 2021

🔗 Helpful links

💊 CI failures summary and remediations

As of commit 753d7cc (more details on the Dr. CI page):


  • 1/1 failures introduced in this PR

🕵️ 1 new failure recognized by patterns

The following CI failures do not appear to be due to upstream breakages:

See GitHub Actions build win-vs2019-cpu-py3 / test (default, 1, 2, windows.4xlarge) (1/1)

Step: "Run test scripts" (full log | diagnosis details | 🔁 rerun)

2021-09-08T15:46:33.7383565Z ERROR [0.016s]: test_poisson_sample (__main__.TestDistributions)
2021-09-08T15:46:33.7374846Z   File "distributions/test_distributions.py", line 812, in _check_sampler_discrete
2021-09-08T15:46:33.7375856Z     chisq, p = scipy.stats.chisquare(counts[msk], pmf[msk] * num_samples)
2021-09-08T15:46:33.7376930Z   File "c:\jenkins\miniconda3\lib\site-packages\scipy\stats\stats.py", line 6852, in chisquare
2021-09-08T15:46:33.7377884Z     return power_divergence(f_obs, f_exp=f_exp, ddof=ddof, axis=axis,
2021-09-08T15:46:33.7378945Z   File "c:\jenkins\miniconda3\lib\site-packages\scipy\stats\stats.py", line 6694, in power_divergence
2021-09-08T15:46:33.7379814Z     raise ValueError(msg)
2021-09-08T15:46:33.7381038Z ValueError: For each axis slice, the sum of the observed frequencies must agree with the sum of the expected frequencies to a relative tolerance of 1e-08, but the percent differences are:
2021-09-08T15:46:33.7382130Z 0.008265582255680495
2021-09-08T15:46:33.7382379Z 
2021-09-08T15:46:33.7382915Z ======================================================================
2021-09-08T15:46:33.7383565Z ERROR [0.016s]: test_poisson_sample (__main__.TestDistributions)
2021-09-08T15:46:33.7384335Z ----------------------------------------------------------------------
2021-09-08T15:46:33.7384982Z Traceback (most recent call last):
2021-09-08T15:46:33.7385841Z   File "distributions/test_distributions.py", line 1352, in test_poisson_sample
2021-09-08T15:46:33.7386693Z     self._check_sampler_discrete(Poisson(rate),
2021-09-08T15:46:33.7388144Z   File "distributions/test_distributions.py", line 812, in _check_sampler_discrete
2021-09-08T15:46:33.7389159Z     chisq, p = scipy.stats.chisquare(counts[msk], pmf[msk] * num_samples)
2021-09-08T15:46:33.7390233Z   File "c:\jenkins\miniconda3\lib\site-packages\scipy\stats\stats.py", line 6852, in chisquare
2021-09-08T15:46:33.7391257Z     return power_divergence(f_obs, f_exp=f_exp, ddof=ddof, axis=axis,
2021-09-08T15:46:33.7392323Z   File "c:\jenkins\miniconda3\lib\site-packages\scipy\stats\stats.py", line 6694, in power_divergence
2021-09-08T15:46:33.7393172Z     raise ValueError(msg)

This comment was automatically generated by Dr. CI (expand for details).Follow this link to opt-out of these comments for your Pull Requests.

Please report bugs/suggestions to the (internal) Dr. CI Users group.

Click here to manually regenerate this comment.

peterbell10 added a commit that referenced this pull request Aug 19, 2021
This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

ghstack-source-id: 602468c
Pull Request resolved: #63612
…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

[ghstack-poisoned]
…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

[ghstack-poisoned]
peterbell10 added a commit that referenced this pull request Aug 20, 2021
This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

ghstack-source-id: de87d6d
Pull Request resolved: #63612
…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

[ghstack-poisoned]
…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

[ghstack-poisoned]
…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

[ghstack-poisoned]
peterbell10 added a commit that referenced this pull request Aug 20, 2021
This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

ghstack-source-id: f656c0e
Pull Request resolved: #63612
…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

[ghstack-poisoned]
Copy link
Contributor

@ezyang ezyang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm willing to give this a shot. Even if the public inheritance is a problem, I'd be willing to keep the split and make the inheritance private, because it makes other things easier. I'm going to let this stew a little more, but if any other reviewers have objections, speak now or forever hold your peace.

@peterbell10
Copy link
Collaborator Author

I'd be willing to keep the split and make the inheritance private, because it makes other things easier.

Can you expand on this? What problems does the inheritance cause?

@ezyang
Copy link
Contributor

ezyang commented Sep 2, 2021

Can you expand on this? What problems does the inheritance cause?

It is mostly the potential for TensorBase v. Tensor confusion, and people doing conversions to shut up the type checker. I definitely agree that right now, as this PR is right now, there are no problems, I'm just not sure if it will stay this way as people who are less familiar with the architecture here start adding new features. (But I'm willing to give it a try!)

@peterbell10
Copy link
Collaborator Author

It is mostly the potential for TensorBase v. Tensor confusion, and people doing conversions to shut up the type checker.

I had thought of this and it's why I marked the TensorBase -> Tensor conversion explicit, so it's at least visible in code review. However, it's really the const TensorBase& arguments that are enabled by inheritance, and those should be painless IMO. Users can call them with a Tensor as normal, and the type checker is completely happy.

…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

Differential Revision: [D30728580](https://our.internmc.facebook.com/intern/diff/D30728580)

[ghstack-poisoned]
Copy link
Collaborator

@albanD albanD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for cleaning some autograd namings by side effect :)

#error This change adds a dependency on native_functions.yaml, \
meaning the file will need to be re-compiled every time an operator \
is changed or added. Consider if your change would be better placed in \
another file, or if a more specific header might achieve the same goal.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that this error message will be helpful for people that don't have context on this PR.
Maybe we want to extend a bit the comment next to TensorBase definition and link it from here.

} else {
// TODO(alband) remove this spurious version counter bump
auto new_grad = new_grad_;
Tensor new_grad(new_grad_base);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the comment above still valid?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR shouldn't change the result of this code in any way, so afaik it's still relevant.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk, let's ask the guy who added it :P

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TensorBase -> Tensor still does a version counter bump right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does a reference count bump; not a version count bump.

…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

Differential Revision: [D30728580](https://our.internmc.facebook.com/intern/diff/D30728580)

[ghstack-poisoned]
@ezyang
Copy link
Contributor

ezyang commented Sep 8, 2021

@ezyang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@ezyang
Copy link
Contributor

ezyang commented Sep 8, 2021

Some internal builds failing with:

buck-out/gen/6ad9e6a1/xplat/caffe2/gen_aten/core/TensorBody.h:5052:36: error: 'unsafe_borrow_t' is a protected member of 'at::TensorBase'
return borrow_type(at::TensorBase::unsafe_borrow_t{}, from); 
                                   ^
buck-out/gen/6ad9e6a1/xplat/caffe2/gen_aten/core/TensorBody.h:5059:36: error: 'unsafe_borrow_t' is a protected member of 'at::TensorBase'
(lhs = borrow_type(at::TensorBase::unsafe_borrow_t{}, rhs)); 
                                   ^
buck-out/gen/6ad9e6a1/xplat/caffe2/gen_aten/core/TensorBody.h:5052:36: error: 'unsafe_borrow_t' is a protected member of 'at::TensorBase'
return borrow_type(at::TensorBase::unsafe_borrow_t{}, from); 
                                   ^
buck-out/gen/6ad9e6a1/xplat/caffe2/gen_aten/core/TensorBody.h:5059:36: error: 'unsafe_borrow_t' is a protected member of 'at::TensorBase'
(lhs = borrow_type(at::TensorBase::unsafe_borrow_t{}, rhs)); 

investigating

…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

Differential Revision: [D30728580](https://our.internmc.facebook.com/intern/diff/D30728580)

[ghstack-poisoned]
ezyang added a commit that referenced this pull request Sep 8, 2021
This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

ghstack-source-id: 35eda7f
Pull Request resolved: #63612
@ezyang
Copy link
Contributor

ezyang commented Sep 8, 2021

@ezyang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

…ors"

This makes Tensor inherit from a new class TensorBase, that provides a subset of Tensor that doesn't
directly depend on native_functions.yaml. Code that only includes TensorBase.h with thus not need to
be rebuilt every time someone changes an operator signature.

Making `Tensor` inherit from this class means that `const TensorBase&` parameters will be callable
with an ordinary `Tensor`. I've also made `Tensor` constructible and assignable from `TensorBase` to
minimize friction in code mixing the two types.

To help enforce that `Tensor.h` and `Functions.h` aren't accidentally included, I've added an error
into `Operators.h` if `TORCH_ASSERT_NO_OPERATORS` is defined. We can either set this in the build
system for certain folders, or just define it at the top of any file.

I've also included an example of manually special-casing the commonly used `contiguous` operator.
The inline function's slow path defers to `TensorBase::__dispatch_contiguous` which is defined in
`Tensor.cpp`. I've made it so `OptionalTensorRef` is constructible from `TensorBase`, so I can
materialize a `Tensor` for use in dispatch without actually increasing its refcount.

Differential Revision: [D30728580](https://our.internmc.facebook.com/intern/diff/D30728580)

[ghstack-poisoned]
explicit TensorBase(unsafe_borrow_t, const TensorBase& rhs)
: impl_(c10::intrusive_ptr<at::TensorImpl, UndefinedTensorImpl>::reclaim(rhs.impl_.get())) {}
friend MaybeOwnedTraits<TensorBase>;
friend OptionalTensorRef; // so it can get at unsafe_borrow_t
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work because OptionalTensorRef isn't declared yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RIP. Well, let's just make it public as you did.

@ezyang
Copy link
Contributor

ezyang commented Sep 8, 2021

@ezyang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@ezyang merged this pull request in d701357.

@facebook-github-bot facebook-github-bot deleted the gh/peterbell10/120/head branch September 12, 2021 14:19
zou3519 added a commit that referenced this pull request Jul 19, 2023
When the hook registered by Tensor::register_hook (in C++) gets passed
an undefined tensor, it raises an internal assert. The cause is that we
attempt to construct an OptionalTensorRef
(https://github.com/pytorch/pytorch/blob/4448c78a5d8ce91573fb8779355838bc78bfea33/aten/src/ATen/core/Tensor.h#L68)
which asserts that the passed-in TensorBase is defined.

The fix is that we create a new TensorRef class to convert the
TensorBase into a Tensor without bumping the refcount (which is what
OptionalTensorRef does). We cannot reuse OptionalTensorRef because
OptionalTensorRef represents `optional<Tensor>` that cannot hold an
Undefined Tensor.

For some more historical context, it looks like this bug was introduced
in #63612

Test Plan:
- new tests

[ghstack-poisoned]
zou3519 added a commit that referenced this pull request Jul 19, 2023
When the hook registered by Tensor::register_hook (in C++) gets passed
an undefined tensor, it raises an internal assert. The cause is that we
attempt to construct an OptionalTensorRef
(https://github.com/pytorch/pytorch/blob/4448c78a5d8ce91573fb8779355838bc78bfea33/aten/src/ATen/core/Tensor.h#L68)
which asserts that the passed-in TensorBase is defined.

The fix is that we create a new TensorRef class to convert the
TensorBase into a Tensor without bumping the refcount (which is what
OptionalTensorRef does). We cannot reuse OptionalTensorRef because
OptionalTensorRef represents `optional<Tensor>` that cannot hold an
Undefined Tensor.

For some more historical context, it looks like this bug was introduced
in #63612

Test Plan:
- new tests

[ghstack-poisoned]
zou3519 added a commit that referenced this pull request Jul 19, 2023
When the hook registered by Tensor::register_hook (in C++) gets passed
an undefined tensor, it raises an internal assert in debug mode.
The cause is that we attempt to construct an OptionalTensorRef
(https://github.com/pytorch/pytorch/blob/4448c78a5d8ce91573fb8779355838bc78bfea33/aten/src/ATen/core/Tensor.h#L68)
which asserts that the passed-in TensorBase is defined.

The fix is that we create a new TensorRef class to convert the
TensorBase into a Tensor without bumping the refcount (which is what
OptionalTensorRef does). We cannot reuse OptionalTensorRef because
OptionalTensorRef represents `optional<Tensor>` that cannot hold an
Undefined Tensor.

For some more historical context, it looks like this behavior was introduced
in #63612

Test Plan:
- new tests

[ghstack-poisoned]
pytorchmergebot pushed a commit that referenced this pull request Jul 21, 2023
When the hook registered by Tensor::register_hook (in C++) gets passed
an undefined tensor, it raises an internal assert in debug mode.
The cause is that we attempt to construct an OptionalTensorRef
(https://github.com/pytorch/pytorch/blob/4448c78a5d8ce91573fb8779355838bc78bfea33/aten/src/ATen/core/Tensor.h#L68)
which asserts that the passed-in TensorBase is defined.

The fix is that we create a new TensorRef class to convert the
TensorBase into a Tensor without bumping the refcount (which is what
OptionalTensorRef does). We cannot reuse OptionalTensorRef because
OptionalTensorRef represents `optional<Tensor>` that cannot hold an
Undefined Tensor.

For some more historical context, it looks like this behavior was introduced
in #63612

Test Plan:
- new tests
Pull Request resolved: #105587
Approved by: https://github.com/soulitzer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants