c# – Iterating Arrays in Cudafy

Question:

There is a code in C # , and I need to redo it so that everything is counted on the video card:

public static double[] SATL(double[] data)
{
    double[] matrix = { 0.0982862174, ..., -0.0229204861, ..., 0.0161380976 };
    int dataLength = data.Length;
    int matrixLength = matrix.Length;
    int start = matrixLength + 1;
    var newData = new double[dataLength];

    if (dataLength <= matrixLength)
    {
        return null;
    }

    for (int i = matrixLength; i < dataLength; i++)
    {
        int counter = i - matrixLength;
        for (int j = 0; j < matrixLength; j++)
        {
            newData[i] += matrix[j] * data[counter++];
        }
    }

    return newData;
}

The problem is that I can't figure out how to run around the second array yet. I don’t understand how indexing works in Cudafy . Here's what I got, but it doesn't work correctly:

public static double[] FATLCuda(double[] data, double[] matrix)
    {
        CudafyModule km = CudafyTranslator.Cudafy();
        GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
        gpu.LoadModule(km);
        ...
        gpu.Launch().add(dev_data, dev_matrix, dev_newdata);                            
    }


[Cudafy]
public static void add(GThread thread, double[] data, double[] matrix, double[] newdata)
{
    int tid = thread.blockIdx.x;
    if (tid < data.Length)
    {
        int jid = 0;
        int counter = tid - matrix.Length;
        if (jid < matrix.Length)
        {
            newdata[tid] += matrix[jid] * data[counter++];
            jid++;
        }
        tid++;
    }
}

Answer:

Not so long ago, .net added support for SIMD . This namespace enables hardware acceleration. To use, you need to have RyuJIT compiler, .NET 4.6 and System.Numerics.Vectors, which is installed via Nuget.

An example of the simplest program using this namespace:

using System;
using System.Numerics;

class Program
{
    static void Main(string[] args)
    {
        const Int32 N = 8;
        Single[] a = { 41982.0F, 81.5091F, 3.14F, 42.666F, 54776.45F, 342.4556F, 6756.2344F, 4563.789F };
        Single[] b = { 85989.111F, 156.5091F, 3.14F, 42.666F, 1006.45F, 9999.4546F, 0.2344F, 7893.789F };
        Single[] c = new Single[N];

        for (int i = 0; i < N; i += Vector<Single>.Count) // Count возвращает 16 для char, 4 для float, 2 для      double и т.п.
        {
            var aSimd = new Vector<Single>(a, i); // создать экземпляр со смещением i
            var bSimd = new Vector<Single>(b, i);
            Vector<Single> cSimd = aSimd + bSimd; // или так Vector<Single> c_simd = Vector.Add(b_simd, a_simd);
            cSimd.CopyTo(c, i); //копировать в массив со смещением
        }

        for (int i = 0; i < a.Length; i++)
        {
            Console.WriteLine(c[i]);
        }
        Console.ReadKey();
    }
}

In other words, by using this namespace, you can make everything much simpler and prettier.

Scroll to Top