8000 Return only complex from stft by mattip · Pull Request #62179 · pytorch/pytorch · GitHub
[go: up one dir, main page]

Skip to content

Return only complex from stft #62179

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

Closed
wants to merge 8 commits into from
Closed

Conversation

mattip
Copy link
Collaborator
@mattip mattip commented Jul 26, 2021

Fixes the first half of #55948.

The first commit changes torch.stft to require (and set as default) return_complex=True

The second part: allow only complex input to torch.istft is still TBD. There is some trickiness around the current code, it does something like

if complex(input):
  input = torch.view_as_real(input)
# check input is compliant
input = reconstruct_complex(input)

so the code that checks the input needs to be carefully rewritten

@facebook-github-bot
Copy link
Contributor
facebook-github-bot commented Jul 26, 2021

🔗 Helpful links

💊 CI failures summary and remediations

As of commit b6195bb (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 CircleCI build pytorch_linux_xenial_cuda11_1_cudnn8_py3_gcc7_build (1/1)

Step: "Build" (full log | diagnosis details | 🔁 rerun)

Aug 03 21:11:02 *** WARNING: renaming "_hashlib...open shared object file: No such file or directory
Aug 03 21:11:02 [ 52%] Building C object confu-deps/XNNPACK/CMakeFiles/XNNPACK.dir/src/f32-igemm/gen/8x8-minmax-fma3-broadcast.c.o
Aug 03 21:11:02 building '_hashlib' extension
Aug 03 21:11:02 gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -fPIC -fPIC -I/var/lib/jenkins/workspace/torch/csrc/deploy/interpreter/cpython/include -I./Include -I/var/lib/jenkins/workspace/torch/csrc/deploy/interpreter/cpython/include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/var/lib/jenkins/workspace/build/torch/csrc/deploy/interpreter/cpython/src/cpython/Include -I/var/lib/jenkins/workspace/build/torch/csrc/deploy/interpreter/cpython/src/cpython -c /var/lib/jenkins/workspace/build/torch/csrc/deploy/interpreter/cpython/src/cpython/Modules/_hashopenssl.c -o build/temp.linux-x86_64-3.8/var/lib/jenkins/workspace/build/torch/csrc/deploy/interpreter/cpython/src/cpython/Modules/_hashopenssl.o
Aug 03 21:11:02 [ 52%] Building C object confu-deps/XNNPACK/CMakeFiles/XNNPACK.dir/src/f32-vhswish/gen/vhswish-fma3-x8.c.o
Aug 03 21:11:02 [ 52%] Building C object confu-deps/XNNPACK/CMakeFiles/XNNPACK.dir/src/f32-vhswish/gen/vhswish-fma3-x16.c.o
Aug 03 21:11:02 [ 52%] Building C object confu-deps/XNNPACK/CMakeFiles/XNNPACK.dir/src/f32-vsqrt/gen/fma3-nr1fma1adj-x8.c.o
Aug 03 21:11:02 gcc -pthread -shared build/temp.linux-x86_64-3.8/var/lib/jenkins/workspace/build/torch/csrc/deploy/interpreter/cpython/src/cpython/Modules/_hashopenssl.o -L/var/lib/jenkins/workspace/torch/csrc/deploy/interpreter/cpython/lib -L/var/lib/jenkins/workspace/torch/csrc/deploy/interpreter/cpython/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -lssl -lcrypto -o build/lib.linux-x86_64-3.8/_hashlib.cpython-38-x86_64-linux-gnu.so
Aug 03 21:11:02 [ 52%] Building C object confu-deps/XNNPACK/CMakeFiles/XNNPACK.dir/src/f32-vsqrt/gen/fma3-nr1fma1adj-x16.c.o
Aug 03 21:11:02 [ 52%] Building C object confu-deps/XNNPACK/CMakeFiles/XNNPACK.dir/src/f32-vsqrt/gen/fma3-nr1fma1adj-x24.c.o
Aug 03 21:11:02 *** WARNING: renaming "_ssl" since importing it failed: libssl.so.1.1: cannot open shared object file: No such file or directory
Aug 03 21:11:02 *** WARNING: renaming "_hashlib" since importing it failed: libcrypto.so.1.1: cannot open shared object file: No such file or directory
Aug 03 21:11:02 
Aug 03 21:11:02 The following modules found by detect_modules() in setup.py, have been
Aug 03 21:11:02 built by the Makefile instead, as configured by the Setup files:
Aug 03 21:11:02 _abc                  atexit                pwd                
Aug 03 21:11:02 time                                                           
Aug 03 21:11:02 
Aug 03 21:11:02 
Aug 03 21:11:02 Following modules built successfully but were removed because they could not be imported:
Aug 03 21:11:02 _hashlib              _ssl                                     
Aug 03 21:11:02 

1 job timed out:

  • pytorch_linux_xenial_cuda11_1_cudnn8_py3_gcc7_build

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.

@mattip
Copy link
Collaborator Author
mattip commented Jul 26, 2021

The failing test is test/backward_compatibility/check_backward_compatibility.py which does not like it that I have changed bool? return_complex=None to bool return_complex=True

@ezyang
Copy link
Contributor
ezyang commented Jul 26, 2021

Yeah, because this is technically BC breaking; previously it was OK to pass return_complex=None but with your change this is now invalid. I don't know the broader context but if this is an intentional break you can suppress the BC test by adding an exclusion in the test file.

@mattip mattip force-pushed the non-complex-stft branch from 2c58f62 to edec854 Compare July 29, 2021 10:42
@ezyang ezyang requested review from anjali411 and removed request for ezyang July 29, 2021 14:55
@mattip mattip force-pushed the non-complex-stft branch from 596621b to 907c4e7 Compare July 29, 2021 16:35
@@ -374,18 +374,9 @@ def stft(input: Tensor, n_fft: int, hop_length: Optional[int] = None,
win_length: Optional[int] = None, window: Optional[Tensor] = None,
center: bool = True, pad_mode: str = 'reflect', normalized: bool = False,
onesided: Optional[bool] = None,
return_complex: Optional[bool] = None) -> Tensor:
return_complex: Optional[bool] = True) -> Tensor:
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return_complex: Optional[bool] = True) -> Tensor:
return_complex: bool = True) -> Tensor:

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

thanks, done

Copy link
Contributor
@anjali411 anjali411 left a comment

Choose a reason for hiding this comment

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

LGTM although I wonder if it would be less disruptive to completely get rid of return_complex in the public API and internally still maintain an optional boolean argument and just simply error out when a value is provided for return_complex saying that stft will always return complex tensor by default and please get rid of this argument. This way we would only be breaking BC once.

@@ -3978,7 +3978,7 @@
# missing the `pad_mode` and `center` arguments, which are taken care of at
# `torch.functional.py`. They shall be moved here once we have mapping between
# Python strings and C++ Enum in codegen.
- func: stft(Tensor self, int n_fft, int? hop_length=None, int? win_length=None, Tensor? window=None, bool normalized=False, bool? onesided=None, bool? return_complex=None) -> Tensor
- func: stft(Tensor self, int n_fft, int? hop_length=None, int? win_length=None, Tensor? window=None, bool normalized=False, bool? onesided=None, bool return_complex=True) -> Tensor
Copy link
Contributor

Choose a reason for hiding this comment

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

the declarations also need to be modified at a few other sites for e.g.,

return_complex: Optional[bool] = None) -> Tensor:
(likely cause of the current test failures)

Copy link
Contributor

Choose a reason for hiding this comment

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

another one:

onesided: Optional[bool] = None, return_complex: Optional[bool] = None):

Copy link
Contributor

Choose a reason for hiding this comment

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

you could find other instances by: grep -rs "bool? return_complex"

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done, I had to check for istft which also has return_complex

@anjali411
Copy link
Contributor

LGTM although I wonder if it would be less disruptive to completely get rid of return_complex in the public API and internally still maintain an optional boolean argument and just simply error out when a value is provided for return_complex saying that stft will always return complex tensor by default and please get rid of this argument. This way we would only be breaking BC once.

@mruberry thoughts?

Copy link
Contributor
@anjali411 anjali411 left a comment

Choose a reason for hiding this comment

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

Hey @mattip this PR mostly looks good to me but can you please exclude the submodule (third_party/nccl/nccl) update changes in your commit?

@mattip mattip force-pushed the non-complex-stft branch from 3f410af to f0e43ed Compare August 2, 2021 14:42
@mattip
Copy link
Collaborator Author
mattip commented Aug 2, 2021

exclude the submodule

Sorry, done

@anjali411
Copy link
Contributor

Synced offline with @peterbell10: We agreed that it'd be better to just make return_complex a required argument (error out for return_complex=False to not silently break BC for users who hadn't been passing the arg) and additionally warn the users that this argument will be removed in the subsequent release. This means we'll break BC twice but that seems like the only option where we don't end up silently breaking BC.

@mattip mattip changed the title WIP: return only complex from stft Return only complex from stft Aug 2, 2021
@mattip
Copy link
Collaborator Author
mattip commented Aug 2, 2021

Changed out of WIP, I will make another PR for the changes needed to only allow complex input to torch.istft

@mattip
Copy link
Collaborator Author
mattip commented Aug 2, 2021

Now mypy is failing: should I rebase?

@mattip mattip force-pushed the non-complex-stft branch from 7ba1ed6 to b6195bb Compare August 3, 2021 20:49
@mattip
Copy link
Collaborator Author
mattip commented Aug 3, 2021

Rebased to clear merge conflict

@@ -374,18 +374,9 @@ def stft(input: Tensor, n_fft: int, hop_length: Optional[int] = None,
win_length: Optional[int] = None, window: Optional[Tensor] = None,
center: bool = True, pad_mode: str = 'reflect', normalized: bool = False,
onesided: Optional[bool] = None,
return_complex: Optional[bool] = None) -> Tensor:
return_complex: bool = True) -> Tensor:
Copy link
Collaborator

Choose a reason for hiding this comment

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

The default needs to be False here, otherwise this is a silent BC breaking change.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or actually, no it still needs to be None so complex tensors pass through correctly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't understand. The intent of this PR is to only return complex Tensors from stft. So what will having return_complex: Optional[bool] = None accomplish here, since it cannot be False later on anyway?

Copy link
Collaborator
@peterbell10 peterbell10 Aug 4, 2021

Choose a reason for hiding this comment

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

The current default is self.is_complex() || (window.defined() && window.is_complex()), so changing it to true is a silent bc-breaking change. Imagine someone has this code:

stft = torch.stft(...)  # doesn't pass any return_complex argument
spectrogram = stft[..., 0]**2 + stft[..., 1]**2

stft would now return a complex result silently without any warning or error, and the spectrogram calculation is completely wrong now.

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we should make return_complex a required argument here? So, they would have to explicitly specify if it’s True or False. And we can throw a warning to urge users to set it to True since that would be the default behavior in the future release

Copy link
Collaborator
@peterbell10 peterbell10 Aug 4, 2021

Choose a reason for hiding this comment

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

There is also the case of complex input which already defaults to complex output, so isn't being changed. There's no reason to break that usage.

Comment on lines -652 to -669
const bool return_complex = return_complexOpt.value_or(
self.is_complex() || (window.defined() && window.is_complex()));
if (!return_complex) {
if (!return_complexOpt.has_value()) {
TORCH_WARN_ONCE(
"stft will soon require the return_complex parameter be given for real inputs, "
"and will further require that return_complex=True in a future PyTorch release."
);
}


// TORCH_WARN_ONCE(
// "stft with return_complex=False is deprecated. In a future pytorch "
// "release, stft will return complex tensors for all inputs, and "
// "return_complex=False will raise an error.\n"
// "Note: you can still call torch.view_as_real on the complex output to "
// "recover the old return format.");
}
Copy link
Collaborator
@peterbell10 peterbell10 Aug 4, 2021

Choose a reason for hiding this comment

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

The next step in the deprecation process would be this:

  const bool return_complex = return_complexOpt.value_or(
      self.is_complex() || (window.defined() && window.is_complex()));
  if (!return_complex) {
    TORCH_CHECK(
        return_complexOpt.has_value(),
        "stft requires the return_complex parameter be given for real inputs");


    TORCH_WARN_ONCE(
        "stft with return_complex=False is deprecated. In a future pytorch "
        "release, stft will return complex tensors for all inputs, and "
        "return_complex=False will raise an error.\n"
        "Note: you can still call torch.view_as_real on the complex output to "
        "recover the old return format.");
  }

Or if we're okay with breaking BC without warning then TORCH_CHECK(return_complex, ...).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That seems like a different PR. This one was meant to do something different. I will start over.

@ezyang ezyang added the triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module label Aug 4, 2021
@mruberry
Copy link
Collaborator

Note we're hashing out some BC/FC plans now so BC/FC issues may have to wait a bit

@mattip
Copy link
Collaborator Author
mattip commented Apr 12, 2022

This turned out to be difficult to do correctly without backward-breaking changes. Closing, maybe someone else can work out a strategy for moving this forward.

@mattip mattip closed this Apr 12, 2022
@anjali411
Copy link
Contributor

#72882 is on the path to address this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla signed module: bc-breaking Related to a BC-breaking change open source triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0