Skip to content

Conversation

@anjali411
Copy link
Contributor

@anjali411 anjali411 commented Jul 10, 2020

Stack from ghstack:

Differential Revision: D22553266

[ghstack-poisoned]
Autograd Support (with and without view_as_real, view_as_complex)
-----------------------------------------------------------------


Copy link
Contributor

Choose a reason for hiding this comment

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

here might be a good places to talk about holomorphic functions. Maybe the "upshot" section of https://jax.readthedocs.io/en/latest/notebooks/autodiff_cookbook.html#Complex-numbers-and-differentiation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

should we just add it to the autograd doc and link that doc here?

JIT
distributions

multiprocessing
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see any reason why this wouldn't work


multiprocessing

distributed
Copy link
Contributor

Choose a reason for hiding this comment

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

If distributed doesn't work, it doesn't for any good reason, and we should fix it (shouldn't be hard)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Synced with @mrshenli and we will have to add mappings between complex and float dtypes for data transfer (because for eg. nccl doesn't support complex dtypes) and add some tests to ensure that it works correctly. These changes will be included as part of 1.7 because it's too last minute to add it in 1.6.

by using Float Tensors with shape :math:`(..., 2)` where the last dimension contains the real and imaginary values.

We support many functions for Complex Tensors eg. SVD, QR etc. Operations on complex tensors are likely to be
faster than operations on float tensors mimicking them. We also have a `Vec256 class` for `ComplexFloat` and
Copy link
Contributor

Choose a reason for hiding this comment

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

Vec256 is a bit internal and I probably wouldn't mention it in a user doc like this

Copy link
Contributor

Choose a reason for hiding this comment

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

Also ComplexFloat and ComplexDouble haven't been defined yet, but they also sound internal.

You can just say something like "Operations involving complex numbers in PyTorch are optimized to use vectorized assembly instructions and specialized kernels (e.g. LAPACK, CuBlas)."

I'm not really sure why you want to compare users writing their own functions -- why would they do that?

anjali411 added a commit that referenced this pull request Jul 10, 2020
ghstack-source-id: f6af725
Pull Request resolved: #41252

Doc note for Complex Numbers

ghstack-source-id: f6af725
Pull Request resolved: #41253
@dr-ci
Copy link

dr-ci bot commented Jul 10, 2020

💊 CI failures summary and remediations

As of commit cbc2df7 (more details on the Dr. CI page):


  • 3/3 failures possibly* introduced in this PR
    • 1/3 non-CircleCI failure(s)

🕵️ 2 new failures recognized by patterns

The following CI failures do not appear to be due to upstream breakages:

See CircleCI build pytorch_xla_linux_bionic_py3_6_clang9_build (1/2)

Step: "(Optional) Merge target branch" (full log | diagnosis details | 🔁 rerun)

Automatic merge failed; fix conflicts and then commit the result.
CONFLICT (add/add): Merge conflict in .circleci/scripts/cpp_doc_push_script.sh 
Auto-merging .circleci/scripts/cpp_doc_push_script.sh 
CONFLICT (add/add): Merge conflict in .circleci/generate_config_yml.py 
Auto-merging .circleci/generate_config_yml.py 
CONFLICT (add/add): Merge conflict in .circleci/config.yml 
Auto-merging .circleci/config.yml 
CONFLICT (add/add): Merge conflict in .circleci/cimodel/data/windows_build_definitions.py 
Auto-merging .circleci/cimodel/data/windows_build_definitions.py 
CONFLICT (add/add): Merge conflict in .circleci/cimodel/data/binary_build_definitions.py 
Auto-merging .circleci/cimodel/data/binary_build_definitions.py 
Automatic merge failed; fix conflicts and then commit the result. 

See CircleCI build pytorch_linux_xenial_py3_6_gcc5_4_build (2/2)

Step: "(Optional) Merge target branch" (full log | diagnosis details | 🔁 rerun)

Automatic merge failed; fix conflicts and then commit the result.
CONFLICT (add/add): Merge conflict in .circleci/scripts/cpp_doc_push_script.sh 
Auto-merging .circleci/scripts/cpp_doc_push_script.sh 
CONFLICT (add/add): Merge conflict in .circleci/generate_config_yml.py 
Auto-merging .circleci/generate_config_yml.py 
CONFLICT (add/add): Merge conflict in .circleci/config.yml 
Auto-merging .circleci/config.yml 
CONFLICT (add/add): Merge conflict in .circleci/cimodel/data/windows_build_definitions.py 
Auto-merging .circleci/cimodel/data/windows_build_definitions.py 
CONFLICT (add/add): Merge conflict in .circleci/cimodel/data/binary_build_definitions.py 
Auto-merging .circleci/cimodel/data/binary_build_definitions.py 
Automatic merge failed; fix conflicts and then commit the result. 

ci.pytorch.org: 1 failed


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 on the GitHub issue tracker or post in the (internal) Dr. CI Users group.

See how this bot performed.

This comment has been revised 19 times.

@anjali411 anjali411 changed the title doc note for complex [WIP] Doc note for complex Jul 12, 2020

Complex Numbers are numbers that can be expressed in the form :math:`a + bi`, where a and b are real numbers,
and *i* is a solution of the equation :math:`x^2 = −1`. Complex numbers frequently occur in mathematics and
engineering, especially in signal processing. The aim of introducing Complex Tensors is to provide a more natural
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: this sentence describes the current state, but it's going to be out of date soon after you write it (i.e., we'll have complex support and torchaudio won't have hacks. You can just say something like "Complex Tensors are provided..."

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: it's a little wordier, but "Tensors of complex dtype" is more descriptive/accurate.

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I believe "workaround" is two words when used as a verb.

by using Float Tensors with shape :math:`(..., 2)` where the last dimension contains the real and imaginary values.

We support many functions for Complex Tensors eg. SVD, QR etc. Operations on complex tensors are likely to be
faster than operations on float tensors mimicking them. We also have a `Vec256 class` for `ComplexFloat` and
Copy link
Contributor

Choose a reason for hiding this comment

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

Also ComplexFloat and ComplexDouble haven't been defined yet, but they also sound internal.

You can just say something like "Operations involving complex numbers in PyTorch are optimized to use vectorized assembly instructions and specialized kernels (e.g. LAPACK, CuBlas)."

I'm not really sure why you want to compare users writing their own functions -- why would they do that?


<add code>

The following factory functions can be used to create complex tensors:
Copy link
Contributor

Choose a reason for hiding this comment

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

are there any factory functions that dont support complex tensors?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

torch.arange, torch.range, torch.linspace, torch.logspace, torch.quantize_per_tensor, torch.quantize_per_channel

do you think it's better to just have a list of the factory functions not supported instead?

Autograd
--------

PyTorch supports Autograd for Complex Numbers.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the core of this should go in the autograd section and you should link it from here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so should we move everything mentioned here (including the example) to autograd mechanics as well?
cc. @albanD

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it is already in the autograd doc as well.
The list explaining what you get for different type of functions is good to have here I think.
Not sure what the code sample brings though.

anjali411 added a commit that referenced this pull request Jul 13, 2020
ghstack-source-id: c849f36
Pull Request resolved: #41252

Doc note for Complex Numbers

ghstack-source-id: c849f36
Pull Request resolved: #41253
Complex Numbers
===============

Complex Numbers are numbers that can be expressed in the form :math:`a + bi`, where a and b are real numbers,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note that you use j in the autograd part of the doc. Maybe you want to make that consistent.


Users who currently worked around the lack of complex tensors with real tensors of shape `(..., 2)`
can easily to switch using the complex tensors in their code using :func:`torch.view_as_complex` and
- :func:`torch.view_as_real` view functions:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure that just saying "view functions" makes it clear to the user that these are views. Maybe you want to insist on it a bit more as it is fairly important.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

...:func:torch.view_as_complex and - :func:torch.view_as_real functions which involve zero copy. does that look better?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or add a new setence: Note that these functions don't perform any copy and return a view of the input Tensor.

For non-holomorphic functions, the gradient is evaluated as if it were holomorphic.
2. :func:`torch.functional.backward` can be used to optimize :math:`C -> R` functions, like
real-values loss functions of complex parameters :math:`x` by taking steps in the direction
of conjugate of :math:`x.grad`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

We might want to double check the conjugate here!
Also if this is true, we might want to update our optimizers to do that when the parameters are complex

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah that's correct! the gradient definition that we are using does specify that right?

Copy link
Collaborator

Choose a reason for hiding this comment

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

If it's already in the gradient definition, no need to do it again here.


We do not support the following subsystems:

Quantization
Copy link
Contributor

Choose a reason for hiding this comment

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

bullet list this?

@ezyang
Copy link
Contributor

ezyang commented Jul 14, 2020

what's the binary pt file?

and *i* is a solution of the equation :math:`x^2 = −1`. Complex numbers frequently occur in mathematics and
engineering, especially in signal processing. The aim of introducing tensors of complex dtypes is to provide
a more natural user experience for users and libraries (eg. TorchAudio) that currently work around the
lack of complex tensors by using Float Tensors with shape :math:`(..., 2)` where the last dimension contains
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems like it's underselling the feature. The goal is to not just replace existing workarounds, right?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would consider introducing these existing workarounds in its own section later. Maybe a section like: "adapting existing code"?

[-0.3773, 1.3487],
[-0.0861, -0.7981]])

Accessing real and imag
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is really about acquiring just the real or imaginary part of the tensor, but the title seems like it's about the attributes themselves

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry I am not sure what you mean. can you provide an alternate suggestion?

@anjali411
Copy link
Contributor Author

what's the binary pt file?

sorry that got added by mistake while I was just locally testing save and load. removed it!

>>> x.grad, y.grad
tensor([-0.6815+0.5931j, 0.5333-1.0872j]) tensor([-0.4869+0.9011j, 0.3673+0.2007j])
>>> x_.grad, y_.grad
tensortensor([-0.6815+0.5931j, 0.5333-1.0872j]) tensor([-0.4869+0.9011j, 0.3673+0.2007j])
Copy link
Contributor

Choose a reason for hiding this comment

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

looks like a copy paste bug tensortensor

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed! (also updated the example to make it more readable)

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.

okey

and *j* is a solution of the equation :math:`x^2 = −1`. Complex numbers frequently occur in mathematics and
engineering, especially in signal processing. Tensors of complex dtypes provide a more natural user experience
for users and libraries (eg. TorchAudio) that previously worked around the lack of complex tensors by using
float tensors with shape :math:`(..., 2)` where the last dimension contained the real and imaginary values.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: there still feels like there is some tense confusion here. Part of it is that there are plenty of libraries, TODAY, that represent complex as float tensors. So it should be present tense. Consider something like, "Tensors of complex dtypes provide a more natural user experience for working with complex numbers, compared with maintaining float tensors with shape :math:(..., 2) where the last dimension contains the real and imaginary values."

memory efficient than operations on float tensors mimicking them. Operations involving complex numbers in
PyTorch are optimized to use vectorized assembly instructions and specialized kernels (e.g. LAPACK, CuBlas).
Thus using functions for complex tensors will provide performance benefits as opposed to users defining
their own functions.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: You probably don't actually need this sentence

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed!

.. note::

The default dtype for complex tensors is determined by the default floating point dtype.
If the default floating point dtype is torch.float64 then complex numbers are inferred to
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: backtick the code fragments


PyTorch supports Autograd for Complex Tensors. The autograd APIs can be
used for both holomorphic and non-holomorphic functions. For non-holomorphic
functions, the gradient is evaluated as if it were holomorphic. For more details,
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if it's meaningful to say "evaluated as if it were holomorphic"; what does that even mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ha I meant to say the gradient evaluation for non-holomorphic functions are done assuming the input function is holomorphic. I'll re-phrase to make it clear

anjali411 added a commit that referenced this pull request Jul 15, 2020
ghstack-source-id: be61901
Pull Request resolved: #41252

Doc note for Complex Numbers

ghstack-source-id: be61901
Pull Request resolved: #41253
All factory functions apart from :func:`torch.linspace`, :func:`torch.logspace`, and :func:`torch.arange` are
supported for complex tensors.

Transition from the old representation
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you consolidate all the historical information in this section?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah however I think some historical context in the introduction sets a better stage to truly justify "more natural user experience" and "faster and more memory efficient than operations on float tensors mimicking them".

Copy link
Contributor

Choose a reason for hiding this comment

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

has anyone made the argument that mimicking complex numbers is a better user experience? faster? I haven't personally come across those arguments, my impression is that everyone recognizes the previous behavior as a hack.

::
>>> # computes the complex dot product for complex vectors
>>> # represented as float vectors
>>> # math: for complex numbers a and b vdot(a, b) = a.conj() * b
Copy link
Contributor

Choose a reason for hiding this comment

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

torch.sum(a.conj() * b)) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

synced offline: remove the code block from autograd section until we have a clear definition of functions that can be used with view_as_real and view_as_complex and for which we can ensure correct gradient computation.

anjali411 added a commit that referenced this pull request Jul 15, 2020
ghstack-source-id: 2664e0e
Pull Request resolved: #41252

Doc note for Complex Numbers

ghstack-source-id: 2664e0e
Pull Request resolved: #41253
@anjali411 anjali411 changed the title [WIP] Doc note for complex Doc note for complex Jul 15, 2020
anjali411 added a commit that referenced this pull request Jul 16, 2020
ghstack-source-id: 239340e
Pull Request resolved: #41252

Doc note for Complex Numbers

ghstack-source-id: 239340e
Pull Request resolved: #41253
@facebook-github-bot
Copy link
Contributor

@anjali411 merged this pull request in b9442bb.

@facebook-github-bot facebook-github-bot deleted the gh/anjali411/41/head branch July 20, 2020 14:18
malfet pushed a commit that referenced this pull request Jul 22, 2020
Summary: Pull Request resolved: #41252

Test Plan: Imported from OSS

Reviewed By: albanD

Differential Revision: D22553266

Pulled By: anjali411

fbshipit-source-id: f6dc409da048496d72b29b0976dfd3dd6645bc4d
anjali411 added a commit that referenced this pull request Jul 22, 2020
ghstack-source-id: 239340e
Pull Request resolved: #41252

Doc note for Complex Numbers

ghstack-source-id: 239340e
Pull Request resolved: #41253
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants