Skip to content

Add ivalue::type(), part 1#25439

Closed
zdevito wants to merge 12 commits intogh/zdevito/101/basefrom
gh/zdevito/101/head
Closed

Add ivalue::type(), part 1#25439
zdevito wants to merge 12 commits intogh/zdevito/101/basefrom
gh/zdevito/101/head

Conversation

@zdevito
Copy link
Contributor

@zdevito zdevito commented Aug 30, 2019

Stack from ghstack:

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

Differential Revision: D17125595

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.
@zdevito zdevito requested a review from apaszke as a code owner August 30, 2019 00:13
@pytorchbot pytorchbot added oncall: jit Add this issue/PR to JIT oncall triage queue module: cpp Related to C++ API module: internals Related to internal abstractions in c10 and ATen module: pybind Related to our Python bindings / interactions with other Python libraries labels Aug 30, 2019
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head

temp
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head

temp
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head

temp
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head

temp
@zdevito zdevito requested a review from suo September 11, 2019 20:00
@eellison
Copy link
Contributor

eellison commented Sep 11, 2019

How do you see this interacting with users who have to construct IValues in c++ ? It should make it easier right ?

@zdevito
Copy link
Contributor Author

zdevito commented Sep 12, 2019

It should make it easier to convert IValues accurately to/from Python since we always will know their types. For C++ it will require specifying the type of list/dict on creation, which is something our API already supports.

Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head

temp
Copy link
Member

@suo suo left a comment

Choose a reason for hiding this comment

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

lgtm, some minor comments/questions inline

std::ostream& out,
const Future& v);

TypePtr type() {
Copy link
Member

Choose a reason for hiding this comment

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

Should be const

Copy link
Contributor Author

Choose a reason for hiding this comment

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

as currently written I think value() is not const because it holds the mutex. I think it isafe to just have it return type_ which also avoids the changing type tag behavior.

const Future& v);

TypePtr type() {
if (!completed()) {
Copy link
Member

Choose a reason for hiding this comment

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

This seems a little strange—should the type of a Future change depending on its completion state?

static c10::intrusive_ptr<Tuple> create(std::vector<IValue> elements_, std::shared_ptr<TupleType> type_) {
TORCH_INTERNAL_ASSERT(nullptr != type_.get(), "Type cannot be nullptr");
// named tuples have additional type information, so we
// direclty create them tagged
Copy link
Member

Choose a reason for hiding this comment

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

spelling: directly

case Tag::Object:
return toObjectRef().type();
case Tag::Uninitialized:
return AnyType::get();
Copy link
Member

Choose a reason for hiding this comment

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

Aside: what is Uninitialized anyway? I'm asking because IValues that are Any type should be scrutinized

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is introduce when we have early returns, break, and continue. It represents an uninitialized IValue that we know because of invariants introduced in the pass cannot be used. This fact isn't representable in the graph directly so this placeholder is needed. The alternative, representing them with optional values, requires a lot of unwrapping logic around use sites.

strides_(tensor.sizes().size()),
requires_grad_(tensor.requires_grad()) {
if (!tensor.is_mkldnn()) {
if (!tensor.is_mkldnn() && !tensor.is_sparse()) {
Copy link
Member

Choose a reason for hiding this comment

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

what's the reason for this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can't ask for strides on tensors that do not have them. We now have tests that ask for the type of tuples, some of which contain sparse tensors, which uncovered this bug.


static DictTypePtr create(TypePtr key, TypePtr value) {
switch (key->kind()) {
case TypeKind::AnyType:
Copy link
Member

Choose a reason for hiding this comment

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

Any is not really a valid key type for dictionaries, right? Since it may end up being something not in the list below.

I suppose there's not an easy way to represent empty dicts without another KeyType cluttering things, so I think it's fine to leave. How are we ensuring that it's not possible to somehow construct a dictionary with an invalid key type?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This check is the at-creation-type check that the dict can't possibly work. There is still a at insertion/lookup-time check that the key is hashable. It is valid to have a Any -> X dictionary. It is just the case that dynamically trying to insert a non-hashable key into it will fail.

Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head

temp
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head

temp
Add ivalue::type(), part 1

This introduces a type() method on IValue that returns the tagged type
of the IValue. The intention is that this value is always present/accurate,
making it possible for clients to recover the Type from an IValue.
Currently our APIs here are incomplete: they can sometimes recover a type but not always.

This PR adds the function, and cleans up remaining cases where Lists/Dicts are not
tagged. However, this information does not survive serialization unchanged.

A second PR will use the type information in the ClassType being serialized
to fixup the serialized ivalues to have the correct types again.
After this patch it will be save to remove our incomplete APIs for recovering types.

gh-metadata: pytorch pytorch 25439 gh/zdevito/101/head

temp
ljk53 added a commit that referenced this pull request Sep 19, 2019
Summary:
Seems CI was broken by PR #25439 - fix based on interface change.

Test Plan:
- build locally

ghstack-source-id: 7d28006
Pull Request resolved: #26448
ljk53 added a commit that referenced this pull request Sep 19, 2019
Summary:
Seems CI was broken by PR #25439 - fix based on interface change.

Test Plan:
- build locally

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 19, 2019
Summary:
Seems CI was broken by PR #25439 - fix based on interface change.

Test Plan:
- build locally

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 19, 2019
Summary:
Seems CI was broken by PR #25439 - fix based on interface change.

Test Plan:
- build locally

ghstack-source-id: 9ce9ffb
Pull Request resolved: #26448
facebook-github-bot pushed a commit that referenced this pull request Sep 19, 2019
Summary:
Pull Request resolved: #26448

Seems CI was broken by PR #25439 - fix based on interface change.

Test Plan: - build locally

Differential Revision: D17468987

Pulled By: ljk53

fbshipit-source-id: 3c1cb582c8d05357a94295b670b2ce61a7a5a4cd
ljk53 added a commit that referenced this pull request Sep 24, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

We could set NoneType by default if we want to enforce non-null type
everywhere, but looks like Tuple can take null TupleType so just follow
it.

Test Plan:
- builds

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

We could set NoneType by default if we want to enforce non-null type
everywhere, but looks like Tuple can take null TupleType so just follow
it.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

We could set NoneType by default if we want to enforce non-null type
everywhere, but looks like Tuple can take null TupleType so just follow
it.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

We could set NoneType by default if we want to enforce non-null type
everywhere, but looks like Tuple can take null TupleType so just follow
it.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

Use NoneType::get() to initialize these Futures.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

Use NoneType::get() to initialize these Futures.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

Use NoneType::get() to initialize these Futures.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

Use NoneType::get() to initialize these Futures.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

Use NoneType::get() to initialize these Futures.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

Use NoneType::get() to initialize these Futures.

Test Plan:
- builds

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

[ghstack-poisoned]
ljk53 added a commit that referenced this pull request Sep 25, 2019
Summary:
PR #25439 introduced type() to IValue, which enforced ivalue::Future to
be constructed with type. This broke ParallelNative.h and a few other
places where Future was constructed without type and simply used as a barrier:
https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/ParallelNative.h#L63

Use NoneType::get() to initialize these Futures.

Test Plan:
- builds

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

[ghstack-poisoned]
@facebook-github-bot facebook-github-bot deleted the gh/zdevito/101/head branch October 28, 2019 22:23
pbelevich added a commit that referenced this pull request Sep 17, 2021
…bsolutely have to, use c10::impl::GenericDict(c10::impl::deprecatedUntypedDict())"

Looks like it was forgotten in #25439




[ghstack-poisoned]
pbelevich added a commit that referenced this pull request Sep 17, 2021
…o, use c10::impl::GenericDict(c10::impl::deprecatedUntypedDict())"

Looks like it was forgotten in #25439




[ghstack-poisoned]
pbelevich added a commit that referenced this pull request Sep 17, 2021
…bsolutely have to, use c10::impl::GenericDict(c10::impl::deprecatedUntypedDict())"

Looks like it was forgotten in #25439




[ghstack-poisoned]
pbelevich added a commit that referenced this pull request Sep 17, 2021
…o, use c10::impl::GenericDict(c10::impl::deprecatedUntypedDict())"

Looks like it was forgotten in #25439




[ghstack-poisoned]
pbelevich added a commit that referenced this pull request Sep 20, 2021
…bsolutely have to, use c10::impl::GenericDict(c10::impl::deprecatedUntypedDict())"

Looks like it was forgotten in #25439




[ghstack-poisoned]
pbelevich added a commit that referenced this pull request Sep 20, 2021
…o, use c10::impl::GenericDict(c10::impl::deprecatedUntypedDict())"

Looks like it was forgotten in #25439




[ghstack-poisoned]
pbelevich added a commit that referenced this pull request Sep 20, 2021
…bsolutely have to, use c10::impl::GenericDict(c10::impl::deprecatedUntypedDict())"

Looks like it was forgotten in #25439




[ghstack-poisoned]
pbelevich added a commit that referenced this pull request Sep 20, 2021
…o, use c10::impl::GenericDict(c10::impl::deprecatedUntypedDict())"

Looks like it was forgotten in #25439




[ghstack-poisoned]
facebook-github-bot pushed a commit that referenced this pull request Sep 21, 2021
…:impl::GenericDict(c10::impl::deprecatedUntypedDict()) (#65164)

Summary:
Pull Request resolved: #65164

Looks like it was forgotten in #25439

Test Plan: Imported from OSS

Reviewed By: malfet

Differential Revision: D31072625

Pulled By: pbelevich

fbshipit-source-id: a5ffcfb0836f962ab6952a187ba7717c4d4a6e33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Merged module: cpp Related to C++ API module: internals Related to internal abstractions in c10 and ATen module: pybind Related to our Python bindings / interactions with other Python libraries oncall: jit Add this issue/PR to JIT oncall triage queue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants