Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

empty_like, to, resize_as_ and clone now preserve memory format #23899

Conversation

VitalyFedyunin
Copy link
Contributor

@VitalyFedyunin VitalyFedyunin commented Aug 6, 2019

This PR adds ability to switch behavior of empty_like, to, cuda, resize_as_ and clone operators.
If set_memory_format_propagation set to True. The output of these operators will be channel last tensor if input tensor is channel last.

torch.get_memory_format_propagation() == False # Default value

torch.set_memory_format_propagation(True)
nhwc = torch.randn(20,3,32,16).contiguous(memory_format=torch.channels_last)
clone = nhwc.clone()
clone.is_contiguous(memory_format=torch.channels_last) == True

# And without switch
torch.set_memory_format_propagation(False)
nhwc = torch.randn(20,3,32,16).contiguous(memory_format=torch.channels_last)
clone = nhwc.clone()
clone.is_contiguous(memory_format=torch.channels_last) == False

It also changes suggest_memory_format function, and makes is sensitive to memory_format_proparation switch.

CC #23403

No noticeable performance impact.

@pytorchbot pytorchbot added module: internals Related to internal abstractions in c10 and ATen module: operators module: tests Issues related to tests (not the torch.testing module) labels Aug 6, 2019
@VitalyFedyunin VitalyFedyunin added the module: memory format Memory format/layout related issues/changes (channels_last, nhwc) label Aug 6, 2019
@pytorchbot pytorchbot added the module: cuda Related to torch.cuda, and CUDA support in general label Aug 8, 2019
@VitalyFedyunin VitalyFedyunin changed the title [WIP] empty_like, to and clone now preserve memory format [WIP] empty_like, to, resize_as_ and clone now preserve memory format Aug 8, 2019
@jjsjann123 jjsjann123 mentioned this pull request Aug 8, 2019
@VitalyFedyunin VitalyFedyunin changed the title [WIP] empty_like, to, resize_as_ and clone now preserve memory format empty_like, to, resize_as_ and clone now preserve memory format Aug 13, 2019
@ezyang
Copy link
Contributor

ezyang commented Aug 13, 2019

This is the first time I've seen set_memory_format_propagation. Is there prior discussion of this flag that I haven't seen yet?

@gchanan
Copy link
Contributor

gchanan commented Aug 13, 2019

what's the plan for the flag? Is it just for temporary transitioning and it will be removed for the next release? I don't believe we can actually correctly write code that works for both states of the flag.

Also, is there any writeup on the plan for resize / resize_as? The behavior is currently pretty unsafe and crazy, and I don't really understand if we'll end up in a good state eventually.

@VitalyFedyunin
Copy link
Contributor Author

This is the first time I've seen set_memory_format_propagation. Is there prior discussion of this flag that I haven't seen yet?

We discussed ability to enable/disable this feature. But not in details, that is why I want you and @gchanan to see this PR first.

what's the plan for the flag? Is it just for temporary transitioning and it will be removed for the next release? I don't believe we can actually correctly write code that works for both states of the flag.

Also, is there any writeup on the plan for resize / resize_as? The behavior is currently pretty unsafe and crazy, and I don't really understand if we'll end up in a good state eventually.

Let me write detailed plan, but hight level is:

  1. Have is False by default (existing behavior).
  2. Every operator that supports True must be test covered with both values.
  3. Officially support switching to True.
  4. Convert viable set of operators ( used in nn).
  5. Set default to True.
  6. Deprecate flag.

@ezyang
Copy link
Contributor

ezyang commented Aug 13, 2019

OK, so it is going to be a "this is how we migrate people to the new behavior" flag. That's fine, but the intent needs to much more clearly communicated, both in the PR description, and also where it lives in the code. I'll give some suggestions inline.

@gchanan
Copy link
Contributor

gchanan commented Aug 13, 2019

just to be explicit: I don't believe we should do a release with this flag available. It's too burdensome to write code when you have to think about both states of this flag. It's fine while in-development though.

_C._set_memory_format_propagation(b)

def get_memory_format_propagation():
return _C._get_memory_format_propagation()
Copy link
Contributor

Choose a reason for hiding this comment

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

I want to bikeshed the API here. I'll give justification for the bikeshedding I suggest.

First, let's move this out of torch top-level namespace, and into a module like torch.__future__. Because the intent of this is to NOT be a permanent feature toggle, but rather a way to opt into what will (eventually) be the default behavior, it needs to be extremely clear to end users that this is NOT a supported way to toggle between one mode or another, it is purely a BC knob. In Python, there is an existing convention for this: from __future__ import absolute_import, for example. I believe that using a name similar to __future__ will inform people about the intent appropriately.

Second, let's not have a getter/setter function, but instead have this be a regular variable living in the namespace, e.g., torch.__future__.propagate_memory_format = True. This brings this toggle in line with other similar global toggles we have, such as torch.backends.cudnn.enabled = True.

I also have some deeper points about the semantics of this flag. More on this shortly.

#include <c10/core/MemoryFormat.h>
namespace c10 {
namespace {
thread_local bool memory_format_propagation_enabled = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

@gchanan has stated that it is too difficult to write code that works under both settings of this toggle, and thus we should not release with this toggle available to users. I have an alternate proposal, which I have written up at #24261 for ensuring this toggle only affects user code, and not internal code.

@@ -183,7 +183,7 @@ class CAFFE2_API Tensor {
}

at::MemoryFormat suggest_memory_format() const {
if (impl_->is_strides_like_channels_last()) {
if (get_memory_format_propagation() && impl_->is_strides_like_channels_last()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

So... this is reverting a change that you made previously?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Will likely be solved through a merge conflict later, but just to point out the potential issue that was addressed in my pending PR: https://github.com/pytorch/pytorch/pull/23861/files#diff-4632522f237f1e4e728cb824300403acR188

@@ -183,7 +183,7 @@ class CAFFE2_API Tensor {
}

at::MemoryFormat suggest_memory_format() const {
Copy link
Contributor

Choose a reason for hiding this comment

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

So, what are the new semantics of suggest_memory_format? Can we get a docstring explaining what exactly this function does, and when you should call it?

@VitalyFedyunin VitalyFedyunin deleted the clone_empty_supports_memory_format branch October 30, 2019 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module: cuda Related to torch.cuda, and CUDA support in general module: internals Related to internal abstractions in c10 and ATen module: memory format Memory format/layout related issues/changes (channels_last, nhwc) module: tests Issues related to tests (not the torch.testing module)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants