0

The C++ standard library has a function called std::arg(). It returns the phase angle (or angular component) of its complex number argument, expressed in radians.

I need to call something like std::arg() in a CUDA kernel. Is there an equivalent function in the CUDA Math library, or CUDA Complex Math library?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
JB_User
  • 3,117
  • 7
  • 31
  • 51
  • 2
    I looked at `cuComplex.h` and it does not exit. CUDA only has rudimentary support for complex numbers; basically what is required by CUBLAS and CUFFT. You can easily compute the function yourself as arg (x + *i* y) = atan2 (y, x). CUDA supports the C++ standard math function `atan2()`. – njuffa Feb 03 '21 at 05:11
  • 1
    Yes. I just did something like this and it worked: double myPhaseAngle = atan2(cuCimag(myComplexDouble), cuCreal(myComplexDouble)); – JB_User Feb 03 '21 at 05:26
  • 1
    https://thrust.github.io/doc/group__complex__numbers_gaaf1fe0eb083839813e90a6f7cb6d7585.html Yes, that is [usable in an ordinary CUDA kernel](https://stackoverflow.com/questions/17473826/cuda-how-to-work-with-complex-numbers/17474278#17474278), it does not require extensive use of other thrust constructs. – Robert Crovella Feb 04 '21 at 16:35

1 Answers1

2

To summarize and expand slightly on the comments:

  • The CUDA math library offers no direct support of an arg() function for complex values.
  • cuComplex.h is very rudimentary. As @njuffa notes: It only has what's required by CUBLAS and CUFFT.
  • You can, and should, use atan2(y, x) (or std::atan2(y, x)), where y is the imaginary component and x is the real one.

Now, what about Thrust? thrust::complex<T> does have an arg() method, after all?

Well, this is how it's implemented:

template <typename T>
__host__ __device__
T arg(const complex<T>& z)
{
  // Find `atan2` by ADL.
  using std::atan2;
  return atan2(z.imag(), z.real());
}

(see also on GitHub.) ... so, atan2() there as well.

einpoklum
  • 118,144
  • 57
  • 340
  • 684