Iterating arrays in Cudafy

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 through the second array yet. I don't understand how indexing happens 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++;
    }
}
Author: Cyrus, 2015-11-03

1 answers

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

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, using this namespace, you can make everything much easier and more beautiful.

 1
Author: Мстислав Павлов, 2016-01-14 23:32:09