-
Notifications
You must be signed in to change notification settings - Fork 22.1k
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
Implement n-dimensional hermitian FFTs #63890
Conversation
🔗 Helpful links
💊 CI failures summary and remediationsAs of commit 7a01f5b (more details on the Dr. CI page):
1 failure not recognized by patterns:
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. |
5d91bd4
to
eeca95d
Compare
d0cee7d
to
b701a60
Compare
This is really exciting but it looks like the test failures are real |
c04a026
to
16cda64
Compare
Codecov Report
@@ Coverage Diff @@
## master #63890 +/- ##
==========================================
- Coverage 67.03% 66.76% -0.27%
==========================================
Files 695 695
Lines 90643 90749 +106
==========================================
- Hits 60760 60588 -172
- Misses 29883 30161 +278 |
@mruberry PTAL, I've fixed the tests. |
@@ -10135,6 +10135,26 @@ | |||
python_module: fft | |||
variants: function | |||
|
|||
- func: fft_hfft2(Tensor self, int[1]? s=None, int[1] dim=[-2,-1], str? norm=None) -> Tensor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice following of SciPy's hfft2 signature
python_module: fft | ||
variants: function | ||
|
||
- func: fft_ihfft2(Tensor self, int[1]? s=None, int[1] dim=[-2,-1], str? norm=None) -> Tensor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ihfft2 signature looks great, too
@@ -10167,6 +10187,26 @@ | |||
python_module: fft | |||
variants: function | |||
|
|||
- func: fft_hfftn(Tensor self, int[1]? s=None, int[1]? dim=None, str? norm=None) -> Tensor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hfftn signature looks great
python_module: fft | ||
variants: function | ||
|
||
- func: fft_ihfftn(Tensor self, int[1]? s=None, int[1]? dim=None, str? norm=None) -> Tensor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome
@@ -25,6 +25,20 @@ | |||
if TEST_LIBROSA: | |||
import librosa | |||
|
|||
has_scipy_fft = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool
except ModuleNotFoundError: | ||
pass | ||
|
||
LooseVersion = distutils.version.LooseVersion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice versioning
@@ -6272,6 +6278,18 @@ def gradcheck_wrapper_triangular_input(op, input, *args, upper=False, **kwargs): | |||
dtypes=all_types_and_complex_and(torch.bool), | |||
default_test_dtypes=floating_and_complex_types(), | |||
check_batched_gradgrad=False), | |||
SpectralFuncInfo('fft.hfftn', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For completeness we should add hfft2 and ihfft2, too (this can be done in a follow-up PR)
hfftn = _add_docstr(_fft.fft_hfftn, r""" | ||
hfftn(input, s=None, dim=None, norm=None, *, out=None) -> Tensor | ||
|
||
Computes the n-dimensional discrete Fourier transform of a Herimitian symmetric |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great first sentence
Computes the n-dimensional discrete Fourier transform of a Herimitian symmetric | ||
:attr:`input` signal. | ||
|
||
:attr:`input` is interpreted as a one-sided Hermitian signal in the time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool
a real signal in the time-domain and gives Hermitian symmetry in the | ||
frequency-domain. The Hermitian FFT is the opposite; Hermitian symmetric in | ||
the time-domain and real-valued in the frequency-domain. For this reason, | ||
special care needs to be taken with the shape argument :attr:`s`, in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This last sentence is a little vague but good enough for now
torch/fft/__init__.py
Outdated
the original data, as given by :attr:`s`. This is because each input shape | ||
could correspond to either an odd or even length signal. By default, the | ||
signal is assumed to be even length and odd signals will not round-trip | ||
properly. So, it is recommended to always pass the signal shape :attr:`s`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"So," can be removed and the last sentence can start with "It is..."
dim (Tuple[int], optional): Dimensions to be transformed. | ||
The last dimension must be the half-Hermitian compressed dimension. | ||
Default: all dimensions, or the last ``len(s)`` dimensions if :attr:`s` is given. | ||
norm (str, optional): Normalization mode. For the forward transform |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great norm description
torch/fft/__init__.py
Outdated
|
||
Example: | ||
|
||
>>> t = torch.rand(10, 10) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example is cool but doesn't actually call ihfftn anywhere
ihfft2 = _add_docstr(_fft.fft_ihfft2, r""" | ||
ihfft2(input, s=None, dim=(-2, -1), norm=None, *, out=None) -> Tensor | ||
|
||
Computes the N-dimensional inverse discrete Fourier transform of real |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great description
torch/fft/__init__.py
Outdated
torch.Size([10, 6]) | ||
|
||
Compared against the full output from :func:`~torch.fft.ifft2`, the | ||
hermitian time-space signal takes up only half the space. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hermitian
|
||
>>> two_ffts = torch.fft.ifft(torch.fft.ihfft(t, dim=1), dim=0) | ||
>>> torch.allclose(t, two_ffts) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @peterbell10! This looks great overall. I made a few doc comments for your review. Nothing major but I think one example is still a placeholder. Just ping me when this is ready to go!
@mruberry PTAL |
desc.shape.back() = last_dim_size / 2 + 1; | ||
auto ld = last_dim_size / 2 + 1; | ||
desc.shape.back() = ld; | ||
TORCH_CHECK(ld >= 1, "Invalid number of data points (", last_dim_size, ") specified"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fname
should probably sneak in here, too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Thanks @peterbell10!
Did you see that JAX added SciPy's dct and dctn? Might be time to revisit #49016.
Looking at uses within Facebook, I can there are some uses of dct and dctn internally, and these ops seem reasonably popular on Github, too.
@mruberry has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
test/test_spectral_ops.py
Outdated
# input_ndim, dim | ||
transform_desc = [ | ||
*product(range(2, 5), (None, (0,), (0, -1))), | ||
*product(range(2, 5), (None,)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: why is this line needed? (2,None) etc that it generates is already generated by the previous line.
test/test_spectral_ops.py
Outdated
(3, (0, -1)), | ||
(3, (1,)), | ||
(1, (0,)), | ||
(4, None), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
test/test_spectral_ops.py
Outdated
*product(range(2, 5), (None,)), | ||
(6, None), | ||
(5, (1, 3, 4)), | ||
(3, (0, -1)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
torch/fft/__init__.py
Outdated
hfft2 = _add_docstr(_fft.fft_hfft2, r""" | ||
hfft2(input, s=None, dim=(-2, -1), norm=None, *, out=None) -> Tensor | ||
|
||
Computes the 2-dimensional discrete Fourier transform of a Herimitian symmetric |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: Herimitian -> Hermitian
Computes the 2-dimensional discrete Fourier transform of a Herimitian symmetric | ||
:attr:`input` signal. Equivalent to :func:`~torch.fft.hfftn` but only | ||
transforms the last two dimensions by default. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the note from hfftn
that input
is interpreted as a one-sided Hermitian signal in the time domain should also be repeated here, otherwise it's unclear what if input
itself is required to have some symmetric properties.
@peterbell10 just ping me when @ngimel's comments are addressed (thanks for taking a look, @ngimel!) |
Remove redundant test parameters and doc tweaks.
f10778f
to
9343d48
Compare
CI Flow Status⚛️ CI FlowRuleset - Version:
You can add a comment to the PR and tag @pytorchbot with the following commands: # ciflow rerun, "ciflow/default" will always be added automatically
@pytorchbot ciflow rerun
# ciflow rerun with additional labels "-l <ciflow/label_name>", which is equivalent to adding these labels manually and trigger the rerun
@pytorchbot ciflow rerun -l ciflow/scheduled -l ciflow/slow For more information, please take a look at the CI Flow Wiki. |
@mruberry PTAL. |
@mruberry has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
@mruberry has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
@mruberry any update on this? |
It's just been hitting some internal unrelated land failures. I'm jedi landing it now to bypass them |
Closes #59127
cc @mruberry @peterbell10 @walterddr