Skip to content

Add memory_format support to and type operators#27107

Closed
VitalyFedyunin wants to merge 11 commits intogh/VitalyFedyunin/2/basefrom
gh/VitalyFedyunin/2/head
Closed

Add memory_format support to and type operators#27107
VitalyFedyunin wants to merge 11 commits intogh/VitalyFedyunin/2/basefrom
gh/VitalyFedyunin/2/head

Conversation

@VitalyFedyunin
Copy link
Contributor

@VitalyFedyunin VitalyFedyunin commented Sep 30, 2019

Stack from ghstack:

Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:

  1. If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
  2. If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
  3. Output tensor is going to be contiguous in all other cases.

Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

Differential Revision: D17931062

@pytorchbot pytorchbot added module: autograd Related to torch.autograd, and the autograd engine in general module: internals Related to internal abstractions in c10 and ATen module: operators module: pybind Related to our Python bindings / interactions with other Python libraries labels Sep 30, 2019
VitalyFedyunin added a commit that referenced this pull request Sep 30, 2019
ghstack-source-id: c5c9d56
Pull Request resolved: #27107
@VitalyFedyunin VitalyFedyunin changed the title [WIP] Add memory_format support to and type operators Add memory_format support to and type operators Oct 2, 2019
Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:
1) If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
2) If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
3) Output tensor is going to be contiguous in all other cases.

---
Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

[ghstack-poisoned]
Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:
1) If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
2) If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
3) Output tensor is going to be contiguous in all other cases.

---
Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

[ghstack-poisoned]
@pytorchbot pytorchbot added the module: onnx Related to torch.onnx label Oct 3, 2019
@ezyang
Copy link
Contributor

ezyang commented Oct 4, 2019

If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.

Define what it means to be in 'channels last' format? :)

Tensor to(Device device, ScalarType dtype, bool non_blocking=false, bool copy=false) const;
Tensor to(ScalarType dtype, bool non_blocking=false, bool copy=false) const;
Tensor to(const Tensor & other, bool non_blocking=false, bool copy=false) const;
Tensor to(const TensorOptions & options, bool non_blocking=false, bool copy=false, c10::optional<MemoryFormat> memory_format=c10::nullopt) const;
Copy link
Contributor

Choose a reason for hiding this comment

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

I told you this before, and I'm going to complain about it again here: MemoryFormat should be a parameter in TensorOptions, not a freestanding positional argument as it is here. The state of positional arguments here is basically unusable for actual users of this API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Going to be merged into TensorOptions as soon as TensorOptions codegen rewrite finished ( CC @izdeby )

"to(Tensor tensor, bool non_blocking=False, bool copy=False)",
"to(Device device=None, ScalarType dtype=None, bool non_blocking=False, bool copy=False, *, MemoryFormat? memory_format=None)",
"to(ScalarType dtype, bool non_blocking=False, bool copy=False, *, MemoryFormat? memory_format=None)",
"to(Tensor tensor, bool non_blocking=False, bool copy=False, *, MemoryFormat? memory_format=None)",
Copy link
Contributor

Choose a reason for hiding this comment

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

Ugh, we should have made non_blocking and copy keyword only too XD

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Going to be separate PR.

@@ -0,0 +1,678 @@
- func: __and__
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not supposed to be part of PR. Removing.

@ezyang
Copy link
Contributor

ezyang commented Oct 14, 2019

Please rerequest review when this is ready

Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:
1) If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
2) If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
3) Output tensor is going to be contiguous in all other cases.

---
Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

[ghstack-poisoned]
@VitalyFedyunin VitalyFedyunin mentioned this pull request Oct 14, 2019
@VitalyFedyunin VitalyFedyunin requested a review from ezyang October 14, 2019 18:16
@VitalyFedyunin
Copy link
Contributor Author

Define what it means to be in 'channels last' format? :)

// Tensor is stored in the channels last memory format, when dimensions

Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:
1) If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
2) If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
3) Output tensor is going to be contiguous in all other cases.

---
Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

[ghstack-poisoned]
…ators"

Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:
1) If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
2) If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
3) Output tensor is going to be contiguous in all other cases.

---
Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

[ghstack-poisoned]
…operators"

Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:
1) If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
2) If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
3) Output tensor is going to be contiguous in all other cases.

---
Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

[ghstack-poisoned]
auto memory_format =
optional_memory_format.value_or(MemoryFormat::Contiguous);

if (self.options() == options && !copy &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't compare options. See #25478 and #27572 (btw, bikeshedding on TensorAxes welcome)

Copy link
Contributor

Choose a reason for hiding this comment

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

Result of in person conversation: Let's add something like "match TensorOptions with Tensor". This tests if a Tensor is "compatible" with a TensorOptions. (This is not an equality test, because options can be left unspecified, and in that case you always match.)

if (self.is_non_overlapping_and_dense()) {
// Copy all strides
auto r = at::empty_strided(self.sizes(), self.strides(), options);
r.copy_(self);
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm pleasantly surprised to learn copy_ does the right thing in this case :>

return to_impl(self, self.options().device(device).dtype(dtype), non_blocking);
return to_impl(
self,
self.options().device(device).dtype(dtype),
Copy link
Contributor

Choose a reason for hiding this comment

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

I know this code originally existed, but I want to point out that it is pretty weird that we have to call self.options() here, because the point of TensorOptions is that it has optional fields, so to_impl should be the method that actually handles the population in the end. No change necessary.

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 did not carefully check the Python arg parser changes

@ezyang
Copy link
Contributor

ezyang commented Oct 15, 2019

To clarify on TensorOptions equality testing: I see in other parts of the code that this was a preexisting pattern. So I won't require it to be fixed in this PR.

@VitalyFedyunin
Copy link
Contributor Author

@ailzhang breaks XLA (as almost every PR in this stack)

zdevito pushed a commit to zdevito/ATen that referenced this pull request Oct 15, 2019
Summary:
Pull Request resolved: pytorch/pytorch#27107

Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:
1) If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
2) If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
3) Output tensor is going to be contiguous in all other cases.

 ---
Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

Test Plan: Imported from OSS

Differential Revision: D17931062

Pulled By: VitalyFedyunin

fbshipit-source-id: 2c5dd3dd05bf58a9a29f25562cd45190b009c3f9
@facebook-github-bot
Copy link
Contributor

@VitalyFedyunin merged this pull request in d39ab03.

@facebook-github-bot facebook-github-bot deleted the gh/VitalyFedyunin/2/head branch October 28, 2019 22:07
xxtEchjovs44 pushed a commit to xxtEchjovs44/pytorch that referenced this pull request Jan 29, 2020
thiagocrepaldi pushed a commit to thiagocrepaldi/pytorch that referenced this pull request Feb 4, 2020
Summary:
Pull Request resolved: pytorch#27107

Adds memory_format keyword argument (positional for cpp).

'Preserve' behavior now follows next rules:
1) If tensor is non-overlapping and dense - output tensor will have the same strides as input tensor.
2) If not (1) and tensor is stored in the channels last format, output tensor going to have channels last format.
3) Output tensor is going to be contiguous in all other cases.

 ---
Dense tensor is the tensor that store values in a contiguous block of memory.
Non-overlapping tensor is the tensor in which elements occupy individual non-repetitive memory.

Test Plan: Imported from OSS

Differential Revision: D17931062

Pulled By: VitalyFedyunin

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

Labels

Merged module: autograd Related to torch.autograd, and the autograd engine in general module: internals Related to internal abstractions in c10 and ATen module: onnx Related to torch.onnx module: pybind Related to our Python bindings / interactions with other Python libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants