0

您好,我有这段代码可以将数组复制到另一个数组中,但它不完全是我想要的。我希望我的内核能够输出一个 2Darray,它就像它记住所有第一个数组更改一样,因此它在每个更新轮次增加一列。但我有问题为 2Darray 创建缓冲区并在内核程序中使用它。

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] ;
                }
";
            }
        }
    }
}

我希望有人可以清楚地帮助互联网缺乏有关 GPU 编码和示例的资源。

4

0 回答 0