Search code examples
c#cwpfopenclfractals

Complex number type and functions Open CL C through C# Wrapper


I am making an application in WPF C# that generates fractals. I am using this code that someone made to create a OpenCL kernel and run it in C#: https://www.codeproject.com/Articles/1116907/How-to-Use-Your-GPU-in-NET (It appears to employ another library called Cloo for actually making the OpenCL stuff).

In the kernel I need to be able to use complex numbers to generate my fractals. I have looked around and there is a default c library you can include by putting the line #include <complex.h> at the top of the string which contains all the functions I need. (I need more than just the basic adding and multiplying which I can code myself, such as exponential and trig functions, which I really don't want to make by hand).

However when I write this line it cannot compile as "complex.h" cannot be found. So I need some way to point the kernel straight to this file. Another fix might be to just shove the entire library into the kernel which is fine by me, but I have no clue what I need to find and copy to make this work as I know little about c and header files etc.

Help would be greatly appreciated.


Solution

  • You can't include C libraries in OpenCL C. But OpenCL C is essentially just C99, so you can make your own complex type as a struct:

    typedef struct __attribute__((packed)) struct_complex {
        float real;
        float imaginary;
    } complex;
    
    complex add(const complex x, const complex y) {
        complex result;
        result.real = x.real+y.real;
        result.imaginary = x.imaginary+y.imaginary;
        return result;
    }
    
    ...
    

    Given that libraries are just code, have a look in the file complex.h and copy/adapt what you need. OpenCL C already provides all math functions for foating-point, see here. Trigonometric functions / exponent with complex numbers are straightforward then: split the complex number up in the real and imaginary components with Euler's formula exp(i*x) == cos(x)+i*sin(x) and apply trigonometric identities. This also might be helpful.