示例#1
0
        public void CommandQueueAPI()
        {
            ErrorCode error;

            using (CommandQueue commandQueue = Cl.CreateCommandQueue(_context, _device, CommandQueueProperties.OutOfOrderExecModeEnable, out error))
            {
                Assert.AreEqual(ErrorCode.Success, error);

                Assert.AreEqual(1, Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.ReferenceCount, out error).CastTo <uint>());

                Cl.RetainCommandQueue(commandQueue);
                Assert.AreEqual(2, Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.ReferenceCount, out error).CastTo <uint>());

                Cl.ReleaseCommandQueue(commandQueue);
                Assert.AreEqual(1, Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.ReferenceCount, out error).CastTo <uint>());

                Assert.AreEqual(Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.Context, out error).CastTo <Context>(), _context);
                Assert.AreEqual(Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.Device, out error).CastTo <Device>(), _device);
                Assert.AreEqual(Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.Properties, out error).CastTo <CommandQueueProperties>(),
                                CommandQueueProperties.OutOfOrderExecModeEnable);
            }
        }
示例#2
0
        public OpenClCompiler(Device device, string source)
        {
            _device = device;
            _ctx    = device.CreateContext();


            Source   = source;
            _program = new Program(Cl.CreateProgramWithSource(_ctx, 1, new string[] { source }, null, out ErrorCode error));
            Cl.BuildProgram(_program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero);

            KernelCount = _program.NumKernels;
            Methodes    = _program.KernelNames;

            _kernels = new Kernel[KernelCount];

            if ((error = Cl.CreateKernelsInProgram(_program, KernelCount, _kernels, out _)) != ErrorCode.Success)
            {
                throw new Exception($"{error}");
            }

            _queue = Cl.CreateCommandQueue(_ctx, _device, CommandQueueProperties.None, out _);
        }
        private void ready()
        {
            ErrorCode error;

            context = Cl.CreateContext(null, 1, new[] { device }, null, IntPtr.Zero, out error);

            string source = System.IO.File.ReadAllText("kernels.cl");

            program = Cl.CreateProgramWithSource(context, 1, new[] { source }, null, out error);

            error = Cl.BuildProgram(program, 1, new[] { device }, string.Empty, null, IntPtr.Zero);
            InfoBuffer buildStatus = Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out error);

            if (buildStatus.CastTo <BuildStatus>() != BuildStatus.Success)
            {
                throw new Exception($"OpenCL could not build the kernel successfully: {buildStatus.CastTo<BuildStatus>()}");
            }
            allGood(error);

            Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error);
            kernel = kernels[0];
            allGood(error);

            queue = Cl.CreateCommandQueue(context, device, CommandQueueProperties.None, out error);
            allGood(error);

            dataOut = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(globalSize * sizeof(int)), out error);
            allGood(error);

            var intSizePtr = new IntPtr(Marshal.SizeOf(typeof(int)));

            error |= Cl.SetKernelArg(kernel, 2, new IntPtr(Marshal.SizeOf(typeof(IntPtr))), dataOut);
            error |= Cl.SetKernelArg(kernel, 3, intSizePtr, new IntPtr(worldSeed));
            error |= Cl.SetKernelArg(kernel, 4, intSizePtr, new IntPtr(globalSize));
            allGood(error);
        }
示例#4
0
        // Partially from OpenTK demo - Submitted by "mfagerlund"
        public void AddArrayAddsCorrectly()
        {
            const string correctSource = @"
                // Simple test; c[i] = a[i] + b[i]

                __kernel void add_array(__global float *a, __global float *b, __global float *c)
                {
                    int xid = get_global_id(0);
                    c[xid] = a[xid] + b[xid];
                }
                
                __kernel void sub_array(__global float *a, __global float *b, __global float *c)
                {
                    int xid = get_global_id(0);
                    c[xid] = a[xid] - b[xid];
                }

                ";

            ErrorCode error;

            using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { correctSource }, null, out error))
            {
                Assert.AreEqual(error, ErrorCode.Success);
                error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero);
                Assert.AreEqual(ErrorCode.Success, error);
                Assert.AreEqual(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>(), BuildStatus.Success);

                Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error);
                Kernel   kernel  = kernels[0];

                const int cnBlockSize = 4;
                const int cnBlocks    = 3;
                IntPtr    cnDimension = new IntPtr(cnBlocks * cnBlockSize);

                // allocate host  vectors
                float[] A = new float[cnDimension.ToInt32()];
                float[] B = new float[cnDimension.ToInt32()];
                float[] C = new float[cnDimension.ToInt32()];

                // initialize host memory
                Random rand = new Random();
                for (int i = 0; i < A.Length; i++)
                {
                    A[i] = rand.Next() % 256;
                    B[i] = rand.Next() % 256;
                }

                //Cl.IMem hDeviceMemA = Cl.CreateBuffer(_context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly, (IntPtr)(sizeof(float) * cnDimension.ToInt32()), A, out error);
                //Assert.AreEqual(Cl.ErrorCode.Success, error);

                IMem <float> hDeviceMemA = Cl.CreateBuffer(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, A, out error);
                Assert.AreEqual(ErrorCode.Success, error);

                IMem hDeviceMemB = Cl.CreateBuffer(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, (IntPtr)(sizeof(float) * cnDimension.ToInt32()), B, out error);
                Assert.AreEqual(ErrorCode.Success, error);
                IMem hDeviceMemC = Cl.CreateBuffer(_context, MemFlags.WriteOnly, (IntPtr)(sizeof(float) * cnDimension.ToInt32()), IntPtr.Zero, out error);
                Assert.AreEqual(ErrorCode.Success, error);

                CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error);

                Event clevent;

                int intPtrSize = 0;
                intPtrSize = Marshal.SizeOf(typeof(IntPtr));

                // setup parameter values
                error = Cl.SetKernelArg(kernel, 0, new IntPtr(intPtrSize), hDeviceMemA);
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.SetKernelArg(kernel, 1, new IntPtr(intPtrSize), hDeviceMemB);
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.SetKernelArg(kernel, 2, new IntPtr(intPtrSize), hDeviceMemC);
                Assert.AreEqual(ErrorCode.Success, error);

                // write data from host to device
                error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemA, Bool.True, IntPtr.Zero,
                                              new IntPtr(cnDimension.ToInt32() * sizeof(float)),
                                              A, 0, null, out clevent);
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemB, Bool.True, IntPtr.Zero,
                                              new IntPtr(cnDimension.ToInt32() * sizeof(float)),
                                              B, 0, null, out clevent);
                Assert.AreEqual(ErrorCode.Success, error);

                // execute kernel
                error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new IntPtr[] { cnDimension }, null, 0, null, out clevent);
                Assert.AreEqual(ErrorCode.Success, error, error.ToString());

                // copy results from device back to host
                IntPtr event_handle = IntPtr.Zero;

                error = Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemC, Bool.True, 0, C.Length, C, 0, null, out clevent);
                Assert.AreEqual(ErrorCode.Success, error, error.ToString());

                for (int i = 0; i < A.Length; i++)
                {
                    Assert.That(A[i] + B[i], Is.EqualTo(C[i]));
                }

                Cl.Finish(cmdQueue);

                Cl.ReleaseMemObject(hDeviceMemA);
                Cl.ReleaseMemObject(hDeviceMemB);
                Cl.ReleaseMemObject(hDeviceMemC);
            }
        }
示例#5
0
    public Bitmap GPUMandel(Bitmap inputBitmap)
    {
        ErrorCode error;
        //Load and compile kernel source code.
        string programPath = System.Environment.CurrentDirectory + "/../../program.cl";

        //The path to the source file may vary

        if (!System.IO.File.Exists(programPath))
        {
            Console.WriteLine("Program doesn't exist at path " + programPath);
            return(inputBitmap);
        }

        string programSource = System.IO.File.ReadAllText(programPath);

        using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error))
        {
            CheckErr(error, "Cl.CreateProgramWithSource");
            //Compile kernel source
            error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero);
            CheckErr(error, "Cl.BuildProgram");
            //Check for any compilation errors
            if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>()
                != BuildStatus.Success)
            {
                CheckErr(error, "Cl.GetProgramBuildInfo");
                Console.WriteLine("Cl.GetProgramBuildInfo != Success");
                Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error));
                return(inputBitmap);
            }
            //Create the required kernel (entry function)
            Kernel kernel = Cl.CreateKernel(program, "Mandelbrot", out error);
            CheckErr(error, "Cl.CreateKernel");


            //Unmanaged output image's raw RGBA byte[] array
            BitmapData bitmapData        = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            int        inputImgBytesSize = bitmapData.Stride * bitmapData.Height;
            int        inputImgWidth     = inputBitmap.Width;
            int        inputImgHeight    = inputBitmap.Height;
            int        intPtrSize        = Marshal.SizeOf(typeof(IntPtr));

            OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8);
            //OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Float);


            byte[] outputByteArray = new byte[inputImgBytesSize];
            //Allocate OpenCL image memory buffer
            Mem outputImage2DBuffer = (Mem)Cl.CreateImage2D(_context, MemFlags.CopyHostPtr |
                                                            MemFlags.WriteOnly, clImageFormat, (IntPtr)inputImgWidth,
                                                            (IntPtr)inputImgHeight, (IntPtr)0, outputByteArray, out error);
            CheckErr(error, "Cl.CreateImage2D output");
            //Pass the memory buffers to our kernel function
            error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, outputImage2DBuffer);
            CheckErr(error, "Cl.SetKernelArg");

            //Create a command queue, where all of the commands for execution will be added
            CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error);
            CheckErr(error, "Cl.CreateCommandQueue");
            Event clevent;
            //Copy input image from the host to the GPU.
            IntPtr[] originPtr        = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };                          //x, y, z
            IntPtr[] regionPtr        = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; //x, y, z
            IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 };

            error = Cl.EnqueueWriteImage(cmdQueue, outputImage2DBuffer, Bool.True,
                                         originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent);

            CheckErr(error, "Cl.EnqueueWriteImage");
            //Execute our kernel (OpenCL code)
            error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent);
            CheckErr(error, "Cl.EnqueueNDRangeKernel");
            //Wait for completion of all calculations on the GPU.
            error = Cl.Finish(cmdQueue);
            CheckErr(error, "Cl.Finish");
            //Read the processed image from GPU to raw RGBA data byte[] array
            error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr,
                                        (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent);
            CheckErr(error, "Cl.clEnqueueReadImage");
            //Clean up memory
            Cl.ReleaseKernel(kernel);
            Cl.ReleaseCommandQueue(cmdQueue);

            //Cl.ReleaseMemObject(inputImage2DBuffer);
            Cl.ReleaseMemObject(outputImage2DBuffer);
            //Get a pointer to our unmanaged output byte[] array
            GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned);
            IntPtr   outputBmpPointer  = pinnedOutputArray.AddrOfPinnedObject();
            //Create a new bitmap with processed data and save it to a file.

            Bitmap outputBitmap = new Bitmap(inputImgWidth, inputImgHeight,
                                             bitmapData.Stride, PixelFormat.Format32bppArgb, outputBmpPointer);

            return(outputBitmap);

            //outputBitmap.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png);
            //pinnedOutputArray.Free();
        }
    }
        public override Bitmap Plot()
        {
            ErrorCode error;

            using (Kernel kernel = CompileKernel("mandelbrot"))
            {
                Bitmap plotImg = new Bitmap(Width, Height);

                int intPtrSize = Marshal.SizeOf(typeof(IntPtr));
                int uint4size  = Marshal.SizeOf(typeof(uint4));

                // Buffer do OpenCL para manter os dados da imagem
                OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8);

                //// Obtém o buffer de pixels
                //BitmapData data = plotImg.LockBits(new Rectangle(0, 0, plotImg.Width, plotImg.Height), ImageLockMode.WriteOnly, plotImg.PixelFormat);
                //int depth = Bitmap.GetPixelFormatSize(data.PixelFormat) / 8; // Tamanho de cada pixel em memória, em bytes

                int    depth  = Bitmap.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8;
                int    stride = 4 * ((Width * depth + 3) / 4);
                byte[] buffer = new byte[Height * stride]; // Cria o buffer para se trabalhar na imagem
                //Marshal.Copy(data.Scan0, buffer, 0, buffer.Length); // Copia as informações da imagem no buffer

                // Cria o buffer do OpenCL para a imagem
                Mem image2dbuffer = (Mem)Cl.CreateImage2D(context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, clImageFormat,
                                                          (IntPtr)Width, (IntPtr)Height,
                                                          (IntPtr)0, buffer, out error);
                CheckErr(error, "Cl.CreateImage2D");

                // Passa os parametros para o kernel
                error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, image2dbuffer);
                CheckErr(error, "Cl.SetKernelArg imageBuffer");

                uint4 startColorUi = new uint4(Colors.StartColor.B, Colors.StartColor.G, Colors.StartColor.R, Colors.StartColor.A);
                error = Cl.SetKernelArg(kernel, 1, (IntPtr)uint4size, startColorUi);
                CheckErr(error, "Cl.SetKernelArg startColor");

                uint4 endColorUi = new uint4(Colors.EndColor.B, Colors.EndColor.G, Colors.EndColor.R, Colors.EndColor.A);
                error = Cl.SetKernelArg(kernel, 2, (IntPtr)uint4size, endColorUi);
                CheckErr(error, "Cl.SetKernelArg endColor");

                error = Cl.SetKernelArg(kernel, 3, (IntPtr)sizeof(int), Iterations);
                CheckErr(error, "Cl.SetKernelArg iterations");


                // Cria uma fila de comandos, com todos os comandos a serem executados pelo kernel
                CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, 0, out error);
                CheckErr(error, "Cl.CreateCommandQueue");

                // Copia a imagem para a GPU
                Event    clevent;
                IntPtr[] imgOriginPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };          //x, y, z
                IntPtr[] imgRegionPtr = new IntPtr[] { (IntPtr)Width, (IntPtr)Height, (IntPtr)1 }; //x, y, z
                error = Cl.EnqueueWriteImage(cmdQueue, image2dbuffer, Bool.True, imgOriginPtr, imgRegionPtr, (IntPtr)0, (IntPtr)0, buffer, 0, null, out clevent);
                CheckErr(error, "Cl.EnqueueWriteImage");

                // Executa o Kernel carregado pelo OpenCL (com múltiplos processadores :D)
                IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)Width, (IntPtr)Height, (IntPtr)1 }; // x, y, z
                error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent);
                CheckErr(error, "Cl.EnqueueNDRangeKernel");

                // Espera terminar a execução
                error = Cl.Finish(cmdQueue);
                CheckErr(error, "Cl.Finish");

                // Lê a imagem processada pela GPU e coloca novamente no buffer
                error = Cl.EnqueueReadImage(cmdQueue, image2dbuffer, Bool.True, imgOriginPtr, imgRegionPtr,
                                            (IntPtr)0, (IntPtr)0, buffer, 0, null, out clevent);
                CheckErr(error, "Cl.clEnqueueReadImage");

                // Limpa a memória
                Cl.ReleaseKernel(kernel);
                Cl.ReleaseCommandQueue(cmdQueue);
                Cl.ReleaseMemObject(image2dbuffer);

                // Get a pointer to our unmanaged output byte[] array
                //GCHandle pinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                //IntPtr bmpPointer = pinnedBuffer.AddrOfPinnedObject();

                BitmapData data = plotImg.LockBits(new Rectangle(0, 0, plotImg.Width, plotImg.Height), ImageLockMode.WriteOnly, plotImg.PixelFormat);
                Marshal.Copy(buffer, 0, data.Scan0, buffer.Length); // Copia as informações no buffer de volta à imagem
                plotImg.UnlockBits(data);                           // Libera a imagem

                //pinnedBuffer.Free();

                return(plotImg);
            }
        }
示例#7
0
        public void ScryptTest()
        {
            ErrorCode error;

            //Load and compile kernel source code.
            string programPath = System.Environment.CurrentDirectory + "/../../scrypt.cl";  //Cl

            if (!System.IO.File.Exists(programPath))
            {
                Console.WriteLine("Program doesn't exist at path " + programPath);                return;
            }

            string programSource = System.IO.File.ReadAllText(programPath);

            IntPtr[] sz      = new IntPtr[programSource.Length * 2];
            Program  program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error);

            if (1 == 1)
            {
                CheckErr(error, "Cl.CreateProgramWithSource");

                //                status = clBuildProgram(clState->program, 1, &devices[gpu], ""-D LOOKUP_GAP=%d -D CONCURRENT_THREADS=%d -D WORKSIZE=%d", NULL, NULL);
                //Compile kernel source
                error = Cl.BuildProgram(program, 1, new[] { _device }, "-D LOOKUP_GAP=1 -D CONCURRENT_THREADS=1 -D WORKSIZE=1", null, IntPtr.Zero);
                CheckErr(error, "Cl.BuildProgram");

                //Check for any compilation errors
                if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>()
                    != BuildStatus.Success && 1 == 0)
                {
                    CheckErr(error, "Cl.GetProgramBuildInfo");
                    Console.WriteLine("Cl.GetProgramBuildInfo != Success");
                    Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error));
                    return;
                }

                //Create the required kernel (entry function) [search]
                Kernel kernel = Cl.CreateKernel(program, "search", out error);

                CheckErr(error, "Cl.CreateKernel");
                int intPtrSize = 0;
                intPtrSize = Marshal.SizeOf(typeof(IntPtr));

                //Image's RGBA data converted to an unmanaged[] array
                byte[] inputByteArray;
                //OpenCL memory buffer that will keep our image's byte[] data.
                Mem inputImage2DBuffer;
                //Create a command queue, where all of the commands for execution will be added
                CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error);
                CheckErr(error, "Cl.CreateCommandQueue");
                clState _clState = new clState();
                _clState.cl_command_queue = cmdQueue;
                _clState.cl_kernel        = kernel;
                _clState.cl_context       = _context;


                IntPtr buffersize = new IntPtr(1024);
                IntPtr blank_res  = new IntPtr(1024);
                Object thrdataRes = new Object();


                //int buffersize = 1024;
                OpenCL.Net.Event clevent;
                //                 status |= clEnqueueWriteBuffer(clState->commandQueue, clState->outputBuffer, CL_TRUE, 0,  buffersize, blank_res, 0, NULL, NULL);
                dev_blk_ctx blk = new dev_blk_ctx();
                ErrorCode   err = queue_scrypt_kernel(_clState, blk);



                ErrorCode status = Cl.EnqueueWriteBuffer(_clState.cl_command_queue,
                                                         _clState.outputBuffer, OpenCL.Net.Bool.True, new IntPtr(0), buffersize, blank_res, 0, null, out clevent);

                IntPtr[] globalThreads = new IntPtr[0];
                IntPtr[] localThreads  = new IntPtr[0];

                //uint16 workdim = new uint16(1);
                uint workdim = 1;

                status = Cl.EnqueueNDRangeKernel(_clState.cl_command_queue, _clState.cl_kernel, workdim, null, globalThreads, localThreads, 0, null, out clevent);
                CheckErr(error, "Cl.EnqueueNDRangeKernel");

                IntPtr offset = new IntPtr(0);

                status = Cl.EnqueueReadBuffer(_clState.cl_command_queue, _clState.outputBuffer, OpenCL.Net.Bool.False, offset, buffersize, thrdataRes, 0, null, out clevent);

                //Wait for completion of all calculations on the GPU.
                error = Cl.Finish(_clState.cl_command_queue);

                CheckErr(error, "Cl.Finish");

                //Clean up memory
                Cl.ReleaseKernel(_clState.cl_kernel);
                Cl.ReleaseCommandQueue(_clState.cl_command_queue);
            }
        }
示例#8
0
        public static void Initialize()
        {
            Platform[] platforms = Cl.GetPlatformIDs(out ErrorCode error);
            if (error != ErrorCode.Success)
            {
                Log.Print("Impossible to run OpenCL, no any graphic platform available, abording launch.");

                Application.Exit();
            }

            Vector2I res          = Graphics.RenderResolution;
            int      pixelXAmount = res.x;
            int      pixelYAmount = res.y;

            int amountOfObjects = 1;

            unsafe
            {
                inputSize  = sizeof(C_CAMERA);
                outputSize = sizeof(byte) * pixelXAmount * pixelYAmount * 4;
            }

            UsedDevice  = Cl.GetDeviceIDs(platforms[0], DeviceType.All, out error)[0];
            gpu_context = Cl.CreateContext(null, 1, new Device[] { UsedDevice }, null, IntPtr.Zero, out error);
            InfoBuffer namebuffer = Cl.GetDeviceInfo(UsedDevice, DeviceInfo.Name, out error);

            Log.Print("OpenCL Running on " + namebuffer);

            Queue = Cl.CreateCommandQueue(gpu_context, UsedDevice, CommandQueueProperties.OutOfOrderExecModeEnable, out error);
            if (error != ErrorCode.Success)
            {
                Console.WriteLine("Impossible to create gpu queue, abording launch.");

                Application.Exit();
            }

            CLoader.LoadProjectPaths(@".\libs", new[] { "c" }, out string[] cfiles, out string[] hfiles);
            Program program = CLoader.LoadProgram(cfiles, hfiles, UsedDevice, gpu_context);

            //Program prog = CLoader.LoadProgram(CLoader.GetCFilesDir(@".\", new[] { "cl" }).ToArray(), new[] { "headers" }, UsedDevice, gpu_context);
            kernel = Cl.CreateKernel(program, "rm_render_entry", out error);

            if (error != ErrorCode.Success)
            {
                Log.Print("Error when creating kernel: " + error.ToString());
            }

            memory    = new IntPtr(outputSize);
            memInput  = (Mem)Cl.CreateBuffer(gpu_context, MemFlags.ReadOnly, inputSize, out error);
            memTime   = (Mem)(Cl.CreateBuffer(gpu_context, MemFlags.ReadOnly, timeSize, out error));
            memOutput = (Mem)Cl.CreateBuffer(gpu_context, MemFlags.WriteOnly, outputSize, out error);



            //GPU_PARAM param = new GPU_PARAM() { X_RESOLUTION = res.x, Y_RESOLUTION = res.y };

            ////Vector3D pos = camera.Malleable.Position;
            //Quaternion q = camera.Malleable.Rotation;



            IntPtr     notused;
            InfoBuffer local = new InfoBuffer(new IntPtr(4));

            error = Cl.GetKernelWorkGroupInfo(kernel, UsedDevice, KernelWorkGroupInfo.WorkGroupSize, new IntPtr(sizeof(int)), local, out notused);
            if (error != ErrorCode.Success)
            {
                Log.Print("Error getting kernel workgroup info: " + error.ToString());
            }

            //int intPtrSize = 0;
            intPtrSize = Marshal.SizeOf(typeof(IntPtr));

            Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, memInput);
            Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, memTime);

            Cl.SetKernelArg(kernel, 4, (IntPtr)intPtrSize, memOutput);

            //Cl.SetKernelArg(kernel, 2, new IntPtr(4), pixelAmount * 4);
            workGroupSizePtr = new IntPtr[] { new IntPtr(pixelXAmount * pixelYAmount) };
        }
示例#9
0
        public void MatMul()
        {
            if (!prepared)
            {
                Prepare(this.BuildIR().InlineIR());
                prepared = true;
            }

            // create kernel
            Cl.Kernel kernel = Cl.CreateKernel(program, "MatMul", out error);
            clSafeCall(error);

            // create command queue
            Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error);
            clSafeCall(error);

            // allocate host matrices
            float[] A = new float[WA * HA];
            float[] B = new float[WB * HB];
            float[] C = new float[WC * HC];

            // initialize host memory
            Random rand = new Random();

            for (int i = 0; i < A.Length; i++)
            {
                A[i] = (float)rand.Next() / short.MaxValue;
            }
            for (int i = 0; i < B.Length; i++)
            {
                B[i] = (float)rand.Next() / short.MaxValue;
            }

            // allocate device vectors
            Cl.Mem hDeviceMemA = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly,
                                                 (IntPtr)(sizeof(float) * A.Length), A, out error);
            clSafeCall(error);
            Cl.Mem hDeviceMemB = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly,
                                                 (IntPtr)(sizeof(float) * B.Length), B, out error);
            clSafeCall(error);
            Cl.Mem hDeviceMemC = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly,
                                                 (IntPtr)(sizeof(float) * C.Length), IntPtr.Zero, out error);
            clSafeCall(error);

            // setup kernel arguments
            clSafeCall(Cl.SetKernelArg(kernel, 0, hDeviceMemA));
            clSafeCall(Cl.SetKernelArg(kernel, 1, hDeviceMemB));
            clSafeCall(Cl.SetKernelArg(kernel, 2, hDeviceMemC));
            clSafeCall(Cl.SetKernelArg(kernel, 3, BLOCK_SIZE * BLOCK_SIZE * sizeof(float), null));
            clSafeCall(Cl.SetKernelArg(kernel, 4, BLOCK_SIZE * BLOCK_SIZE * sizeof(float), null));
            clSafeCall(Cl.SetKernelArg(kernel, 5, WA));
            clSafeCall(Cl.SetKernelArg(kernel, 6, WB));

            // execute kernel
            clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, new[] { (IntPtr)WC, (IntPtr)HC },
                                               new[] { (IntPtr)BLOCK_SIZE, (IntPtr)BLOCK_SIZE }, 0, null, out clevent));

            // copy results from device back to host
            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemC, Cl.Bool.True, IntPtr.Zero,
                                            (IntPtr)(sizeof(float) * C.Length), C, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            for (int i = 0; i < HA; ++i)
            {
                for (int j = 0; j < WB; ++j)
                {
                    float sum = 0;
                    for (int k = 0; k < WA; ++k)
                    {
                        sum += A[i * WA + k] * B[k * WB + j];
                    }
                    float err = Math.Abs((sum - C[i * WB + j]) / sum);
                    Assert.That(err, Is.LessThanOrEqualTo(1E-3F));
                }
            }
        }
示例#10
0
        private static long PoissonRBSOR(Cl.Device device, Cl.Context context, Cl.Program program, bool lmem,
                                         float x0, float y0, float x1, float y1, int dimX, int dimY, int N, float omega,
                                         string fileName = null, string options = "")
        {
            Cl.ErrorCode error;
            Cl.Event     clevent;

            // build program
            clSafeCall(Cl.BuildProgram(program, 1, new[] { device }, options, null, IntPtr.Zero));
            Cl.BuildStatus status = Cl.GetProgramBuildInfo(program, device, Cl.ProgramBuildInfo.Status, out error).CastTo <Cl.BuildStatus>();
            if (status != Cl.BuildStatus.Success)
            {
                throw new Exception(status.ToString());
            }

            // save binary
            if (fileName != null)
            {
                Cl.InfoBuffer binarySizes = Cl.GetProgramInfo(program, Cl.ProgramInfo.BinarySizes, out error);
                clSafeCall(error);
                Cl.InfoBufferArray binaries = new Cl.InfoBufferArray(
                    binarySizes.CastToEnumerable <IntPtr>(Enumerable.Range(0, 1)).Select(sz => new Cl.InfoBuffer(sz)).ToArray());
                IntPtr szRet;
                clSafeCall(Cl.GetProgramInfo(program, Cl.ProgramInfo.Binaries, binaries.Size, binaries, out szRet));
                byte[] binary = binaries[0].CastToArray <byte>(binarySizes.CastTo <IntPtr>(0).ToInt32());
                File.WriteAllBytes(fileName, binary);
            }

            // create kernel
            Cl.Kernel kernel = Cl.CreateKernel(program, "PoissonRBSOR" + (lmem ? "_LMem" : ""), out error);
            clSafeCall(error);

            // create command queue
            Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error);
            clSafeCall(error);

            float hx = (x1 - x0) / dimX;
            float hy = (y1 - y0) / dimY;

            // boundary values

            float[] hgrid = new float[dimX * dimY];

            int gstride = dimX;

            for (int i = 1; i < dimY - 1; i++)
            {
                int   y_idx = i * gstride;
                float y_val = y0 + i * hy;
                hgrid[y_idx]            = u(x0, y_val);
                hgrid[y_idx + dimX - 1] = u(x0 + (dimX - 1) * hx, y_val);
            }

            for (int j = 1; j < dimX - 1; j++)
            {
                float x_val = x0 + j * hx;
                hgrid[j] = u(x_val, y0);
                hgrid[j + (dimY - 1) * gstride] = u(x_val, y0 + (dimY - 1) * hy);
            }

            // laplacian values

            float[] hlaplacian = new float[(dimX - 2) * (dimY - 2)];

            int lstride = dimX - 2;

            for (int i = 1; i < dimY - 1; i++)
            {
                for (int j = 1; j < dimX - 1; j++)
                {
                    hlaplacian[j - 1 + (i - 1) * lstride] = J(x0 + j * hx, y0 + i * hy);
                }
            }

            // allocate device vectors
            Cl.Mem dgrid = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadWrite,
                                           (IntPtr)(sizeof(float) * hgrid.Length), hgrid, out error);
            clSafeCall(error);
            Cl.Mem dlaplacian = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly,
                                                (IntPtr)(sizeof(float) * hlaplacian.Length), hlaplacian, out error);
            clSafeCall(error);

            // setup kernel arguments
            clSafeCall(Cl.SetKernelArg(kernel, 0, dgrid));
            clSafeCall(Cl.SetKernelArg(kernel, 1, dlaplacian));
            clSafeCall(Cl.SetKernelArg(kernel, 2, dimX));
            clSafeCall(Cl.SetKernelArg(kernel, 3, dimY));
            clSafeCall(Cl.SetKernelArg(kernel, 4, gstride));
            clSafeCall(Cl.SetKernelArg(kernel, 5, lstride));
            clSafeCall(Cl.SetKernelArg(kernel, 6, hx));
            clSafeCall(Cl.SetKernelArg(kernel, 7, hy));
            clSafeCall(Cl.SetKernelArg(kernel, 8, omega));
            if (lmem)
            {
                clSafeCall(Cl.SetKernelArg(kernel, 10, (AREA_SIZE_Y + 2) * (AREA_SIZE_X + 2) * sizeof(float), null));
            }

            IntPtr[] lo = { (IntPtr)TILE_SIZE_X, (IntPtr)TILE_SIZE_Y };
            IntPtr[] gl =
            {
                (IntPtr)((dimX - 2 + (lmem ? AREA_SIZE_X : TILE_SIZE_X) - 1) /
                         (lmem ? AREA_SIZE_X : TILE_SIZE_X) * TILE_SIZE_X),
                (IntPtr)((dimY - 2 + (lmem ? AREA_SIZE_Y : TILE_SIZE_Y) - 1) /
                         (lmem ? AREA_SIZE_Y : TILE_SIZE_Y) * TILE_SIZE_Y)
            };

            // execute RED kernel
            clSafeCall(Cl.SetKernelArg(kernel, 9, 1));
            clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent));

            // execute BLACK kernel
            clSafeCall(Cl.SetKernelArg(kernel, 9, 0));
            clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            for (int idx = 1; idx < N; idx++)
            {
                // execute RED kernel
                clSafeCall(Cl.SetKernelArg(kernel, 9, 1));
                clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent));

                // execute BLACK kernel
                clSafeCall(Cl.SetKernelArg(kernel, 9, 0));
                clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent));
            }

            clSafeCall(Cl.Finish(cmdQueue));

            stopwatch.Stop();

            // copy results from device back to host
            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dgrid, Cl.Bool.True, IntPtr.Zero,
                                            (IntPtr)(sizeof(float) * hgrid.Length), hgrid, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            cmdQueue.Dispose();
            kernel.Dispose();
            dgrid.Dispose();

            float avgerr = 0, maxerr = 0;

            for (int i = 1; i < dimY - 1; i++)
            {
                for (int j = 1; j < dimX - 1; j++)
                {
                    float theory = u(x0 + j * hx, y0 + i * hy);
                    float err    = Math.Abs(theory - hgrid[j + i * gstride]) / Math.Abs(theory);
                    avgerr += err;
                    maxerr  = Math.Max(maxerr, err);
                }
            }
            avgerr /= dimX * dimY;

            long elapsedTime = stopwatch.ElapsedMilliseconds;

            Console.WriteLine("average error = {0}%\nmaximal error = {1}%\nelapsed time: {2}ms\niterations per second: {3}",
                              avgerr * 100, maxerr * 100, elapsedTime, (double)N / (double)elapsedTime * 1000.0d);

            return(elapsedTime);
        }
 public static CommandQueue CreateCommandQueue(Context context, Device device, out ErrorCode error)
 {
     return(Cl.CreateCommandQueue(context, device, CommandQueueProperties.None, out error));
 }
        public void Prototype()
        {
            ErrorCode error;
            Device    device = (from d in
                                Cl.GetDeviceIDs(
                                    (from platform in Cl.GetPlatformIDs(out error)
                                     where Cl.GetPlatformInfo(platform, PlatformInfo.Name, out error).ToString() == "AMD Accelerated Parallel Processing" // Use "NVIDIA CUDA" if you don't have amd
                                     select platform).First(), DeviceType.Gpu, out error)
                                select d).First();

            Context context = Cl.CreateContext(null, 1, new[] { device }, null, IntPtr.Zero, out error);

            string source = System.IO.File.ReadAllText("kernels.cl");

            int    chunkHalfLength  = 300000000;
            int    worldSeed        = 420;
            int    workItems        = 3000;
            int    outputAllocation = 100;
            IntPtr outputSize       = new IntPtr(workItems * outputAllocation);

            var xr = new int[outputSize.ToInt32()];
            var zr = new int[outputSize.ToInt32()];
            var sc = new int[outputSize.ToInt32()];


            using (Program program = Cl.CreateProgramWithSource(context, 1, new[] { source }, null, out error))
            {
                Assert.AreEqual(error, ErrorCode.Success);
                error = Cl.BuildProgram(program, 1, new[] { device }, "", null, IntPtr.Zero);
                Assert.AreEqual(error, ErrorCode.Success);
                var buildInfo = Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>();
                Assert.AreEqual(buildInfo, BuildStatus.Success);
                Assert.AreEqual(error, ErrorCode.Success);

                Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error);
                Assert.AreEqual(error, ErrorCode.Success);
                Kernel kernel = kernels[0];

                IMem hDeviceMemXr = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(sizeof(int) * outputSize.ToInt32()), IntPtr.Zero, out error);
                Assert.AreEqual(ErrorCode.Success, error);
                IMem hDeviceMemZr = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(sizeof(int) * outputSize.ToInt32()), IntPtr.Zero, out error);
                Assert.AreEqual(ErrorCode.Success, error);
                IMem hDeviceMemSc = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(sizeof(int) * outputSize.ToInt32()), IntPtr.Zero, out error);
                Assert.AreEqual(ErrorCode.Success, error);


                CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, (CommandQueueProperties)0, out error);

                int intPtrSize = Marshal.SizeOf(typeof(IntPtr));
                int intSize    = Marshal.SizeOf(typeof(int));

                error = Cl.SetKernelArg(kernel, 0, new IntPtr(intPtrSize), hDeviceMemXr);
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.SetKernelArg(kernel, 1, new IntPtr(intPtrSize), hDeviceMemZr);
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.SetKernelArg(kernel, 2, new IntPtr(intPtrSize), hDeviceMemSc);
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.SetKernelArg(kernel, 3, new IntPtr(intSize), new IntPtr(chunkHalfLength));
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.SetKernelArg(kernel, 4, new IntPtr(intSize), new IntPtr(worldSeed));
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.SetKernelArg(kernel, 5, new IntPtr(intSize), new IntPtr(workItems));
                Assert.AreEqual(ErrorCode.Success, error);
                error = Cl.SetKernelArg(kernel, 6, new IntPtr(intSize), new IntPtr(outputAllocation));
                Assert.AreEqual(ErrorCode.Success, error);

                error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemXr, Bool.True, IntPtr.Zero,
                                              new IntPtr(outputSize.ToInt32() * sizeof(float)),
                                              xr, 0, null, out Event clevent);
                Assert.AreEqual(ErrorCode.Success, error);

                error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new IntPtr[] { new IntPtr(workItems) }, null, 0, null, out clevent);

                error = Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemXr, Bool.True, 0, xr.Length, xr, 0, null, out clevent);
                Assert.AreEqual(ErrorCode.Success, error, error.ToString());

                Cl.Finish(cmdQueue);
            }
        }
        public void TestSlimeFinder()
        {
            const int squareLength = 1024;
            int       globalSize   = squareLength * squareLength;
            var       candidates   = new int[globalSize];

            ErrorCode error;
            Device    device = (from d in
                                Cl.GetDeviceIDs(
                                    (from platform in Cl.GetPlatformIDs(out error)
                                     where Cl.GetPlatformInfo(platform, PlatformInfo.Name, out error).ToString() == "AMD Accelerated Parallel Processing" // Use "NVIDIA CUDA" if you don't have amd
                                     select platform).First(), DeviceType.Gpu, out error)
                                select d).First();

            Context context = Cl.CreateContext(null, 1, new[] { device }, null, IntPtr.Zero, out error);

            string source = System.IO.File.ReadAllText("kernels.cl");

            using Program program = Cl.CreateProgramWithSource(context, 1, new[] { source }, null, out error);

            error = Cl.BuildProgram(program, 1, new[] { device }, string.Empty, null, IntPtr.Zero);
            InfoBuffer buildStatus = Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out error);

            Assert.AreEqual(buildStatus.CastTo <BuildStatus>(), BuildStatus.Success);
            Assert.AreEqual(error, ErrorCode.Success);

            Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error);
            Kernel   kernel  = kernels[0];

            Assert.AreEqual(error, ErrorCode.Success);

            CommandQueue queue = Cl.CreateCommandQueue(context, device, CommandQueueProperties.None, out error);

            Assert.AreEqual(error, ErrorCode.Success);

            IMem dataOut = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(globalSize * sizeof(int)), out error);

            Assert.AreEqual(error, ErrorCode.Success);

            var intSizePtr = new IntPtr(Marshal.SizeOf(typeof(int)));

            error  = Cl.SetKernelArg(kernel, 0, intSizePtr, new IntPtr(0));
            error |= Cl.SetKernelArg(kernel, 1, intSizePtr, new IntPtr(0));
            error |= Cl.SetKernelArg(kernel, 2, new IntPtr(Marshal.SizeOf(typeof(IntPtr))), dataOut);
            error |= Cl.SetKernelArg(kernel, 3, intSizePtr, new IntPtr(420));
            error |= Cl.SetKernelArg(kernel, 4, intSizePtr, new IntPtr(globalSize));
            Assert.AreEqual(error, ErrorCode.Success);

            int local_size  = 256;
            int global_size = (int)Math.Ceiling(globalSize / (float)local_size) * local_size;
            var stopW       = new Stopwatch();

            stopW.Start();
            error = Cl.EnqueueNDRangeKernel(queue, kernel, 1, null, new IntPtr[] { new IntPtr(global_size) }, new IntPtr[] { new IntPtr(local_size) }, 0, null, out Event clevent);
            Assert.AreEqual(error, ErrorCode.Success);

            Cl.Finish(queue);
            stopW.Stop();


            Cl.EnqueueReadBuffer(queue, dataOut, Bool.True, IntPtr.Zero, (IntPtr)(globalSize * sizeof(int)), candidates, 0, null, out clevent);
            candidates.ForEach(c =>
            {
                if (c > 50)
                {
                    Console.Write($"{c},");
                }
            });

            Console.WriteLine($"\n{stopW.ElapsedMilliseconds} ms");


            error  = Cl.SetKernelArg(kernel, 0, intSizePtr, new IntPtr(16383));
            error |= Cl.SetKernelArg(kernel, 1, intSizePtr, new IntPtr(16383));

            stopW.Start();
            error = Cl.EnqueueNDRangeKernel(queue, kernel, 1, null, new IntPtr[] { new IntPtr(global_size) }, new IntPtr[] { new IntPtr(local_size) }, 0, null, out clevent);
            Assert.AreEqual(error, ErrorCode.Success);

            Cl.Finish(queue);
            stopW.Stop();


            Cl.EnqueueReadBuffer(queue, dataOut, Bool.True, IntPtr.Zero, (IntPtr)(globalSize * sizeof(int)), candidates, 0, null, out clevent);
            candidates.ForEach(c =>
            {
                if (c > 50)
                {
                    Console.Write($"{c},");
                }
            });

            Console.WriteLine($"\n{stopW.ElapsedMilliseconds} ms");

            Cl.ReleaseKernel(kernel);
            Cl.ReleaseMemObject(dataOut);
            Cl.ReleaseCommandQueue(queue);
            Cl.ReleaseProgram(program);
            Cl.ReleaseContext(context);
        }
        public void SquareArray()
        {
            // Adapted from
            //https://github.com/rsnemmen/OpenCL-examples/blob/master/square_array/square.cl
            int array_size = 100000;
            var bytes      = (IntPtr)(array_size * sizeof(float));

            var hdata   = new float[array_size];
            var houtput = new float[array_size];

            for (int i = 0; i < array_size; i++)
            {
                hdata[i] = 1.0f * i;
            }

            ErrorCode error;
            Device    device = (from d in
                                Cl.GetDeviceIDs(
                                    (from platform in Cl.GetPlatformIDs(out error)
                                     where Cl.GetPlatformInfo(platform, PlatformInfo.Name, out error).ToString() == "AMD Accelerated Parallel Processing" // Use "NVIDIA CUDA" if you don't have amd
                                     select platform).First(), DeviceType.Gpu, out error)
                                select d).First();

            Context context = Cl.CreateContext(null, 1, new[] { device }, null, IntPtr.Zero, out error);

            string source = System.IO.File.ReadAllText("squared.cl");

            using (Program program = Cl.CreateProgramWithSource(context, 1, new[] { source }, null, out error))
            {
                Assert.AreEqual(error, ErrorCode.Success);
                error = Cl.BuildProgram(program, 1, new[] { device }, string.Empty, null, IntPtr.Zero);
                Assert.AreEqual(ErrorCode.Success, error);
                Assert.AreEqual(Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>(), BuildStatus.Success);

                Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error);
                Kernel   kernel  = kernels[0];

                CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, (CommandQueueProperties)0, out error);

                IMem ddata   = Cl.CreateBuffer(context, MemFlags.ReadOnly, bytes, null, out error);
                IMem doutput = Cl.CreateBuffer(context, MemFlags.WriteOnly, bytes, null, out error);

                error = Cl.EnqueueWriteBuffer(cmdQueue, ddata, Bool.True, (IntPtr)0, bytes, hdata, 0, null, out Event clevent);
                Assert.AreEqual(ErrorCode.Success, error);

                error  = Cl.SetKernelArg(kernel, 0, new IntPtr(Marshal.SizeOf(typeof(IntPtr))), ddata);
                error |= Cl.SetKernelArg(kernel, 1, new IntPtr(Marshal.SizeOf(typeof(IntPtr))), doutput);
                error |= Cl.SetKernelArg(kernel, 2, new IntPtr(Marshal.SizeOf(typeof(int))), new IntPtr(array_size));
                Assert.AreEqual(error, ErrorCode.Success);

                int local_size  = 256;
                var infoBufferr = new InfoBuffer();
                error = Cl.GetKernelWorkGroupInfo(kernel, device, KernelWorkGroupInfo.WorkGroupSize, new IntPtr(sizeof(int)), new InfoBuffer(), out IntPtr localSize);
                var x           = localSize.ToInt32();//Why is it giving me 8??? Vega 56 has 256 work group size
                int global_size = (int)Math.Ceiling(array_size / (float)local_size) * local_size;

                error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new IntPtr[] { new IntPtr(global_size) }, new IntPtr[] { new IntPtr(local_size) }, 0, null, out clevent);
                Cl.Finish(cmdQueue);
                Cl.EnqueueReadBuffer(cmdQueue, doutput, Bool.True, IntPtr.Zero, bytes, houtput, 0, null, out clevent);
                houtput.ForEach(o => Console.Write($"{o}, "));


                Cl.ReleaseKernel(kernel);
                Cl.ReleaseMemObject(ddata);
                Cl.ReleaseMemObject(doutput);
                Cl.ReleaseCommandQueue(cmdQueue);
                Cl.ReleaseProgram(program);
                Cl.ReleaseContext(context);
            }
        }
示例#15
0
        public HTTPResponse GetResponse(HTTPRequest request)
        {
            HTTPResponse  response = new HTTPResponse(200);
            StringBuilder sb       = new StringBuilder();
            ErrorCode     error;

            if (!_isInit)
            {
                init();
                _isInit = true;
            }

            if (request.Method == HTTPRequest.METHOD_GET)
            {
                sb.Append("<html><body>");
                sb.Append(GenUploadForm());
                sb.Append("</body></html>");
                response.Body = Encoding.UTF8.GetBytes(sb.ToString());
                return(response);
            }
            else if (request.Method == HTTPRequest.METHOD_POST)
            {
                sb.Append(request.Body);
                response.Body = Encoding.UTF8.GetBytes(sb.ToString());
                string programPath = System.Environment.CurrentDirectory + "/Kernel.cl";
                if (!System.IO.File.Exists(programPath))
                {
                    Console.WriteLine("Program doesn't exist at path " + programPath);
                    return(new HTTPResponse(404));
                }

                sb.Append("<html><body>");
                string programSource = System.IO.File.ReadAllText(programPath);
                using (OpenCL.Net.Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) {
                    LogError(error, "Cl.CreateProgramWithSource");
                    error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero);
                    LogError(error, "Cl.BuildProgram");
                    if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <OpenCL.Net.BuildStatus>()
                        != BuildStatus.Success)
                    {
                        LogError(error, "Cl.GetProgramBuildInfo");
                        Console.WriteLine("Cl.GetProgramBuildInfo != Success");
                        Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error));
                        return(new HTTPResponse(404));
                    }
                    Kernel kernel = Cl.CreateKernel(program, "answer", out error);
                    LogError(error, "Cl.CreateKernel");

                    Random rand   = new Random();
                    int[]  input  = (from i in Enumerable.Range(0, 100) select(int) rand.Next()).ToArray();
                    int[]  output = new int[100];

                    var buffIn     = _context.CreateBuffer(input, MemFlags.ReadOnly);
                    var buffOut    = _context.CreateBuffer(output, MemFlags.WriteOnly);
                    int IntPtrSize = Marshal.SizeOf(typeof(IntPtr));
                    error  = Cl.SetKernelArg(kernel, 0, (IntPtr)IntPtrSize, buffIn);
                    error |= Cl.SetKernelArg(kernel, 1, (IntPtr)IntPtrSize, buffOut);
                    LogError(error, "Cl.SetKernelArg");
                    CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error);
                    LogError(error, "Cl.CreateCommandQueue");
                    Event clevent;
                    error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, new[] { (IntPtr)100, (IntPtr)1 }, null, 0, null, out clevent);
                    LogError(error, "Cl.EnqueueNDRangeKernel");
                    error = Cl.Finish(cmdQueue);
                    LogError(error, "Cl.Finih");
                    error = Cl.EnqueueReadBuffer(cmdQueue, buffOut, OpenCL.Net.Bool.True, 0, 100, output, 0, null, out clevent);
                    LogError(error, "Cl.EnqueueReadBuffer");
                    error = Cl.Finish(cmdQueue);
                    LogError(error, "Cl.Finih");


                    Cl.ReleaseKernel(kernel);
                    Cl.ReleaseCommandQueue(cmdQueue);
                    Cl.ReleaseMemObject(buffIn);
                    Cl.ReleaseMemObject(buffOut);
                    sb.Append("<pre>");
                    for (int i = 0; i != 100; i++)
                    {
                        sb.Append(input[i] + " % 42 = " + output[i] + "<br />");
                    }
                    sb.Append("</pre>");
                }
                sb.Append("</body></html>");
                response.Body = Encoding.UTF8.GetBytes(sb.ToString());
                return(response);
            }
            return(new HTTPResponse(501));
        }
示例#16
0
        public void VecAdd()
        {
            if (!prepared)
            {
                Prepare(this.BuildIR().InlineIR());
                prepared = true;
            }

            // create kernel
            Cl.Kernel kernel = Cl.CreateKernel(program, "VecAdd", out error);
            clSafeCall(error);

            // create command queue
            Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error);
            clSafeCall(error);

            int length = 1 << 10;

            // allocate host vectors
            float[] A = new float[length];
            float[] B = new float[length];
            float[] C = new float[length];

            // initialize host memory
            Random rand = new Random();

            for (int i = 0; i < length; i++)
            {
                A[i] = (float)rand.Next() / short.MaxValue;
                B[i] = (float)rand.Next() / short.MaxValue;
            }

            // allocate device vectors
            Cl.Mem hDeviceMemA = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly,
                                                 (IntPtr)(sizeof(float) * length), A, out error);
            clSafeCall(error);
            Cl.Mem hDeviceMemB = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly,
                                                 (IntPtr)(sizeof(float) * length), B, out error);
            clSafeCall(error);
            Cl.Mem hDeviceMemC = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly,
                                                 (IntPtr)(sizeof(float) * length), IntPtr.Zero, out error);
            clSafeCall(error);

            // setup kernel arguments
            clSafeCall(Cl.SetKernelArg(kernel, 0, hDeviceMemA));
            clSafeCall(Cl.SetKernelArg(kernel, 1, hDeviceMemB));
            clSafeCall(Cl.SetKernelArg(kernel, 2, hDeviceMemC));
            clSafeCall(Cl.SetKernelArg(kernel, 3, length));

            // execute kernel
            clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new[] { (IntPtr)length }, new[] { (IntPtr)256 },
                                               0, null, out clevent));

            // copy results from device back to host
            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemC, Cl.Bool.True, IntPtr.Zero,
                                            (IntPtr)(sizeof(float) * length), C, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            for (int i = 0; i < length; i++)
            {
                float sum = A[i] + B[i];
                float err = Math.Abs((sum - C[i]) / sum);
                Assert.That(err, Is.LessThanOrEqualTo(1E-3F));
            }
        }
示例#17
0
        /* Broken at the moment. */
        public void GetStatGPU(string file)
        {
            var stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            stopwatch.Restart();
            ErrorCode err;


            using (OpenCL.Net.Program program = Cl.CreateProgramWithSource(clInfo._context, 1, new[] { clInfo.KernelSrc }, null, out err))
            {
                clInfo.CheckErr(err, "Cl.CreateProgramWithSource");

                //Compile Kernels & check errors.
                err = Cl.BuildProgram(program, 1, new[] { clInfo._device }, string.Empty, null, IntPtr.Zero);
                clInfo.CheckErr(err, "Cl.BuildProgram");
                if (Cl.GetProgramBuildInfo(program, clInfo._device, ProgramBuildInfo.Status, out err).CastTo <BuildStatus>() != BuildStatus.Success)
                {
                    clInfo.CheckErr(err, "Cl.GetProgramBuildInfo");
                    Console.WriteLine("Cl.GetProgramBuildInfo != Success");
                    Console.WriteLine(Cl.GetProgramBuildInfo(program, clInfo._device, ProgramBuildInfo.Log, out err));
                }

                //Specify the specific kernel for use
                Kernel kernel = Cl.CreateKernel(program, "satAvg", out err);
                clInfo.CheckErr(err, "Cl.CreateKernel");

                int intPtrSize = 0;
                intPtrSize = Marshal.SizeOf(typeof(IntPtr));

                IMem image2DBuffer;
                OpenCL.Net.ImageFormat imageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8);
                int imageWidth, imageHeight, imageBytesSize, imageStride;

                using (FileStream imgStream = new FileStream(file, FileMode.Open))
                {
                    Image image = Image.FromStream(imgStream);

                    if (image == null)
                    {
                        Console.Error.WriteLine($"failed to open file {file}");
                        return;
                    }
                    imageWidth  = image.Width;
                    imageHeight = image.Height;

                    //Create a bitmap from the file with the correct channel settings.
                    Bitmap     inputBitmap = new Bitmap(image);
                    BitmapData bitmapDat   = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height),
                                                                  ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

                    imageStride    = bitmapDat.Stride;
                    imageBytesSize = imageStride * bitmapDat.Height;

                    byte[] inputByteArray = new byte[imageBytesSize];
                    Marshal.Copy(bitmapDat.Scan0, inputByteArray, 0, imageBytesSize);

                    //Create & populate memory buffer for use in Kernel
                    image2DBuffer = Cl.CreateImage2D(clInfo._context,
                                                     MemFlags.CopyHostPtr | MemFlags.ReadOnly, imageFormat,
                                                     (IntPtr)inputBitmap.Width,
                                                     (IntPtr)inputBitmap.Height,
                                                     (IntPtr)0, inputByteArray, out err);

                    clInfo.CheckErr(err, "Cl.CreateImage2D output");
                }
                //Create an output buffer for the average saturation of the image.
                float saturation = 0;
                IMem  sat = Cl.CreateBuffer(clInfo._context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, (IntPtr)intPtrSize, (object)saturation, out err);
                clInfo.CheckErr(err, "Cl.CreateBuffer saturation");

                //Passing buffers to the CL kernel
                err = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, image2DBuffer);
                //TODO: Figure out how to pass a float to the kernel
                //err |= Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, sat );
                clInfo.CheckErr(err, "Cl.SetKernelArg");

                //Create & queue commands
                CommandQueue cmdQueue = Cl.CreateCommandQueue(clInfo._context, clInfo._device, CommandQueueProperties.None, out err);
                clInfo.CheckErr(err, "Cl.CreateCommandQueue");

                Event @event;

                //Transfer image data to kernel buffers
                IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };
                IntPtr[] regionPtr = new IntPtr[] { (IntPtr)imageWidth, (IntPtr)imageHeight, (IntPtr)1 };
                IntPtr[] workGroupPtr = new IntPtr[] { (IntPtr)imageWidth, (IntPtr)imageHeight, (IntPtr)1 };

                err = Cl.EnqueueReadImage(cmdQueue, image2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, null, 0, null, out @event);
                clInfo.CheckErr(err, "Cl.EnqueueReadImage");

                //Execute the kerenl
                err = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupPtr, null, 0, null, out @event);
                clInfo.CheckErr(err, "Cl.EnqueueNDRangeKernel");

                err = Cl.Finish(cmdQueue);
                clInfo.CheckErr(err, "Cl.Finish");

                Cl.ReleaseKernel(kernel);
                Cl.ReleaseCommandQueue(cmdQueue);

                Cl.ReleaseMemObject(image2DBuffer);
            }
            Console.WriteLine(stopwatch.Elapsed);
            stopwatch.Stop();
        }
示例#18
0
        public void PoissonJacobi()
        {
            if (!prepared)
            {
                Prepare(this.BuildIR().InlineIR());
                prepared = true;
            }

            // create kernel
            Cl.Kernel kernel = Cl.CreateKernel(program, "PoissonJacobi", out error);
            clSafeCall(error);

            // create command queue
            Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error);
            clSafeCall(error);

            // initialize host memory

            uint dimX = 162;
            uint dimY = 122;
            uint N    = 15000;

            float x0 = (float)(-0.25 * Math.PI);
            float y0 = (float)(-0.25 * Math.PI);

            float hx = 2.0f * Math.Abs(x0) / dimX;
            float hy = 2.0f * Math.Abs(y0) / dimY;

            float[] hData = new float[dimX * dimY];

            uint stride = dimX;

            //boundary values

            for (uint i = 1; i < dimY - 1; i++)
            {
                uint  y_idx = i * stride;
                float y_val = y0 + i * hy;
                hData[y_idx]            = u(x0, y_val);
                hData[y_idx + dimX - 1] = u(x0 + (dimX - 1) * hx, y_val);
            }

            for (uint j = 1; j < dimX - 1; j++)
            {
                float x_val = x0 + j * hx;
                hData[j] = u(x_val, y0);
                hData[j + (dimY - 1) * stride] = u(x_val, y0 + (dimY - 1) * hy);
            }

            // allocate device vectors
            Cl.Mem input = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadWrite,
                                           (IntPtr)(sizeof(float) * hData.Length), hData, out error);
            clSafeCall(error);
            Cl.Mem output = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadWrite,
                                            (IntPtr)(sizeof(float) * hData.Length), hData, out error);
            clSafeCall(error);

            float a1 = 2 * hy / hx;
            float a2 = 2 * hx / hy;
            float a3 = a1;
            float a4 = a2;
            float a  = a1 + a2 + a3 + a4;

            // setup kernel arguments
            clSafeCall(Cl.SetKernelArg(kernel, 2, (AREA_SIZE_Y + 2) * (AREA_SIZE_X + 2) * sizeof(float), null));
            clSafeCall(Cl.SetKernelArg(kernel, 3, dimX));
            clSafeCall(Cl.SetKernelArg(kernel, 4, dimY));
            clSafeCall(Cl.SetKernelArg(kernel, 5, stride));
            clSafeCall(Cl.SetKernelArg(kernel, 6, a1));
            clSafeCall(Cl.SetKernelArg(kernel, 7, a2));
            clSafeCall(Cl.SetKernelArg(kernel, 8, a3));
            clSafeCall(Cl.SetKernelArg(kernel, 9, a4));
            clSafeCall(Cl.SetKernelArg(kernel, 10, a));
            clSafeCall(Cl.SetKernelArg(kernel, 11, hx));
            clSafeCall(Cl.SetKernelArg(kernel, 12, hy));
            clSafeCall(Cl.SetKernelArg(kernel, 13, x0));
            clSafeCall(Cl.SetKernelArg(kernel, 14, y0));

            IntPtr[] lo = { (IntPtr)16, (IntPtr)16 };
            IntPtr[] gl = { (IntPtr)((dimX - 2 + AREA_SIZE_X - 1) / AREA_SIZE_X * 16),
                            (IntPtr)((dimY - 2 + AREA_SIZE_Y - 1) / AREA_SIZE_Y * 16) };

            Cl.Mem curIn  = input;
            Cl.Mem curOut = output;

            // execute kernel (and perform data transfering silently)
            clSafeCall(Cl.SetKernelArg(kernel, 0, curIn));
            clSafeCall(Cl.SetKernelArg(kernel, 1, curOut));
            clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            for (uint idx = 1; idx < N; idx++)
            {
                // swap buffers
                Cl.Mem temp = curIn;
                curIn  = curOut;
                curOut = temp;

                // execute kernel
                clSafeCall(Cl.SetKernelArg(kernel, 0, curIn));
                clSafeCall(Cl.SetKernelArg(kernel, 1, curOut));
                clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent));
            }

            clSafeCall(Cl.Finish(cmdQueue));

            stopwatch.Stop();

            // copy results from device back to host
            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, curOut, Cl.Bool.True, IntPtr.Zero,
                                            (IntPtr)(sizeof(float) * hData.Length), hData, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            float avgerr = 0, maxerr = 0;

            for (uint i = 1; i < dimY - 1; i++)
            {
                for (uint j = 1; j < dimX - 1; j++)
                {
                    float theory = u(x0 + j * hx, y0 + i * hy);
                    float err    = Math.Abs(theory - hData[j + i * stride]) / Math.Abs(theory);
                    avgerr += err;
                    maxerr  = Math.Max(maxerr, err);
                }
            }
            avgerr /= dimX * dimY;

            long   elapsedTime          = stopwatch.ElapsedMilliseconds;
            double dataSizePerIteration = dimX * dimY * 2 * sizeof(float);
            double dataSizeTotal        = dataSizePerIteration * N;
            double elapsedSeconds       = elapsedTime * 0.001;
            double gigabyteFactor       = 1 << 30;
            double bandwidth            = dataSizeTotal / (gigabyteFactor * elapsedSeconds);

            Console.WriteLine("avgerr = {0} maxerr = {1} elapsedTime = {2} ms bandwidth = {3} GB/s",
                              avgerr, maxerr, elapsedTime, bandwidth);

            Assert.That(maxerr, Is.LessThanOrEqualTo(5E-2F));
            Assert.That(avgerr, Is.LessThanOrEqualTo(1E-2F));
        }
示例#19
0
        public static void SetupSpace(int deviceID)
        {
            //int deviceID; // will be asked to user

            List <Device> devicesList   = new List <Device>();
            List <string> deviceNames   = new List <string>();
            List <string> platformNames = new List <string>();
            int           nDevices      = 0;


            // Get list of available platforms
            Console.WriteLine("\nSearching for OpenCL-capable platforms... ");
            Platform[] platforms = Cl.GetPlatformIDs(out ClError);
            CheckErr(ClError, "CL.Setup: Cl.GetPlatformIDs");
            Console.WriteLine("{0} platforms found.\n", platforms.Length);

            foreach (Platform platform in platforms)
            {
                // Get platform info
                string platformName = Cl.GetPlatformInfo(platform, PlatformInfo.Name, out ClError).ToString();
                Console.WriteLine("Platform: " + platformName);
                CheckErr(ClError, "CL.Setup: Cl.GetPlatformInfo");

                // Get all available devices within this platform and list them on screen
                foreach (Device dev in Cl.GetDeviceIDs(platform, DeviceType.All, out ClError))
                {
                    CheckErr(ClError, "CL.Setup: Cl.GetDeviceIDs");
                    string deviceName = Cl.GetDeviceInfo(dev, DeviceInfo.Name, out ClError).ToString();
                    CheckErr(ClError, "CL.Setup: Cl.GetDeviceInfo");
                    Console.WriteLine("Device {0}: {1}", nDevices, deviceName);

                    devicesList.Add(dev);
                    deviceNames.Add(deviceName);
                    platformNames.Add(platformName);
                    nDevices++;
                }
                Console.WriteLine();
            }

            if (nDevices == 0)
            {
                throw new PlatformNotSupportedException("No OpenCL-capable platform and/or devices were found on this system.");
            }

            //Console.Write("Enter ID of device to use: ");
            //deviceID = int.Parse(Console.ReadLine());

            // Select device according to user's choice
            device = devicesList[deviceID];
            Console.WriteLine("\nUsing device {0}", deviceNames[deviceID]);

            // Create OpenCL context
            context = Cl.CreateContext(null, 1, new[] { device }, ContextNotify, IntPtr.Zero, out ClError);    //Second parameter is amount of devices
            CheckErr(ClError, "CL.Setup: Cl.CreateContext");

            // Create OpenCL command queue
            queue = Cl.CreateCommandQueue(context, device, (CommandQueueProperties)0, out ClError);
            CheckErr(ClError, "CL.Setup: Cl.CreateCommandQueue");

            // Extract some device info
            maxWorkItemSizes = Cl.GetDeviceInfo(device, DeviceInfo.MaxWorkItemSizes, out ClError).CastToEnumerable <int>(new int[] { 0, 1, 2 }).ToList();
            Console.WriteLine("Max work item sizes: {0}, {1}, {2}", maxWorkItemSizes[0], maxWorkItemSizes[1], maxWorkItemSizes[2]);

            maxWorkGroupSize = Cl.GetDeviceInfo(device, DeviceInfo.MaxWorkGroupSize, out ClError).CastTo <int>();
            Console.WriteLine("Max work group size: {0}", maxWorkGroupSize);

            maxComputeUnits = Cl.GetDeviceInfo(device, DeviceInfo.MaxComputeUnits, out ClError).CastTo <int>();
            Console.WriteLine("Max compute units: {0}", maxComputeUnits);
        }
示例#20
0
        public void ImagingTest(string inputImagePath, string outputImagePath)
        {
            ErrorCode error;

            //Load and compile kernel source code.
            string programPath = System.Environment.CurrentDirectory + "/../../imagingtest.cl";  //The path to the source file may vary

            if (!System.IO.File.Exists(programPath))
            {
                Console.WriteLine("Program doesn't exist at path " + programPath);
                return;
            }

            string programSource = System.IO.File.ReadAllText(programPath);

            using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error))
            {
                CheckErr(error, "Cl.CreateProgramWithSource");

                //Compile kernel source
                error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero);
                CheckErr(error, "Cl.BuildProgram");

                //Check for any compilation errors
                if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>()
                    != BuildStatus.Success && 1 == 0)
                {
                    CheckErr(error, "Cl.GetProgramBuildInfo");
                    Console.WriteLine("Cl.GetProgramBuildInfo != Success");
                    Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error));
                    return;
                }

                //Create the required kernel (entry function)
                Kernel kernel = Cl.CreateKernel(program, "imagingTest", out error);
                CheckErr(error, "Cl.CreateKernel");

                int intPtrSize = 0;
                intPtrSize = Marshal.SizeOf(typeof(IntPtr));

                //Image's RGBA data converted to an unmanaged[] array
                byte[] inputByteArray;
                //OpenCL memory buffer that will keep our image's byte[] data.
                Mem inputImage2DBuffer;

                OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8);

                int inputImgWidth, inputImgHeight;

                int inputImgBytesSize;

                int inputImgStride;

                //Try loading the input image
                using (FileStream imageFileStream = new FileStream(inputImagePath, FileMode.Open))
                {
                    System.Drawing.Image inputImage = System.Drawing.Image.FromStream(imageFileStream);

                    if (inputImage == null)
                    {
                        Console.WriteLine("Unable to load input image");
                        return;
                    }

                    inputImgWidth  = inputImage.Width;
                    inputImgHeight = inputImage.Height;

                    System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(inputImage);

                    //Get raw pixel data of the bitmap
                    //The format should match the format of clImageFormat
                    BitmapData bitmapData = bmpImage.LockBits(new Rectangle(0, 0, bmpImage.Width, bmpImage.Height),
                                                              ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);//inputImage.PixelFormat);

                    inputImgStride    = bitmapData.Stride;
                    inputImgBytesSize = bitmapData.Stride * bitmapData.Height;

                    //Copy the raw bitmap data to an unmanaged byte[] array
                    inputByteArray = new byte[inputImgBytesSize];
                    Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, inputImgBytesSize);

                    //Allocate OpenCL image memory buffer
                    inputImage2DBuffer = (OpenCL.Net.Mem)OpenCL.Net.Cl.CreateImage2D(_context,
                                                                                     OpenCL.Net.MemFlags.CopyHostPtr | OpenCL.Net.MemFlags.ReadOnly, clImageFormat,
                                                                                     (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height,
                                                                                     (IntPtr)0, inputByteArray, out error);
                    CheckErr(error, "Cl.CreateImage2D input");
                }

                //Unmanaged output image's raw RGBA byte[] array
                byte[] outputByteArray = new byte[inputImgBytesSize];

                //Allocate OpenCL image memory buffer
                OpenCL.Net.Mem outputImage2DBuffer = (OpenCL.Net.Mem)OpenCL.Net.Cl.CreateImage2D(_context, OpenCL.Net.MemFlags.CopyHostPtr | OpenCL.Net.MemFlags.WriteOnly, clImageFormat,
                                                                                                 (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)0, outputByteArray, out error);

                CheckErr(error, "Cl.CreateImage2D output");

                //Pass the memory buffers to our kernel function
                error  = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, inputImage2DBuffer);
                error |= Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, outputImage2DBuffer);
                CheckErr(error, "Cl.SetKernelArg");

                //Create a command queue, where all of the commands for execution will be added
                CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error);
                CheckErr(error, "Cl.CreateCommandQueue");

                OpenCL.Net.Event clevent;

                //Copy input image from the host to the GPU.
                IntPtr[] originPtr        = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };                          //x, y, z
                IntPtr[] regionPtr        = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; //x, y, z
                IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 };
                error = Cl.EnqueueWriteImage(cmdQueue, inputImage2DBuffer, OpenCL.Net.Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, inputByteArray, 0, null, out clevent);
                CheckErr(error, "Cl.EnqueueWriteImage");

                //Execute our kernel (OpenCL code)
                //                  CommandQueue q =  new OpenCL.Net.CommandQueue();



                //enqueue nd range kernel

                // error = cmdQueue.EnqueueKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent);
                //   OpenCL.Net.Cl.EnqueueNDRangeKernel(
                OpenCL.Net.Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent);

                CheckErr(error, "Cl.EnqueueNDRangeKernel");

                //Wait for completion of all calculations on the GPU.
                error = Cl.Finish(cmdQueue);
                CheckErr(error, "Cl.Finish");

                //Read the processed image from GPU to raw RGBA data byte[] array
                error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, OpenCL.Net.Bool.True, originPtr, regionPtr,
                                            (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent);
                CheckErr(error, "Cl.clEnqueueReadImage");

                //Clean up memory
                Cl.ReleaseKernel(kernel);
                Cl.ReleaseCommandQueue(cmdQueue);

                Cl.ReleaseMemObject(inputImage2DBuffer);
                Cl.ReleaseMemObject(outputImage2DBuffer);

                //Get a pointer to our unmanaged output byte[] array
                GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned);
                IntPtr   outputBmpPointer  = pinnedOutputArray.AddrOfPinnedObject();

                //Create a new bitmap with processed data and save it to a file.
                Bitmap outputBitmap = new Bitmap(inputImgWidth, inputImgHeight, inputImgStride, PixelFormat.Format32bppArgb, outputBmpPointer);

                outputBitmap.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png);

                pinnedOutputArray.Free();
            }
        }
示例#21
0
        public void SmallTypes(Cl.Program program)
        {
            // create kernel
            Cl.Kernel kernel = Cl.CreateKernel(program, "SmallTypes", out error);
            clSafeCall(error);

            // create command queue
            Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error);
            clSafeCall(error);

            // allocate host vectors
            short[] hres1 = { 0 };
            short[] hres2 = { 0 };

            // allocate device vectors
            Cl.Mem dres1 = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly,
                                           (IntPtr)(sizeof(short) * hres1.Length), IntPtr.Zero, out error);
            clSafeCall(error);
            Cl.Mem dres2 = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly,
                                           (IntPtr)(sizeof(short) * hres2.Length), IntPtr.Zero, out error);
            clSafeCall(error);

            // setup kernel arguments
            clSafeCall(Cl.SetKernelArg(kernel, 0, dres1));
            clSafeCall(Cl.SetKernelArg(kernel, 1, dres2));
            clSafeCall(Cl.SetKernelArg(kernel, 2, (byte)1));
            clSafeCall(Cl.SetKernelArg(kernel, 3, (sbyte)-20));
            clSafeCall(Cl.SetKernelArg(kernel, 4, (ushort)30));
            clSafeCall(Cl.SetKernelArg(kernel, 5, (short)-4));
            clSafeCall(Cl.SetKernelArg(kernel, 6, true));

            // execute kernel
            clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new[] { (IntPtr)1 }, null, 0, null, out clevent));

            // copy results from device back to host
            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dres1, Cl.Bool.True, IntPtr.Zero,
                                            (IntPtr)(sizeof(short) * hres1.Length), hres1, 0, null, out clevent));
            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dres2, Cl.Bool.True, IntPtr.Zero,
                                            (IntPtr)(sizeof(short) * hres1.Length), hres2, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            Assert.AreEqual(7, hres1[0]);
            Assert.AreEqual(-7, hres2[0]);

            // setup kernel arguments
            clSafeCall(Cl.SetKernelArg(kernel, 6, false));

            // execute kernel
            clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new[] { (IntPtr)1 }, null, 0, null, out clevent));

            // copy results from device back to host
            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dres1, Cl.Bool.True, IntPtr.Zero,
                                            (IntPtr)(sizeof(short) * hres1.Length), hres1, 0, null, out clevent));
            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dres2, Cl.Bool.True, IntPtr.Zero,
                                            (IntPtr)(sizeof(short) * hres1.Length), hres2, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            Assert.AreEqual(-7, hres1[0]);
            Assert.AreEqual(7, hres2[0]);
        }
示例#22
0
        public HTTPResponse GetResponse(HTTPRequest request)
        {
            HTTPResponse  response = new HTTPResponse(200);
            StringBuilder sb       = new StringBuilder();
            ErrorCode     error;

            if (!_isInit)
            {
                init();
                _isInit = true;
            }

            if (request.Method == HTTPRequest.METHOD_GET)
            {
                // Input form, this can be place by any HTML page
                sb.Append("<html><body>");
                sb.Append(GenUploadForm());
                sb.Append("</body></html>");
                response.Body = Encoding.UTF8.GetBytes(sb.ToString());
                return(response);
            }
            else if (request.Method == HTTPRequest.METHOD_POST)
            {
                // Get remote image from URL
                string url = Uri.UnescapeDataString(request.GetRequestByKey("imageUploadUrl"));
                byte[] data;
                try {
                    data = DownloadImageFromUrl(url);
                } catch (Exception) {
                    return(new HTTPResponse(400));
                }
                // https://www.codeproject.com/Articles/502829/GPGPU-image-processing-basics-using-OpenCL-NET
                // Convert image to bitmap binary
                Image inputImage = Image.FromStream(new MemoryStream(data));
                if (inputImage == null)
                {
                    return(new HTTPResponse(500));
                }
                int imagewidth  = inputImage.Width;
                int imageHeight = inputImage.Height;

                Bitmap     bmpImage           = new Bitmap(inputImage);
                BitmapData bitmapData         = bmpImage.LockBits(new Rectangle(0, 0, bmpImage.Width, bmpImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                int        inputImageByteSize = bitmapData.Stride * bitmapData.Height;
                byte[]     inputByteArray     = new byte[inputImageByteSize];
                Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, inputImageByteSize);

                // Load kernel source code
                string programPath = System.Environment.CurrentDirectory + "/Kernel.cl";
                if (!System.IO.File.Exists(programPath))
                {
                    return(new HTTPResponse(404));
                }

                string programSource = System.IO.File.ReadAllText(programPath);
                using (OpenCL.Net.Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) {
                    // Create kernel
                    LogError(error, "Cl.CreateProgramWithSource");
                    error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero);
                    LogError(error, "Cl.BuildProgram");
                    if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <OpenCL.Net.BuildStatus>()
                        != BuildStatus.Success)
                    {
                        LogError(error, "Cl.GetProgramBuildInfo");
                        return(new HTTPResponse(404));
                    }
                    Kernel kernel = Cl.CreateKernel(program, _parameters["KernelFunction"], out error);
                    LogError(error, "Cl.CreateKernel");

                    // Create image memory objects
                    OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8);
                    IMem inputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly,
                                                               clImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height,
                                                               (IntPtr)0, inputByteArray, out error);
                    LogError(error, "CreateImage2D input");
                    byte[] outputByteArray     = new byte[inputImageByteSize];
                    IMem   outputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.WriteOnly,
                                                                  clImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height,
                                                                  (IntPtr)0, outputByteArray, out error);
                    LogError(error, "CreateImage2D output");

                    // Set arguments
                    int IntPtrSize = Marshal.SizeOf(typeof(IntPtr));
                    error  = Cl.SetKernelArg(kernel, 0, (IntPtr)IntPtrSize, inputImage2DBuffer);
                    error |= Cl.SetKernelArg(kernel, 1, (IntPtr)IntPtrSize, outputImage2DBuffer);
                    LogError(error, "Cl.SetKernelArg");

                    // Create command queue
                    CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error);
                    LogError(error, "Cl.CreateCommandQueue");
                    Event clevent;

                    // Copy input image from the host to the GPU
                    IntPtr[] originPtr        = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };
                    IntPtr[] regionPtr        = new IntPtr[] { (IntPtr)imagewidth, (IntPtr)imageHeight, (IntPtr)1 };
                    IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)imagewidth, (IntPtr)imageHeight, (IntPtr)1 };
                    error = Cl.EnqueueWriteImage(cmdQueue, inputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0,
                                                 (IntPtr)0, inputByteArray, 0, null, out clevent);
                    LogError(error, "Cl.EnqueueWriteImage");

                    // Run the kernel
                    error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent);
                    LogError(error, "Cl.EnqueueNDRangeKernel");

                    // Wait for finish event
                    error = Cl.Finish(cmdQueue);
                    LogError(error, "Cl.Finish");

                    // Read the output image back from GPU
                    error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0,
                                                (IntPtr)0, outputByteArray, 0, null, out clevent);
                    LogError(error, "Cl.EnqueueReadImage");
                    error = Cl.Finish(cmdQueue);
                    LogError(error, "Cl.Finih");

                    // Release memory
                    Cl.ReleaseKernel(kernel);
                    Cl.ReleaseCommandQueue(cmdQueue);
                    Cl.ReleaseMemObject(inputImage2DBuffer);
                    Cl.ReleaseMemObject(outputImage2DBuffer);

                    // Convert binary bitmap to JPEG image and return as response
                    GCHandle     pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned);
                    IntPtr       outputBmpPointer  = pinnedOutputArray.AddrOfPinnedObject();
                    Bitmap       outputBitmap      = new Bitmap(imagewidth, imageHeight, bitmapData.Stride, PixelFormat.Format32bppArgb, outputBmpPointer);
                    MemoryStream msOutput          = new MemoryStream();
                    outputBitmap.Save(msOutput, System.Drawing.Imaging.ImageFormat.Jpeg);
                    response.Body = msOutput.ToArray();
                    response.Type = "image/jpeg";
                    return(response);
                }
            }
            return(new HTTPResponse(501));
        }
示例#23
0
        public void BlockMutation()
        {
            AssemblyName    assemblyName    = new AssemblyName("UniGPUTestFixture");
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder   moduleBuilder   = assemblyBuilder.DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".dll");
            TypeBuilder     typeBuilder     = moduleBuilder.DefineType("CILBBTypeMutation", TypeAttributes.Public);
            MethodBuilder   methodBuilder   = typeBuilder.DefineMethod("TestCase", MethodAttributes.Public | MethodAttributes.Static,
                                                                       typeof(void), new Type[] { typeof(int), typeof(int[]) });

            methodBuilder.DefineParameter(1, ParameterAttributes.None, "arg");
            methodBuilder.DefineParameter(2, ParameterAttributes.None, "addr");

            ILGenerator il = methodBuilder.GetILGenerator();

            LocalBuilder lb = il.DeclareLocal(typeof(float));

            Label ZERO             = il.DefineLabel();
            Label LOOP             = il.DefineLabel();
            Label LOOP_FLT_MUTATOR = il.DefineLabel();
            Label LOOP_INT_MUTATOR = il.DefineLabel();

            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldc_I4_0);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Brfalse, ZERO);

            il.MarkLabel(LOOP);
            il.Emit(OpCodes.Conv_I2);
            il.Emit(OpCodes.Starg, 0);
            il.Emit(OpCodes.Ldarga, 0);
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Ldind_I4);
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Ldc_I4_2);
            il.Emit(OpCodes.Rem);
            il.Emit(OpCodes.Not);
            il.Emit(OpCodes.Ldc_I4_1);
            il.Emit(OpCodes.And);
            il.Emit(OpCodes.Brtrue, LOOP_FLT_MUTATOR);

            il.MarkLabel(LOOP_INT_MUTATOR);
            il.Emit(OpCodes.Conv_I4);
            il.Emit(OpCodes.Starg, 0);
            il.Emit(OpCodes.Ldind_I4);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Add);
            il.Emit(OpCodes.Ldc_I4_2);
            il.Emit(OpCodes.Div);
            il.Emit(OpCodes.Ldc_I4_M1);
            il.Emit(OpCodes.Neg);
            il.Emit(OpCodes.Sub);
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Ldc_I4_1);
            il.Emit(OpCodes.Bge, LOOP);

            il.Emit(OpCodes.Br, ZERO);

            il.MarkLabel(LOOP_FLT_MUTATOR);
            il.Emit(OpCodes.Conv_R4);
            il.Emit(OpCodes.Stloc_0);
            il.Emit(OpCodes.Pop);
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Ldc_R4, 1.0f);
            il.Emit(OpCodes.Sub);
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Ldc_R4, 1.0f);
            il.Emit(OpCodes.Bge, LOOP);

            il.Emit(OpCodes.Conv_I4);

            il.MarkLabel(ZERO);
            il.Emit(OpCodes.Ldc_I4_1);
            il.Emit(OpCodes.Add);
            il.Emit(OpCodes.Stelem_I4);
            il.Emit(OpCodes.Ret);

            MethodInfo method = typeBuilder.CreateType().GetMethod(methodBuilder.Name);

            int[] res = { 0 };

            method.Invoke(null, new object[] { 8, res });

            //Assert.AreEqual(1, res[0]);

            Cl.Program program = method.BuildIR().ToGPUClProgram(device, context);
            clSafeCall(Cl.BuildProgram(program, 1, new[] { device }, string.Empty, null, IntPtr.Zero));
            Assert.AreEqual(Cl.BuildStatus.Success, Cl.GetProgramBuildInfo(program, device, Cl.ProgramBuildInfo.Status, out error).
                            CastTo <Cl.BuildStatus>());

            Cl.Kernel kernel = Cl.CreateKernel(program, "TestCase", out error);
            clSafeCall(error);

            Cl.Mem cl_res = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly, (IntPtr)sizeof(int), IntPtr.Zero, out error);
            clSafeCall(error);

            Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, (Cl.CommandQueueProperties) 0, out error);
            clSafeCall(error);

            clSafeCall(Cl.SetKernelArg(kernel, 0, 8));
            clSafeCall(Cl.SetKernelArg(kernel, 1, cl_res));

            clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new[] { (IntPtr)1 }, null, 0, null, out clevent));

            clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, cl_res, Cl.Bool.True, IntPtr.Zero, (IntPtr)sizeof(int), res, 0, null, out clevent));

            clSafeCall(Cl.Finish(cmdQueue));

            clSafeCall(Cl.ReleaseMemObject(cl_res));

            program.Dispose();

            Assert.AreEqual(1, res[0]);
        }
示例#24
0
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            uint      platformCount;
            ErrorCode result = Cl.GetPlatformIDs(0, null, out platformCount);

            Console.WriteLine("{0} platforms found", platformCount);


            var platformIds = new Platform[platformCount];

            result = Cl.GetPlatformIDs(platformCount, platformIds, out platformCount);
            var platformCounter = 0;

            foreach (var platformId in platformIds)
            {
                IntPtr paramSize;
                result = Cl.GetPlatformInfo(platformId, PlatformInfo.Name, IntPtr.Zero, InfoBuffer.Empty, out paramSize);

                using (var buffer = new InfoBuffer(paramSize))
                {
                    result = Cl.GetPlatformInfo(platformIds[0], PlatformInfo.Name, paramSize, buffer, out paramSize);

                    Console.WriteLine($"Platform {platformCounter}: {buffer}");
                }
                platformCounter++;
            }

            Console.WriteLine($"Using first platform...");

            uint deviceCount;

            result = Cl.GetDeviceIDs(platformIds[0], DeviceType.All, 0, null, out deviceCount);
            Console.WriteLine("{0} devices found", deviceCount);

            var deviceIds = new Device[deviceCount];

            result = Cl.GetDeviceIDs(platformIds[0], DeviceType.All, deviceCount, deviceIds, out var numberDevices);

            var selectedDevice = deviceIds[0];

            var context = Cl.CreateContext(null, 1, new[] { selectedDevice }, null, IntPtr.Zero, out var error);

            const string kernelSrc = @"
            // Simple test; c[i] = a[i] + b[i]
            __kernel void add_array(__global float *a, __global float *b, __global float *c)
            {
                int xid = get_global_id(0);
                c[xid] = a[xid] + b[xid] - 1500;
            }
            
            __kernel void sub_array(__global float *a, __global float *b, __global float *c)
            {
                int xid = get_global_id(0);
                c[xid] = a[xid] - b[xid] - 2000;
            }
                        
            __kernel void double_everything(__global float *a)
            {
                int xid = get_global_id(0);
                a[xid] = a[xid] * 2;
            }

            ";


            var src = kernelSrc;

            Console.WriteLine("=== src ===");
            Console.WriteLine(src);
            Console.WriteLine("============");

            var program = Cl.CreateProgramWithSource(context, 1, new[] { src }, null, out var error2);

            error2 = Cl.BuildProgram(program, 1, new[] { selectedDevice }, string.Empty, null, IntPtr.Zero);

            if (error2 == ErrorCode.BuildProgramFailure)
            {
                Console.Error.WriteLine(Cl.GetProgramBuildInfo(program, selectedDevice, ProgramBuildInfo.Log, out error));
            }

            Console.WriteLine(error2);

            // Get the kernels.
            var kernels = Cl.CreateKernelsInProgram(program, out error);

            Console.WriteLine($"Program contains {kernels.Length} kernels.");
            var kernelAdd    = kernels[0];
            var kernelDouble = kernels[2];

            //
            float[] A = new float[1000];
            float[] B = new float[1000];
            float[] C = new float[1000];

            for (var i = 0; i < 1000; i++)
            {
                A[i] = i;
                B[i] = i;
            }

            IMem <float> hDeviceMemA = Cl.CreateBuffer(context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, A, out error);
            IMem <float> hDeviceMemB = Cl.CreateBuffer(context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, B, out error);
            IMem <float> hDeviceMemC = Cl.CreateBuffer(context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, C, out error);

            // Create a command queue.
            var cmdQueue = Cl.CreateCommandQueue(context, selectedDevice, CommandQueueProperties.None, out error);

            int intPtrSize = 0;

            intPtrSize = Marshal.SizeOf(typeof(IntPtr));

            error = Cl.SetKernelArg(kernelDouble, 0, new IntPtr(intPtrSize), hDeviceMemA);

            error = Cl.SetKernelArg(kernelAdd, 0, new IntPtr(intPtrSize), hDeviceMemA);
            error = Cl.SetKernelArg(kernelAdd, 1, new IntPtr(intPtrSize), hDeviceMemB);
            error = Cl.SetKernelArg(kernelAdd, 2, new IntPtr(intPtrSize), hDeviceMemC);

            // write data from host to device
            Event clevent;

            error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemA, Bool.True, IntPtr.Zero,
                                          new IntPtr(1000 * sizeof(float)),
                                          A, 0, null, out clevent);
            error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemB, Bool.True, IntPtr.Zero,
                                          new IntPtr(1000 * sizeof(float)),
                                          B, 1, new [] { clevent }, out clevent);

            // execute kernel
            error = Cl.EnqueueNDRangeKernel(cmdQueue, kernelDouble, 1, null, new IntPtr[] { new IntPtr(1000) }, null, 1, new [] { clevent }, out clevent);


            var infoBuffer = Cl.GetEventInfo(clevent, EventInfo.CommandExecutionStatus, out var e2);

            error = Cl.EnqueueNDRangeKernel(cmdQueue, kernelAdd, 1, null, new IntPtr[] { new IntPtr(1000) }, null, 1, new [] { clevent }, out clevent);
            Console.WriteLine($"Run result: {error}");



            error = Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemC, Bool.False, 0, C.Length, C, 1, new [] { clevent }, out clevent);
            Cl.WaitForEvents(1, new [] { clevent });

            for (var i = 0; i < 1000; i++)
            {
                Console.WriteLine($"[{i}]: {C[i]}");
            }

            program.Dispose();

            foreach (var res in typeof(SourceLoader).Assembly.GetManifestResourceNames())
            {
                Console.WriteLine(res);
            }
        }
示例#25
0
        private void init(string oclProgramSourcePath)
        {
            string kernelSource = File.ReadAllText(oclProgramSourcePath);

            string[] kernelNames = new string[] { "accumulate", "quickBlurImgH", "quickBlurImgV", "upsizeImg", "halfSizeImgH", "halfSizeImgV", "getLumaImg", "mapToGreyscaleBmp", "getContrastImg", "capHolesImg", "maxReduceImgH", "maxReduceImgV", "mapToFauxColorsBmp", "quickSpikesFilterImg", "convolveImg" };

            bool gpu = true;

            //err = clGetDeviceIDs(NULL, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &device_id, NULL);
            // NVidia driver doesn't seem to support a NULL first param (properties)
            // http://stackoverflow.com/questions/19140989/how-to-remove-cl-invalid-platform-error-in-opencl-code

            // now get all the platform IDs
            Platform[] platforms = Cl.GetPlatformIDs(out err);
            assert(err, "Error: Failed to get platform ids!");

            InfoBuffer deviceInfo = Cl.GetPlatformInfo(platforms[0], PlatformInfo.Name, out err);

            assert(err, "error retrieving platform name");
            Console.WriteLine("Platform name: {0}\n", deviceInfo.ToString());


            //                                 Arbitrary, should be configurable
            Device[] devices = Cl.GetDeviceIDs(platforms[0], gpu ? DeviceType.Gpu : DeviceType.Cpu, out err);
            assert(err, "Error: Failed to create a device group!");

            _device = devices[0]; // Arbitrary, should be configurable

            deviceInfo = Cl.GetDeviceInfo(_device, DeviceInfo.Name, out err);
            assert(err, "error retrieving device name");
            Debug.WriteLine("Device name: {0}", deviceInfo.ToString());

            deviceInfo = Cl.GetDeviceInfo(_device, DeviceInfo.ImageSupport, out err);
            assert(err, "error retrieving device image capability");
            Debug.WriteLine("Device supports img: {0}", (deviceInfo.CastTo <Bool>() == Bool.True));

            // Create a compute context
            //
            _context = Cl.CreateContext(null, 1, new[] { _device }, ContextNotify, IntPtr.Zero, out err);
            assert(err, "Error: Failed to create a compute context!");

            // Create the compute program from the source buffer
            //
            _program = Cl.CreateProgramWithSource(_context, 1, new[] { kernelSource }, new[] { (IntPtr)kernelSource.Length }, out err);
            assert(err, "Error: Failed to create compute program!");

            // Build the program executable
            //
            err = Cl.BuildProgram(_program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero);
            assert(err, "Error: Failed to build program executable!");
            InfoBuffer buffer = Cl.GetProgramBuildInfo(_program, _device, ProgramBuildInfo.Log, out err);

            Debug.WriteLine("build success: {0}", buffer.CastTo <BuildStatus>() == BuildStatus.Success);

            foreach (string kernelName in kernelNames)
            {
                // Create the compute kernel in the program we wish to run
                //
                OpenCL.Net.Kernel kernel = Cl.CreateKernel(_program, kernelName, out err);
                assert(err, "Error: Failed to create compute kernel!");
                _kernels.Add(kernelName, kernel);
            }

            // Create a command queue
            //
            _commandsQueue = Cl.CreateCommandQueue(_context, _device, CommandQueueProperties.None, out err);
            assert(err, "Error: Failed to create a command commands!");
        }