0

Hello i have this code that copy array into an other but its not exactly what i want. i want my kernel able to output a 2Darray that act like it memorise all the first array change so it increment a column at each update turn. but i have probleme creating a buffer for the 2Darray and use it in kernel program.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using OpenCL;
using System.Diagnostics;
using Cloo;
using Cloo.Bindings;

namespace CSharp_GPU
{
    class Program
    {
        static ComputePlatform platform;

        static ComputeEventList eventList = new ComputeEventList();

        static ComputeContext context;

        static ComputeProgram program;

        static ComputeDevice device;

        static ComputeKernel kernel;

        static ComputeCommandQueue commands;
        private static void notify(CLProgramHandle programHandle, IntPtr userDataPtr)
        {
            Console.WriteLine("Program build notification.");
            byte[] bytes = program.Binaries[0];
            Console.WriteLine("Beginning of program binary (compiled for the 1st selected device):");
            Console.WriteLine(BitConverter.ToString(bytes, 0, 24) + "...");
        }
        static void Main(string[] args)
        {
           
                //Generate the arrays for the demo
          
            ComputePlatform platform = ComputePlatform.Platforms[0];
            List<ComputeDevice> devices = new List<ComputeDevice>();
            devices.Add(platform.Devices[0]);
            ComputeContextPropertyList properties = new ComputeContextPropertyList(platform);
            context = new ComputeContext(devices, properties, null, IntPtr.Zero);
            program = new ComputeProgram(context, kernelSources);
            device = platform.Devices[0]; 

            const int arrayLength = 2000;
            double[] ARR1D = new double[arrayLength];
            Random random = new Random();

            program = new ComputeProgram(context, kernelSources);
            program.Build(null, null, notify, IntPtr.Zero);

            // Create the command queue. This is used to control kernel execution and manage read/write/copy operations.
            commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);
            // Create the kernel function and set its arguments.
            kernel = program.CreateKernel("addArray");

            try
            {
                while (true)
                {
                    //updating first array data
                    for (int i = 0; i < arrayLength; i++)
                    {
                        ARR1D[i] = random.NextDouble() * 100;
                    }

                   double[] ARR2D = new double[arrayLength]; // this should be a 2DArray that memorise update history   double[,]
                   //mutlidimentional result atempt
                  //  double[,] ARR2D = new double[arrayLength, ARR2D.GetLength(1) + 1];


                    ComputeBuffer<double> a = new ComputeBuffer<double>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, ARR1D);
                    ComputeBuffer<double> b = new ComputeBuffer<double>(context, ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.CopyHostPointer, ARR2D);
                  
                    kernel.SetMemoryArgument(0, a);
                    kernel.SetMemoryArgument(1, b);

                    commands.Execute(kernel, null, new long[] { arrayLength }, null, eventList);

                 
                    commands.ReadFromBuffer(b, ref ARR2D, false, eventList);

                    commands.Finish();

                    Console.WriteLine("ARR1D Copied into ARR2D ");

                    // Print the results to a log/console.
                    for (int i = 0; i < arrayLength; i++)
                        Console.WriteLine("{0} + {1} ", ARR1D[i], ARR2D[i]);

                    foreach (ComputeEventBase eventBase in eventList)
                    {
                         eventBase.Dispose();
                    }
                    eventList.Clear();

                    // cleanup kernel
                    //  kernel.Dispose();

                    // cleanup program
                    //    program.Dispose();

                    // cleanup buffers
                    a.Dispose();
                    b.Dispose();
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.ReadKey();
        }

        static string kernelSources
        {
            get
            {
              
                return @"
                kernel void addArray(global double * a, global double * b)
                {

                    int id = get_global_id(0);
                    b[id] = a[id] ;
                }
";
            }
        }
    }
}

i hope someone can clearly help internet lack ressource about GPU coding and sample.

Zwan
  • 632
  • 2
  • 6
  • 23
  • You can still use 1D array and 2D kernel and compute the index as idx+idy*width. get_global_id(1) gives the y-dimension size. When executing, give it 2D workitem settings instead of 1D. – huseyin tugrul buyukisik Jan 31 '22 at 08:42
  • 2D into kernel ? can you update the code for show implementation? – Zwan Jan 31 '22 at 09:12
  • @huseyin tugrul buyukisik i think my main problem is i dont find clear info on how to use get_global_id(1) that is an other dimension. – Zwan Jan 31 '22 at 11:03

0 Answers0