Pytorch 1.10 complex number change is horrible, please change it back

pytorch 1.10 says

x = torch.tensor([1+2j])
y = x.conj()
z = y.imag
print(z.is_neg())
True

z.add_(2)
print(x)
tensor([1.-0.j])

This is anti-math! People who us complex number will not expect this behavior. Please change it back to the way in 1.9.

cc @anjali411 who is working on this topic

Hey @chenhao1umbc This is because the conjugation is now a view operation. So in this case, it’s expected that x, y and z will share memory. We made conjugation a view to take fuse it with matmul which now gives as much as 50% perf gain and 30% memory savings. In any case, if that doesn’t match your use case, I understand your concern and you can do the following things to get the old behavior:

y = x.conj_physical() # returns a conjugated tensor that does not share memory with x
z = y.imag 

or

y = x.conj()
if y.is_conj():
     y = y.resolve_conj() # can also use y.clone()
z = y.imag

I can tell pytorch 1.10 doing this is for performance and memory saving. But for a user, especially engineer, we will not expect this behavior. Changing the z wil lead to x change, so I need a lot of “.clone()” to void math calculation wrong. This will not speed up anything… Both coding and performance are even slower.

Also, does the numpy people know .conj() using share memory will be faster? Of course, they know. But why didn’t they do it? Because it is anti-math, people using complex number heavily depend on math. If it is too different from math way, it is really hard for the user…

That is my a opinion. Maybe, I am wrong, but please think about it. Thanks.

Actually the performance will be exactly the same since calling the new torch.conj() is a constant time operation.

However as I mentioned above, you can still get the old conj behavior if you use torch.conj_physical (out-of-place operation instead of a view operation)

Hi Anjali!

I do agree that the 1.10 behavior of .conj() is unexpected.

Would it make sense to rename the new .conj() to .conj_view()? If
so, I would then vote for leaving .conj_physical() as is to help make
clear what is going on. (Renaming .conj_physical() to .conj() might
make use of .conj() the tempting default, tricking people into the
aforementioned performance hit.)

Best.

K. Frank