15

What CUDA headers should I include in my programme if I want to work with complex numbers and do simple maths operations (addition and multiplication) to these complex double numbers within the kernel itself?

In C++ I can multiply a constant number with a complex double> as long as they are both double. However in CUDA I get lots of errors when I try to do simple maths operations to complex double>s whenever it isn't with another complex double>. What am I missing?

Thank you!

Robert Crovella
  • 143,785
  • 11
  • 213
  • 257
user2550888
  • 293
  • 1
  • 9
  • 18

1 Answers1

21

The header to include is:

#include <cuComplex.h>

On a standard linux CUDA install, it is located in:

/usr/local/cuda/include

You will need to inspect that header file and use the functions defined in it to manipulate complex numbers on the device.

To multiply a (double) complex number by a real number, I would:

#include <cuComplex.h>
...
double cr = 1;
double ci = 2;
double r = 3;
cuDoubleComplex c = make_cuDoubleComplex(cr, ci);
cuDoubleComplex result = cuCmul(c, make_cuDoubleComplex(r, 0));

EDIT: With the recently released Thrust v1.8 in CUDA 7 RC, it is possible to use thrust::complex in either thrust code or CUDA device code. This makes it possible to write more natural-looking operations such as:

#include <thrust/complex.h>
...
thrust::complex<float> c = thrust::complex<float>(2.0f, 5.0f);
thrust::complex<float> c2 = c*c;
float r = c2.real();

EDIT: In the last few years, NVIDIA has been developing a "standard" library for CUDA (libcu++) that mimics some aspects of std::. This library includes complex functionality, here is an example of usage.

Robert Crovella
  • 143,785
  • 11
  • 213
  • 257
  • Thanks for the quick response. I'm still trying to get my head around this.. This is probably a really silly question but where can I find more information about functions for different headers? For example, if you hadn't mentioned cuCmul I wouldn't have been able to figure out what it does just by going through the cuComplex.h File Reference in http://graphics.im.ntu.edu.tw/~bossliaw/nvCuda_doxygen/html/cu_complex_8h.html#ace9e79c66b2bfc9a8adeb1d641b12df4 – user2550888 Jul 04 '13 at 16:31
  • I don't know that there is any additional documentation for that header or perhaps other headers. I'm not aware of it, anyway. The `cuCmul` function is actually quite simple, and duplicates complex multiplication as [defined in basic principles of math](http://en.wikipedia.org/wiki/Complex_numbers#Multiplication_and_division). If you're not able to follow the conversion of that formula into C code as in `cuCmul`, then I would suggest learning more about basic computer programming including the C language. – Robert Crovella Jul 04 '13 at 16:39
  • I understand the cuCmul function now, but what I meant to say was, if you hadn't told me that cuCmul is the function for basic complex number multiplication I wouldn't have known just by looking at the header file reference as it gives no indication as to what it does.. Or maybe I am not using it properly as I can't really figure out what the call graph is showing? In the future, how can I know if a certain operation that I might need already has a function? – user2550888 Jul 04 '13 at 16:49
  • I don't know how to answer that question. It requires research. Many aspects of CUDA are documented [here](http://docs.nvidia.com/cuda/index.html), but certainly not every possible question is answered there. There are various forums, like this one, where people can get answers. I think it just requires effort. If you see a header file call cuComplex.h, it's reasonable to assume it might have something to do with complex numbers. If you look in that header file and see functions like cuCadd, cuCsub, cuCmul, cuCdiv, it's reasonable to assume they might have something to do with +,-,*, / – Robert Crovella Jul 04 '13 at 17:08
  • I guess I was looking for something similar to the cplusplus.com/reference section, where, what each function/header does it clearly explained. More research it is! Thanks again for your detailed answers – user2550888 Jul 04 '13 at 17:15
  • It's 3 years later, and I'm having this same issue. Where's the standard reference documentation for these functions? I understand I can get the info from the headers, but that seems remarkably low level for such a widely adopted library. – Fadecomic Dec 16 '16 at 16:19
  • 1
    I googled "thrust complex cuda" and [this](https://thrust.github.io/doc/group__complex__numbers.html) was the first hit I got. If your objection is around documentation for `cuComplex.h`, I would agree with you, but let's note that 1. It's not really a library. It's **just** a header file. 2. CUDA does not have "native" support for complex types anyway (just like C and C++ don't AFAIK). 3. `thrust::complex` functionality goes well beyond what you can do with just `cuComplex.h` So my suggestion would be to use `thrust::complex` for convenience, which appears to have documentation available – Robert Crovella Dec 16 '16 at 16:30
  • @RobertCrovella Just a small note that C has had native support for complex numbers since c99. – Simd Dec 30 '16 at 20:02
  • C picks up support via standard header "library" called `complex.h`. Likewise c++ picks up support via `std::complex`. The point I was trying to make is that without inclusion of such, there is no "native" support for complex types in either language, as contrasted with POD types like `int`, `float`, etc. It seems that C11 has made the use of the header optional, and in fact [C99 still makes complex support optional](https://en.wikichip.org/wiki/c/complex.h), as far as I can tell. Anyway, not arguing, "native" was a poor choice of words. If I could conveniently edit the comment I would. – Robert Crovella Dec 30 '16 at 22:36