Rome
Rome

Reputation: 442

Simple FFT in C# as single core, multi core and OpenCL versions?

I searched the web and Stack Overflow for FFT versions in C# and this was asked several times and some answers were given, but...

  1. All of the FFT versions I found were optimized for speed but are hard to understand.
  2. Almost all of those were iterative versions, thus not optimized for multi core systems.
  3. Opencl versions were optimized for certain gpu models.

As I am working on a case study for single core, multi core, opencl comparison of algorithms, I am looking for the most simple and free C# / Opencl versions of the FFT, working on float[] (real, complex not needed), forward and also inverse optional would be great. It would also be good if they would work on any array-length. Has anyone stumbled upon such?

Upvotes: 0

Views: 1764

Answers (1)

Ani
Ani

Reputation: 10906

This sample source from Brahma (my open-source project) has both a C# implementation and an LINQ implementation (OpenCL) of this FFT paper from Microsoft research.

The kernels automagically generated by Brahma are:

The FFT kernel

    __kernel void brahmaKernel(int fftSize,__global float* a,__global float* ib,__global float* c,__global float* id,int size) 
    {
        int x = get_global_id(0);
        int b = ((floor(convert_float((x / fftSize))) * fftSize) / ((int)2));
        int offset = (x % (fftSize / ((int)2)));
        int x0 = (b + offset);
        int x1 = (x0 + (size / ((int)2)));
        float val0A = a[x0];
        float val0B = ib[x0];
        float val1A = a[x1];
        float val1B = ib[x1];
        float angle = (((float)-6.283185) * (convert_float(x) / convert_float(fftSize)));
        float tA = native_cos(angle);
        float tB = native_sin(angle);
        (c[x] = ((val0A + (tA * val1A)) - (tB * val1B)));(id[x] = ((val0B + (tB * val1A)) + (tA * val1B)));
    }

Conjugate and scale kernel

    __kernel void brahmaKernel(float scale,__global float* a,__global float* ib) 
    {
        int x = get_global_id(0);
        (a[x] = (a[x] * scale));(ib[x] = (-(ib[x]) * scale));;
    }

Hope this helps!

Upvotes: 1

Related Questions